diff --git a/.gitignore b/.gitignore index 8363e48cdcdc67bad8834a08ec8dd57b8cb41635..fdcce40226d7d4273a08cc4ef84bb25755a710a4 100644 --- a/.gitignore +++ b/.gitignore @@ -53,3 +53,5 @@ cscope.* *.orig *.rej +*~ +\#*# diff --git a/Documentation/00-INDEX b/Documentation/00-INDEX index 30b327a116eaa8d15af97c3047ab2c07ebc41089..fc8e7c7d182f5cbcc179fc5dec2575912ce46653 100644 --- a/Documentation/00-INDEX +++ b/Documentation/00-INDEX @@ -183,8 +183,6 @@ i386/ - directory with info about Linux on Intel 32 bit architecture. ia64/ - directory with info about Linux on Intel 64 bit architecture. -ide.txt - - important info for users of ATA devices (IDE/EIDE disks and CD-ROMS). infiniband/ - directory with documents concerning Linux InfiniBand support. initrd.txt @@ -227,8 +225,6 @@ kprobes.txt - documents the kernel probes debugging feature. kref.txt - docs on adding reference counters (krefs) to kernel objects. -laptop-mode.txt - - how to conserve battery power using laptop-mode. laptops/ - directory with laptop related info and laptop driver documentation. ldm.txt @@ -303,12 +299,8 @@ pcmcia/ - info on the Linux PCMCIA driver. pi-futex.txt - documentation on lightweight PI-futexes. -pm.txt - - info on Linux power management support. pnp.txt - Linux Plug and Play documentation. -power_supply_class.txt - - Tells userspace about battery, UPS, AC or DC power supply properties power/ - directory with info on Linux PCI power management. powerpc/ diff --git a/Documentation/DocBook/kernel-api.tmpl b/Documentation/DocBook/kernel-api.tmpl index f31601e8bd89acba6eaef4d27c5bd45eb2928edf..dc0f30c3e5715d6801e482dc51988fe992d7bf82 100644 --- a/Documentation/DocBook/kernel-api.tmpl +++ b/Documentation/DocBook/kernel-api.tmpl @@ -361,12 +361,14 @@ X!Edrivers/pnp/system.c Block Devices !Eblock/blk-core.c +!Iblock/blk-core.c !Eblock/blk-map.c !Iblock/blk-sysfs.c !Eblock/blk-settings.c !Eblock/blk-exec.c !Eblock/blk-barrier.c !Eblock/blk-tag.c +!Iblock/blk-tag.c diff --git a/Documentation/acpi/dsdt-override.txt b/Documentation/acpi/dsdt-override.txt index 5008f256a2dbec6d642866262bb00ecb0eea65c1..febbb1ba4d2317b984e7217796ac39151f867531 100644 --- a/Documentation/acpi/dsdt-override.txt +++ b/Documentation/acpi/dsdt-override.txt @@ -1,15 +1,7 @@ -Linux supports two methods of overriding the BIOS DSDT: +Linux supports a method of overriding the BIOS DSDT: CONFIG_ACPI_CUSTOM_DSDT builds the image into the kernel. -CONFIG_ACPI_CUSTOM_DSDT_INITRD adds the image to the initrd. - -When to use these methods is described in detail on the +When to use this method is described in detail on the Linux/ACPI home page: http://www.lesswatts.org/projects/acpi/overridingDSDT.php - -Note that if both options are used, the DSDT supplied -by the INITRD method takes precedence. - -Documentation/initramfs-add-dsdt.sh is provided for convenience -for use with the CONFIG_ACPI_CUSTOM_DSDT_INITRD method. diff --git a/Documentation/acpi/initramfs-add-dsdt.sh b/Documentation/acpi/initramfs-add-dsdt.sh deleted file mode 100755 index 17ef6e838e14f90706f567357b6073c4981a196d..0000000000000000000000000000000000000000 --- a/Documentation/acpi/initramfs-add-dsdt.sh +++ /dev/null @@ -1,43 +0,0 @@ -#!/bin/bash -# Adds a DSDT file to the initrd (if it's an initramfs) -# first argument is the name of archive -# second argument is the name of the file to add -# The file will be copied as /DSDT.aml - -# 20060126: fix "Premature end of file" with some old cpio (Roland Robic) -# 20060205: this time it should really work - -# check the arguments -if [ $# -ne 2 ]; then - program_name=$(basename $0) - echo "\ -$program_name: too few arguments -Usage: $program_name initrd-name.img DSDT-to-add.aml -Adds a DSDT file to an initrd (in initramfs format) - - initrd-name.img: filename of the initrd in initramfs format - DSDT-to-add.aml: filename of the DSDT file to add - " 1>&2 - exit 1 -fi - -# we should check it's an initramfs - -tempcpio=$(mktemp -d) -# cleanup on exit, hangup, interrupt, quit, termination -trap 'rm -rf $tempcpio' 0 1 2 3 15 - -# extract the archive -gunzip -c "$1" > "$tempcpio"/initramfs.cpio || exit 1 - -# copy the DSDT file at the root of the directory so that we can call it "/DSDT.aml" -cp -f "$2" "$tempcpio"/DSDT.aml - -# add the file -cd "$tempcpio" -(echo DSDT.aml | cpio --quiet -H newc -o -A -O "$tempcpio"/initramfs.cpio) || exit 1 -cd "$OLDPWD" - -# re-compress the archive -gzip -c "$tempcpio"/initramfs.cpio > "$1" - diff --git a/Documentation/cdrom/ide-cd b/Documentation/cdrom/ide-cd index 29721bfcde129f98a0f35eb51b72582cf776e70c..91c0dcc6fa5ca92d29124951e83f7e8c8b4e3b32 100644 --- a/Documentation/cdrom/ide-cd +++ b/Documentation/cdrom/ide-cd @@ -45,7 +45,7 @@ This driver provides the following features: --------------- 0. The ide-cd relies on the ide disk driver. See - Documentation/ide.txt for up-to-date information on the ide + Documentation/ide/ide.txt for up-to-date information on the ide driver. 1. Make sure that the ide and ide-cd drivers are compiled into the @@ -64,7 +64,7 @@ This driver provides the following features: Depending on what type of IDE interface you have, you may need to specify additional configuration options. See - Documentation/ide.txt. + Documentation/ide/ide.txt. 2. You should also ensure that the iso9660 filesystem is either compiled into the kernel or available as a loadable module. You @@ -84,7 +84,7 @@ This driver provides the following features: on the primary IDE interface are called `hda' and `hdb', respectively. The drives on the secondary interface are called `hdc' and `hdd'. (Interfaces at other locations get other letters - in the third position; see Documentation/ide.txt.) + in the third position; see Documentation/ide/ide.txt.) If you want your CDROM drive to be found automatically by the driver, you should make sure your IDE interface uses either the @@ -93,7 +93,7 @@ This driver provides the following features: be jumpered as `master'. (If for some reason you cannot configure your system in this manner, you can probably still use the driver. You may have to pass extra configuration information to the kernel - when you boot, however. See Documentation/ide.txt for more + when you boot, however. See Documentation/ide/ide.txt for more information.) 4. Boot the system. If the drive is recognized, you should see a @@ -201,7 +201,7 @@ TEST This section discusses some common problems encountered when trying to use the driver, and some possible solutions. Note that if you are experiencing problems, you should probably also review -Documentation/ide.txt for current information about the underlying +Documentation/ide/ide.txt for current information about the underlying IDE support code. Some of these items apply only to earlier versions of the driver, but are mentioned here for completeness. @@ -211,7 +211,7 @@ from the driver. a. Drive is not detected during booting. - Review the configuration instructions above and in - Documentation/ide.txt, and check how your hardware is + Documentation/ide/ide.txt, and check how your hardware is configured. - If your drive is the only device on an IDE interface, it should @@ -219,7 +219,7 @@ a. Drive is not detected during booting. - If your IDE interface is not at the standard addresses of 0x170 or 0x1f0, you'll need to explicitly inform the driver using a - lilo option. See Documentation/ide.txt. (This feature was + lilo option. See Documentation/ide/ide.txt. (This feature was added around kernel version 1.3.30.) - If the autoprobing is not finding your drive, you can tell the @@ -245,7 +245,7 @@ a. Drive is not detected during booting. Support for some interfaces needing extra initialization is provided in later 1.3.x kernels. You may need to turn on additional kernel configuration options to get them to work; - see Documentation/ide.txt. + see Documentation/ide/ide.txt. Even if support is not available for your interface, you may be able to get it to work with the following procedure. First boot @@ -299,7 +299,7 @@ c. System hangups. be worked around by specifying the `serialize' option when booting. Recent kernels should be able to detect the need for this automatically in most cases, but the detection is not - foolproof. See Documentation/ide.txt for more information + foolproof. See Documentation/ide/ide.txt for more information about the `serialize' option and the CMD640B. - Note that many MS-DOS CDROM drivers will work with such buggy diff --git a/Documentation/controllers/memory.txt b/Documentation/controllers/memory.txt index 6015347b41e2676378be5fc029444b35a2ae3664..866b9cd9a9590d6b6b8c3d577038e8d51234082b 100644 --- a/Documentation/controllers/memory.txt +++ b/Documentation/controllers/memory.txt @@ -1,4 +1,8 @@ -Memory Controller +Memory Resource Controller + +NOTE: The Memory Resource Controller has been generically been referred +to as the memory controller in this document. Do not confuse memory controller +used here with the memory controller that is used in hardware. Salient features @@ -152,7 +156,7 @@ The memory controller uses the following hierarchy a. Enable CONFIG_CGROUPS b. Enable CONFIG_RESOURCE_COUNTERS -c. Enable CONFIG_CGROUP_MEM_CONT +c. Enable CONFIG_CGROUP_MEM_RES_CTLR 1. Prepare the cgroups # mkdir -p /cgroups @@ -164,7 +168,7 @@ c. Enable CONFIG_CGROUP_MEM_CONT Since now we're in the 0 cgroup, We can alter the memory limit: -# echo -n 4M > /cgroups/0/memory.limit_in_bytes +# echo 4M > /cgroups/0/memory.limit_in_bytes NOTE: We can use a suffix (k, K, m, M, g or G) to indicate values in kilo, mega or gigabytes. @@ -185,7 +189,7 @@ number of factors, such as rounding up to page boundaries or the total availability of memory on the system. The user is required to re-read this file after a write to guarantee the value committed by the kernel. -# echo -n 1 > memory.limit_in_bytes +# echo 1 > memory.limit_in_bytes # cat memory.limit_in_bytes 4096 @@ -197,7 +201,7 @@ caches, RSS and Active pages/Inactive pages are shown. The memory.force_empty gives an interface to drop *all* charges by force. -# echo -n 1 > memory.force_empty +# echo 1 > memory.force_empty will drop all charges in cgroup. Currently, this is maintained for test. diff --git a/Documentation/debugging-via-ohci1394.txt b/Documentation/debugging-via-ohci1394.txt index de4804e8b396eb29000b37dd8fa575f5cd7dee8d..c360d4e91b4892d6be5a6ed5efcb981d4a3ad19f 100644 --- a/Documentation/debugging-via-ohci1394.txt +++ b/Documentation/debugging-via-ohci1394.txt @@ -36,14 +36,15 @@ available (notebooks) or too slow for extensive debug information (like ACPI). Drivers ------- -The OHCI-1394 drivers in drivers/firewire and drivers/ieee1394 initialize -the OHCI-1394 controllers to a working state and can be used to enable -physical DMA. By default you only have to load the driver, and physical -DMA access will be granted to all remote nodes, but it can be turned off -when using the ohci1394 driver. - -Because these drivers depend on the PCI enumeration to be completed, an -initialization routine which can runs pretty early (long before console_init(), +The ohci1394 driver in drivers/ieee1394 initializes the OHCI-1394 controllers +to a working state and enables physical DMA by default for all remote nodes. +This can be turned off by ohci1394's module parameter phys_dma=0. + +The alternative firewire-ohci driver in drivers/firewire uses filtered physical +DMA, hence is not yet suitable for remote debugging. + +Because ohci1394 depends on the PCI enumeration to be completed, an +initialization routine which runs pretty early (long before console_init() which makes the printk buffer appear on the console can be called) was written. To activate it, enable CONFIG_PROVIDE_OHCI1394_DMA_INIT (Kernel hacking menu: diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt index 7279595b96c3e031e6906ca6187fbc5dc0b080c3..9119d037c2ce11bd31bbbaf6d7d42932132daedb 100644 --- a/Documentation/feature-removal-schedule.txt +++ b/Documentation/feature-removal-schedule.txt @@ -172,6 +172,16 @@ Who: Len Brown --------------------------- +What: ide-tape driver +When: July 2008 +Files: drivers/ide/ide-tape.c +Why: This driver might not have any users anymore and maintaining it for no + reason is an effort no one wants to make. +Who: Bartlomiej Zolnierkiewicz , Borislav Petkov + + +--------------------------- + What: libata spindown skipping and warning When: Dec 2008 Why: Some halt(8) implementations synchronize caches for and spin @@ -279,3 +289,15 @@ Why: Largely unmaintained and almost entirely unused. File system is largely pointless as without a lot of work only the most trivial of Solaris binaries can work with the emulation code. Who: David S. Miller + +--------------------------- + +What: init_mm export +When: 2.6.26 +Why: Not used in-tree. The current out-of-tree users used it to + work around problems in the CPA code which should be resolved + by now. One usecase was described to provide verification code + of the CPA operation. That's a good idea in general, but such + code / infrastructure should be in the kernel and not in some + out-of-tree driver. +Who: Thomas Gleixner diff --git a/Documentation/filesystems/proc.txt b/Documentation/filesystems/proc.txt index 5681e2fa1496167e6f876b6dab39e9605597a117..518ebe609e2b1c9392580c9ae840d5da4aa84e68 100644 --- a/Documentation/filesystems/proc.txt +++ b/Documentation/filesystems/proc.txt @@ -1506,13 +1506,13 @@ laptop_mode ----------- laptop_mode is a knob that controls "laptop mode". All the things that are -controlled by this knob are discussed in Documentation/laptop-mode.txt. +controlled by this knob are discussed in Documentation/laptops/laptop-mode.txt. block_dump ---------- block_dump enables block I/O debugging when set to a nonzero value. More -information on block I/O debugging is in Documentation/laptop-mode.txt. +information on block I/O debugging is in Documentation/laptops/laptop-mode.txt. swap_token_timeout ------------------ diff --git a/Documentation/gpio.txt b/Documentation/gpio.txt index 8da724e2a0ff795d450e8b0b7b61118d7bf604a6..54630095aa3c8f841c097e723eef518f660a30a7 100644 --- a/Documentation/gpio.txt +++ b/Documentation/gpio.txt @@ -2,6 +2,9 @@ GPIO Interfaces This provides an overview of GPIO access conventions on Linux. +These calls use the gpio_* naming prefix. No other calls should use that +prefix, or the related __gpio_* prefix. + What is a GPIO? =============== @@ -69,11 +72,13 @@ in this document, but drivers acting as clients to the GPIO interface must not care how it's implemented.) That said, if the convention is supported on their platform, drivers should -use it when possible. Platforms should declare GENERIC_GPIO support in -Kconfig (boolean true), which multi-platform drivers can depend on when -using the include file: +use it when possible. Platforms must declare GENERIC_GPIO support in their +Kconfig (boolean true), and provide an file. Drivers that can't +work without standard GPIO calls should have Kconfig entries which depend +on GENERIC_GPIO. The GPIO calls are available, either as "real code" or as +optimized-away stubs, when drivers use the include file: - #include + #include If you stick to this convention then it'll be easier for other developers to see what your code is doing, and help maintain it. @@ -316,6 +321,9 @@ pulldowns integrated on some platforms. Not all platforms support them, or support them in the same way; and any given board might use external pullups (or pulldowns) so that the on-chip ones should not be used. (When a circuit needs 5 kOhm, on-chip 100 kOhm resistors won't do.) +Likewise drive strength (2 mA vs 20 mA) and voltage (1.8V vs 3.3V) is a +platform-specific issue, as are models like (not) having a one-to-one +correspondence between configurable pins and GPIOs. There are other system-specific mechanisms that are not specified here, like the aforementioned options for input de-glitching and wire-OR output. diff --git a/Documentation/ide/00-INDEX b/Documentation/ide/00-INDEX new file mode 100644 index 0000000000000000000000000000000000000000..d6b778842b754c31dbf14460bf6b8ed09ad34c53 --- /dev/null +++ b/Documentation/ide/00-INDEX @@ -0,0 +1,12 @@ +00-INDEX + - this file +ChangeLog.ide-cd.1994-2004 + - ide-cd changelog +ChangeLog.ide-floppy.1996-2002 + - ide-floppy changelog +ChangeLog.ide-tape.1995-2002 + - ide-tape changelog +ide-tape.txt + - info on the IDE ATAPI streaming tape driver +ide.txt + - important info for users of ATA devices (IDE/EIDE disks and CD-ROMS). diff --git a/Documentation/ide.txt b/Documentation/ide/ide.txt similarity index 88% rename from Documentation/ide.txt rename to Documentation/ide/ide.txt index 94e2e3b9e77f03ebcb0a3d0b146e53397a6fcfc0..e3b3425328b6185f611b2d926893f273720a88ed 100644 --- a/Documentation/ide.txt +++ b/Documentation/ide/ide.txt @@ -3,11 +3,11 @@ ============================================================================== - + The hdparm utility can be used to control various IDE features on a running system. It is packaged separately. Please Look for it on popular linux FTP sites. - + *** IMPORTANT NOTICES: BUGGY IDE CHIPSETS CAN CORRUPT DATA!! @@ -51,7 +51,7 @@ Common pitfalls: ================================================================================ -This is the multiple IDE interface driver, as evolved from hd.c. +This is the multiple IDE interface driver, as evolved from hd.c. It supports up to 9 IDE interfaces per default, on one or more IRQs (usually 14 & 15). There can be up to two drives per interface, as per the ATA-6 spec. @@ -215,17 +215,17 @@ Summary of ide driver parameters for kernel command line -------------------------------------------------------- "hdx=" is recognized for all "x" from "a" to "h", such as "hdc". - + "idex=" is recognized for all "x" from "0" to "3", such as "ide1". "hdx=noprobe" : drive may be present, but do not probe for it - + "hdx=none" : drive is NOT present, ignore cmos and do not probe - + "hdx=nowerr" : ignore the WRERR_STAT bit on this drive - + "hdx=cdrom" : drive is present, and is a cdrom drive - + "hdx=cyl,head,sect" : disk drive is present, with specified geometry "hdx=remap" : remap access of sector 0 to sector 1 (for EZDrive) @@ -258,12 +258,10 @@ Summary of ide driver parameters for kernel command line As for VLB, it is safest to not specify it. Bigger values are safer than smaller ones. - "idex=noprobe" : do not attempt to access/use this interface - "idex=base" : probe for an interface at the addr specified, where "base" is usually 0x1f0 or 0x170 and "ctl" is assumed to be "base"+0x206 - + "idex=base,ctl" : specify both base and ctl "idex=base,ctl,irq" : specify base, ctl, and irq number @@ -274,7 +272,7 @@ Summary of ide driver parameters for kernel command line to take effect. "idex=four" : four drives on idex and ide(x^1) share same ports - + "idex=reset" : reset interface after probe "idex=ata66" : informs the interface that it has an 80c cable @@ -307,53 +305,6 @@ Also for legacy CMD640 host driver (cmd640) you need to use "probe_vlb" kernel paremeter to enable probing for VLB version of the chipset (PCI ones are detected automatically). -================================================================================ - -IDE ATAPI streaming tape driver -------------------------------- - -This driver is a part of the Linux ide driver and works in co-operation -with linux/drivers/block/ide.c. - -The driver, in co-operation with ide.c, basically traverses the -request-list for the block device interface. The character device -interface, on the other hand, creates new requests, adds them -to the request-list of the block device, and waits for their completion. - -Pipelined operation mode is now supported on both reads and writes. - -The block device major and minor numbers are determined from the -tape's relative position in the ide interfaces, as explained in ide.c. - -The character device interface consists of the following devices: - - ht0 major 37, minor 0 first IDE tape, rewind on close. - ht1 major 37, minor 1 second IDE tape, rewind on close. - ... - nht0 major 37, minor 128 first IDE tape, no rewind on close. - nht1 major 37, minor 129 second IDE tape, no rewind on close. - ... - -Run /dev/MAKEDEV to create the above entries. - -The general magnetic tape commands compatible interface, as defined by -include/linux/mtio.h, is accessible through the character device. - -General ide driver configuration options, such as the interrupt-unmask -flag, can be configured by issuing an ioctl to the block device interface, -as any other ide device. - -Our own ide-tape ioctl's can be issued to either the block device or -the character device interface. - -Maximal throughput with minimal bus load will usually be achieved in the -following scenario: - - 1. ide-tape is operating in the pipelined operation mode. - 2. No buffering is performed by the user backup program. - - - ================================================================================ Some Terminology diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index 9a5b6658c65e0ee4a6b55df39da68d5836e9889b..622f7849edb968024f6879927aa7c6a2e008f695 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt @@ -138,7 +138,7 @@ and is between 256 and 4096 characters. It is defined in the file strict -- Be less tolerant of platforms that are not strictly ACPI specification compliant. - See also Documentation/pm.txt, pci=noacpi + See also Documentation/power/pm.txt, pci=noacpi acpi_apic_instance= [ACPI, IOAPIC] Format: @@ -177,9 +177,6 @@ and is between 256 and 4096 characters. It is defined in the file acpi_no_auto_ssdt [HW,ACPI] Disable automatic loading of SSDT - acpi_no_initrd_override [KNL,ACPI] - Disable loading custom ACPI tables from the initramfs - acpi_os_name= [HW,ACPI] Tell ACPI BIOS the name of the OS Format: To spoof as Windows 98: ="Microsoft Windows" @@ -712,7 +709,7 @@ and is between 256 and 4096 characters. It is defined in the file Format: ,, hd?= [HW] (E)IDE subsystem - hd?lun= See Documentation/ide.txt. + hd?lun= See Documentation/ide/ide.txt. highmem=nn[KMG] [KNL,BOOT] forces the highmem zone to have an exact size of . This works even on boxes that have no @@ -766,14 +763,14 @@ and is between 256 and 4096 characters. It is defined in the file ide= [HW] (E)IDE subsystem Format: ide=nodma or ide=doubler or ide=reverse - See Documentation/ide.txt. + See Documentation/ide/ide.txt. ide?= [HW] (E)IDE subsystem Format: ide?=noprobe or chipset specific parameters. - See Documentation/ide.txt. + See Documentation/ide/ide.txt. idebus= [HW] (E)IDE subsystem - VLB/PCI bus speed - See Documentation/ide.txt. + See Documentation/ide/ide.txt. idle= [X86] Format: idle=poll or idle=mwait diff --git a/Documentation/kprobes.txt b/Documentation/kprobes.txt index 83f515c2905a806d88276ea587da5d9ef5196c52..be89f393274fbd086a4f14b4e56bb82c0a29c76d 100644 --- a/Documentation/kprobes.txt +++ b/Documentation/kprobes.txt @@ -192,7 +192,8 @@ code mapping. The Kprobes API includes a "register" function and an "unregister" function for each type of probe. Here are terse, mini-man-page specifications for these functions and the associated probe handlers -that you'll write. See the latter half of this document for examples. +that you'll write. See the files in the samples/kprobes/ sub-directory +for examples. 4.1 register_kprobe @@ -420,249 +421,15 @@ e. Watchpoint probes (which fire on data references). 8. Kprobes Example -Here's a sample kernel module showing the use of kprobes to dump a -stack trace and selected i386 registers when do_fork() is called. ------ cut here ----- -/*kprobe_example.c*/ -#include -#include -#include -#include - -/*For each probe you need to allocate a kprobe structure*/ -static struct kprobe kp; - -/*kprobe pre_handler: called just before the probed instruction is executed*/ -int handler_pre(struct kprobe *p, struct pt_regs *regs) -{ - printk("pre_handler: p->addr=0x%p, eip=%lx, eflags=0x%lx\n", - p->addr, regs->eip, regs->eflags); - dump_stack(); - return 0; -} - -/*kprobe post_handler: called after the probed instruction is executed*/ -void handler_post(struct kprobe *p, struct pt_regs *regs, unsigned long flags) -{ - printk("post_handler: p->addr=0x%p, eflags=0x%lx\n", - p->addr, regs->eflags); -} - -/* fault_handler: this is called if an exception is generated for any - * instruction within the pre- or post-handler, or when Kprobes - * single-steps the probed instruction. - */ -int handler_fault(struct kprobe *p, struct pt_regs *regs, int trapnr) -{ - printk("fault_handler: p->addr=0x%p, trap #%dn", - p->addr, trapnr); - /* Return 0 because we don't handle the fault. */ - return 0; -} - -static int __init kprobe_init(void) -{ - int ret; - kp.pre_handler = handler_pre; - kp.post_handler = handler_post; - kp.fault_handler = handler_fault; - kp.symbol_name = "do_fork"; - - ret = register_kprobe(&kp); - if (ret < 0) { - printk("register_kprobe failed, returned %d\n", ret); - return ret; - } - printk("kprobe registered\n"); - return 0; -} - -static void __exit kprobe_exit(void) -{ - unregister_kprobe(&kp); - printk("kprobe unregistered\n"); -} - -module_init(kprobe_init) -module_exit(kprobe_exit) -MODULE_LICENSE("GPL"); ------ cut here ----- - -You can build the kernel module, kprobe-example.ko, using the following -Makefile: ------ cut here ----- -obj-m := kprobe-example.o -KDIR := /lib/modules/$(shell uname -r)/build -PWD := $(shell pwd) -default: - $(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules -clean: - rm -f *.mod.c *.ko *.o ------ cut here ----- - -$ make -$ su - -... -# insmod kprobe-example.ko - -You will see the trace data in /var/log/messages and on the console -whenever do_fork() is invoked to create a new process. +See samples/kprobes/kprobe_example.c 9. Jprobes Example -Here's a sample kernel module showing the use of jprobes to dump -the arguments of do_fork(). ------ cut here ----- -/*jprobe-example.c */ -#include -#include -#include -#include -#include - -/* - * Jumper probe for do_fork. - * Mirror principle enables access to arguments of the probed routine - * from the probe handler. - */ - -/* Proxy routine having the same arguments as actual do_fork() routine */ -long jdo_fork(unsigned long clone_flags, unsigned long stack_start, - struct pt_regs *regs, unsigned long stack_size, - int __user * parent_tidptr, int __user * child_tidptr) -{ - printk("jprobe: clone_flags=0x%lx, stack_size=0x%lx, regs=0x%p\n", - clone_flags, stack_size, regs); - /* Always end with a call to jprobe_return(). */ - jprobe_return(); - /*NOTREACHED*/ - return 0; -} - -static struct jprobe my_jprobe = { - .entry = jdo_fork -}; - -static int __init jprobe_init(void) -{ - int ret; - my_jprobe.kp.symbol_name = "do_fork"; - - if ((ret = register_jprobe(&my_jprobe)) <0) { - printk("register_jprobe failed, returned %d\n", ret); - return -1; - } - printk("Planted jprobe at %p, handler addr %p\n", - my_jprobe.kp.addr, my_jprobe.entry); - return 0; -} - -static void __exit jprobe_exit(void) -{ - unregister_jprobe(&my_jprobe); - printk("jprobe unregistered\n"); -} - -module_init(jprobe_init) -module_exit(jprobe_exit) -MODULE_LICENSE("GPL"); ------ cut here ----- - -Build and insert the kernel module as shown in the above kprobe -example. You will see the trace data in /var/log/messages and on -the console whenever do_fork() is invoked to create a new process. -(Some messages may be suppressed if syslogd is configured to -eliminate duplicate messages.) +See samples/kprobes/jprobe_example.c 10. Kretprobes Example -Here's a sample kernel module showing the use of return probes to -report failed calls to sys_open(). ------ cut here ----- -/*kretprobe-example.c*/ -#include -#include -#include -#include - -/* per-instance private data */ -struct my_data { - ktime_t entry_stamp; -}; - -static const char *probed_func = "sys_open"; - -/* Timestamp function entry. */ -static int entry_handler(struct kretprobe_instance *ri, struct pt_regs *regs) -{ - struct my_data *data; - - if(!current->mm) - return 1; /* skip kernel threads */ - - data = (struct my_data *)ri->data; - data->entry_stamp = ktime_get(); - return 0; -} - -/* If the probed function failed, log the return value and duration. - * Duration may turn out to be zero consistently, depending upon the - * granularity of time accounting on the platform. */ -static int return_handler(struct kretprobe_instance *ri, struct pt_regs *regs) -{ - int retval = regs_return_value(regs); - struct my_data *data = (struct my_data *)ri->data; - s64 delta; - ktime_t now; - - if (retval < 0) { - now = ktime_get(); - delta = ktime_to_ns(ktime_sub(now, data->entry_stamp)); - printk("%s: return val = %d (duration = %lld ns)\n", - probed_func, retval, delta); - } - return 0; -} - -static struct kretprobe my_kretprobe = { - .handler = return_handler, - .entry_handler = entry_handler, - .data_size = sizeof(struct my_data), - .maxactive = 20, /* probe up to 20 instances concurrently */ -}; - -static int __init kretprobe_init(void) -{ - int ret; - my_kretprobe.kp.symbol_name = (char *)probed_func; - - if ((ret = register_kretprobe(&my_kretprobe)) < 0) { - printk("register_kretprobe failed, returned %d\n", ret); - return -1; - } - printk("Kretprobe active on %s\n", my_kretprobe.kp.symbol_name); - return 0; -} - -static void __exit kretprobe_exit(void) -{ - unregister_kretprobe(&my_kretprobe); - printk("kretprobe unregistered\n"); - /* nmissed > 0 suggests that maxactive was set too low. */ - printk("Missed probing %d instances of %s\n", - my_kretprobe.nmissed, probed_func); -} - -module_init(kretprobe_init) -module_exit(kretprobe_exit) -MODULE_LICENSE("GPL"); ------ cut here ----- - -Build and insert the kernel module as shown in the above kprobe -example. You will see the trace data in /var/log/messages and on the -console whenever sys_open() returns a negative value. (Some messages -may be suppressed if syslogd is configured to eliminate duplicate -messages.) +See samples/kprobes/kretprobe_example.c For additional information on Kprobes, refer to the following URLs: http://www-106.ibm.com/developerworks/library/l-kprobes.html?ca=dgr-lnxw42Kprobe diff --git a/Documentation/laptops/00-INDEX b/Documentation/laptops/00-INDEX index 729c2c062e109ab0d57a5b8760d4a29821cb9943..ee5692b26dd4d629901cabc387e791c0576df243 100644 --- a/Documentation/laptops/00-INDEX +++ b/Documentation/laptops/00-INDEX @@ -2,6 +2,8 @@ - This file acer-wmi.txt - information on the Acer Laptop WMI Extras driver. +laptop-mode.txt + - how to conserve battery power using laptop-mode. sony-laptop.txt - Sony Notebook Control Driver (SNC) Readme. sonypi.txt diff --git a/Documentation/laptops/acer-wmi.txt b/Documentation/laptops/acer-wmi.txt index 68ef0fc047871fa0723ef28e89a5844f1c7d79e0..79b7dbd2214190ae9bf9bce988faa176491c5bce 100644 --- a/Documentation/laptops/acer-wmi.txt +++ b/Documentation/laptops/acer-wmi.txt @@ -48,7 +48,7 @@ DSDT. To send me the DSDT, as root/sudo: -cat /sys/firmware/acpi/DSDT > dsdt +cat /sys/firmware/acpi/tables/DSDT > dsdt And send me the resulting 'dsdt' file. @@ -169,7 +169,7 @@ can be added to acer-wmi. The LED is exposed through the LED subsystem, and can be found in: -/sys/devices/platform/acer-wmi/leds/acer-mail:green/ +/sys/devices/platform/acer-wmi/leds/acer-wmi::mail/ The mail LED is autodetected, so if you don't have one, the LED device won't be registered. diff --git a/Documentation/laptop-mode.txt b/Documentation/laptops/laptop-mode.txt similarity index 100% rename from Documentation/laptop-mode.txt rename to Documentation/laptops/laptop-mode.txt diff --git a/Documentation/lguest/lguest.c b/Documentation/lguest/lguest.c index 0f23d67f958ff5b6ee96a0248fdd2c9b9ab65586..bec5a32e4095d705ee16d6bd9a538b4fdaadfe52 100644 --- a/Documentation/lguest/lguest.c +++ b/Documentation/lguest/lguest.c @@ -486,9 +486,12 @@ static void concat(char *dst, char *args[]) unsigned int i, len = 0; for (i = 0; args[i]; i++) { + if (i) { + strcat(dst+len, " "); + len++; + } strcpy(dst+len, args[i]); - strcat(dst+len, " "); - len += strlen(args[i]) + 1; + len += strlen(args[i]); } /* In case it's empty. */ dst[len] = '\0'; diff --git a/Documentation/pci.txt b/Documentation/pci.txt index 72b20c63959651ce7be7dad2f2e854c983f660e0..d2c2e6e2b224ce4bcb84d3870cddfba85cb3b979 100644 --- a/Documentation/pci.txt +++ b/Documentation/pci.txt @@ -123,7 +123,8 @@ initialization with a pointer to a structure describing the driver The ID table is an array of struct pci_device_id entries ending with an -all-zero entry. Each entry consists of: +all-zero entry; use of the macro DEFINE_PCI_DEVICE_TABLE is the preferred +method of declaring the table. Each entry consists of: vendor,device Vendor and device ID to match (or PCI_ANY_ID) @@ -191,7 +192,8 @@ Tips on when/where to use the above attributes: o Do not mark the struct pci_driver. - o The ID table array should be marked __devinitdata. + o The ID table array should be marked __devinitconst; this is done + automatically if the table is declared with DEFINE_PCI_DEVICE_TABLE(). o The probe() and remove() functions should be marked __devinit and __devexit respectively. All initialization functions diff --git a/Documentation/power/00-INDEX b/Documentation/power/00-INDEX index 8db4e41a052d9a9df37bfa39dc5dda1a7b1d12a1..a55d7f1c836d7de2ad0b09b9ea2c138562db01a6 100644 --- a/Documentation/power/00-INDEX +++ b/Documentation/power/00-INDEX @@ -14,6 +14,12 @@ notifiers.txt - Registering suspend notifiers in device drivers pci.txt - How the PCI Subsystem Does Power Management +pm.txt + - info on Linux power management support. +pm_qos_interface.txt + - info on Linux PM Quality of Service interface +power_supply_class.txt + - Tells userspace about battery, UPS, AC or DC power supply properties s2ram.txt - How to get suspend to ram working (and debug it when it isn't) states.txt diff --git a/Documentation/pm.txt b/Documentation/power/pm.txt similarity index 99% rename from Documentation/pm.txt rename to Documentation/power/pm.txt index da8589a0e07df08b77ae15c5bb83f7800f9b2bdf..be841507e43fa0745f6c6eef55e06356ae725709 100644 --- a/Documentation/pm.txt +++ b/Documentation/power/pm.txt @@ -108,7 +108,7 @@ void pm_unregister_all(pm_callback cback); * EINVAL if the request is not supported * EBUSY if the device is now busy and cannot handle the request * ENOMEM if the device was unable to handle the request due to memory - * + * * Details: The device request callback will be called before the * device/system enters a suspend state (ACPI D1-D3) or * or after the device/system resumes from suspend (ACPI D0). diff --git a/Documentation/pm_qos_interface.txt b/Documentation/power/pm_qos_interface.txt similarity index 100% rename from Documentation/pm_qos_interface.txt rename to Documentation/power/pm_qos_interface.txt diff --git a/Documentation/power_supply_class.txt b/Documentation/power/power_supply_class.txt similarity index 100% rename from Documentation/power_supply_class.txt rename to Documentation/power/power_supply_class.txt diff --git a/Documentation/scheduler/sched-stats.txt b/Documentation/scheduler/sched-stats.txt index 442e14d35dea272f6906d65723055b82d0566ef3..01e69404ee5e14bd4bb41cb4d81abb22a13ccc40 100644 --- a/Documentation/scheduler/sched-stats.txt +++ b/Documentation/scheduler/sched-stats.txt @@ -142,7 +142,7 @@ of idleness (idle, busy, and newly idle): /proc//schedstat ---------------- -schedstats also adds a new /proc//schedstat file to include some of the same information on a per-process level. There are three fields in this file correlating for that process to: 1) time spent on the cpu diff --git a/Documentation/scsi/ChangeLog.arcmsr b/Documentation/scsi/ChangeLog.arcmsr index de2bcacfa870a6f1e3bc94369fda343db1e8b4a7..038a3e6ecaa43d5c064061734ea7e893675893e9 100644 --- a/Documentation/scsi/ChangeLog.arcmsr +++ b/Documentation/scsi/ChangeLog.arcmsr @@ -109,4 +109,10 @@ ** 8.replace pci_alloc_consistent()/pci_free_consistent() with kmalloc()/kfree() in arcmsr_iop_message_xfer() ** 9. fix the release of dma memory for type B in arcmsr_free_ccb_pool() ** 10.fix the arcmsr_polling_hbb_ccbdone() +** 1.20.00.15 02/27/2008 Erich Chen & Nick Cheng +** 1.arcmsr_iop_message_xfer() is called from atomic context under the +** queuecommand scsi_host_template handler. James Bottomley pointed out +** that the current GFP_KERNEL|GFP_DMA flags are wrong: firstly we are in +** atomic context, secondly this memory is not used for DMA. +** Also removed some unneeded casts. Thanks to Daniel Drake ************************************************************************** diff --git a/Documentation/thermal/sysfs-api.txt b/Documentation/thermal/sysfs-api.txt index ba9c2da5a8c200fbb6a27b84c7a2f85a441e979d..d9f28be75403cea53c07cfe8e965074a71037619 100644 --- a/Documentation/thermal/sysfs-api.txt +++ b/Documentation/thermal/sysfs-api.txt @@ -143,10 +143,10 @@ type Strings which represent the thermal zone type. This is given by thermal zone driver as part of registration. Eg: "ACPI thermal zone" indicates it's a ACPI thermal device RO - Optional + Required temp Current temperature as reported by thermal zone (sensor) - Unit: degree Celsius + Unit: millidegree Celsius RO Required @@ -163,7 +163,7 @@ mode One of the predefined values in [kernel, user] charge of the thermal management. trip_point_[0-*]_temp The temperature above which trip point will be fired - Unit: degree Celsius + Unit: millidegree Celsius RO Optional @@ -193,7 +193,7 @@ type String which represents the type of device eg. For memory controller device on intel_menlow platform: this should be "Memory controller" RO - Optional + Required max_state The maximum permissible cooling state of this cooling device. RO @@ -219,16 +219,16 @@ the sys I/F structure will be built like this: |thermal_zone1: |-----type: ACPI thermal zone - |-----temp: 37 + |-----temp: 37000 |-----mode: kernel - |-----trip_point_0_temp: 100 + |-----trip_point_0_temp: 100000 |-----trip_point_0_type: critical - |-----trip_point_1_temp: 80 + |-----trip_point_1_temp: 80000 |-----trip_point_1_type: passive - |-----trip_point_2_temp: 70 - |-----trip_point_2_type: active[0] - |-----trip_point_3_temp: 60 - |-----trip_point_3_type: active[1] + |-----trip_point_2_temp: 70000 + |-----trip_point_2_type: active0 + |-----trip_point_3_temp: 60000 + |-----trip_point_3_type: active1 |-----cdev0: --->/sys/class/thermal/cooling_device0 |-----cdev0_trip_point: 1 /* cdev0 can be used for passive */ |-----cdev1: --->/sys/class/thermal/cooling_device3 diff --git a/Documentation/usb/usb-help.txt b/Documentation/usb/usb-help.txt index a7408593829feb51c205f35b5647b961a8334a24..4273ca2b86bade2aa6c33b145bfa7035a61602db 100644 --- a/Documentation/usb/usb-help.txt +++ b/Documentation/usb/usb-help.txt @@ -1,5 +1,5 @@ usb-help.txt -2000-July-12 +2008-Mar-7 For USB help other than the readme files that are located in Documentation/usb/*, see the following: @@ -10,9 +10,7 @@ Linux-USB project: http://www.linux-usb.org Linux USB Guide: http://linux-usb.sourceforge.net Linux-USB device overview (working devices and drivers): http://www.qbik.ch/usb/devices/ - -The Linux-USB mailing lists are: - linux-usb-users@lists.sourceforge.net for general user help - linux-usb-devel@lists.sourceforge.net for developer discussions + +The Linux-USB mailing list is at linux-usb@vger.kernel.org ### diff --git a/Documentation/vm/slub.txt b/Documentation/vm/slub.txt index dcf8bcf846d6a5486b737c840b4dce7d71ae89e2..7c13f22a0c9ee44aac54dd0c40ea65a828a545d9 100644 --- a/Documentation/vm/slub.txt +++ b/Documentation/vm/slub.txt @@ -50,14 +50,14 @@ F.e. in order to boot just with sanity checks and red zoning one would specify: Trying to find an issue in the dentry cache? Try - slub_debug=,dentry_cache + slub_debug=,dentry to only enable debugging on the dentry cache. Red zoning and tracking may realign the slab. We can just apply sanity checks to the dentry cache with - slub_debug=F,dentry_cache + slub_debug=F,dentry In case you forgot to enable debugging on the kernel command line: It is possible to enable debugging manually when the kernel is up. Look at the diff --git a/MAINTAINERS b/MAINTAINERS index b9fc1f620f29d24ad9732ae544099ea430ba419f..c13408ccaf9c76c2e1083dc60202840c9c77a201 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -266,6 +266,15 @@ L: linux-acpi@vger.kernel.org W: http://www.lesswatts.org/projects/acpi/ S: Maintained +AD1889 ALSA SOUND DRIVER +P: Kyle McMartin +M: kyle@parisc-linux.org +P: Thibaut Varene +M: T-Bone@parisc-linux.org +W: http://wiki.parisc-linux.org/AD1889 +L: linux-parisc@vger.kernel.org +S: Maintained + ADM1025 HARDWARE MONITOR DRIVER P: Jean Delvare M: khali@linux-fr.org @@ -767,14 +776,14 @@ S: Maintained BLACKFIN ARCHITECTURE P: Bryan Wu -M: bryan.wu@analog.com +M: cooloney@kernel.org L: uclinux-dist-devel@blackfin.uclinux.org (subscribers-only) W: http://blackfin.uclinux.org S: Supported BLACKFIN EMAC DRIVER P: Bryan Wu -M: bryan.wu@analog.com +M: cooloney@kernel.org L: uclinux-dist-devel@blackfin.uclinux.org (subscribers-only) W: http://blackfin.uclinux.org S: Supported @@ -1129,6 +1138,12 @@ L: accessrunner-general@lists.sourceforge.net W: http://accessrunner.sourceforge.net/ S: Maintained +CONTROL GROUPS (CGROUPS) +P: Paul Menage +M: menage@google.com +L: containers@lists.linux-foundation.org +S: Maintained + CORETEMP HARDWARE MONITORING DRIVER P: Rudolf Marek M: r.marek@assembler.cz @@ -1580,6 +1595,13 @@ L: linux-fbdev-devel@lists.sourceforge.net (moderated for non-subscribers) W: http://linux-fbdev.sourceforge.net/ S: Maintained +FREESCALE DMA DRIVER +P; Zhang Wei +M: wei.zhang@freescale.com +L: linuxppc-embedded@ozlabs.org +L: linux-kernel@vger.kernel.org +S: Maintained + FREESCALE SOC FS_ENET DRIVER P: Pantelis Antoniou M: pantelis.antoniou@gmail.com @@ -2110,7 +2132,7 @@ L: netdev@vger.kernel.org S: Maintained IPATH DRIVER: -P: Arthur Jones +P: Ralph Campbell M: infinipath@qlogic.com L: general@lists.openfabrics.org T: git git://git.qlogic.com/ipath-linux-2.6 @@ -2593,6 +2615,17 @@ L: linux-kernel@vger.kernel.org W: http://www.linux-mm.org S: Maintained +MEMORY RESOURCE CONTROLLER +P: Balbir Singh +M: balbir@linux.vnet.ibm.com +P: Pavel Emelyanov +M: xemul@openvz.org +P: KAMEZAWA Hiroyuki +M: kamezawa.hiroyu@jp.fujitsu.com +L: linux-mm@kvack.org +L: linux-kernel@vger.kernel.org +S: Maintained + MEI MN10300/AM33 PORT P: David Howells M: dhowells@redhat.com @@ -2717,6 +2750,8 @@ S: Maintained NETEFFECT IWARP RNIC DRIVER (IW_NES) P: Faisal Latif M: flatif@neteffect.com +P: Nishi Gupta +M: ngupta@neteffect.com P: Glenn Streiff M: gstreiff@neteffect.com L: general@lists.openfabrics.org diff --git a/Makefile b/Makefile index a22978413b6558793a9d605abf95cd65dd672699..7a4d34b91e032099d119adae92a0f347dc481901 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ VERSION = 2 PATCHLEVEL = 6 SUBLEVEL = 25 -EXTRAVERSION = -rc3 +EXTRAVERSION = -rc6 NAME = Funky Weasel is Jiggy wit it # *DOCUMENTATION* diff --git a/arch/Kconfig b/arch/Kconfig index 3d72dc3fc8f52f5d822cc6c256e21fb21e2b4f61..694c9af520bbed3e9a36a6c16aa693f541b192b8 100644 --- a/arch/Kconfig +++ b/arch/Kconfig @@ -27,5 +27,12 @@ config KPROBES for kernel debugging, non-intrusive instrumentation and testing. If in doubt, say "N". +config KRETPROBES + def_bool y + depends on KPROBES && HAVE_KRETPROBES + config HAVE_KPROBES def_bool n + +config HAVE_KRETPROBES + def_bool n diff --git a/arch/alpha/Kconfig b/arch/alpha/Kconfig index 002703b8c0b033d72eea6297b869796f772c2c6e..729cdbdf8036203d99c1b59728aedf37d7a5349f 100644 --- a/arch/alpha/Kconfig +++ b/arch/alpha/Kconfig @@ -330,6 +330,9 @@ config PCI_DOMAINS config PCI_SYSCALL def_bool PCI +config IOMMU_HELPER + def_bool PCI + config ALPHA_CORE_AGP bool depends on ALPHA_GENERIC || ALPHA_TITAN || ALPHA_MARVEL diff --git a/arch/alpha/kernel/pci_iommu.c b/arch/alpha/kernel/pci_iommu.c index 26d3789dfdd0420bc4e7ce496995138b1decda14..4e1c08636edd66b4c08b58aee5c358b55a0c382c 100644 --- a/arch/alpha/kernel/pci_iommu.c +++ b/arch/alpha/kernel/pci_iommu.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #include @@ -31,7 +32,6 @@ #endif #define DEBUG_NODIRECT 0 -#define DEBUG_FORCEDAC 0 #define ISA_DMA_MASK 0x00ffffff @@ -128,37 +128,55 @@ iommu_arena_new(struct pci_controller *hose, dma_addr_t base, /* Must be called with the arena lock held */ static long -iommu_arena_find_pages(struct pci_iommu_arena *arena, long n, long mask) +iommu_arena_find_pages(struct device *dev, struct pci_iommu_arena *arena, + long n, long mask) { unsigned long *ptes; long i, p, nent; + int pass = 0; + unsigned long base; + unsigned long boundary_size; + + base = arena->dma_base >> PAGE_SHIFT; + if (dev) { + boundary_size = dma_get_seg_boundary(dev) + 1; + boundary_size >>= PAGE_SHIFT; + } else { + boundary_size = 1UL << (32 - PAGE_SHIFT); + } /* Search forward for the first mask-aligned sequence of N free ptes */ ptes = arena->ptes; nent = arena->size >> PAGE_SHIFT; - p = (arena->next_entry + mask) & ~mask; + p = ALIGN(arena->next_entry, mask + 1); i = 0; + +again: while (i < n && p+i < nent) { + if (!i && iommu_is_span_boundary(p, n, base, boundary_size)) { + p = ALIGN(p + 1, mask + 1); + goto again; + } + if (ptes[p+i]) - p = (p + i + 1 + mask) & ~mask, i = 0; + p = ALIGN(p + i + 1, mask + 1), i = 0; else i = i + 1; } if (i < n) { - /* Reached the end. Flush the TLB and restart the - search from the beginning. */ - alpha_mv.mv_pci_tbi(arena->hose, 0, -1); - - p = 0, i = 0; - while (i < n && p+i < nent) { - if (ptes[p+i]) - p = (p + i + 1 + mask) & ~mask, i = 0; - else - i = i + 1; - } - - if (i < n) + if (pass < 1) { + /* + * Reached the end. Flush the TLB and restart + * the search from the beginning. + */ + alpha_mv.mv_pci_tbi(arena->hose, 0, -1); + + pass++; + p = 0; + i = 0; + goto again; + } else return -1; } @@ -168,7 +186,8 @@ iommu_arena_find_pages(struct pci_iommu_arena *arena, long n, long mask) } static long -iommu_arena_alloc(struct pci_iommu_arena *arena, long n, unsigned int align) +iommu_arena_alloc(struct device *dev, struct pci_iommu_arena *arena, long n, + unsigned int align) { unsigned long flags; unsigned long *ptes; @@ -179,7 +198,7 @@ iommu_arena_alloc(struct pci_iommu_arena *arena, long n, unsigned int align) /* Search for N empty ptes */ ptes = arena->ptes; mask = max(align, arena->align_entry) - 1; - p = iommu_arena_find_pages(arena, n, mask); + p = iommu_arena_find_pages(dev, arena, n, mask); if (p < 0) { spin_unlock_irqrestore(&arena->lock, flags); return -1; @@ -229,6 +248,7 @@ pci_map_single_1(struct pci_dev *pdev, void *cpu_addr, size_t size, unsigned long paddr; dma_addr_t ret; unsigned int align = 0; + struct device *dev = pdev ? &pdev->dev : NULL; paddr = __pa(cpu_addr); @@ -276,7 +296,7 @@ pci_map_single_1(struct pci_dev *pdev, void *cpu_addr, size_t size, /* Force allocation to 64KB boundary for ISA bridges. */ if (pdev && pdev == isa_bridge) align = 8; - dma_ofs = iommu_arena_alloc(arena, npages, align); + dma_ofs = iommu_arena_alloc(dev, arena, npages, align); if (dma_ofs < 0) { printk(KERN_WARNING "pci_map_single failed: " "could not allocate dma page tables\n"); @@ -563,7 +583,7 @@ sg_fill(struct device *dev, struct scatterlist *leader, struct scatterlist *end, paddr &= ~PAGE_MASK; npages = calc_npages(paddr + size); - dma_ofs = iommu_arena_alloc(arena, npages, 0); + dma_ofs = iommu_arena_alloc(dev, arena, npages, 0); if (dma_ofs < 0) { /* If we attempted a direct map above but failed, die. */ if (leader->dma_address == 0) @@ -830,7 +850,7 @@ iommu_reserve(struct pci_iommu_arena *arena, long pg_count, long align_mask) /* Search for N empty ptes. */ ptes = arena->ptes; - p = iommu_arena_find_pages(arena, pg_count, align_mask); + p = iommu_arena_find_pages(NULL, arena, pg_count, align_mask); if (p < 0) { spin_unlock_irqrestore(&arena->lock, flags); return -1; diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 9619c43783ffd333ad8346aa6e9b85f0de750d7e..955fc53c1c019e1c47acf52251bdb30fa36cceb1 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -12,6 +12,7 @@ config ARM select SYS_SUPPORTS_APM_EMULATION select HAVE_OPROFILE select HAVE_KPROBES if (!XIP_KERNEL) + select HAVE_KRETPROBES if (HAVE_KPROBES) help The ARM series is a line of low-power-consumption RISC chip designs licensed by ARM Ltd and targeted at embedded applications and @@ -939,7 +940,8 @@ config KEXEC config ATAGS_PROC bool "Export atags in procfs" - default n + depends on KEXEC + default y help Should the atags used to boot the kernel be exported in an "atags" file in procfs. Useful with kexec. diff --git a/arch/arm/Makefile b/arch/arm/Makefile index 7b8ff66febe1ffe27f9f734a3a7f45b58e86a464..1a4649667ec8d420a541ee55c9a88c9b4bf8d5d8 100644 --- a/arch/arm/Makefile +++ b/arch/arm/Makefile @@ -251,6 +251,7 @@ define archhelp echo '* zImage - Compressed kernel image (arch/$(ARCH)/boot/zImage)' echo ' Image - Uncompressed kernel image (arch/$(ARCH)/boot/Image)' echo '* xipImage - XIP kernel image, if configured (arch/$(ARCH)/boot/xipImage)' + echo ' uImage - U-Boot wrapped zImage' echo ' bootpImage - Combined zImage and initial RAM disk' echo ' (supply initrd image via make variable INITRD=)' echo ' install - Install uncompressed kernel' diff --git a/arch/arm/common/it8152.c b/arch/arm/common/it8152.c index 97b7dc13d9aa9832e94995874293ed22332be748..538262241483202545dad88ac247b427b9e6c3b6 100644 --- a/arch/arm/common/it8152.c +++ b/arch/arm/common/it8152.c @@ -274,7 +274,7 @@ static int it8152_pci_platform_notify_remove(struct device *dev) int dma_needs_bounce(struct device *dev, dma_addr_t dma_addr, size_t size) { dev_dbg(dev, "%s: dma_addr %08x, size %08x\n", - __FUNCTION__, dma_addr, size); + __func__, dma_addr, size); return (dev->bus == &pci_bus_type) && ((dma_addr + size - PHYS_OFFSET) >= SZ_64M); } @@ -289,7 +289,7 @@ int dma_needs_bounce(struct device *dev, dma_addr_t dma_addr, size_t size) */ int pci_set_dma_mask(struct pci_dev *dev, u64 mask) { - dev_dbg(&dev->dev, "%s: %llx\n", __FUNCTION__, mask); + dev_dbg(&dev->dev, "%s: %llx\n", __func__, mask); if (mask >= PHYS_OFFSET + SZ_64M - 1) return 0; @@ -299,7 +299,7 @@ int pci_set_dma_mask(struct pci_dev *dev, u64 mask) int pci_set_consistent_dma_mask(struct pci_dev *dev, u64 mask) { - dev_dbg(&dev->dev, "%s: %llx\n", __FUNCTION__, mask); + dev_dbg(&dev->dev, "%s: %llx\n", __func__, mask); if (mask >= PHYS_OFFSET + SZ_64M - 1) return 0; diff --git a/arch/arm/configs/omap_h2_1610_defconfig b/arch/arm/configs/omap_h2_1610_defconfig index c2345af3707a0b825e2017ffabe83d25aaccc3a1..323c1deeb9536005323c963c52a2fd4ba20c5fe1 100644 --- a/arch/arm/configs/omap_h2_1610_defconfig +++ b/arch/arm/configs/omap_h2_1610_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.24-rc5 -# Mon Dec 17 20:04:38 2007 +# Linux kernel version: 2.6.25-rc3 +# Mon Mar 3 03:39:48 2008 # CONFIG_ARM=y CONFIG_SYS_SUPPORTS_APM_EMULATION=y @@ -21,6 +21,7 @@ CONFIG_RWSEM_GENERIC_SPINLOCK=y # CONFIG_ARCH_HAS_ILOG2_U64 is not set CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_ARCH_SUPPORTS_AOUT=y CONFIG_ZONE_DMA=y CONFIG_VECTORS_BASE=0xffff0000 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" @@ -40,17 +41,22 @@ CONFIG_SYSVIPC_SYSCTL=y # CONFIG_POSIX_MQUEUE is not set # CONFIG_BSD_PROCESS_ACCT is not set # CONFIG_TASKSTATS is not set -# CONFIG_USER_NS is not set -# CONFIG_PID_NS is not set # CONFIG_AUDIT is not set # CONFIG_IKCONFIG is not set CONFIG_LOG_BUF_SHIFT=14 # CONFIG_CGROUPS is not set +CONFIG_GROUP_SCHED=y CONFIG_FAIR_GROUP_SCHED=y -CONFIG_FAIR_USER_SCHED=y -# CONFIG_FAIR_CGROUP_SCHED is not set +# CONFIG_RT_GROUP_SCHED is not set +CONFIG_USER_SCHED=y +# CONFIG_CGROUP_SCHED is not set # CONFIG_SYSFS_DEPRECATED is not set # CONFIG_RELAY is not set +CONFIG_NAMESPACES=y +# CONFIG_UTS_NS is not set +# CONFIG_IPC_NS is not set +# CONFIG_USER_NS is not set +# CONFIG_PID_NS is not set CONFIG_BLK_DEV_INITRD=y CONFIG_INITRAMFS_SOURCE="" CONFIG_CC_OPTIMIZE_FOR_SIZE=y @@ -64,17 +70,26 @@ CONFIG_HOTPLUG=y CONFIG_PRINTK=y CONFIG_BUG=y CONFIG_ELF_CORE=y +CONFIG_COMPAT_BRK=y CONFIG_BASE_FULL=y CONFIG_FUTEX=y CONFIG_ANON_INODES=y CONFIG_EPOLL=y CONFIG_SIGNALFD=y +CONFIG_TIMERFD=y CONFIG_EVENTFD=y CONFIG_SHMEM=y CONFIG_VM_EVENT_COUNTERS=y CONFIG_SLAB=y # CONFIG_SLUB is not set # CONFIG_SLOB is not set +# CONFIG_PROFILING is not set +# CONFIG_MARKERS is not set +CONFIG_HAVE_OPROFILE=y +# CONFIG_KPROBES is not set +CONFIG_HAVE_KPROBES=y +CONFIG_PROC_PAGE_MONITOR=y +CONFIG_SLABINFO=y CONFIG_RT_MUTEXES=y # CONFIG_TINY_SHMEM is not set CONFIG_BASE_SMALL=0 @@ -102,6 +117,8 @@ CONFIG_DEFAULT_AS=y # CONFIG_DEFAULT_CFQ is not set # CONFIG_DEFAULT_NOOP is not set CONFIG_DEFAULT_IOSCHED="anticipatory" +CONFIG_CLASSIC_RCU=y +# CONFIG_PREEMPT_RCU is not set # # System Type @@ -130,6 +147,7 @@ CONFIG_DEFAULT_IOSCHED="anticipatory" # CONFIG_ARCH_KS8695 is not set # CONFIG_ARCH_NS9XXX is not set # CONFIG_ARCH_MXC is not set +# CONFIG_ARCH_ORION is not set # CONFIG_ARCH_PNX4008 is not set # CONFIG_ARCH_PXA is not set # CONFIG_ARCH_RPC is not set @@ -139,6 +157,7 @@ CONFIG_DEFAULT_IOSCHED="anticipatory" # CONFIG_ARCH_LH7A40X is not set # CONFIG_ARCH_DAVINCI is not set CONFIG_ARCH_OMAP=y +# CONFIG_ARCH_MSM7X00A is not set # # TI OMAP Implementations @@ -155,6 +174,7 @@ CONFIG_OMAP_MUX=y # CONFIG_OMAP_MUX_DEBUG is not set CONFIG_OMAP_MUX_WARNINGS=y CONFIG_OMAP_MCBSP=y +# CONFIG_OMAP_MMU_FWK is not set # CONFIG_OMAP_MPU_TIMER is not set CONFIG_OMAP_32K_TIMER=y CONFIG_OMAP_32K_TIMER_HZ=128 @@ -266,6 +286,7 @@ CONFIG_ZBOOT_ROM_BSS=0x0 CONFIG_CMDLINE="mem=32M console=ttyS0,115200n8 root=0801 ro init=/bin/sh" # CONFIG_XIP_KERNEL is not set # CONFIG_KEXEC is not set +# CONFIG_ATAGS_PROC is not set # # CPU Frequency scaling @@ -311,9 +332,10 @@ CONFIG_PM=y # CONFIG_PM_LEGACY is not set # CONFIG_PM_DEBUG is not set CONFIG_PM_SLEEP=y -CONFIG_SUSPEND_UP_POSSIBLE=y CONFIG_SUSPEND=y +CONFIG_SUSPEND_FREEZER=y # CONFIG_APM_EMULATION is not set +CONFIG_ARCH_SUSPEND_POSSIBLE=y # # Networking @@ -330,6 +352,7 @@ CONFIG_XFRM=y # CONFIG_XFRM_USER is not set # CONFIG_XFRM_SUB_POLICY is not set # CONFIG_XFRM_MIGRATE is not set +# CONFIG_XFRM_STATISTICS is not set # CONFIG_NET_KEY is not set CONFIG_INET=y # CONFIG_IP_MULTICAST is not set @@ -384,6 +407,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # # CONFIG_NET_PKTGEN is not set # CONFIG_HAMRADIO is not set +# CONFIG_CAN is not set # CONFIG_IRDA is not set # CONFIG_BT is not set # CONFIG_AF_RXRPC is not set @@ -421,11 +445,13 @@ CONFIG_BLK_DEV_LOOP=y CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_COUNT=16 CONFIG_BLK_DEV_RAM_SIZE=8192 -CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 +# CONFIG_BLK_DEV_XIP is not set # CONFIG_CDROM_PKTCDVD is not set CONFIG_ATA_OVER_ETH=m CONFIG_MISC_DEVICES=y # CONFIG_EEPROM_93CX6 is not set +# CONFIG_ENCLOSURE_SERVICES is not set +# CONFIG_HAVE_IDE is not set # # SCSI device support @@ -489,6 +515,7 @@ CONFIG_SMC91X=y # CONFIG_IBM_NEW_EMAC_EMAC4 is not set # CONFIG_B44 is not set CONFIG_NETDEV_1000=y +# CONFIG_E1000E_ENABLED is not set CONFIG_NETDEV_10000=y # @@ -512,7 +539,6 @@ CONFIG_SLIP_COMPRESSED=y CONFIG_SLHC=y # CONFIG_SLIP_SMART is not set # CONFIG_SLIP_MODE_SLIP6 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 @@ -616,12 +642,10 @@ CONFIG_I2C_OMAP=y # # Miscellaneous I2C Chip support # -# CONFIG_SENSORS_DS1337 is not set -# CONFIG_SENSORS_DS1374 is not set # CONFIG_DS1682 is not set # CONFIG_SENSORS_EEPROM is not set # CONFIG_SENSORS_PCF8574 is not set -# CONFIG_SENSORS_PCA9539 is not set +# CONFIG_PCF8575 is not set # CONFIG_SENSORS_PCF8591 is not set # CONFIG_ISP1301_OMAP is not set CONFIG_TPS65010=y @@ -649,6 +673,7 @@ CONFIG_HWMON=y # CONFIG_SENSORS_ADM1031 is not set # CONFIG_SENSORS_ADM9240 is not set # CONFIG_SENSORS_ADT7470 is not set +# CONFIG_SENSORS_ADT7473 is not set # CONFIG_SENSORS_ATXP1 is not set # CONFIG_SENSORS_DS1621 is not set # CONFIG_SENSORS_F71805F is not set @@ -676,6 +701,7 @@ CONFIG_HWMON=y # CONFIG_SENSORS_SMSC47M1 is not set # CONFIG_SENSORS_SMSC47M192 is not set # CONFIG_SENSORS_SMSC47B397 is not set +# CONFIG_SENSORS_ADS7828 is not set # CONFIG_SENSORS_THMC50 is not set # CONFIG_SENSORS_VT1211 is not set # CONFIG_SENSORS_W83781D is not set @@ -683,6 +709,7 @@ CONFIG_HWMON=y # CONFIG_SENSORS_W83792D is not set # CONFIG_SENSORS_W83793 is not set # CONFIG_SENSORS_W83L785TS is not set +# CONFIG_SENSORS_W83L786NG is not set # CONFIG_SENSORS_W83627HF is not set # CONFIG_SENSORS_W83627EHF is not set # CONFIG_HWMON_DEBUG_CHIP is not set @@ -705,6 +732,7 @@ CONFIG_SSB_POSSIBLE=y # Multifunction device drivers # # CONFIG_MFD_SM501 is not set +# CONFIG_MFD_ASIC3 is not set # # Multimedia devices @@ -802,10 +830,6 @@ CONFIG_USB_ARCH_HAS_OHCI=y # # NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' # - -# -# USB Gadget Support -# # CONFIG_USB_GADGET is not set # CONFIG_MMC is not set # CONFIG_NEW_LEDS is not set @@ -826,12 +850,10 @@ CONFIG_EXT2_FS=y # CONFIG_XFS_FS is not set # CONFIG_GFS2_FS is not set # CONFIG_OCFS2_FS is not set -# CONFIG_MINIX_FS is not set -CONFIG_ROMFS_FS=y +CONFIG_DNOTIFY=y CONFIG_INOTIFY=y CONFIG_INOTIFY_USER=y # CONFIG_QUOTA is not set -CONFIG_DNOTIFY=y # CONFIG_AUTOFS_FS is not set # CONFIG_AUTOFS4_FS is not set # CONFIG_FUSE_FS is not set @@ -874,8 +896,10 @@ CONFIG_SYSFS=y # CONFIG_EFS_FS is not set CONFIG_CRAMFS=y # CONFIG_VXFS_FS is not set +# CONFIG_MINIX_FS is not set # CONFIG_HPFS_FS is not set # CONFIG_QNX4FS_FS is not set +CONFIG_ROMFS_FS=y # CONFIG_SYSV_FS is not set # CONFIG_UFS_FS is not set CONFIG_NETWORK_FILESYSTEMS=y @@ -946,9 +970,6 @@ CONFIG_NLS_ISO8859_1=y # CONFIG_NLS_KOI8_U is not set # CONFIG_NLS_UTF8 is not set # CONFIG_DLM is not set -CONFIG_INSTRUMENTATION=y -# CONFIG_PROFILING is not set -# CONFIG_MARKERS is not set # # Kernel hacking @@ -975,6 +996,7 @@ CONFIG_FRAME_POINTER=y CONFIG_CRYPTO=y CONFIG_CRYPTO_ALGAPI=y CONFIG_CRYPTO_BLKCIPHER=y +# CONFIG_CRYPTO_SEQIV is not set CONFIG_CRYPTO_MANAGER=y # CONFIG_CRYPTO_HMAC is not set # CONFIG_CRYPTO_XCBC is not set @@ -992,6 +1014,9 @@ CONFIG_CRYPTO_CBC=y CONFIG_CRYPTO_PCBC=m # CONFIG_CRYPTO_LRW is not set # CONFIG_CRYPTO_XTS is not set +# CONFIG_CRYPTO_CTR is not set +# CONFIG_CRYPTO_GCM is not set +# CONFIG_CRYPTO_CCM is not set # CONFIG_CRYPTO_CRYPTD is not set CONFIG_CRYPTO_DES=y # CONFIG_CRYPTO_FCRYPT is not set @@ -1006,12 +1031,14 @@ CONFIG_CRYPTO_DES=y # CONFIG_CRYPTO_KHAZAD is not set # CONFIG_CRYPTO_ANUBIS is not set # CONFIG_CRYPTO_SEED is not set +# CONFIG_CRYPTO_SALSA20 is not set # CONFIG_CRYPTO_DEFLATE is not set # CONFIG_CRYPTO_MICHAEL_MIC is not set # CONFIG_CRYPTO_CRC32C is not set # CONFIG_CRYPTO_CAMELLIA is not set # CONFIG_CRYPTO_TEST is not set # CONFIG_CRYPTO_AUTHENC is not set +# CONFIG_CRYPTO_LZO is not set CONFIG_CRYPTO_HW=y # diff --git a/arch/arm/configs/omap_osk_5912_defconfig b/arch/arm/configs/omap_osk_5912_defconfig index d592a64871144e82e66a415be8f205cda2142920..d4ca5e6e4ffa7b4472f5254b3c75dffaff53cf2d 100644 --- a/arch/arm/configs/omap_osk_5912_defconfig +++ b/arch/arm/configs/omap_osk_5912_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.24-rc5 -# Mon Dec 17 21:12:45 2007 +# Linux kernel version: 2.6.25-rc3 +# Mon Mar 3 03:35:17 2008 # CONFIG_ARM=y CONFIG_SYS_SUPPORTS_APM_EMULATION=y @@ -21,6 +21,7 @@ CONFIG_RWSEM_GENERIC_SPINLOCK=y # CONFIG_ARCH_HAS_ILOG2_U64 is not set CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_ARCH_SUPPORTS_AOUT=y CONFIG_ZONE_DMA=y CONFIG_VECTORS_BASE=0xffff0000 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" @@ -39,17 +40,22 @@ CONFIG_SYSVIPC_SYSCTL=y # CONFIG_POSIX_MQUEUE is not set # CONFIG_BSD_PROCESS_ACCT is not set # CONFIG_TASKSTATS is not set -# CONFIG_USER_NS is not set -# CONFIG_PID_NS is not set # CONFIG_AUDIT is not set # CONFIG_IKCONFIG is not set CONFIG_LOG_BUF_SHIFT=14 # CONFIG_CGROUPS is not set +CONFIG_GROUP_SCHED=y CONFIG_FAIR_GROUP_SCHED=y -CONFIG_FAIR_USER_SCHED=y -# CONFIG_FAIR_CGROUP_SCHED is not set +# CONFIG_RT_GROUP_SCHED is not set +CONFIG_USER_SCHED=y +# CONFIG_CGROUP_SCHED is not set # CONFIG_SYSFS_DEPRECATED is not set # CONFIG_RELAY is not set +CONFIG_NAMESPACES=y +# CONFIG_UTS_NS is not set +# CONFIG_IPC_NS is not set +# CONFIG_USER_NS is not set +# CONFIG_PID_NS is not set CONFIG_BLK_DEV_INITRD=y CONFIG_INITRAMFS_SOURCE="" CONFIG_CC_OPTIMIZE_FOR_SIZE=y @@ -63,17 +69,26 @@ CONFIG_HOTPLUG=y CONFIG_PRINTK=y CONFIG_BUG=y CONFIG_ELF_CORE=y +CONFIG_COMPAT_BRK=y CONFIG_BASE_FULL=y CONFIG_FUTEX=y CONFIG_ANON_INODES=y CONFIG_EPOLL=y CONFIG_SIGNALFD=y +CONFIG_TIMERFD=y CONFIG_EVENTFD=y CONFIG_SHMEM=y CONFIG_VM_EVENT_COUNTERS=y CONFIG_SLAB=y # CONFIG_SLUB is not set # CONFIG_SLOB is not set +# CONFIG_PROFILING is not set +# CONFIG_MARKERS is not set +CONFIG_HAVE_OPROFILE=y +# CONFIG_KPROBES is not set +CONFIG_HAVE_KPROBES=y +CONFIG_PROC_PAGE_MONITOR=y +CONFIG_SLABINFO=y CONFIG_RT_MUTEXES=y # CONFIG_TINY_SHMEM is not set CONFIG_BASE_SMALL=0 @@ -101,6 +116,8 @@ CONFIG_IOSCHED_CFQ=y CONFIG_DEFAULT_CFQ=y # CONFIG_DEFAULT_NOOP is not set CONFIG_DEFAULT_IOSCHED="cfq" +CONFIG_CLASSIC_RCU=y +# CONFIG_PREEMPT_RCU is not set # # System Type @@ -129,6 +146,7 @@ CONFIG_DEFAULT_IOSCHED="cfq" # CONFIG_ARCH_KS8695 is not set # CONFIG_ARCH_NS9XXX is not set # CONFIG_ARCH_MXC is not set +# CONFIG_ARCH_ORION is not set # CONFIG_ARCH_PNX4008 is not set # CONFIG_ARCH_PXA is not set # CONFIG_ARCH_RPC is not set @@ -138,6 +156,7 @@ CONFIG_DEFAULT_IOSCHED="cfq" # CONFIG_ARCH_LH7A40X is not set # CONFIG_ARCH_DAVINCI is not set CONFIG_ARCH_OMAP=y +# CONFIG_ARCH_MSM7X00A is not set # # TI OMAP Implementations @@ -154,6 +173,7 @@ CONFIG_OMAP_MUX=y # CONFIG_OMAP_MUX_DEBUG is not set CONFIG_OMAP_MUX_WARNINGS=y CONFIG_OMAP_MCBSP=y +# CONFIG_OMAP_MMU_FWK is not set # CONFIG_OMAP_MPU_TIMER is not set CONFIG_OMAP_32K_TIMER=y CONFIG_OMAP_32K_TIMER_HZ=128 @@ -173,13 +193,13 @@ CONFIG_ARCH_OMAP16XX=y # # OMAP Board Type # -# CONFIG_MACH_OMAP_INNOVATOR is not set -# CONFIG_MACH_OMAP_H2 is not set -# CONFIG_MACH_OMAP_H3 is not set +CONFIG_MACH_OMAP_INNOVATOR=y +CONFIG_MACH_OMAP_H2=y +CONFIG_MACH_OMAP_H3=y CONFIG_MACH_OMAP_OSK=y # CONFIG_OMAP_OSK_MISTRAL is not set -# CONFIG_MACH_NOKIA770 is not set -# CONFIG_MACH_OMAP_GENERIC is not set +CONFIG_MACH_NOKIA770=y +CONFIG_MACH_OMAP_GENERIC=y # # OMAP CPU Speed @@ -275,6 +295,7 @@ CONFIG_ZBOOT_ROM_BSS=0x0 CONFIG_CMDLINE="mem=32M console=ttyS0,115200 initrd=0x10400000,8M root=/dev/ram0 rw" # CONFIG_XIP_KERNEL is not set # CONFIG_KEXEC is not set +# CONFIG_ATAGS_PROC is not set # # CPU Frequency scaling @@ -307,9 +328,10 @@ CONFIG_PM=y # CONFIG_PM_LEGACY is not set # CONFIG_PM_DEBUG is not set CONFIG_PM_SLEEP=y -CONFIG_SUSPEND_UP_POSSIBLE=y CONFIG_SUSPEND=y +CONFIG_SUSPEND_FREEZER=y # CONFIG_APM_EMULATION is not set +CONFIG_ARCH_SUSPEND_POSSIBLE=y # # Networking @@ -326,6 +348,7 @@ CONFIG_XFRM=y # CONFIG_XFRM_USER is not set # CONFIG_XFRM_SUB_POLICY is not set # CONFIG_XFRM_MIGRATE is not set +# CONFIG_XFRM_STATISTICS is not set # CONFIG_NET_KEY is not set CONFIG_INET=y CONFIG_IP_MULTICAST=y @@ -381,6 +404,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # # CONFIG_NET_PKTGEN is not set # CONFIG_HAMRADIO is not set +# CONFIG_CAN is not set # CONFIG_IRDA is not set # CONFIG_BT is not set # CONFIG_AF_RXRPC is not set @@ -493,11 +517,13 @@ CONFIG_BLK_DEV_LOOP=y CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_COUNT=16 CONFIG_BLK_DEV_RAM_SIZE=8192 -CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 +# CONFIG_BLK_DEV_XIP is not set # CONFIG_CDROM_PKTCDVD is not set # CONFIG_ATA_OVER_ETH is not set CONFIG_MISC_DEVICES=y # CONFIG_EEPROM_93CX6 is not set +# CONFIG_ENCLOSURE_SERVICES is not set +CONFIG_HAVE_IDE=y CONFIG_IDE=m CONFIG_BLK_DEV_IDE=m @@ -519,7 +545,6 @@ CONFIG_IDE_PROC_FS=y # # CONFIG_IDE_GENERIC is not set # CONFIG_BLK_DEV_PLATFORM is not set -# CONFIG_IDE_ARM is not set # CONFIG_BLK_DEV_IDEDMA is not set CONFIG_IDE_ARCH_OBSOLETE_INIT=y # CONFIG_BLK_DEV_HD is not set @@ -553,6 +578,7 @@ CONFIG_SMC91X=y # CONFIG_IBM_NEW_EMAC_EMAC4 is not set # CONFIG_B44 is not set CONFIG_NETDEV_1000=y +# CONFIG_E1000E_ENABLED is not set CONFIG_NETDEV_10000=y # @@ -574,7 +600,6 @@ CONFIG_PPP_MULTILINK=y # CONFIG_PPPOL2TP is not set # CONFIG_SLIP is not set CONFIG_SLHC=y -# CONFIG_SHAPER is not set # CONFIG_NETCONSOLE is not set # CONFIG_NETPOLL is not set # CONFIG_NET_POLL_CONTROLLER is not set @@ -671,6 +696,7 @@ CONFIG_HW_RANDOM_OMAP=m # CONFIG_SYNCLINK_CS is not set # CONFIG_CARDMAN_4000 is not set # CONFIG_CARDMAN_4040 is not set +# CONFIG_IPWIRELESS is not set # CONFIG_RAW_DRIVER is not set # CONFIG_TCG_TPM is not set CONFIG_I2C=y @@ -698,12 +724,10 @@ CONFIG_I2C_OMAP=y # # Miscellaneous I2C Chip support # -# CONFIG_SENSORS_DS1337 is not set -# CONFIG_SENSORS_DS1374 is not set # CONFIG_DS1682 is not set # CONFIG_SENSORS_EEPROM is not set # CONFIG_SENSORS_PCF8574 is not set -# CONFIG_SENSORS_PCA9539 is not set +# CONFIG_PCF8575 is not set # CONFIG_SENSORS_PCF8591 is not set # CONFIG_ISP1301_OMAP is not set CONFIG_TPS65010=y @@ -731,6 +755,7 @@ CONFIG_HWMON=y # CONFIG_SENSORS_ADM1031 is not set # CONFIG_SENSORS_ADM9240 is not set # CONFIG_SENSORS_ADT7470 is not set +# CONFIG_SENSORS_ADT7473 is not set # CONFIG_SENSORS_ATXP1 is not set # CONFIG_SENSORS_DS1621 is not set # CONFIG_SENSORS_F71805F is not set @@ -758,6 +783,7 @@ CONFIG_HWMON=y # CONFIG_SENSORS_SMSC47M1 is not set # CONFIG_SENSORS_SMSC47M192 is not set # CONFIG_SENSORS_SMSC47B397 is not set +# CONFIG_SENSORS_ADS7828 is not set # CONFIG_SENSORS_THMC50 is not set # CONFIG_SENSORS_VT1211 is not set # CONFIG_SENSORS_W83781D is not set @@ -765,6 +791,7 @@ CONFIG_HWMON=y # CONFIG_SENSORS_W83792D is not set # CONFIG_SENSORS_W83793 is not set # CONFIG_SENSORS_W83L785TS is not set +# CONFIG_SENSORS_W83L786NG is not set # CONFIG_SENSORS_W83627HF is not set # CONFIG_SENSORS_W83627EHF is not set # CONFIG_HWMON_DEBUG_CHIP is not set @@ -780,6 +807,7 @@ CONFIG_SSB_POSSIBLE=y # Multifunction device drivers # # CONFIG_MFD_SM501 is not set +# CONFIG_MFD_ASIC3 is not set # # Multimedia devices @@ -865,10 +893,6 @@ CONFIG_USB_ARCH_HAS_OHCI=y # # NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' # - -# -# USB Gadget Support -# # CONFIG_USB_GADGET is not set # CONFIG_MMC is not set # CONFIG_NEW_LEDS is not set @@ -889,12 +913,10 @@ CONFIG_EXT2_FS=y # CONFIG_XFS_FS is not set # CONFIG_GFS2_FS is not set # CONFIG_OCFS2_FS is not set -# CONFIG_MINIX_FS is not set -# CONFIG_ROMFS_FS is not set +CONFIG_DNOTIFY=y CONFIG_INOTIFY=y CONFIG_INOTIFY_USER=y # CONFIG_QUOTA is not set -CONFIG_DNOTIFY=y CONFIG_AUTOFS_FS=y CONFIG_AUTOFS4_FS=y # CONFIG_FUSE_FS is not set @@ -948,8 +970,10 @@ CONFIG_JFFS2_RTIME=y # CONFIG_JFFS2_RUBIN is not set # CONFIG_CRAMFS is not set # CONFIG_VXFS_FS is not set +# CONFIG_MINIX_FS is not set # CONFIG_HPFS_FS is not set # CONFIG_QNX4FS_FS is not set +# CONFIG_ROMFS_FS is not set # CONFIG_SYSV_FS is not set # CONFIG_UFS_FS is not set CONFIG_NETWORK_FILESYSTEMS=y @@ -1019,9 +1043,6 @@ CONFIG_NLS_ISO8859_1=m # CONFIG_NLS_KOI8_U is not set # CONFIG_NLS_UTF8 is not set # CONFIG_DLM is not set -CONFIG_INSTRUMENTATION=y -# CONFIG_PROFILING is not set -# CONFIG_MARKERS is not set # # Kernel hacking @@ -1045,7 +1066,51 @@ CONFIG_FRAME_POINTER=y # CONFIG_KEYS is not set # CONFIG_SECURITY is not set # CONFIG_SECURITY_FILE_CAPABILITIES is not set -# CONFIG_CRYPTO is not set +CONFIG_CRYPTO=y +# CONFIG_CRYPTO_SEQIV is not set +# CONFIG_CRYPTO_MANAGER is not set +# CONFIG_CRYPTO_HMAC is not set +# CONFIG_CRYPTO_XCBC is not set +# CONFIG_CRYPTO_NULL is not set +# CONFIG_CRYPTO_MD4 is not set +# CONFIG_CRYPTO_MD5 is not set +# CONFIG_CRYPTO_SHA1 is not set +# CONFIG_CRYPTO_SHA256 is not set +# CONFIG_CRYPTO_SHA512 is not set +# CONFIG_CRYPTO_WP512 is not set +# CONFIG_CRYPTO_TGR192 is not set +# CONFIG_CRYPTO_GF128MUL is not set +# CONFIG_CRYPTO_ECB is not set +# CONFIG_CRYPTO_CBC is not set +# CONFIG_CRYPTO_PCBC is not set +# CONFIG_CRYPTO_LRW is not set +# CONFIG_CRYPTO_XTS is not set +# CONFIG_CRYPTO_CTR is not set +# CONFIG_CRYPTO_GCM is not set +# CONFIG_CRYPTO_CCM is not set +# CONFIG_CRYPTO_CRYPTD is not set +# CONFIG_CRYPTO_DES is not set +# CONFIG_CRYPTO_FCRYPT is not set +# CONFIG_CRYPTO_BLOWFISH is not set +# CONFIG_CRYPTO_TWOFISH is not set +# CONFIG_CRYPTO_SERPENT is not set +# CONFIG_CRYPTO_AES is not set +# CONFIG_CRYPTO_CAST5 is not set +# CONFIG_CRYPTO_CAST6 is not set +# CONFIG_CRYPTO_TEA is not set +# CONFIG_CRYPTO_ARC4 is not set +# CONFIG_CRYPTO_KHAZAD is not set +# CONFIG_CRYPTO_ANUBIS is not set +# CONFIG_CRYPTO_SEED is not set +# CONFIG_CRYPTO_SALSA20 is not set +# CONFIG_CRYPTO_DEFLATE is not set +# CONFIG_CRYPTO_MICHAEL_MIC is not set +# CONFIG_CRYPTO_CRC32C is not set +# CONFIG_CRYPTO_CAMELLIA is not set +# CONFIG_CRYPTO_TEST is not set +# CONFIG_CRYPTO_AUTHENC is not set +# CONFIG_CRYPTO_LZO is not set +CONFIG_CRYPTO_HW=y # # Library routines diff --git a/arch/arm/kernel/head-common.S b/arch/arm/kernel/head-common.S index 024a9cf469b47d6e841da0147e3c02355268ca81..50f667febe29ff638f2fa1544ab3217f1eb26a0d 100644 --- a/arch/arm/kernel/head-common.S +++ b/arch/arm/kernel/head-common.S @@ -11,6 +11,9 @@ * */ +#define ATAG_CORE 0x54410001 +#define ATAG_CORE_SIZE ((2*4 + 3*4) >> 2) + .type __switch_data, %object __switch_data: .long __mmap_switched diff --git a/arch/arm/kernel/head.S b/arch/arm/kernel/head.S index 7898cbc9861a9d484d655079c66b3f1e76dccd0b..bff4c6e90dd5458f1f71d2d70a5703ea394017c5 100644 --- a/arch/arm/kernel/head.S +++ b/arch/arm/kernel/head.S @@ -29,9 +29,6 @@ #define KERNEL_RAM_VADDR (PAGE_OFFSET + TEXT_OFFSET) #define KERNEL_RAM_PADDR (PHYS_OFFSET + TEXT_OFFSET) -#define ATAG_CORE 0x54410001 -#define ATAG_CORE_SIZE ((2*4 + 3*4) >> 2) - /* * swapper_pg_dir is the virtual address of the initial page table. diff --git a/arch/arm/kernel/kprobes.c b/arch/arm/kernel/kprobes.c index a22a98c43ca5911e9b8f9328509fbd4b9a973ca3..13e371aad8792686df6fee77d0642fa3030f8a69 100644 --- a/arch/arm/kernel/kprobes.c +++ b/arch/arm/kernel/kprobes.c @@ -431,6 +431,11 @@ int __kprobes longjmp_break_handler(struct kprobe *p, struct pt_regs *regs) return 0; } +int __kprobes arch_trampoline_kprobe(struct kprobe *p) +{ + return 0; +} + static struct undef_hook kprobes_break_hook = { .instr_mask = 0xffffffff, .instr_val = KPROBE_BREAKPOINT_INSTRUCTION, diff --git a/arch/arm/mach-at91/board-sam9263ek.c b/arch/arm/mach-at91/board-sam9263ek.c index 38313abef657d0a01684634c3aaf43eba6e82c2b..bf103b24c9379e208bf395bfdc9499aea0963daa 100644 --- a/arch/arm/mach-at91/board-sam9263ek.c +++ b/arch/arm/mach-at91/board-sam9263ek.c @@ -245,10 +245,7 @@ static struct fb_monspecs at91fb_default_monspecs = { static void at91_lcdc_power_control(int on) { - if (on) - at91_set_gpio_value(AT91_PIN_PD12, 0); /* power up */ - else - at91_set_gpio_value(AT91_PIN_PD12, 1); /* power down */ + at91_set_gpio_value(AT91_PIN_PA30, on); } /* Driver datas */ diff --git a/arch/arm/mach-at91/gpio.c b/arch/arm/mach-at91/gpio.c index f629c2b5f0c544bbec401964e6f7c13550e1e851..ee4964abcaf5ab7f70880e3361625288b8695372 100644 --- a/arch/arm/mach-at91/gpio.c +++ b/arch/arm/mach-at91/gpio.c @@ -490,6 +490,11 @@ postcore_initcall(at91_gpio_debugfs_init); /*--------------------------------------------------------------------------*/ +/* This lock class tells lockdep that GPIO irqs are in a different + * category than their parents, so it won't report false recursion. + */ +static struct lock_class_key gpio_lock_class; + /* * Called from the processor-specific init to enable GPIO interrupt support. */ @@ -510,6 +515,8 @@ void __init at91_gpio_irq_setup(void) __raw_writel(~0, this->regbase + PIO_IDR); for (i = 0, pin = this->chipbase; i < 32; i++, pin++) { + lockdep_set_class(&irq_desc[pin].lock, &gpio_lock_class); + /* * Can use the "simple" and not "edge" handler since it's * shorter, and the AIC handles interrupts sanely. diff --git a/arch/arm/mach-h720x/common.c b/arch/arm/mach-h720x/common.c index 7f31816896ad2ae662196c3772bf595781fc1dbd..45144ad2bed9cad00a573d02d0d15ce51e34b32f 100644 --- a/arch/arm/mach-h720x/common.c +++ b/arch/arm/mach-h720x/common.c @@ -103,7 +103,7 @@ static void h720x_gpio_handler(unsigned int mask, unsigned int irq, struct irq_desc *desc) { - IRQDBG("%s irq: %d\n",__FUNCTION__,irq); + IRQDBG("%s irq: %d\n", __func__, irq); desc = irq_desc + irq; while (mask) { if (mask & 1) { @@ -123,7 +123,7 @@ h720x_gpioa_demux_handler(unsigned int irq_unused, struct irq_desc *desc) mask = CPU_REG(GPIO_A_VIRT,GPIO_STAT); irq = IRQ_CHAINED_GPIOA(0); - IRQDBG("%s mask: 0x%08x irq: %d\n",__FUNCTION__,mask,irq); + IRQDBG("%s mask: 0x%08x irq: %d\n", __func__, mask,irq); h720x_gpio_handler(mask, irq, desc); } @@ -133,7 +133,7 @@ h720x_gpiob_demux_handler(unsigned int irq_unused, struct irq_desc *desc) unsigned int mask, irq; mask = CPU_REG(GPIO_B_VIRT,GPIO_STAT); irq = IRQ_CHAINED_GPIOB(0); - IRQDBG("%s mask: 0x%08x irq: %d\n",__FUNCTION__,mask,irq); + IRQDBG("%s mask: 0x%08x irq: %d\n", __func__, mask,irq); h720x_gpio_handler(mask, irq, desc); } @@ -144,7 +144,7 @@ h720x_gpioc_demux_handler(unsigned int irq_unused, struct irq_desc *desc) mask = CPU_REG(GPIO_C_VIRT,GPIO_STAT); irq = IRQ_CHAINED_GPIOC(0); - IRQDBG("%s mask: 0x%08x irq: %d\n",__FUNCTION__,mask,irq); + IRQDBG("%s mask: 0x%08x irq: %d\n", __func__, mask,irq); h720x_gpio_handler(mask, irq, desc); } @@ -155,7 +155,7 @@ h720x_gpiod_demux_handler(unsigned int irq_unused, struct irq_desc *desc) mask = CPU_REG(GPIO_D_VIRT,GPIO_STAT); irq = IRQ_CHAINED_GPIOD(0); - IRQDBG("%s mask: 0x%08x irq: %d\n",__FUNCTION__,mask,irq); + IRQDBG("%s mask: 0x%08x irq: %d\n", __func__, mask,irq); h720x_gpio_handler(mask, irq, desc); } @@ -167,7 +167,7 @@ h720x_gpioe_demux_handler(unsigned int irq_unused, struct irq_desc *desc) mask = CPU_REG(GPIO_E_VIRT,GPIO_STAT); irq = IRQ_CHAINED_GPIOE(0); - IRQDBG("%s mask: 0x%08x irq: %d\n",__FUNCTION__,mask,irq); + IRQDBG("%s mask: 0x%08x irq: %d\n", __func__, mask,irq); h720x_gpio_handler(mask, irq, desc); } #endif diff --git a/arch/arm/mach-imx/dma.c b/arch/arm/mach-imx/dma.c index bc6fb02d213bd6cf0e4072a735ba4709dc0a06af..a59ff2987cb7c582b3ad469281dc899d901ebd41 100644 --- a/arch/arm/mach-imx/dma.c +++ b/arch/arm/mach-imx/dma.c @@ -54,7 +54,7 @@ static inline int imx_dma_sg_next(imx_dmach_t dma_ch, unsigned int lastcount) if (!imxdma->name) { printk(KERN_CRIT "%s: called for not allocated channel %d\n", - __FUNCTION__, dma_ch); + __func__, dma_ch); return 0; } @@ -288,7 +288,7 @@ imx_dma_setup_handlers(imx_dmach_t dma_ch, if (!imxdma->name) { printk(KERN_CRIT "%s: called for not allocated channel %d\n", - __FUNCTION__, dma_ch); + __func__, dma_ch); return -ENODEV; } @@ -321,7 +321,7 @@ void imx_dma_enable(imx_dmach_t dma_ch) if (!imxdma->name) { printk(KERN_CRIT "%s: called for not allocated channel %d\n", - __FUNCTION__, dma_ch); + __func__, dma_ch); return; } @@ -365,7 +365,7 @@ int imx_dma_request(imx_dmach_t dma_ch, const char *name) if (dma_ch >= IMX_DMA_CHANNELS) { printk(KERN_CRIT "%s: called for non-existed channel %d\n", - __FUNCTION__, dma_ch); + __func__, dma_ch); return -EINVAL; } @@ -396,7 +396,7 @@ void imx_dma_free(imx_dmach_t dma_ch) if (!imxdma->name) { printk(KERN_CRIT "%s: trying to free channel %d which is already freed\n", - __FUNCTION__, dma_ch); + __func__, dma_ch); return; } @@ -456,7 +456,7 @@ imx_dma_request_by_prio(imx_dmach_t * pdma_ch, const char *name, } } - printk(KERN_ERR "%s: no free DMA channel found\n", __FUNCTION__); + printk(KERN_ERR "%s: no free DMA channel found\n", __func__); return -ENODEV; } diff --git a/arch/arm/mach-imx/irq.c b/arch/arm/mach-imx/irq.c index a7465db8489373a54bc785a4d0a72a809698c327..e6695c4e623b80facd70a60feb7244466a09cedc 100644 --- a/arch/arm/mach-imx/irq.c +++ b/arch/arm/mach-imx/irq.c @@ -160,21 +160,21 @@ imx_gpio_irq_type(unsigned int _irq, unsigned int type) static void imx_gpio_ack_irq(unsigned int irq) { - DEBUG_IRQ("%s: irq %d\n", __FUNCTION__, irq); + DEBUG_IRQ("%s: irq %d\n", __func__, irq); ISR(IRQ_TO_REG(irq)) = 1 << ((irq - IRQ_GPIOA(0)) % 32); } static void imx_gpio_mask_irq(unsigned int irq) { - DEBUG_IRQ("%s: irq %d\n", __FUNCTION__, irq); + DEBUG_IRQ("%s: irq %d\n", __func__, irq); IMR(IRQ_TO_REG(irq)) &= ~( 1 << ((irq - IRQ_GPIOA(0)) % 32)); } static void imx_gpio_unmask_irq(unsigned int irq) { - DEBUG_IRQ("%s: irq %d\n", __FUNCTION__, irq); + DEBUG_IRQ("%s: irq %d\n", __func__, irq); IMR(IRQ_TO_REG(irq)) |= 1 << ((irq - IRQ_GPIOA(0)) % 32); } diff --git a/arch/arm/mach-iop13xx/iq81340mc.c b/arch/arm/mach-iop13xx/iq81340mc.c index 268a8d84999cf41101130064f2aab57a94bade7e..77b24cd1d88da677e0ec1f5681d0c88aa59b2a5d 100644 --- a/arch/arm/mach-iop13xx/iq81340mc.c +++ b/arch/arm/mach-iop13xx/iq81340mc.c @@ -81,7 +81,7 @@ static void __init iq81340mc_init(void) static void __init iq81340mc_timer_init(void) { unsigned long bus_freq = iop13xx_core_freq() / iop13xx_xsi_bus_ratio(); - printk(KERN_DEBUG "%s: bus frequency: %lu\n", __FUNCTION__, bus_freq); + printk(KERN_DEBUG "%s: bus frequency: %lu\n", __func__, bus_freq); iop_init_time(bus_freq); } diff --git a/arch/arm/mach-iop13xx/iq81340sc.c b/arch/arm/mach-iop13xx/iq81340sc.c index a51ffd2683e5ae6e80e856883072b772a1751019..e8522b3b81634cccb91707ccc9c7f49f927336b2 100644 --- a/arch/arm/mach-iop13xx/iq81340sc.c +++ b/arch/arm/mach-iop13xx/iq81340sc.c @@ -83,7 +83,7 @@ static void __init iq81340sc_init(void) static void __init iq81340sc_timer_init(void) { unsigned long bus_freq = iop13xx_core_freq() / iop13xx_xsi_bus_ratio(); - printk(KERN_DEBUG "%s: bus frequency: %lu\n", __FUNCTION__, bus_freq); + printk(KERN_DEBUG "%s: bus frequency: %lu\n", __func__, bus_freq); iop_init_time(bus_freq); } diff --git a/arch/arm/mach-iop13xx/pci.c b/arch/arm/mach-iop13xx/pci.c index 99d94cb1bafdc6818e96d4edc6bc64fbeb152a71..7825c1aaa27b073b61b34744d3d3ddf92021c160 100644 --- a/arch/arm/mach-iop13xx/pci.c +++ b/arch/arm/mach-iop13xx/pci.c @@ -94,13 +94,13 @@ void iop13xx_map_pci_memory(void) , 0, iop13xx_atux_mem_size, MT_DEVICE); if (!iop13xx_atux_mem_base) { printk("%s: atux allocation " - "failed\n", __FUNCTION__); + "failed\n", __func__); BUG(); } } else iop13xx_atux_mem_size = 0; PRINTK("%s: atu: %d bus_size: %d mem_base: %x\n", - __FUNCTION__, atu, iop13xx_atux_mem_size, + __func__, atu, iop13xx_atux_mem_size, iop13xx_atux_mem_base); break; case 1: @@ -120,13 +120,13 @@ void iop13xx_map_pci_memory(void) , 0, iop13xx_atue_mem_size, MT_DEVICE); if (!iop13xx_atue_mem_base) { printk("%s: atue allocation " - "failed\n", __FUNCTION__); + "failed\n", __func__); BUG(); } } else iop13xx_atue_mem_size = 0; PRINTK("%s: atu: %d bus_size: %d mem_base: %x\n", - __FUNCTION__, atu, iop13xx_atue_mem_size, + __func__, atu, iop13xx_atue_mem_size, iop13xx_atue_mem_base); break; } diff --git a/arch/arm/mach-iop13xx/setup.c b/arch/arm/mach-iop13xx/setup.c index bfe0c87e33976e96fad4f673fc3ca334d5dcbf81..246f6d4787209fb526e4680426d629bbf5938569 100644 --- a/arch/arm/mach-iop13xx/setup.c +++ b/arch/arm/mach-iop13xx/setup.c @@ -519,7 +519,7 @@ void __init iop13xx_platform_init(void) if (iq8134x_flash_resource.end > iq8134x_flash_resource.start) iop13xx_devices[plat_idx++] = &iq8134x_flash; else - printk(KERN_ERR "%s: Failed to probe flash size\n", __FUNCTION__); + printk(KERN_ERR "%s: Failed to probe flash size\n", __func__); #endif platform_add_devices(iop13xx_devices, plat_idx); diff --git a/arch/arm/mach-ixp4xx/common-pci.c b/arch/arm/mach-ixp4xx/common-pci.c index bf04121d1a31748ac99b93f4b2982f5b4675103e..64be341109b3623a39b2b1e659bbecd0d1760dad 100644 --- a/arch/arm/mach-ixp4xx/common-pci.c +++ b/arch/arm/mach-ixp4xx/common-pci.c @@ -87,7 +87,7 @@ static inline int check_master_abort(void) if (isr & PCI_ISR_PFE) { /* make sure the Master Abort bit is reset */ *PCI_ISR = PCI_ISR_PFE; - pr_debug("%s failed\n", __FUNCTION__); + pr_debug("%s failed\n", __func__); return 1; } diff --git a/arch/arm/mach-ixp4xx/gtwx5715-pci.c b/arch/arm/mach-ixp4xx/gtwx5715-pci.c index 0d5a42455820322c804d046233e7563826d66106..49dec78688078f3bcc387af331b33ddb88be2895 100644 --- a/arch/arm/mach-ixp4xx/gtwx5715-pci.c +++ b/arch/arm/mach-ixp4xx/gtwx5715-pci.c @@ -65,7 +65,7 @@ static int __init gtwx5715_map_irq(struct pci_dev *dev, u8 slot, u8 pin) else rc = gtwx5715_irqmap[slot][pin-1]; - printk("%s: Mapped slot %d pin %d to IRQ %d\n", __FUNCTION__,slot, pin, rc); + printk("%s: Mapped slot %d pin %d to IRQ %d\n", __func__, slot, pin, rc); return(rc); } diff --git a/arch/arm/mach-netx/generic.c b/arch/arm/mach-netx/generic.c index b9ca8f98265da182787fff8efa2b94d72129b33f..fd7537f7d11e798c3257ba46a5b21211b45a5b1c 100644 --- a/arch/arm/mach-netx/generic.c +++ b/arch/arm/mach-netx/generic.c @@ -133,7 +133,7 @@ netx_hif_ack_irq(unsigned int _irq) val &= ~((1 << 24) << irq); writel(val, NETX_DPMAS_INT_EN); - DEBUG_IRQ("%s: irq %d\n", __FUNCTION__, _irq); + DEBUG_IRQ("%s: irq %d\n", __func__, _irq); } static void @@ -145,7 +145,7 @@ netx_hif_mask_irq(unsigned int _irq) val = readl(NETX_DPMAS_INT_EN); val &= ~((1 << 24) << irq); writel(val, NETX_DPMAS_INT_EN); - DEBUG_IRQ("%s: irq %d\n", __FUNCTION__, _irq); + DEBUG_IRQ("%s: irq %d\n", __func__, _irq); } static void @@ -157,7 +157,7 @@ netx_hif_unmask_irq(unsigned int _irq) val = readl(NETX_DPMAS_INT_EN); val |= (1 << 24) << irq; writel(val, NETX_DPMAS_INT_EN); - DEBUG_IRQ("%s: irq %d\n", __FUNCTION__, _irq); + DEBUG_IRQ("%s: irq %d\n", __func__, _irq); } static struct irq_chip netx_hif_chip = { diff --git a/arch/arm/mach-ns9xxx/gpio.c b/arch/arm/mach-ns9xxx/gpio.c index b2230213b983deacd3db7e0a251fc1d27b9f2e69..5286e9fc1d307bac62f1341dd6c4e728a83be33a 100644 --- a/arch/arm/mach-ns9xxx/gpio.c +++ b/arch/arm/mach-ns9xxx/gpio.c @@ -31,7 +31,7 @@ static spinlock_t gpio_lock = __SPIN_LOCK_UNLOCKED(gpio_lock); /* only access gpiores with atomic ops */ -static DECLARE_BITMAP(gpiores, GPIO_MAX); +static DECLARE_BITMAP(gpiores, GPIO_MAX + 1); static inline int ns9xxx_valid_gpio(unsigned gpio) { diff --git a/arch/arm/mach-omap1/board-h2.c b/arch/arm/mach-omap1/board-h2.c index 070345ee39a54834939f9c627387222c9d12a003..5079877200154364cf5d5d5921898909f53b2c2a 100644 --- a/arch/arm/mach-omap1/board-h2.c +++ b/arch/arm/mach-omap1/board-h2.c @@ -350,6 +350,10 @@ static void __init h2_init_smc91x(void) static struct i2c_board_info __initdata h2_i2c_board_info[] = { { + I2C_BOARD_INFO("tps65010", 0x48), + .type = "tps65010", + .irq = OMAP_GPIO_IRQ(58), + }, { I2C_BOARD_INFO("isp1301_omap", 0x2d), .type = "isp1301_omap", .irq = OMAP_GPIO_IRQ(2), diff --git a/arch/arm/mach-omap1/board-h3.c b/arch/arm/mach-omap1/board-h3.c index 6fc516855a8cec0bc93b6cda648da65c2d001fe2..c3ef1ee5f77bcd4a01fb9a5ecac297493c850651 100644 --- a/arch/arm/mach-omap1/board-h3.c +++ b/arch/arm/mach-omap1/board-h3.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include @@ -51,6 +52,8 @@ #include #include +#define H3_TS_GPIO 48 + static int h3_keymap[] = { KEY(0, 0, KEY_LEFT), KEY(0, 1, KEY_RIGHT), @@ -373,6 +376,17 @@ static struct platform_device h3_lcd_device = { .id = -1, }; +static struct spi_board_info h3_spi_board_info[] __initdata = { + [0] = { + .modalias = "tsc2101", + .bus_num = 2, + .chip_select = 0, + .irq = OMAP_GPIO_IRQ(H3_TS_GPIO), + .max_speed_hz = 16000000, + /* .platform_data = &tsc_platform_data, */ + }, +}; + static struct omap_mcbsp_reg_cfg mcbsp_regs = { .spcr2 = FREE | FRST | GRST | XRST | XINTM(3), .spcr1 = RINTM(3) | RRST, @@ -457,6 +471,14 @@ static struct omap_board_config_kernel h3_config[] __initdata = { { OMAP_TAG_LCD, &h3_lcd_config }, }; +static struct i2c_board_info __initdata h3_i2c_board_info[] = { + { + I2C_BOARD_INFO("tps65010", 0x48), + .type = "tps65013", + /* .irq = OMAP_GPIO_IRQ(??), */ + }, +}; + static struct omap_gpio_switch h3_gpio_switches[] __initdata = { { .name = "mmc_slot", diff --git a/arch/arm/mach-omap1/pm.c b/arch/arm/mach-omap1/pm.c index 8eb5dcdaead2aaeb299f2320e687dafe4cfacfd8..e6c64e10b7ec283b46d58177e2a7e5d7b9984b0a 100644 --- a/arch/arm/mach-omap1/pm.c +++ b/arch/arm/mach-omap1/pm.c @@ -717,7 +717,7 @@ static int __init omap_pm_init(void) #endif #ifdef CONFIG_OMAP_32K_TIMER - error = sysfs_create_file(power_kobj, &sleep_while_idle_attr); + error = sysfs_create_file(power_kobj, &sleep_while_idle_attr.attr); if (error) printk(KERN_ERR "sysfs_create_file failed: %d\n", error); #endif diff --git a/arch/arm/mach-omap2/io.c b/arch/arm/mach-omap2/io.c index 5a4091f582edc23aeafc051785898547a1decc8f..69c8174f3aace0f5b377021e347e7785800ef1cb 100644 --- a/arch/arm/mach-omap2/io.c +++ b/arch/arm/mach-omap2/io.c @@ -42,6 +42,12 @@ static struct map_desc omap2_io_desc[] __initdata = { .length = L3_24XX_SIZE, .type = MT_DEVICE }, + { + .virtual = L4_24XX_VIRT, + .pfn = __phys_to_pfn(L4_24XX_PHYS), + .length = L4_24XX_SIZE, + .type = MT_DEVICE + }, #ifdef CONFIG_ARCH_OMAP2430 { .virtual = L4_WK_243X_VIRT, diff --git a/arch/arm/mach-orion/addr-map.c b/arch/arm/mach-orion/addr-map.c index 2e2fd63643c39760ee02153fc62ccba89defba88..58cc3c0333b6b3ee46a2db6f852d865f3dddf147 100644 --- a/arch/arm/mach-orion/addr-map.c +++ b/arch/arm/mach-orion/addr-map.c @@ -97,14 +97,20 @@ #define PCIE_BAR_CTRL(n) ORION_PCIE_REG(0x1804 + ((n - 1) * 4)) #define PCIE_BAR_LO(n) ORION_PCIE_REG(0x0010 + ((n) * 8)) #define PCIE_BAR_HI(n) ORION_PCIE_REG(0x0014 + ((n) * 8)) -#define PCIE_WIN_CTRL(n) ORION_PCIE_REG(0x1820 + ((n) << 4)) -#define PCIE_WIN_BASE(n) ORION_PCIE_REG(0x1824 + ((n) << 4)) -#define PCIE_WIN_REMAP(n) ORION_PCIE_REG(0x182c + ((n) << 4)) +#define PCIE_WIN_CTRL(n) (((n) < 5) ? \ + ORION_PCIE_REG(0x1820 + ((n) << 4)) : \ + ORION_PCIE_REG(0x1880)) +#define PCIE_WIN_BASE(n) (((n) < 5) ? \ + ORION_PCIE_REG(0x1824 + ((n) << 4)) : \ + ORION_PCIE_REG(0x1884)) +#define PCIE_WIN_REMAP(n) (((n) < 5) ? \ + ORION_PCIE_REG(0x182c + ((n) << 4)) : \ + ORION_PCIE_REG(0x188c)) #define PCIE_DEFWIN_CTRL ORION_PCIE_REG(0x18b0) #define PCIE_EXPROM_WIN_CTRL ORION_PCIE_REG(0x18c0) #define PCIE_EXPROM_WIN_REMP ORION_PCIE_REG(0x18c4) #define PCIE_MAX_BARS 3 -#define PCIE_MAX_WINS 5 +#define PCIE_MAX_WINS 6 /* * Use PCIE BAR '1' for all DDR banks diff --git a/arch/arm/mach-orion/common.c b/arch/arm/mach-orion/common.c index 5f0ee4b8a9b73a5a1cfced1a0e0a5efa91e1e993..bbc2b4ec932ca8a407188a3810a3dcbcfd317840 100644 --- a/arch/arm/mach-orion/common.c +++ b/arch/arm/mach-orion/common.c @@ -17,7 +17,9 @@ #include #include #include +#include #include +#include #include #include #include "common.h" @@ -177,8 +179,8 @@ static struct platform_device orion_ehci1 = { static struct resource orion_eth_shared_resources[] = { { - .start = ORION_ETH_PHYS_BASE, - .end = ORION_ETH_PHYS_BASE + 0xffff, + .start = ORION_ETH_PHYS_BASE + 0x2000, + .end = ORION_ETH_PHYS_BASE + 0x3fff, .flags = IORESOURCE_MEM, }, }; @@ -347,3 +349,21 @@ void __init orion_init(void) platform_device_register(&orion_ehci1); platform_device_register(&orion_i2c); } + +/* + * Many orion-based systems have buggy bootloader implementations. + * This is a common fixup for bogus memory tags. + */ +void __init tag_fixup_mem32(struct machine_desc *mdesc, struct tag *t, + char **from, struct meminfo *meminfo) +{ + for (; t->hdr.size; t = tag_next(t)) + if (t->hdr.tag == ATAG_MEM && + (!t->u.mem.size || t->u.mem.size & ~PAGE_MASK || + t->u.mem.start & ~PAGE_MASK)) { + printk(KERN_WARNING + "Clearing invalid memory bank %dKB@0x%08x\n", + t->u.mem.size / 1024, t->u.mem.start); + t->hdr.tag = 0; + } +} diff --git a/arch/arm/mach-orion/common.h b/arch/arm/mach-orion/common.h index 10154ec885dfb1c08339732710e59d2c3d9f333a..501497cc2c4df431658a0b036358d374d5f86c5a 100644 --- a/arch/arm/mach-orion/common.h +++ b/arch/arm/mach-orion/common.h @@ -83,4 +83,10 @@ struct mv_sata_platform_data; void __init orion_sata_init(struct mv_sata_platform_data *sata_data); +struct machine_desc; +struct meminfo; +struct tag; +extern void __init tag_fixup_mem32(struct machine_desc *, struct tag *, + char **, struct meminfo *); + #endif /* __ARCH_ORION_COMMON_H__ */ diff --git a/arch/arm/mach-orion/dns323-setup.c b/arch/arm/mach-orion/dns323-setup.c index 02b280c2482064d465fd23a489e046a2d36b3aa3..076e155ad5106106980f6ea05ef93762d986a4c7 100644 --- a/arch/arm/mach-orion/dns323-setup.c +++ b/arch/arm/mach-orion/dns323-setup.c @@ -319,4 +319,5 @@ MACHINE_START(DNS323, "D-Link DNS-323") .map_io = orion_map_io, .init_irq = orion_init_irq, .timer = &orion_timer, + .fixup = tag_fixup_mem32, MACHINE_END diff --git a/arch/arm/mach-orion/gpio.c b/arch/arm/mach-orion/gpio.c index d5f00c86d6163fb8a191bcea06089ed89a5e21d6..f713818c66a3dd3814f45c44fe31f02fa7e5dc64 100644 --- a/arch/arm/mach-orion/gpio.c +++ b/arch/arm/mach-orion/gpio.c @@ -36,7 +36,7 @@ int gpio_direction_input(unsigned pin) unsigned long flags; if (pin >= GPIO_MAX || !test_bit(pin, gpio_valid)) { - pr_debug("%s: invalid GPIO %d\n", __FUNCTION__, pin); + pr_debug("%s: invalid GPIO %d\n", __func__, pin); return -EINVAL; } @@ -62,7 +62,7 @@ int gpio_direction_output(unsigned pin, int value) int mask; if (pin >= GPIO_MAX || !test_bit(pin, gpio_valid)) { - pr_debug("%s: invalid GPIO %d\n", __FUNCTION__, pin); + pr_debug("%s: invalid GPIO %d\n", __func__, pin); return -EINVAL; } @@ -141,7 +141,7 @@ int gpio_request(unsigned pin, const char *label) unsigned long flags; if (pin >= GPIO_MAX || !test_bit(pin, gpio_valid)) { - pr_debug("%s: invalid GPIO %d\n", __FUNCTION__, pin); + pr_debug("%s: invalid GPIO %d\n", __func__, pin); return -EINVAL; } @@ -149,7 +149,7 @@ int gpio_request(unsigned pin, const char *label) if (gpio_label[pin]) { pr_debug("%s: GPIO %d already used as %s\n", - __FUNCTION__, pin, gpio_label[pin]); + __func__, pin, gpio_label[pin]); ret = -EBUSY; } else gpio_label[pin] = label ? label : "?"; @@ -162,12 +162,12 @@ EXPORT_SYMBOL(gpio_request); void gpio_free(unsigned pin) { if (pin >= GPIO_MAX || !test_bit(pin, gpio_valid)) { - pr_debug("%s: invalid GPIO %d\n", __FUNCTION__, pin); + pr_debug("%s: invalid GPIO %d\n", __func__, pin); return; } if (!gpio_label[pin]) - pr_warning("%s: GPIO %d already freed\n", __FUNCTION__, pin); + pr_warning("%s: GPIO %d already freed\n", __func__, pin); else gpio_label[pin] = NULL; } diff --git a/arch/arm/mach-orion/kurobox_pro-setup.c b/arch/arm/mach-orion/kurobox_pro-setup.c index 6817aca4aa2653b6d92647add7ee6e65a1e66aaf..785a07bdf1e24681f63b28a0a603f43a2c89e00e 100644 --- a/arch/arm/mach-orion/kurobox_pro-setup.c +++ b/arch/arm/mach-orion/kurobox_pro-setup.c @@ -240,4 +240,5 @@ MACHINE_START(KUROBOX_PRO, "Buffalo/Revogear Kurobox Pro") .map_io = orion_map_io, .init_irq = orion_init_irq, .timer = &orion_timer, + .fixup = tag_fixup_mem32, MACHINE_END diff --git a/arch/arm/mach-orion/ts209-setup.c b/arch/arm/mach-orion/ts209-setup.c index b8cfe6813e9d5313f8d7d5ad7d29b3b2e75050c5..45764dad16d0fb3bb121b5e5911761ae36051162 100644 --- a/arch/arm/mach-orion/ts209-setup.c +++ b/arch/arm/mach-orion/ts209-setup.c @@ -357,4 +357,5 @@ MACHINE_START(TS209, "QNAP TS-109/TS-209") .map_io = orion_map_io, .init_irq = orion_init_irq, .timer = &orion_timer, + .fixup = tag_fixup_mem32, MACHINE_END diff --git a/arch/arm/mach-pnx4008/clock.c b/arch/arm/mach-pnx4008/clock.c index daa8d3d98eff13b7d33927d7a8218bdc021d4bc7..8e00ed43fb95d76fb0dc5243cf0a3acdf0d2d809 100644 --- a/arch/arm/mach-pnx4008/clock.c +++ b/arch/arm/mach-pnx4008/clock.c @@ -976,7 +976,7 @@ static int __init clk_init(void) (*clkp)->set_parent((*clkp), (*clkp)->parent); } pr_debug("%s: clock %s, rate %ld\n", - __FUNCTION__, (*clkp)->name, (*clkp)->rate); + __func__, (*clkp)->name, (*clkp)->rate); } local_clk_use(&ck_pll4); diff --git a/arch/arm/mach-pnx4008/dma.c b/arch/arm/mach-pnx4008/dma.c index f7009d845be838e58ede89dc9851d743a810bd4c..fe152e82590b366990ab96f5dfc91bdc6eb2b41b 100644 --- a/arch/arm/mach-pnx4008/dma.c +++ b/arch/arm/mach-pnx4008/dma.c @@ -192,7 +192,7 @@ void pnx4008_free_channel(int ch) if (!dma_channels[ch].name) { printk(KERN_CRIT "%s: trying to free channel %d which is already freed\n", - __FUNCTION__, ch); + __func__, ch); return; } diff --git a/arch/arm/mach-pxa/cm-x270-pci.c b/arch/arm/mach-pxa/cm-x270-pci.c index 15c4e0df3e10dcc375180b79b33247a1ea9fe4e2..fcda7d5cb693a15096f9b6420fa86572f33f206c 100644 --- a/arch/arm/mach-pxa/cm-x270-pci.c +++ b/arch/arm/mach-pxa/cm-x270-pci.c @@ -104,7 +104,7 @@ static int __init cmx270_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin) { int irq; - dev_dbg(&dev->dev, "%s: slot=%x, pin=%x\n", __FUNCTION__, slot, pin); + dev_dbg(&dev->dev, "%s: slot=%x, pin=%x\n", __func__, slot, pin); irq = it8152_pci_map_irq(dev, slot, pin); if (irq) diff --git a/arch/arm/mach-pxa/cm-x270.c b/arch/arm/mach-pxa/cm-x270.c index 6012177a29a35b5afb0227c8f0d31bd95ed0f81c..ecdbc96a4de1240f026c6b7c813409faf1073911 100644 --- a/arch/arm/mach-pxa/cm-x270.c +++ b/arch/arm/mach-pxa/cm-x270.c @@ -504,11 +504,11 @@ static void cmx270_mci_setpower(struct device *dev, unsigned int vdd) struct pxamci_platform_data *p_d = dev->platform_data; if ((1 << vdd) & p_d->ocr_mask) { - printk(KERN_DEBUG "%s: on\n", __FUNCTION__); + printk(KERN_DEBUG "%s: on\n", __func__); GPCR(105) = GPIO_bit(105); } else { GPSR(105) = GPIO_bit(105); - printk(KERN_DEBUG "%s: off\n", __FUNCTION__); + printk(KERN_DEBUG "%s: off\n", __func__); } } diff --git a/arch/arm/mach-pxa/cpu-pxa.c b/arch/arm/mach-pxa/cpu-pxa.c index 939a3867f77c8696caa0a62a9b20bfea8f6038ec..4b21479332ae40c073c1f184b1980a502aca4c40 100644 --- a/arch/arm/mach-pxa/cpu-pxa.c +++ b/arch/arm/mach-pxa/cpu-pxa.c @@ -43,7 +43,7 @@ #ifdef DEBUG static unsigned int freq_debug; -MODULE_PARM(freq_debug, "i"); +module_param(freq_debug, uint, 0); MODULE_PARM_DESC(freq_debug, "Set the debug messages to on=1/off=0"); #else #define freq_debug 0 diff --git a/arch/arm/mach-pxa/dma.c b/arch/arm/mach-pxa/dma.c index 93c4f31f127faa053dcd555f5fe7aa66fb5aee34..3215316d7b063fe31ff5a5cc4b3867f40a4344d7 100644 --- a/arch/arm/mach-pxa/dma.c +++ b/arch/arm/mach-pxa/dma.c @@ -81,7 +81,7 @@ void pxa_free_dma (int dma_ch) if (!dma_channels[dma_ch].name) { printk (KERN_CRIT "%s: trying to free channel %d which is already freed\n", - __FUNCTION__, dma_ch); + __func__, dma_ch); return; } diff --git a/arch/arm/mach-pxa/em-x270.c b/arch/arm/mach-pxa/em-x270.c index 3d0ad5065ee5c132b1d1f8ed47b3344ffb440650..3bb31314429af0568b9a3920e76895fca580d29b 100644 --- a/arch/arm/mach-pxa/em-x270.c +++ b/arch/arm/mach-pxa/em-x270.c @@ -264,7 +264,7 @@ static int em_x270_mci_init(struct device *dev, "MMC card detect", data); if (err) { printk(KERN_ERR "%s: can't request MMC card detect IRQ: %d\n", - __FUNCTION__, err); + __func__, err); return err; } diff --git a/arch/arm/mach-pxa/mainstone.c b/arch/arm/mach-pxa/mainstone.c index 345c3deeb02ef586eeae1628459ef16aa1cf7c6f..72a436fb9a291f4509a314f6b8c39202b5080d16 100644 --- a/arch/arm/mach-pxa/mainstone.c +++ b/arch/arm/mach-pxa/mainstone.c @@ -390,11 +390,11 @@ static void mainstone_mci_setpower(struct device *dev, unsigned int vdd) struct pxamci_platform_data* p_d = dev->platform_data; if (( 1 << vdd) & p_d->ocr_mask) { - printk(KERN_DEBUG "%s: on\n", __FUNCTION__); + printk(KERN_DEBUG "%s: on\n", __func__); MST_MSCWR1 |= MST_MSCWR1_MMC_ON; MST_MSCWR1 &= ~MST_MSCWR1_MS_SEL; } else { - printk(KERN_DEBUG "%s: off\n", __FUNCTION__); + printk(KERN_DEBUG "%s: off\n", __func__); MST_MSCWR1 &= ~MST_MSCWR1_MMC_ON; } } diff --git a/arch/arm/mach-pxa/pxa3xx.c b/arch/arm/mach-pxa/pxa3xx.c index 7cd9ef8deb02f28c9d81ab62cdac9603d4170929..35f25fdaeba3925303ed0dc1dacd4ed9f105c71a 100644 --- a/arch/arm/mach-pxa/pxa3xx.c +++ b/arch/arm/mach-pxa/pxa3xx.c @@ -129,28 +129,20 @@ static void clk_pxa3xx_cken_enable(struct clk *clk) { unsigned long mask = 1ul << (clk->cken & 0x1f); - local_irq_disable(); - if (clk->cken < 32) CKENA |= mask; else CKENB |= mask; - - local_irq_enable(); } static void clk_pxa3xx_cken_disable(struct clk *clk) { unsigned long mask = 1ul << (clk->cken & 0x1f); - local_irq_disable(); - if (clk->cken < 32) CKENA &= ~mask; else CKENB &= ~mask; - - local_irq_enable(); } static const struct clkops clk_pxa3xx_cken_ops = { diff --git a/arch/arm/mach-pxa/trizeps4.c b/arch/arm/mach-pxa/trizeps4.c index 853fc9433750efc0ea33987aa62df87a7ed237f6..f207fcd30cd7426f041806d88f0b52db6be69832 100644 --- a/arch/arm/mach-pxa/trizeps4.c +++ b/arch/arm/mach-pxa/trizeps4.c @@ -217,7 +217,7 @@ void board_pcmcia_power(int power) ConXS_BCR = trizeps_conxs_bcr; } - pr_debug("%s: o%s 0x%x\n", __FUNCTION__, power ? "n": "ff", trizeps_conxs_bcr); + pr_debug("%s: o%s 0x%x\n", __func__, power ? "n": "ff", trizeps_conxs_bcr); } /* backlight power switching for LCD panel */ @@ -228,7 +228,7 @@ static void board_backlight_power(int on) } else { trizeps_conxs_bcr &= ~ConXS_BCR_L_DISP; } - pr_debug("%s: o%s 0x%x\n", __FUNCTION__, on ? "n" : "ff", trizeps_conxs_bcr); + pr_debug("%s: o%s 0x%x\n", __func__, on ? "n" : "ff", trizeps_conxs_bcr); ConXS_BCR = trizeps_conxs_bcr; } @@ -238,10 +238,10 @@ static void board_mci_power(struct device *dev, unsigned int vdd) struct pxamci_platform_data* p_d = dev->platform_data; if (( 1 << vdd) & p_d->ocr_mask) { - pr_debug("%s: on\n", __FUNCTION__); + pr_debug("%s: on\n", __func__); /* FIXME fill in values here */ } else { - pr_debug("%s: off\n", __FUNCTION__); + pr_debug("%s: off\n", __func__); /* FIXME fill in values here */ } } diff --git a/arch/arm/mach-pxa/zylonite.c b/arch/arm/mach-pxa/zylonite.c index 7731d50dd86cfe00e2144ded09ca1caa1805d690..afd2cbfca0d91c993d94a8fd6400d73ff5807cf4 100644 --- a/arch/arm/mach-pxa/zylonite.c +++ b/arch/arm/mach-pxa/zylonite.c @@ -58,7 +58,7 @@ static struct platform_device smc91x_device = { .resource = smc91x_resources, }; -#if defined(CONFIG_FB_PXA) || (CONFIG_FB_PXA_MODULES) +#if defined(CONFIG_FB_PXA) || defined(CONFIG_FB_PXA_MODULE) static void zylonite_backlight_power(int on) { gpio_set_value(gpio_backlight, on); diff --git a/arch/arm/mach-sa1100/badge4.c b/arch/arm/mach-sa1100/badge4.c index f60b7a66dfa022bc66699a7e26b151cb8c1f1c58..842d9e6dc5ff77c94c802baa47647cba879ed73a 100644 --- a/arch/arm/mach-sa1100/badge4.c +++ b/arch/arm/mach-sa1100/badge4.c @@ -206,7 +206,7 @@ static int __init badge4_init(void) if (ret < 0) printk(KERN_ERR "%s: SA-1111 initialization failed (%d)\n", - __FUNCTION__, ret); + __func__, ret); /* maybe turn on 5v0 from the start */ @@ -240,11 +240,11 @@ void badge4_set_5V(unsigned subsystem, int on) /* detect on->off and off->on transitions */ if ((!old_5V_bitmap) && (badge4_5V_bitmap)) { /* was off, now on */ - printk(KERN_INFO "%s: enabling 5V supply rail\n", __FUNCTION__); + printk(KERN_INFO "%s: enabling 5V supply rail\n", __func__); GPSR = BADGE4_GPIO_PCMEN5V; } else if ((old_5V_bitmap) && (!badge4_5V_bitmap)) { /* was on, now off */ - printk(KERN_INFO "%s: disabling 5V supply rail\n", __FUNCTION__); + printk(KERN_INFO "%s: disabling 5V supply rail\n", __func__); GPCR = BADGE4_GPIO_PCMEN5V; } diff --git a/arch/arm/mach-sa1100/cpu-sa1100.c b/arch/arm/mach-sa1100/cpu-sa1100.c index d68630b74d787fa4a733120e4f89a6b5c5fcf733..343368aa82de471137232e8848d8d4c1cb30d9d2 100644 --- a/arch/arm/mach-sa1100/cpu-sa1100.c +++ b/arch/arm/mach-sa1100/cpu-sa1100.c @@ -139,7 +139,7 @@ static void sa1100_update_dram_timings(int current_speed, int new_speed) if (settings->speed == 0) { panic("%s: couldn't find dram setting for speed %d\n", - __FUNCTION__, new_speed); + __func__, new_speed); } /* No risk, no fun: run with interrupts on! */ diff --git a/arch/arm/mach-sa1100/dma.c b/arch/arm/mach-sa1100/dma.c index 1fbe053e8b5998cd46216d9ba445fb26849a3a4e..e5080286060e3be165e4830b29a0a401b8108950 100644 --- a/arch/arm/mach-sa1100/dma.c +++ b/arch/arm/mach-sa1100/dma.c @@ -129,7 +129,7 @@ int sa1100_request_dma (dma_device_t device, const char *device_id, if (err) { printk(KERN_ERR "%s: unable to request IRQ %d for %s\n", - __FUNCTION__, IRQ_DMA0 + i, device_id); + __func__, IRQ_DMA0 + i, device_id); dma->device = 0; return err; } @@ -165,12 +165,12 @@ void sa1100_free_dma(dma_regs_t *regs) if (regs == (dma_regs_t *)&DDAR(i)) break; if (i >= SA1100_DMA_CHANNELS) { - printk(KERN_ERR "%s: bad DMA identifier\n", __FUNCTION__); + printk(KERN_ERR "%s: bad DMA identifier\n", __func__); return; } if (!dma_chan[i].device) { - printk(KERN_ERR "%s: Trying to free free DMA\n", __FUNCTION__); + printk(KERN_ERR "%s: Trying to free free DMA\n", __func__); return; } @@ -329,7 +329,7 @@ void sa1100_reset_dma(dma_regs_t *regs) if (regs == (dma_regs_t *)&DDAR(i)) break; if (i >= SA1100_DMA_CHANNELS) { - printk(KERN_ERR "%s: bad DMA identifier\n", __FUNCTION__); + printk(KERN_ERR "%s: bad DMA identifier\n", __func__); return; } diff --git a/arch/arm/mach-sa1100/h3600.c b/arch/arm/mach-sa1100/h3600.c index b72fee0f2538ee6865a69389b7cb8eb253040c8b..8473c37b77d6e1bf4f5c7d6ce06109793c4275c4 100644 --- a/arch/arm/mach-sa1100/h3600.c +++ b/arch/arm/mach-sa1100/h3600.c @@ -596,7 +596,7 @@ static void h3800_control_egpio(enum ipaq_egpio_type x, int setp) case IPAQ_EGPIO_CODEC_NRESET: case IPAQ_EGPIO_AUDIO_ON: case IPAQ_EGPIO_QMUTE: - printk("%s: error - should not be called\n", __FUNCTION__); + printk("%s: error - should not be called\n", __func__); break; case IPAQ_EGPIO_OPT_NVRAM_ON: SET_ASIC2(GPIO2_OPT_ON_NVRAM); @@ -638,7 +638,7 @@ static int h3800_pm_callback(int req) static u16 asic2_data; int result = 0; - printk("%s %d\n", __FUNCTION__, req); + printk("%s %d\n", __func__, req); switch (req) { case PM_RESUME: @@ -666,7 +666,7 @@ static int h3800_pm_callback(int req) asic2_data = H3800_ASIC2_GPIOPIOD; break; default: - printk("%s: unrecognized PM callback\n", __FUNCTION__); + printk("%s: unrecognized PM callback\n", __func__); break; } return result; @@ -706,7 +706,7 @@ static void h3800_IRQ_demux(unsigned int irq, struct irq_desc *desc) { int i; - if (0) printk("%s: interrupt received\n", __FUNCTION__); + if (0) printk("%s: interrupt received\n", __func__); desc->chip->ack(irq); @@ -716,21 +716,21 @@ static void h3800_IRQ_demux(unsigned int irq, struct irq_desc *desc) /* KPIO */ irq = H3800_ASIC2_KPIINTFLAG; - if (0) printk("%s KPIO 0x%08X\n", __FUNCTION__, irq); + if (0) printk("%s KPIO 0x%08X\n", __func__, irq); for (j = 0; j < H3800_KPIO_IRQ_COUNT; j++) if (irq & kpio_irq_mask[j]) handle_edge_irq(H3800_KPIO_IRQ_COUNT + j, irq_desc + H3800_KPIO_IRQ_COUNT + j); /* GPIO2 */ irq = H3800_ASIC2_GPIINTFLAG; - if (0) printk("%s GPIO 0x%08X\n", __FUNCTION__, irq); + if (0) printk("%s GPIO 0x%08X\n", __func__, irq); for (j = 0; j < H3800_GPIO_IRQ_COUNT; j++) if (irq & gpio_irq_mask[j]) handle_edge_irq(H3800_GPIO_IRQ_COUNT + j, irq_desc + H3800_GPIO_IRQ_COUNT + j); } if (i >= MAX_ASIC_ISR_LOOPS) - printk("%s: interrupt processing overrun\n", __FUNCTION__); + printk("%s: interrupt processing overrun\n", __func__); /* For level-based interrupts */ desc->chip->unmask(irq); diff --git a/arch/arm/mm/mmap.c b/arch/arm/mm/mmap.c index 2728b0e7d2bbd9a165e3f031454b9b5f1f7fc8aa..3f6dc40b835321fd469a23ce8ffa49089377e74b 100644 --- a/arch/arm/mm/mmap.c +++ b/arch/arm/mm/mmap.c @@ -120,6 +120,8 @@ full_search: */ int valid_phys_addr_range(unsigned long addr, size_t size) { + if (addr < PHYS_OFFSET) + return 0; if (addr + size > __pa(high_memory)) return 0; diff --git a/arch/arm/mm/pgd.c b/arch/arm/mm/pgd.c index 500c9610ab3085094ec48d012610b4f557136ec1..e0f19ab91163e589562d7b070f29d673fc9ef33f 100644 --- a/arch/arm/mm/pgd.c +++ b/arch/arm/mm/pgd.c @@ -75,7 +75,7 @@ no_pgd: void free_pgd_slow(struct mm_struct *mm, pgd_t *pgd) { pmd_t *pmd; - struct page *pte; + pgtable_t pte; if (!pgd) return; @@ -90,10 +90,8 @@ void free_pgd_slow(struct mm_struct *mm, pgd_t *pgd) goto free; } - pte = pmd_page(*pmd); + pte = pmd_pgtable(*pmd); pmd_clear(pmd); - dec_zone_page_state(virt_to_page((unsigned long *)pgd), NR_PAGETABLE); - pte_lock_deinit(pte); pte_free(mm, pte); pmd_free(mm, pmd); free: diff --git a/arch/arm/plat-iop/pci.c b/arch/arm/plat-iop/pci.c index 2b5aa1135b117395188b617eff8967a28682b5e9..98d01517b5634faf1448164f82183ba08c4f1aa7 100644 --- a/arch/arm/plat-iop/pci.c +++ b/arch/arm/plat-iop/pci.c @@ -371,7 +371,7 @@ static int __init iop3xx_init_atu_setup(char *str) default: printk(KERN_DEBUG "\"%s\" malformed at " "character: \'%c\'", - __FUNCTION__, + __func__, *str); *(str + 1) = '\0'; } diff --git a/arch/arm/plat-omap/cpu-omap.c b/arch/arm/plat-omap/cpu-omap.c index c0d63b0c61c9c5a54a11a298ea0f8d7334444e58..d719c15daa558286e27351df5443f1c436a3b484 100644 --- a/arch/arm/plat-omap/cpu-omap.c +++ b/arch/arm/plat-omap/cpu-omap.c @@ -33,43 +33,33 @@ #define MPU_CLK "virt_prcm_set" #endif +static struct clk *mpu_clk; + /* TODO: Add support for SDRAM timing changes */ int omap_verify_speed(struct cpufreq_policy *policy) { - struct clk * mpu_clk; - if (policy->cpu) return -EINVAL; cpufreq_verify_within_limits(policy, policy->cpuinfo.min_freq, policy->cpuinfo.max_freq); - mpu_clk = clk_get(NULL, MPU_CLK); - if (IS_ERR(mpu_clk)) - return PTR_ERR(mpu_clk); + policy->min = clk_round_rate(mpu_clk, policy->min * 1000) / 1000; policy->max = clk_round_rate(mpu_clk, policy->max * 1000) / 1000; cpufreq_verify_within_limits(policy, policy->cpuinfo.min_freq, policy->cpuinfo.max_freq); - clk_put(mpu_clk); - return 0; } unsigned int omap_getspeed(unsigned int cpu) { - struct clk * mpu_clk; unsigned long rate; if (cpu) return 0; - mpu_clk = clk_get(NULL, MPU_CLK); - if (IS_ERR(mpu_clk)) - return 0; rate = clk_get_rate(mpu_clk) / 1000; - clk_put(mpu_clk); - return rate; } @@ -77,14 +67,9 @@ static int omap_target(struct cpufreq_policy *policy, unsigned int target_freq, unsigned int relation) { - struct clk * mpu_clk; struct cpufreq_freqs freqs; int ret = 0; - mpu_clk = clk_get(NULL, MPU_CLK); - if (IS_ERR(mpu_clk)) - return PTR_ERR(mpu_clk); - freqs.old = omap_getspeed(0); freqs.new = clk_round_rate(mpu_clk, target_freq * 1000) / 1000; freqs.cpu = 0; @@ -92,15 +77,12 @@ static int omap_target(struct cpufreq_policy *policy, cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); ret = clk_set_rate(mpu_clk, target_freq * 1000); cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); - clk_put(mpu_clk); return ret; } static int __init omap_cpu_init(struct cpufreq_policy *policy) { - struct clk * mpu_clk; - mpu_clk = clk_get(NULL, MPU_CLK); if (IS_ERR(mpu_clk)) return PTR_ERR(mpu_clk); @@ -111,17 +93,23 @@ static int __init omap_cpu_init(struct cpufreq_policy *policy) policy->cpuinfo.min_freq = clk_round_rate(mpu_clk, 0) / 1000; policy->cpuinfo.max_freq = clk_round_rate(mpu_clk, VERY_HI_RATE) / 1000; policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL; - clk_put(mpu_clk); return 0; } +static int omap_cpu_exit(struct cpufreq_policy *policy) +{ + clk_put(mpu_clk); + return 0; +} + static struct cpufreq_driver omap_driver = { .flags = CPUFREQ_STICKY, .verify = omap_verify_speed, .target = omap_target, .get = omap_getspeed, .init = omap_cpu_init, + .exit = omap_cpu_exit, .name = "omap", }; diff --git a/arch/arm/plat-omap/devices.c b/arch/arm/plat-omap/devices.c index c5dab1d6417e113aeae93658b45a5d5730cdebb1..4a53f9ba6c43ce3c353531f4e7ba6edef98ac1b2 100644 --- a/arch/arm/plat-omap/devices.c +++ b/arch/arm/plat-omap/devices.c @@ -88,68 +88,6 @@ EXPORT_SYMBOL(dsp_kfunc_device_register); static inline void omap_init_dsp(void) { } #endif /* CONFIG_OMAP_DSP */ -/*-------------------------------------------------------------------------*/ -#if defined(CONFIG_I2C_OMAP) || defined(CONFIG_I2C_OMAP_MODULE) - -#define OMAP1_I2C_BASE 0xfffb3800 -#define OMAP2_I2C_BASE1 0x48070000 -#define OMAP_I2C_SIZE 0x3f -#define OMAP1_I2C_INT INT_I2C -#define OMAP2_I2C_INT1 56 - -static struct resource i2c_resources1[] = { - { - .start = 0, - .end = 0, - .flags = IORESOURCE_MEM, - }, - { - .start = 0, - .flags = IORESOURCE_IRQ, - }, -}; - -/* DMA not used; works around erratum writing to non-empty i2c fifo */ - -static struct platform_device omap_i2c_device1 = { - .name = "i2c_omap", - .id = 1, - .num_resources = ARRAY_SIZE(i2c_resources1), - .resource = i2c_resources1, -}; - -/* See also arch/arm/mach-omap2/devices.c for second I2C on 24xx */ -static void omap_init_i2c(void) -{ - if (cpu_is_omap24xx()) { - i2c_resources1[0].start = OMAP2_I2C_BASE1; - i2c_resources1[0].end = OMAP2_I2C_BASE1 + OMAP_I2C_SIZE; - i2c_resources1[1].start = OMAP2_I2C_INT1; - } else { - i2c_resources1[0].start = OMAP1_I2C_BASE; - i2c_resources1[0].end = OMAP1_I2C_BASE + OMAP_I2C_SIZE; - i2c_resources1[1].start = OMAP1_I2C_INT; - } - - /* FIXME define and use a boot tag, in case of boards that - * either don't wire up I2C, or chips that mux it differently... - * it can include clocking and address info, maybe more. - */ - if (cpu_is_omap24xx()) { - omap_cfg_reg(M19_24XX_I2C1_SCL); - omap_cfg_reg(L15_24XX_I2C1_SDA); - } else { - omap_cfg_reg(I2C_SCL); - omap_cfg_reg(I2C_SDA); - } - - (void) platform_device_register(&omap_i2c_device1); -} - -#else -static inline void omap_init_i2c(void) {} -#endif - /*-------------------------------------------------------------------------*/ #if defined(CONFIG_KEYBOARD_OMAP) || defined(CONFIG_KEYBOARD_OMAP_MODULE) @@ -501,7 +439,6 @@ static int __init omap_init_devices(void) * in alphabetical order so they're easier to sort through. */ omap_init_dsp(); - omap_init_i2c(); omap_init_kp(); omap_init_mmc(); omap_init_uwire(); diff --git a/arch/arm/plat-omap/dma.c b/arch/arm/plat-omap/dma.c index a46676db81138e5f1e06394179d2ee62fed6c95f..91004a3c4794fe1f90f41d856d3d389537465529 100644 --- a/arch/arm/plat-omap/dma.c +++ b/arch/arm/plat-omap/dma.c @@ -137,7 +137,7 @@ static void omap_disable_channel_irq(int lch); static inline void omap_enable_channel_irq(int lch); #define REVISIT_24XX() printk(KERN_ERR "FIXME: no %s on 24xx\n", \ - __FUNCTION__); + __func__); #ifdef CONFIG_ARCH_OMAP15XX /* Returns 1 if the DMA module is in OMAP1510-compatible mode, 0 otherwise */ @@ -699,7 +699,7 @@ omap_dma_set_global_params(int arb_rate, int max_fifo_depth, int tparams) u32 reg; if (!cpu_class_is_omap2()) { - printk(KERN_ERR "FIXME: no %s on 15xx/16xx\n", __FUNCTION__); + printk(KERN_ERR "FIXME: no %s on 15xx/16xx\n", __func__); return; } @@ -1705,14 +1705,8 @@ static int omap2_dma_handle_ch(int ch) status = OMAP_DMA_CSR_REG(ch); } - if (likely(dma_chan[ch].callback != NULL)) { - if (dma_chan[ch].chain_id != -1) - dma_chan[ch].callback(dma_chan[ch].chain_id, status, - dma_chan[ch].data); - else - dma_chan[ch].callback(ch, status, dma_chan[ch].data); - - } + if (likely(dma_chan[ch].callback != NULL)) + dma_chan[ch].callback(ch, status, dma_chan[ch].data); OMAP_DMA_CSR_REG(ch) = status; diff --git a/arch/arm/plat-omap/dmtimer.c b/arch/arm/plat-omap/dmtimer.c index e719d0eeb5c88f2b079d2d67c07486730dc55bbb..302ad8dff2cb5d49a088c43feb1fdea5fe46b027 100644 --- a/arch/arm/plat-omap/dmtimer.c +++ b/arch/arm/plat-omap/dmtimer.c @@ -268,7 +268,7 @@ struct omap_dm_timer *omap_dm_timer_request_specific(int id) if (id <= 0 || id > dm_timer_count || dm_timers[id-1].reserved) { spin_unlock_irqrestore(&dm_timer_lock, flags); printk("BUG: warning at %s:%d/%s(): unable to get timer %d\n", - __FILE__, __LINE__, __FUNCTION__, id); + __FILE__, __LINE__, __func__, id); dump_stack(); return NULL; } diff --git a/arch/arm/plat-omap/gpio.c b/arch/arm/plat-omap/gpio.c index 56f4d1394d562bdfc652a2d7f13ee436042ed88c..66a1455595f49c7d15c5b861ce332d5e6a448586 100644 --- a/arch/arm/plat-omap/gpio.c +++ b/arch/arm/plat-omap/gpio.c @@ -333,13 +333,14 @@ static void _set_gpio_direction(struct gpio_bank *bank, int gpio, int is_input) void omap_set_gpio_direction(int gpio, int is_input) { struct gpio_bank *bank; + unsigned long flags; if (check_gpio(gpio) < 0) return; bank = get_gpio_bank(gpio); - spin_lock(&bank->lock); + spin_lock_irqsave(&bank->lock, flags); _set_gpio_direction(bank, get_gpio_index(gpio), is_input); - spin_unlock(&bank->lock); + spin_unlock_irqrestore(&bank->lock, flags); } static void _set_gpio_dataout(struct gpio_bank *bank, int gpio, int enable) @@ -406,13 +407,14 @@ static void _set_gpio_dataout(struct gpio_bank *bank, int gpio, int enable) void omap_set_gpio_dataout(int gpio, int enable) { struct gpio_bank *bank; + unsigned long flags; if (check_gpio(gpio) < 0) return; bank = get_gpio_bank(gpio); - spin_lock(&bank->lock); + spin_lock_irqsave(&bank->lock, flags); _set_gpio_dataout(bank, get_gpio_index(gpio), enable); - spin_unlock(&bank->lock); + spin_unlock_irqrestore(&bank->lock, flags); } int omap_get_gpio_datain(int gpio) @@ -624,6 +626,7 @@ static int gpio_irq_type(unsigned irq, unsigned type) struct gpio_bank *bank; unsigned gpio; int retval; + unsigned long flags; if (!cpu_class_is_omap2() && irq > IH_MPUIO_BASE) gpio = OMAP_MPUIO(irq - IH_MPUIO_BASE); @@ -642,13 +645,13 @@ static int gpio_irq_type(unsigned irq, unsigned type) return -EINVAL; bank = get_irq_chip_data(irq); - spin_lock(&bank->lock); + spin_lock_irqsave(&bank->lock, flags); retval = _set_gpio_triggering(bank, get_gpio_index(gpio), type); if (retval == 0) { irq_desc[irq].status &= ~IRQ_TYPE_SENSE_MASK; irq_desc[irq].status |= type; } - spin_unlock(&bank->lock); + spin_unlock_irqrestore(&bank->lock, flags); return retval; } @@ -830,11 +833,13 @@ static inline void _set_gpio_irqenable(struct gpio_bank *bank, int gpio, int ena */ static int _set_gpio_wakeup(struct gpio_bank *bank, int gpio, int enable) { + unsigned long flags; + switch (bank->method) { #ifdef CONFIG_ARCH_OMAP16XX case METHOD_MPUIO: case METHOD_GPIO_1610: - spin_lock(&bank->lock); + spin_lock_irqsave(&bank->lock, flags); if (enable) { bank->suspend_wakeup |= (1 << gpio); enable_irq_wake(bank->irq); @@ -842,7 +847,7 @@ static int _set_gpio_wakeup(struct gpio_bank *bank, int gpio, int enable) disable_irq_wake(bank->irq); bank->suspend_wakeup &= ~(1 << gpio); } - spin_unlock(&bank->lock); + spin_unlock_irqrestore(&bank->lock, flags); return 0; #endif #if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX) @@ -853,7 +858,7 @@ static int _set_gpio_wakeup(struct gpio_bank *bank, int gpio, int enable) (bank - gpio_bank) * 32 + gpio); return -EINVAL; } - spin_lock(&bank->lock); + spin_lock_irqsave(&bank->lock, flags); if (enable) { bank->suspend_wakeup |= (1 << gpio); enable_irq_wake(bank->irq); @@ -861,7 +866,7 @@ static int _set_gpio_wakeup(struct gpio_bank *bank, int gpio, int enable) disable_irq_wake(bank->irq); bank->suspend_wakeup &= ~(1 << gpio); } - spin_unlock(&bank->lock); + spin_unlock_irqrestore(&bank->lock, flags); return 0; #endif default: @@ -897,16 +902,17 @@ static int gpio_wake_enable(unsigned int irq, unsigned int enable) int omap_request_gpio(int gpio) { struct gpio_bank *bank; + unsigned long flags; if (check_gpio(gpio) < 0) return -EINVAL; bank = get_gpio_bank(gpio); - spin_lock(&bank->lock); + spin_lock_irqsave(&bank->lock, flags); if (unlikely(bank->reserved_map & (1 << get_gpio_index(gpio)))) { printk(KERN_ERR "omap-gpio: GPIO %d is already reserved!\n", gpio); dump_stack(); - spin_unlock(&bank->lock); + spin_unlock_irqrestore(&bank->lock, flags); return -1; } bank->reserved_map |= (1 << get_gpio_index(gpio)); @@ -925,7 +931,7 @@ int omap_request_gpio(int gpio) __raw_writel(__raw_readl(reg) | (1 << get_gpio_index(gpio)), reg); } #endif - spin_unlock(&bank->lock); + spin_unlock_irqrestore(&bank->lock, flags); return 0; } @@ -933,15 +939,16 @@ int omap_request_gpio(int gpio) void omap_free_gpio(int gpio) { struct gpio_bank *bank; + unsigned long flags; if (check_gpio(gpio) < 0) return; bank = get_gpio_bank(gpio); - spin_lock(&bank->lock); + spin_lock_irqsave(&bank->lock, flags); if (unlikely(!(bank->reserved_map & (1 << get_gpio_index(gpio))))) { printk(KERN_ERR "omap-gpio: GPIO %d wasn't reserved!\n", gpio); dump_stack(); - spin_unlock(&bank->lock); + spin_unlock_irqrestore(&bank->lock, flags); return; } #ifdef CONFIG_ARCH_OMAP16XX @@ -960,7 +967,7 @@ void omap_free_gpio(int gpio) #endif bank->reserved_map &= ~(1 << get_gpio_index(gpio)); _reset_gpio(bank, gpio); - spin_unlock(&bank->lock); + spin_unlock_irqrestore(&bank->lock, flags); } /* @@ -1194,11 +1201,12 @@ static int omap_mpuio_suspend_late(struct platform_device *pdev, pm_message_t me { struct gpio_bank *bank = platform_get_drvdata(pdev); void __iomem *mask_reg = bank->base + OMAP_MPUIO_GPIO_MASKIT; + unsigned long flags; - spin_lock(&bank->lock); + spin_lock_irqsave(&bank->lock, flags); bank->saved_wakeup = __raw_readl(mask_reg); __raw_writel(0xffff & ~bank->suspend_wakeup, mask_reg); - spin_unlock(&bank->lock); + spin_unlock_irqrestore(&bank->lock, flags); return 0; } @@ -1207,10 +1215,11 @@ static int omap_mpuio_resume_early(struct platform_device *pdev) { struct gpio_bank *bank = platform_get_drvdata(pdev); void __iomem *mask_reg = bank->base + OMAP_MPUIO_GPIO_MASKIT; + unsigned long flags; - spin_lock(&bank->lock); + spin_lock_irqsave(&bank->lock, flags); __raw_writel(bank->saved_wakeup, mask_reg); - spin_unlock(&bank->lock); + spin_unlock_irqrestore(&bank->lock, flags); return 0; } @@ -1277,6 +1286,11 @@ static struct clk *gpio_fclks[OMAP34XX_NR_GPIOS]; static struct clk *gpio_iclks[OMAP34XX_NR_GPIOS]; #endif +/* This lock class tells lockdep that GPIO irqs are in a different + * category than their parents, so it won't report false recursion. + */ +static struct lock_class_key gpio_lock_class; + static int __init _omap_gpio_init(void) { int i; @@ -1450,6 +1464,7 @@ static int __init _omap_gpio_init(void) #endif for (j = bank->virtual_irq_start; j < bank->virtual_irq_start + gpio_count; j++) { + lockdep_set_class(&irq_desc[j].lock, &gpio_lock_class); set_irq_chip_data(j, bank); if (bank_is_mpuio(bank)) set_irq_chip(j, &mpuio_irq_chip); @@ -1489,6 +1504,7 @@ static int omap_gpio_suspend(struct sys_device *dev, pm_message_t mesg) void __iomem *wake_status; void __iomem *wake_clear; void __iomem *wake_set; + unsigned long flags; switch (bank->method) { #ifdef CONFIG_ARCH_OMAP16XX @@ -1509,11 +1525,11 @@ static int omap_gpio_suspend(struct sys_device *dev, pm_message_t mesg) continue; } - spin_lock(&bank->lock); + spin_lock_irqsave(&bank->lock, flags); bank->saved_wakeup = __raw_readl(wake_status); __raw_writel(0xffffffff, wake_clear); __raw_writel(bank->suspend_wakeup, wake_set); - spin_unlock(&bank->lock); + spin_unlock_irqrestore(&bank->lock, flags); } return 0; @@ -1530,6 +1546,7 @@ static int omap_gpio_resume(struct sys_device *dev) struct gpio_bank *bank = &gpio_bank[i]; void __iomem *wake_clear; void __iomem *wake_set; + unsigned long flags; switch (bank->method) { #ifdef CONFIG_ARCH_OMAP16XX @@ -1548,10 +1565,10 @@ static int omap_gpio_resume(struct sys_device *dev) continue; } - spin_lock(&bank->lock); + spin_lock_irqsave(&bank->lock, flags); __raw_writel(0xffffffff, wake_clear); __raw_writel(bank->saved_wakeup, wake_set); - spin_unlock(&bank->lock); + spin_unlock_irqrestore(&bank->lock, flags); } return 0; diff --git a/arch/arm/plat-s3c24xx/dma.c b/arch/arm/plat-s3c24xx/dma.c index ac9ff1666fccf729ba3f2b85b38c21e4e2ed5626..60f162dc4fad5d1617f074c5256dc5c8b8227e03 100644 --- a/arch/arm/plat-s3c24xx/dma.c +++ b/arch/arm/plat-s3c24xx/dma.c @@ -130,8 +130,8 @@ dmadbg_showregs(const char *fname, int line, struct s3c2410_dma_chan *chan) dmadbg_dumpregs(fname, line, chan, &state); } -#define dbg_showregs(chan) dmadbg_showregs(__FUNCTION__, __LINE__, (chan)) -#define dbg_showchan(chan) dmadbg_showchan(__FUNCTION__, __LINE__, (chan)) +#define dbg_showregs(chan) dmadbg_showregs(__func__, __LINE__, (chan)) +#define dbg_showchan(chan) dmadbg_showchan(__func__, __LINE__, (chan)) #else #define dbg_showregs(chan) do { } while(0) #define dbg_showchan(chan) do { } while(0) @@ -403,7 +403,7 @@ static int s3c2410_dma_start(struct s3c2410_dma_chan *chan) if (s3c2410_dma_waitforload(chan, __LINE__) == 0) { pr_debug("%s: buff not yet loaded, no more todo\n", - __FUNCTION__); + __func__); } else { chan->load_state = S3C2410_DMALOAD_1RUNNING; s3c2410_dma_loadbuffer(chan, chan->next); @@ -463,16 +463,16 @@ int s3c2410_dma_enqueue(unsigned int channel, void *id, return -EINVAL; pr_debug("%s: id=%p, data=%08x, size=%d\n", - __FUNCTION__, id, (unsigned int)data, size); + __func__, id, (unsigned int)data, size); buf = kmem_cache_alloc(dma_kmem, GFP_ATOMIC); if (buf == NULL) { pr_debug("%s: out of memory (%ld alloc)\n", - __FUNCTION__, (long)sizeof(*buf)); + __func__, (long)sizeof(*buf)); return -ENOMEM; } - //pr_debug("%s: new buffer %p\n", __FUNCTION__, buf); + //pr_debug("%s: new buffer %p\n", __func__, buf); //dbg_showchan(chan); buf->next = NULL; @@ -486,18 +486,18 @@ int s3c2410_dma_enqueue(unsigned int channel, void *id, if (chan->curr == NULL) { /* we've got nothing loaded... */ pr_debug("%s: buffer %p queued onto empty channel\n", - __FUNCTION__, buf); + __func__, buf); chan->curr = buf; chan->end = buf; chan->next = NULL; } else { pr_debug("dma%d: %s: buffer %p queued onto non-empty channel\n", - chan->number, __FUNCTION__, buf); + chan->number, __func__, buf); if (chan->end == NULL) pr_debug("dma%d: %s: %p not empty, and chan->end==NULL?\n", - chan->number, __FUNCTION__, chan); + chan->number, __func__, chan); chan->end->next = buf; chan->end = buf; @@ -572,7 +572,7 @@ s3c2410_dma_lastxfer(struct s3c2410_dma_chan *chan) if (s3c2410_dma_waitforload(chan, __LINE__) == 0) { /* flag error? */ printk(KERN_ERR "dma%d: timeout waiting for load (%s)\n", - chan->number, __FUNCTION__); + chan->number, __func__); return; } break; @@ -658,7 +658,7 @@ s3c2410_dma_irq(int irq, void *devpw) if (buf->magic != BUF_MAGIC) { printk(KERN_ERR "dma%d: %s: buf %p incorrect magic\n", - chan->number, __FUNCTION__, buf); + chan->number, __func__, buf); return IRQ_HANDLED; } @@ -692,7 +692,7 @@ s3c2410_dma_irq(int irq, void *devpw) if (s3c2410_dma_waitforload(chan, __LINE__) == 0) { /* flag error? */ printk(KERN_ERR "dma%d: timeout waiting for load (%s)\n", - chan->number, __FUNCTION__); + chan->number, __func__); return IRQ_HANDLED; } @@ -759,7 +759,7 @@ int s3c2410_dma_request(unsigned int channel, if (!chan->irq_claimed) { pr_debug("dma%d: %s : requesting irq %d\n", - channel, __FUNCTION__, chan->irq); + channel, __func__, chan->irq); chan->irq_claimed = 1; local_irq_restore(flags); @@ -786,7 +786,7 @@ int s3c2410_dma_request(unsigned int channel, /* need to setup */ - pr_debug("%s: channel initialised, %p\n", __FUNCTION__, chan); + pr_debug("%s: channel initialised, %p\n", __func__, chan); return chan->number | DMACH_LOW_LEVEL; } @@ -823,7 +823,7 @@ int s3c2410_dma_free(dmach_t channel, struct s3c2410_dma_client *client) if (chan->state != S3C2410_DMA_IDLE) { pr_debug("%s: need to stop dma channel %p\n", - __FUNCTION__, chan); + __func__, chan); /* possibly flush the channel */ s3c2410_dma_ctrl(channel, S3C2410_DMAOP_STOP); @@ -852,7 +852,7 @@ static int s3c2410_dma_dostop(struct s3c2410_dma_chan *chan) unsigned long flags; unsigned long tmp; - pr_debug("%s:\n", __FUNCTION__); + pr_debug("%s:\n", __func__); dbg_showchan(chan); @@ -907,14 +907,14 @@ static int s3c2410_dma_flush(struct s3c2410_dma_chan *chan) struct s3c2410_dma_buf *buf, *next; unsigned long flags; - pr_debug("%s: chan %p (%d)\n", __FUNCTION__, chan, chan->number); + pr_debug("%s: chan %p (%d)\n", __func__, chan, chan->number); dbg_showchan(chan); local_irq_save(flags); if (chan->state != S3C2410_DMA_IDLE) { - pr_debug("%s: stopping channel...\n", __FUNCTION__ ); + pr_debug("%s: stopping channel...\n", __func__ ); s3c2410_dma_ctrl(chan->number, S3C2410_DMAOP_STOP); } @@ -929,7 +929,7 @@ static int s3c2410_dma_flush(struct s3c2410_dma_chan *chan) next = buf->next; pr_debug("%s: free buffer %p, next %p\n", - __FUNCTION__, buf, buf->next); + __func__, buf, buf->next); s3c2410_dma_buffdone(chan, buf, S3C2410_RES_ABORT); s3c2410_dma_freebuf(buf); @@ -976,7 +976,7 @@ static int s3c2410_dma_started(struct s3c2410_dma_chan *chan) if (s3c2410_dma_waitforload(chan, __LINE__) == 0) { pr_debug("%s: buff not yet loaded, no more todo\n", - __FUNCTION__); + __func__); } else { chan->load_state = S3C2410_DMALOAD_1RUNNING; s3c2410_dma_loadbuffer(chan, chan->next); @@ -1050,16 +1050,16 @@ int s3c2410_dma_config(dmach_t channel, struct s3c2410_dma_chan *chan = lookup_dma_channel(channel); pr_debug("%s: chan=%d, xfer_unit=%d, dcon=%08x\n", - __FUNCTION__, channel, xferunit, dcon); + __func__, channel, xferunit, dcon); if (chan == NULL) return -EINVAL; - pr_debug("%s: Initial dcon is %08x\n", __FUNCTION__, dcon); + pr_debug("%s: Initial dcon is %08x\n", __func__, dcon); dcon |= chan->dcon & dma_sel.dcon_mask; - pr_debug("%s: New dcon is %08x\n", __FUNCTION__, dcon); + pr_debug("%s: New dcon is %08x\n", __func__, dcon); switch (xferunit) { case 1: @@ -1075,14 +1075,14 @@ int s3c2410_dma_config(dmach_t channel, break; default: - pr_debug("%s: bad transfer size %d\n", __FUNCTION__, xferunit); + pr_debug("%s: bad transfer size %d\n", __func__, xferunit); return -EINVAL; } dcon |= S3C2410_DCON_HWTRIG; dcon |= S3C2410_DCON_INTREQ; - pr_debug("%s: dcon now %08x\n", __FUNCTION__, dcon); + pr_debug("%s: dcon now %08x\n", __func__, dcon); chan->dcon = dcon; chan->xfer_unit = xferunit; @@ -1099,7 +1099,7 @@ int s3c2410_dma_setflags(dmach_t channel, unsigned int flags) if (chan == NULL) return -EINVAL; - pr_debug("%s: chan=%p, flags=%08x\n", __FUNCTION__, chan, flags); + pr_debug("%s: chan=%p, flags=%08x\n", __func__, chan, flags); chan->flags = flags; @@ -1120,7 +1120,7 @@ int s3c2410_dma_set_opfn(dmach_t channel, s3c2410_dma_opfn_t rtn) if (chan == NULL) return -EINVAL; - pr_debug("%s: chan=%p, op rtn=%p\n", __FUNCTION__, chan, rtn); + pr_debug("%s: chan=%p, op rtn=%p\n", __func__, chan, rtn); chan->op_fn = rtn; @@ -1136,7 +1136,7 @@ int s3c2410_dma_set_buffdone_fn(dmach_t channel, s3c2410_dma_cbfn_t rtn) if (chan == NULL) return -EINVAL; - pr_debug("%s: chan=%p, callback rtn=%p\n", __FUNCTION__, chan, rtn); + pr_debug("%s: chan=%p, callback rtn=%p\n", __func__, chan, rtn); chan->callback_fn = rtn; @@ -1170,7 +1170,7 @@ int s3c2410_dma_devconfig(int channel, return -EINVAL; pr_debug("%s: source=%d, hwcfg=%08x, devaddr=%08lx\n", - __FUNCTION__, (int)source, hwcfg, devaddr); + __func__, (int)source, hwcfg, devaddr); chan->source = source; chan->dev_addr = devaddr; @@ -1180,7 +1180,7 @@ int s3c2410_dma_devconfig(int channel, case S3C2410_DMASRC_HW: /* source is hardware */ pr_debug("%s: hw source, devaddr=%08lx, hwcfg=%d\n", - __FUNCTION__, devaddr, hwcfg); + __func__, devaddr, hwcfg); dma_wrreg(chan, S3C2410_DMA_DISRCC, hwcfg & 3); dma_wrreg(chan, S3C2410_DMA_DISRC, devaddr); dma_wrreg(chan, S3C2410_DMA_DIDSTC, (0<<1) | (0<<0)); @@ -1190,8 +1190,8 @@ int s3c2410_dma_devconfig(int channel, case S3C2410_DMASRC_MEM: /* source is memory */ - pr_debug( "%s: mem source, devaddr=%08lx, hwcfg=%d\n", - __FUNCTION__, devaddr, hwcfg); + pr_debug("%s: mem source, devaddr=%08lx, hwcfg=%d\n", + __func__, devaddr, hwcfg); dma_wrreg(chan, S3C2410_DMA_DISRCC, (0<<1) | (0<<0)); dma_wrreg(chan, S3C2410_DMA_DIDST, devaddr); dma_wrreg(chan, S3C2410_DMA_DIDSTC, hwcfg & 3); diff --git a/arch/avr32/boards/atstk1000/atstk1004.c b/arch/avr32/boards/atstk1000/atstk1004.c index 5a77030e07a091a8cf22bfa1b1d52867f025dc50..e765a8652b3ee58480847302923170ed668150d3 100644 --- a/arch/avr32/boards/atstk1000/atstk1004.c +++ b/arch/avr32/boards/atstk1000/atstk1004.c @@ -129,7 +129,7 @@ static int __init atstk1004_init(void) #ifdef CONFIG_BOARD_ATSTK100X_SPI1 at32_add_device_spi(1, spi1_board_info, ARRAY_SIZE(spi1_board_info)); #endif -#ifndef CONFIG_BOARD_ATSTK1002_SW2_CUSTOM +#ifndef CONFIG_BOARD_ATSTK100X_SW2_CUSTOM at32_add_device_mci(0); #endif at32_add_device_lcdc(0, &atstk1000_lcdc_data, diff --git a/arch/avr32/kernel/process.c b/arch/avr32/kernel/process.c index eaaa69bbdc38d5546b395311f29896a6a2c357db..7f4af0b1e111448f4941fbb7d3ae94589f13a961 100644 --- a/arch/avr32/kernel/process.c +++ b/arch/avr32/kernel/process.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include @@ -30,8 +31,10 @@ void cpu_idle(void) { /* endless idle loop with no priority at all */ while (1) { + tick_nohz_stop_sched_tick(); while (!need_resched()) cpu_idle_sleep(); + tick_nohz_restart_sched_tick(); preempt_enable_no_resched(); schedule(); preempt_disable(); @@ -345,6 +348,7 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long usp, p->thread.cpu_context.ksp = (unsigned long)childregs; p->thread.cpu_context.pc = (unsigned long)ret_from_fork; + clear_tsk_thread_flag(p, TIF_DEBUG); if ((clone_flags & CLONE_PTRACE) && test_thread_flag(TIF_DEBUG)) ocd_enable(p); diff --git a/arch/avr32/mm/fault.c b/arch/avr32/mm/fault.c index 6560cb18b4e3403e498cb9076ea7025b61cbb2d0..ce4e4296b95467f3e0b715a9ec953398917be8f7 100644 --- a/arch/avr32/mm/fault.c +++ b/arch/avr32/mm/fault.c @@ -189,6 +189,8 @@ no_context: page = sysreg_read(PTBR); printk(KERN_ALERT "ptbr = %08lx", page); + if (address >= TASK_SIZE) + page = (unsigned long)swapper_pg_dir; if (page) { page = ((unsigned long *)page)[address >> 22]; printk(" pgd = %08lx", page); diff --git a/arch/blackfin/Makefile b/arch/blackfin/Makefile index fe254f886a6e15c8702f49d9d08b9c90fefc1a17..75eba2ca788149fb610f3b91ff63aa2286e013bf 100644 --- a/arch/blackfin/Makefile +++ b/arch/blackfin/Makefile @@ -98,8 +98,11 @@ drivers-$(CONFIG_OPROFILE) += arch/$(ARCH)/oprofile/ # them changed. We use .mach to indicate when they were updated # last, otherwise make uses the target directory mtime. + show_mach_symlink = : + quiet_show_mach_symlink = echo ' SYMLINK include/asm-$(ARCH)/mach-$(MACHINE) -> include/asm-$(ARCH)/mach' +silent_show_mach_symlink = : include/asm-blackfin/.mach: $(wildcard include/config/arch/*.h) include/config/auto.conf - @echo ' SYMLINK include/asm-$(ARCH)/mach-$(MACHINE) -> include/asm-$(ARCH)/mach' + @$($(quiet)show_mach_symlink) ifneq ($(KBUILD_SRC),) $(Q)mkdir -p include/asm-$(ARCH) $(Q)ln -fsn $(srctree)/include/asm-$(ARCH)/mach-$(MACHINE) include/asm-$(ARCH)/mach diff --git a/arch/blackfin/configs/BF527-EZKIT_defconfig b/arch/blackfin/configs/BF527-EZKIT_defconfig index d59ee1530bd400938ca73324fe4b9efcd6ee9907..ae320dcfedefe9b064bdeddfdf45ae052d340c27 100644 --- a/arch/blackfin/configs/BF527-EZKIT_defconfig +++ b/arch/blackfin/configs/BF527-EZKIT_defconfig @@ -1,7 +1,6 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.22.14 -# Thu Nov 29 17:32:47 2007 +# Linux kernel version: 2.6.22.16 # # CONFIG_MMU is not set # CONFIG_FPU is not set @@ -116,7 +115,10 @@ CONFIG_PREEMPT_VOLUNTARY=y # Processor and Board Settings # # CONFIG_BF522 is not set +# CONFIG_BF523 is not set +# CONFIG_BF524 is not set # CONFIG_BF525 is not set +# CONFIG_BF526 is not set CONFIG_BF527=y # CONFIG_BF531 is not set # CONFIG_BF532 is not set @@ -306,6 +308,7 @@ CONFIG_BFIN_DCACHE=y # CONFIG_BFIN_WB is not set CONFIG_BFIN_WT=y CONFIG_L1_MAX_PIECE=16 +# CONFIG_MPU is not set # # Asynchonous Memory Configuration @@ -354,6 +357,7 @@ CONFIG_BINFMT_ZFLAT=y # Power management options # # CONFIG_PM is not set +# CONFIG_PM_WAKEUP_BY_GPIO is not set # # Networking @@ -496,7 +500,6 @@ CONFIG_MTD_CFI_I2=y # CONFIG_MTD_CFI_INTELEXT is not set # CONFIG_MTD_CFI_AMDSTD is not set # CONFIG_MTD_CFI_STAA is not set -CONFIG_MTD_MW320D=m CONFIG_MTD_RAM=y CONFIG_MTD_ROM=m # CONFIG_MTD_ABSENT is not set @@ -506,9 +509,6 @@ CONFIG_MTD_ROM=m # CONFIG_MTD_COMPLEX_MAPPINGS=y # CONFIG_MTD_PHYSMAP is not set -CONFIG_MTD_BF5xx=m -CONFIG_BFIN_FLASH_SIZE=0x400000 -CONFIG_EBIU_FLASH_BASE=0x20000000 # CONFIG_MTD_UCLINUX is not set # CONFIG_MTD_PLATRAM is not set @@ -684,7 +684,6 @@ CONFIG_INPUT_MISC=y # CONFIG_INPUT_POWERMATE is not set # CONFIG_INPUT_YEALINK is not set # CONFIG_INPUT_UINPUT is not set -# CONFIG_BF53X_PFBUTTONS is not set # CONFIG_TWI_KEYPAD is not set # @@ -702,12 +701,12 @@ CONFIG_INPUT_MISC=y # CONFIG_BF5xx_PPIFCD is not set # CONFIG_BFIN_SIMPLE_TIMER is not set # CONFIG_BF5xx_PPI is not set +CONFIG_BFIN_OTP=y +# CONFIG_BFIN_OTP_WRITE_ENABLE is not set # CONFIG_BFIN_SPORT is not set # CONFIG_BFIN_TIMER_LATENCY is not set # CONFIG_TWI_LCD is not set # CONFIG_AD5304 is not set -# CONFIG_BF5xx_TEA5764 is not set -# CONFIG_BF5xx_FBDMA is not set # CONFIG_VT is not set # CONFIG_SERIAL_NONSTANDARD is not set @@ -772,7 +771,6 @@ CONFIG_I2C_CHARDEV=m # # I2C Hardware Bus support # -# CONFIG_I2C_BLACKFIN_GPIO is not set CONFIG_I2C_BLACKFIN_TWI=m CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ=50 # CONFIG_I2C_GPIO is not set diff --git a/arch/blackfin/configs/BF533-EZKIT_defconfig b/arch/blackfin/configs/BF533-EZKIT_defconfig index 811711f59a25664ecb3a83af9825d02f8b55b49d..9621caa60b5fc36a5ff0a26d06294f40cb71ae26 100644 --- a/arch/blackfin/configs/BF533-EZKIT_defconfig +++ b/arch/blackfin/configs/BF533-EZKIT_defconfig @@ -322,10 +322,9 @@ CONFIG_PM=y # CONFIG_PM_LEGACY is not set # CONFIG_PM_DEBUG is not set # CONFIG_PM_SYSFS_DEPRECATED is not set -CONFIG_PM_WAKEUP_GPIO_BY_SIC_IWR=y +CONFIG_PM_BFIN_SLEEP_DEEPER=y +# CONFIG_PM_BFIN_SLEEP is not set # CONFIG_PM_WAKEUP_BY_GPIO is not set -# CONFIG_PM_WAKEUP_GPIO_API is not set -CONFIG_PM_WAKEUP_SIC_IWR=0x80 # # CPU Frequency scaling @@ -697,7 +696,6 @@ CONFIG_SERIAL_BFIN_DMA=y # CONFIG_SERIAL_BFIN_PIO is not set CONFIG_SERIAL_BFIN_UART0=y # CONFIG_BFIN_UART0_CTSRTS is not set -# CONFIG_SERIAL_BFIN_UART1 is not set CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y # CONFIG_SERIAL_BFIN_SPORT is not set diff --git a/arch/blackfin/configs/BF533-STAMP_defconfig b/arch/blackfin/configs/BF533-STAMP_defconfig index 198f4123af4b4239f2171487d567ca7c2caa2fba..b51e76ce7f4f9812c4e6676e60890842f3300c18 100644 --- a/arch/blackfin/configs/BF533-STAMP_defconfig +++ b/arch/blackfin/configs/BF533-STAMP_defconfig @@ -323,10 +323,9 @@ CONFIG_PM=y # CONFIG_PM_LEGACY is not set # CONFIG_PM_DEBUG is not set # CONFIG_PM_SYSFS_DEPRECATED is not set -CONFIG_PM_WAKEUP_GPIO_BY_SIC_IWR=y +CONFIG_PM_BFIN_SLEEP_DEEPER=y +# CONFIG_PM_BFIN_SLEEP is not set # CONFIG_PM_WAKEUP_BY_GPIO is not set -# CONFIG_PM_WAKEUP_GPIO_API is not set -CONFIG_PM_WAKEUP_SIC_IWR=0x80 # # CPU Frequency scaling @@ -714,7 +713,6 @@ CONFIG_SERIAL_BFIN_DMA=y # CONFIG_SERIAL_BFIN_PIO is not set CONFIG_SERIAL_BFIN_UART0=y # CONFIG_BFIN_UART0_CTSRTS is not set -# CONFIG_SERIAL_BFIN_UART1 is not set CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y # CONFIG_SERIAL_BFIN_SPORT is not set diff --git a/arch/blackfin/configs/BF537-STAMP_defconfig b/arch/blackfin/configs/BF537-STAMP_defconfig index b37ccc681e7a7b904aa49693e270d8d80d4765e3..d45fa535dad7d4c8494cd279dff63cd51c6bb54d 100644 --- a/arch/blackfin/configs/BF537-STAMP_defconfig +++ b/arch/blackfin/configs/BF537-STAMP_defconfig @@ -330,10 +330,9 @@ CONFIG_PM=y # CONFIG_PM_LEGACY is not set # CONFIG_PM_DEBUG is not set # CONFIG_PM_SYSFS_DEPRECATED is not set -CONFIG_PM_WAKEUP_GPIO_BY_SIC_IWR=y +CONFIG_PM_BFIN_SLEEP_DEEPER=y +# CONFIG_PM_BFIN_SLEEP is not set # CONFIG_PM_WAKEUP_BY_GPIO is not set -# CONFIG_PM_WAKEUP_GPIO_API is not set -CONFIG_PM_WAKEUP_SIC_IWR=0x8 # # CPU Frequency scaling @@ -1013,6 +1012,7 @@ CONFIG_SND_BFIN_AD73311_SE=4 CONFIG_SND_SOC_AC97_BUS=y CONFIG_SND_SOC=m CONFIG_SND_BF5XX_SOC=m +CONFIG_SND_MMAP_SUPPORT=y CONFIG_SND_BF5XX_SOC_AC97=m # CONFIG_SND_BF5XX_SOC_WM8750 is not set # CONFIG_SND_BF5XX_SOC_WM8731 is not set diff --git a/arch/blackfin/configs/BF548-EZKIT_defconfig b/arch/blackfin/configs/BF548-EZKIT_defconfig index fd702161ef59f930f69eceab71421d615e2de5ed..c9707f7665ad8ca021bbfe9819a1dec06af40471 100644 --- a/arch/blackfin/configs/BF548-EZKIT_defconfig +++ b/arch/blackfin/configs/BF548-EZKIT_defconfig @@ -396,6 +396,7 @@ CONFIG_BINFMT_ZFLAT=y # Power management options # # CONFIG_PM is not set +# CONFIG_PM_WAKEUP_BY_GPIO is not set # # CPU Frequency scaling @@ -1075,6 +1076,7 @@ CONFIG_SND_VERBOSE_PROCFS=y CONFIG_SND_SOC_AC97_BUS=y CONFIG_SND_SOC=y CONFIG_SND_BF5XX_SOC=y +CONFIG_SND_MMAP_SUPPORT=y CONFIG_SND_BF5XX_SOC_AC97=y CONFIG_SND_BF5XX_SOC_BF548_EZKIT=y # CONFIG_SND_BF5XX_SOC_WM8750 is not set diff --git a/arch/blackfin/configs/BF561-EZKIT_defconfig b/arch/blackfin/configs/BF561-EZKIT_defconfig index 8546994939fb08c9bfacf7da7c13d81d601475a2..4d8a633313091b95189547d1be6d50d9ea1cce59 100644 --- a/arch/blackfin/configs/BF561-EZKIT_defconfig +++ b/arch/blackfin/configs/BF561-EZKIT_defconfig @@ -367,6 +367,7 @@ CONFIG_BINFMT_ZFLAT=y # Power management options # # CONFIG_PM is not set +# CONFIG_PM_WAKEUP_BY_GPIO is not set # # Networking diff --git a/arch/blackfin/kernel/bfin_dma_5xx.c b/arch/blackfin/kernel/bfin_dma_5xx.c index 5453bc3664fc40eb47474f8a2297c6ae7e0835ac..8fd5d22cec34d124dfedb031bcad84a4149a4b33 100644 --- a/arch/blackfin/kernel/bfin_dma_5xx.c +++ b/arch/blackfin/kernel/bfin_dma_5xx.c @@ -105,13 +105,14 @@ int request_dma(unsigned int channel, char *device_id) mutex_unlock(&(dma_ch[channel].dmalock)); #ifdef CONFIG_BF54x - if (channel >= CH_UART2_RX && channel <= CH_UART3_TX && - strncmp(device_id, "BFIN_UART", 9) == 0) - dma_ch[channel].regs->peripheral_map |= - (channel - CH_UART2_RX + 0xC); - else - dma_ch[channel].regs->peripheral_map |= - (channel - CH_UART2_RX + 0x6); + if (channel >= CH_UART2_RX && channel <= CH_UART3_TX) { + if (strncmp(device_id, "BFIN_UART", 9) == 0) + dma_ch[channel].regs->peripheral_map |= + (channel - CH_UART2_RX + 0xC); + else + dma_ch[channel].regs->peripheral_map |= + (channel - CH_UART2_RX + 0x6); + } #endif dma_ch[channel].device_id = device_id; diff --git a/arch/blackfin/kernel/fixed_code.S b/arch/blackfin/kernel/fixed_code.S index 90262691b11a299993108608e0ad63d19feb0a63..5ed47228a39075a284e99801d7c79165f6b7367f 100644 --- a/arch/blackfin/kernel/fixed_code.S +++ b/arch/blackfin/kernel/fixed_code.S @@ -101,9 +101,9 @@ ENDPROC (_atomic_ior32) .align 16 /* - * Atomic ior, 32 bit. + * Atomic and, 32 bit. * Inputs: P0: memory address to use - * R0: value to ior + * R0: value to and * Outputs: R0: new contents of the memory address. * R1: previous contents of the memory address. */ @@ -112,13 +112,13 @@ ENTRY(_atomic_and32) R0 = R1 & R0; [P0] = R0; rts; -ENDPROC (_atomic_ior32) +ENDPROC (_atomic_and32) .align 16 /* - * Atomic ior, 32 bit. + * Atomic xor, 32 bit. * Inputs: P0: memory address to use - * R0: value to ior + * R0: value to xor * Outputs: R0: new contents of the memory address. * R1: previous contents of the memory address. */ @@ -127,7 +127,7 @@ ENTRY(_atomic_xor32) R0 = R1 ^ R0; [P0] = R0; rts; -ENDPROC (_atomic_ior32) +ENDPROC (_atomic_xor32) .align 16 /* diff --git a/arch/blackfin/kernel/gptimers.c b/arch/blackfin/kernel/gptimers.c index 5cf4bdb1df3bffdd09bea1bd295033345fddcfc9..1904d8b53328fad9440b33a4cfdb391e7d2f0473 100644 --- a/arch/blackfin/kernel/gptimers.c +++ b/arch/blackfin/kernel/gptimers.c @@ -1,9 +1,9 @@ /* - * bfin_gptimers.c - derived from bf53x_timers.c - * Driver for General Purpose Timer functions on the Blackfin processor + * gptimers.c - Blackfin General Purpose Timer core API * - * Copyright (C) 2005 John DeHority - * Copyright (C) 2006 Hella Aglaia GmbH (awe@aglaia-gmbh.de) + * Copyright (c) 2005-2008 Analog Devices Inc. + * Copyright (C) 2005 John DeHority + * Copyright (C) 2006 Hella Aglaia GmbH (awe@aglaia-gmbh.de) * * Licensed under the GPLv2. */ diff --git a/arch/blackfin/kernel/setup.c b/arch/blackfin/kernel/setup.c index 8229b1090eb9622a427561d675cf59f1df153d85..2255c289a714db37938d0b96345de10335dbc7ae 100644 --- a/arch/blackfin/kernel/setup.c +++ b/arch/blackfin/kernel/setup.c @@ -32,6 +32,7 @@ static DEFINE_PER_CPU(struct cpu, cpu_devices); u16 _bfin_swrst; +EXPORT_SYMBOL(_bfin_swrst); unsigned long memory_start, memory_end, physical_mem_end; unsigned long reserved_mem_dcache_on; @@ -514,6 +515,7 @@ static __init void memory_setup(void) printk(KERN_INFO "Kernel Managed Memory: %ldMB\n", _ramend >> 20); printk(KERN_INFO "Memory map:\n" + KERN_INFO " fixedcode = 0x%p-0x%p\n" KERN_INFO " text = 0x%p-0x%p\n" KERN_INFO " rodata = 0x%p-0x%p\n" KERN_INFO " bss = 0x%p-0x%p\n" @@ -527,7 +529,8 @@ static __init void memory_setup(void) #if DMA_UNCACHED_REGION > 0 KERN_INFO " DMA Zone = 0x%p-0x%p\n" #endif - , _stext, _etext, + , (void *)FIXED_CODE_START, (void *)FIXED_CODE_END, + _stext, _etext, __start_rodata, __end_rodata, __bss_start, __bss_stop, _sdata, _edata, diff --git a/arch/blackfin/kernel/vmlinux.lds.S b/arch/blackfin/kernel/vmlinux.lds.S index aed832540b3b1e158fe440b566d7aedd50f34c37..cb01a9de26802aad098eef036a434cdaf8d6b0d7 100644 --- a/arch/blackfin/kernel/vmlinux.lds.S +++ b/arch/blackfin/kernel/vmlinux.lds.S @@ -147,44 +147,64 @@ SECTIONS __l1_lma_start = .; +#if L1_CODE_LENGTH +# define LDS_L1_CODE *(.l1.text) +#else +# define LDS_L1_CODE +#endif .text_l1 L1_CODE_START : AT(LOADADDR(.init.ramfs) + SIZEOF(.init.ramfs)) { . = ALIGN(4); __stext_l1 = .; - *(.l1.text) - + LDS_L1_CODE . = ALIGN(4); __etext_l1 = .; } +#if L1_DATA_A_LENGTH +# define LDS_L1_A_DATA *(.l1.data) +# define LDS_L1_A_BSS *(.l1.bss) +# define LDS_L1_A_CACHE *(.data_l1.cacheline_aligned) +#else +# define LDS_L1_A_DATA +# define LDS_L1_A_BSS +# define LDS_L1_A_CACHE +#endif .data_l1 L1_DATA_A_START : AT(LOADADDR(.text_l1) + SIZEOF(.text_l1)) { . = ALIGN(4); __sdata_l1 = .; - *(.l1.data) + LDS_L1_A_DATA __edata_l1 = .; . = ALIGN(4); __sbss_l1 = .; - *(.l1.bss) + LDS_L1_A_BSS . = ALIGN(32); - *(.data_l1.cacheline_aligned) + LDS_L1_A_CACHE . = ALIGN(4); __ebss_l1 = .; } +#if L1_DATA_B_LENGTH +# define LDS_L1_B_DATA *(.l1.data.B) +# define LDS_L1_B_BSS *(.l1.bss.B) +#else +# define LDS_L1_B_DATA +# define LDS_L1_B_BSS +#endif .data_b_l1 L1_DATA_B_START : AT(LOADADDR(.data_l1) + SIZEOF(.data_l1)) { . = ALIGN(4); __sdata_b_l1 = .; - *(.l1.data.B) + LDS_L1_B_DATA __edata_b_l1 = .; . = ALIGN(4); __sbss_b_l1 = .; - *(.l1.bss.B) + LDS_L1_B_BSS . = ALIGN(4); __ebss_b_l1 = .; diff --git a/arch/blackfin/mach-bf527/boards/ezkit.c b/arch/blackfin/mach-bf527/boards/ezkit.c index 337515fba612e43a3b8f23aaf1822a1196f911fa..cf4bc0d8335521737422e2d3c3796278e4962fee 100644 --- a/arch/blackfin/mach-bf527/boards/ezkit.c +++ b/arch/blackfin/mach-bf527/boards/ezkit.c @@ -180,8 +180,8 @@ static struct mtd_partition partition_info[] = { }, { .name = "File System", - .offset = 4 * SIZE_1M, - .size = (256 - 4) * SIZE_1M, + .offset = MTDPART_OFS_APPEND, + .size = MTDPART_SIZ_FULL, }, }; @@ -422,11 +422,11 @@ static struct mtd_partition bfin_spi_flash_partitions[] = { }, { .name = "kernel", .size = 0xe0000, - .offset = 0x20000 + .offset = MTDPART_OFS_APPEND, }, { .name = "file system", - .size = 0x700000, - .offset = 0x00100000, + .size = MTDPART_SIZ_FULL, + .offset = MTDPART_OFS_APPEND, } }; @@ -484,13 +484,6 @@ static struct bfin5xx_spi_chip spi_si3xxx_chip_info = { }; #endif -#if defined(CONFIG_AD5304) || defined(CONFIG_AD5304_MODULE) -static struct bfin5xx_spi_chip ad5304_chip_info = { - .enable_dma = 0, - .bits_per_word = 16, -}; -#endif - #if defined(CONFIG_TOUCHSCREEN_AD7877) || defined(CONFIG_TOUCHSCREEN_AD7877_MODULE) static struct bfin5xx_spi_chip spi_ad7877_chip_info = { .enable_dma = 0, @@ -611,17 +604,6 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = { .mode = SPI_MODE_3, }, #endif -#if defined(CONFIG_AD5304) || defined(CONFIG_AD5304_MODULE) - { - .modalias = "ad5304_spi", - .max_speed_hz = 1250000, /* max spi clock (SCK) speed in HZ */ - .bus_num = 0, - .chip_select = 2, - .platform_data = NULL, - .controller_data = &ad5304_chip_info, - .mode = SPI_MODE_2, - }, -#endif #if defined(CONFIG_TOUCHSCREEN_AD7877) || defined(CONFIG_TOUCHSCREEN_AD7877_MODULE) { .modalias = "ad7877", @@ -818,6 +800,19 @@ static struct platform_device bfin_device_gpiokeys = { }; #endif +static struct resource bfin_gpios_resources = { + .start = 0, + .end = MAX_BLACKFIN_GPIOS - 1, + .flags = IORESOURCE_IRQ, +}; + +static struct platform_device bfin_gpios_device = { + .name = "simple-gpio", + .id = -1, + .num_resources = 1, + .resource = &bfin_gpios_resources, +}; + static struct platform_device *stamp_devices[] __initdata = { #if defined(CONFIG_MTD_NAND_BF5XX) || defined(CONFIG_MTD_NAND_BF5XX_MODULE) &bf5xx_nand_device, @@ -895,6 +890,8 @@ static struct platform_device *stamp_devices[] __initdata = { #if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE) &bfin_device_gpiokeys, #endif + + &bfin_gpios_device, }; static int __init stamp_init(void) @@ -921,13 +918,18 @@ void native_machine_restart(char *cmd) bfin_gpio_reset_spi0_ssel1(); } -/* - * Currently the MAC address is saved in Flash by U-Boot - */ -#define FLASH_MAC 0x203f0000 void bfin_get_ether_addr(char *addr) { - *(u32 *)(&(addr[0])) = bfin_read32(FLASH_MAC); - *(u16 *)(&(addr[4])) = bfin_read16(FLASH_MAC + 4); + /* the MAC is stored in OTP memory page 0xDF */ + u32 ret; + u64 otp_mac; + u32 (*otp_read)(u32 page, u32 flags, u64 *page_content) = (void *)0xEF00001A; + + ret = otp_read(0xDF, 0x00, &otp_mac); + if (!(ret & 0x1)) { + char *otp_mac_p = (char *)&otp_mac; + for (ret = 0; ret < 6; ++ret) + addr[ret] = otp_mac_p[5 - ret]; + } } EXPORT_SYMBOL(bfin_get_ether_addr); diff --git a/arch/blackfin/mach-bf533/boards/ezkit.c b/arch/blackfin/mach-bf533/boards/ezkit.c index 2b09aa39f565274725c770b53ab3abe60513b425..241b5a20a36a78003e1128ce79f9af98e7ae89cd 100644 --- a/arch/blackfin/mach-bf533/boards/ezkit.c +++ b/arch/blackfin/mach-bf533/boards/ezkit.c @@ -99,11 +99,11 @@ static struct mtd_partition bfin_spi_flash_partitions[] = { }, { .name = "kernel", .size = 0xe0000, - .offset = 0x20000 + .offset = MTDPART_OFS_APPEND, }, { .name = "file system", - .size = 0x700000, - .offset = 0x00100000, + .size = MTDPART_SIZ_FULL, + .offset = MTDPART_OFS_APPEND, } }; @@ -298,6 +298,19 @@ static struct platform_device bfin_device_gpiokeys = { }; #endif +static struct resource bfin_gpios_resources = { + .start = 0, + .end = MAX_BLACKFIN_GPIOS - 1, + .flags = IORESOURCE_IRQ, +}; + +static struct platform_device bfin_gpios_device = { + .name = "simple-gpio", + .id = -1, + .num_resources = 1, + .resource = &bfin_gpios_resources, +}; + #if defined(CONFIG_I2C_GPIO) || defined(CONFIG_I2C_GPIO_MODULE) #include @@ -350,6 +363,8 @@ static struct platform_device *ezkit_devices[] __initdata = { #if defined(CONFIG_I2C_GPIO) || defined(CONFIG_I2C_GPIO_MODULE) &i2c_gpio_device, #endif + + &bfin_gpios_device, }; static int __init ezkit_init(void) diff --git a/arch/blackfin/mach-bf533/boards/stamp.c b/arch/blackfin/mach-bf533/boards/stamp.c index a645f6fd091b36a8cd1f6896ef9fa0d0e7d871e5..b2ac4816ae62d585633de456c74e5a07dedee751 100644 --- a/arch/blackfin/mach-bf533/boards/stamp.c +++ b/arch/blackfin/mach-bf533/boards/stamp.c @@ -112,7 +112,7 @@ static struct platform_device net2272_bfin_device = { static struct mtd_partition stamp_partitions[] = { { .name = "Bootloader", - .size = 0x20000, + .size = 0x40000, .offset = 0, }, { .name = "Kernel", @@ -160,17 +160,17 @@ static struct platform_device stamp_flash_device = { static struct mtd_partition bfin_spi_flash_partitions[] = { { .name = "bootloader", - .size = 0x00020000, + .size = 0x00040000, .offset = 0, .mask_flags = MTD_CAP_ROM }, { .name = "kernel", .size = 0xe0000, - .offset = 0x20000 + .offset = MTDPART_OFS_APPEND, }, { .name = "file system", - .size = 0x700000, - .offset = 0x00100000, + .size = MTDPART_SIZ_FULL, + .offset = MTDPART_OFS_APPEND, } }; @@ -212,13 +212,6 @@ static struct bfin5xx_spi_chip spi_si3xxx_chip_info = { }; #endif -#if defined(CONFIG_AD5304) || defined(CONFIG_AD5304_MODULE) -static struct bfin5xx_spi_chip ad5304_chip_info = { - .enable_dma = 0, - .bits_per_word = 16, -}; -#endif - #if defined(CONFIG_SPI_MMC) || defined(CONFIG_SPI_MMC_MODULE) static struct bfin5xx_spi_chip spi_mmc_chip_info = { .enable_dma = 1, @@ -308,17 +301,6 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = { }, #endif -#if defined(CONFIG_AD5304) || defined(CONFIG_AD5304_MODULE) - { - .modalias = "ad5304_spi", - .max_speed_hz = 1000000, /* max spi clock (SCK) speed in HZ */ - .bus_num = 0, - .chip_select = 2, - .platform_data = NULL, - .controller_data = &ad5304_chip_info, - .mode = SPI_MODE_2, - }, -#endif #if defined(CONFIG_SPI_SPIDEV) || defined(CONFIG_SPI_SPIDEV_MODULE) { .modalias = "spidev", @@ -457,6 +439,19 @@ static struct platform_device bfin_device_gpiokeys = { }; #endif +static struct resource bfin_gpios_resources = { + .start = 0, + .end = MAX_BLACKFIN_GPIOS - 1, + .flags = IORESOURCE_IRQ, +}; + +static struct platform_device bfin_gpios_device = { + .name = "simple-gpio", + .id = -1, + .num_resources = 1, + .resource = &bfin_gpios_resources, +}; + #if defined(CONFIG_I2C_GPIO) || defined(CONFIG_I2C_GPIO_MODULE) #include @@ -518,6 +513,8 @@ static struct platform_device *stamp_devices[] __initdata = { #if defined(CONFIG_I2C_GPIO) || defined(CONFIG_I2C_GPIO_MODULE) &i2c_gpio_device, #endif + + &bfin_gpios_device, &stamp_flash_device, }; diff --git a/arch/blackfin/mach-bf537/boards/generic_board.c b/arch/blackfin/mach-bf537/boards/generic_board.c index 8a3397db1d212ec35dc10b08d71bc0d1026c494a..c95395ba7bfa97c09b948fe9475709ef3da1c317 100644 --- a/arch/blackfin/mach-bf537/boards/generic_board.c +++ b/arch/blackfin/mach-bf537/boards/generic_board.c @@ -371,13 +371,6 @@ static struct bfin5xx_spi_chip spi_si3xxx_chip_info = { }; #endif -#if defined(CONFIG_AD5304) || defined(CONFIG_AD5304_MODULE) -static struct bfin5xx_spi_chip ad5304_chip_info = { - .enable_dma = 0, - .bits_per_word = 16, -}; -#endif - #if defined(CONFIG_TOUCHSCREEN_AD7877) || defined(CONFIG_TOUCHSCREEN_AD7877_MODULE) static struct bfin5xx_spi_chip spi_ad7877_chip_info = { .enable_dma = 0, @@ -483,17 +476,6 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = { .mode = SPI_MODE_3, }, #endif -#if defined(CONFIG_AD5304) || defined(CONFIG_AD5304_MODULE) - { - .modalias = "ad5304_spi", - .max_speed_hz = 1250000, /* max spi clock (SCK) speed in HZ */ - .bus_num = 0, - .chip_select = 2, - .platform_data = NULL, - .controller_data = &ad5304_chip_info, - .mode = SPI_MODE_2, - }, -#endif #if defined(CONFIG_TOUCHSCREEN_AD7877) || defined(CONFIG_TOUCHSCREEN_AD7877_MODULE) { .modalias = "ad7877", diff --git a/arch/blackfin/mach-bf537/boards/stamp.c b/arch/blackfin/mach-bf537/boards/stamp.c index 9e2277e0d25cde2c628abc69e3a85665beee33d6..ea83148993da1f4dd8266d0d04e2e2744b984b56 100644 --- a/arch/blackfin/mach-bf537/boards/stamp.c +++ b/arch/blackfin/mach-bf537/boards/stamp.c @@ -128,6 +128,19 @@ static struct platform_device bfin_device_gpiokeys = { }; #endif +static struct resource bfin_gpios_resources = { + .start = 0, + .end = MAX_BLACKFIN_GPIOS - 1, + .flags = IORESOURCE_IRQ, +}; + +static struct platform_device bfin_gpios_device = { + .name = "simple-gpio", + .id = -1, + .num_resources = 1, + .resource = &bfin_gpios_resources, +}; + #if defined(CONFIG_BFIN_CFPCMCIA) || defined(CONFIG_BFIN_CFPCMCIA_MODULE) static struct resource bfin_pcmcia_cf_resources[] = { { @@ -343,7 +356,7 @@ static struct platform_device net2272_bfin_device = { static struct mtd_partition stamp_partitions[] = { { .name = "Bootloader", - .size = 0x20000, + .size = 0x40000, .offset = 0, }, { .name = "Kernel", @@ -351,7 +364,7 @@ static struct mtd_partition stamp_partitions[] = { .offset = MTDPART_OFS_APPEND, }, { .name = "RootFS", - .size = 0x400000 - 0x20000 - 0xE0000 - 0x10000, + .size = 0x400000 - 0x40000 - 0xE0000 - 0x10000, .offset = MTDPART_OFS_APPEND, }, { .name = "MAC Address", @@ -391,17 +404,17 @@ static struct platform_device stamp_flash_device = { static struct mtd_partition bfin_spi_flash_partitions[] = { { .name = "bootloader", - .size = 0x00020000, + .size = 0x00040000, .offset = 0, .mask_flags = MTD_CAP_ROM }, { .name = "kernel", .size = 0xe0000, - .offset = 0x20000 + .offset = MTDPART_OFS_APPEND, }, { .name = "file system", - .size = 0x700000, - .offset = 0x00100000, + .size = MTDPART_SIZ_FULL, + .offset = MTDPART_OFS_APPEND, } }; @@ -459,13 +472,6 @@ static struct bfin5xx_spi_chip spi_si3xxx_chip_info = { }; #endif -#if defined(CONFIG_AD5304) || defined(CONFIG_AD5304_MODULE) -static struct bfin5xx_spi_chip ad5304_chip_info = { - .enable_dma = 0, - .bits_per_word = 16, -}; -#endif - #if defined(CONFIG_TOUCHSCREEN_AD7877) || defined(CONFIG_TOUCHSCREEN_AD7877_MODULE) static struct bfin5xx_spi_chip spi_ad7877_chip_info = { .enable_dma = 0, @@ -578,17 +584,6 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = { .mode = SPI_MODE_3, }, #endif -#if defined(CONFIG_AD5304) || defined(CONFIG_AD5304_MODULE) - { - .modalias = "ad5304_spi", - .max_speed_hz = 1250000, /* max spi clock (SCK) speed in HZ */ - .bus_num = 0, - .chip_select = 2, - .platform_data = NULL, - .controller_data = &ad5304_chip_info, - .mode = SPI_MODE_2, - }, -#endif #if defined(CONFIG_TOUCHSCREEN_AD7877) || defined(CONFIG_TOUCHSCREEN_AD7877_MODULE) { .modalias = "ad7877", @@ -821,6 +816,8 @@ static struct platform_device *stamp_devices[] __initdata = { #if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE) &bfin_device_gpiokeys, #endif + + &bfin_gpios_device, &stamp_flash_device, }; diff --git a/arch/blackfin/mach-bf548/boards/ezkit.c b/arch/blackfin/mach-bf548/boards/ezkit.c index 916e963e83ba4eed13b2d36460fc084df260f523..40846aa034c4a7d6bb659c47b92dc3d19d3590f1 100644 --- a/arch/blackfin/mach-bf548/boards/ezkit.c +++ b/arch/blackfin/mach-bf548/boards/ezkit.c @@ -285,8 +285,8 @@ static struct mtd_partition partition_info[] = { }, { .name = "File System", - .offset = 4 * SIZE_1M, - .size = (256 - 4) * SIZE_1M, + .offset = MTDPART_OFS_APPEND, + .size = MTDPART_SIZ_FULL, }, }; @@ -323,7 +323,7 @@ static struct platform_device bf5xx_nand_device = { }; #endif -#if defined(CONFIG_SDH_BFIN) || defined(CONFIG_SDH_BFIN) +#if defined(CONFIG_SDH_BFIN) || defined(CONFIG_SDH_BFIN_MODULE) static struct platform_device bf54x_sdh_device = { .name = "bfin-sdh", .id = 0, @@ -333,7 +333,7 @@ static struct platform_device bf54x_sdh_device = { static struct mtd_partition ezkit_partitions[] = { { .name = "Bootloader", - .size = 0x20000, + .size = 0x40000, .offset = 0, }, { .name = "Kernel", @@ -381,8 +381,8 @@ static struct mtd_partition bfin_spi_flash_partitions[] = { .mask_flags = MTD_CAP_ROM }, { .name = "linux kernel", - .size = 0x1c0000, - .offset = 0x40000 + .size = MTDPART_SIZ_FULL, + .offset = MTDPART_OFS_APPEND, } }; @@ -594,6 +594,19 @@ static struct platform_device bfin_device_gpiokeys = { }; #endif +static struct resource bfin_gpios_resources = { + .start = 0, + .end = MAX_BLACKFIN_GPIOS - 1, + .flags = IORESOURCE_IRQ, +}; + +static struct platform_device bfin_gpios_device = { + .name = "simple-gpio", + .id = -1, + .num_resources = 1, + .resource = &bfin_gpios_resources, +}; + static struct platform_device *ezkit_devices[] __initdata = { #if defined(CONFIG_RTC_DRV_BFIN) || defined(CONFIG_RTC_DRV_BFIN_MODULE) &rtc_device, @@ -623,7 +636,7 @@ static struct platform_device *ezkit_devices[] __initdata = { &bf5xx_nand_device, #endif -#if defined(CONFIG_SDH_BFIN) || defined(CONFIG_SDH_BFIN) +#if defined(CONFIG_SDH_BFIN) || defined(CONFIG_SDH_BFIN_MODULE) &bf54x_sdh_device, #endif @@ -646,6 +659,8 @@ static struct platform_device *ezkit_devices[] __initdata = { #if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE) &bfin_device_gpiokeys, #endif + + &bfin_gpios_device, &ezkit_flash_device, }; diff --git a/arch/blackfin/mach-bf548/dma.c b/arch/blackfin/mach-bf548/dma.c index 374803a8d2e87bf55ecb57ea8e30ff175dd8b65f..f5479298bb7913fd55baee1538ed310d090f8cec 100644 --- a/arch/blackfin/mach-bf548/dma.c +++ b/arch/blackfin/mach-bf548/dma.c @@ -27,6 +27,8 @@ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ +#include + #include #include diff --git a/arch/blackfin/mach-bf548/head.S b/arch/blackfin/mach-bf548/head.S index 74fe258421a5546c88eb231f8265c6e5aba22fa9..46222a75321a5d7f8fa21e103b4ce9ae666967cd 100644 --- a/arch/blackfin/mach-bf548/head.S +++ b/arch/blackfin/mach-bf548/head.S @@ -28,6 +28,7 @@ */ #include +#include #include #include #if CONFIG_BFIN_KERNEL_CLOCK @@ -44,10 +45,9 @@ #define INITIAL_STACK 0xFFB01000 -.text +__INIT ENTRY(__start) -ENTRY(__stext) /* R0: argument of command line string, passed from uboot, save it */ R7 = R0; /* Enable Cycle Counter and Nesting Of Interrupts */ @@ -213,6 +213,7 @@ ENTRY(__stext) .LWAIT_HERE: jump .LWAIT_HERE; +ENDPROC(__start) ENTRY(_real_start) [ -- sp ] = reti; @@ -285,6 +286,9 @@ ENTRY(_real_start) call _start_kernel; .L_exit: jump.s .L_exit; +ENDPROC(_real_start) + +__FINIT .section .l1.text #if CONFIG_BFIN_KERNEL_CLOCK @@ -450,6 +454,7 @@ ENTRY(_start_dma_code) SSYNC; RTS; +ENDPROC(_start_dma_code) #endif /* CONFIG_BFIN_KERNEL_CLOCK */ .data diff --git a/arch/blackfin/mach-bf561/boards/ezkit.c b/arch/blackfin/mach-bf561/boards/ezkit.c index 43c1b0982819bb6557b6d380cf09e4d21ade30a9..d357f648d963295f630b5db160607804a3bb9ba5 100644 --- a/arch/blackfin/mach-bf561/boards/ezkit.c +++ b/arch/blackfin/mach-bf561/boards/ezkit.c @@ -223,7 +223,7 @@ static struct platform_device bfin_uart_device = { static struct mtd_partition ezkit_partitions[] = { { .name = "Bootloader", - .size = 0x20000, + .size = 0x40000, .offset = 0, }, { .name = "Kernel", @@ -389,6 +389,19 @@ static struct platform_device bfin_device_gpiokeys = { }; #endif +static struct resource bfin_gpios_resources = { + .start = 0, + .end = MAX_BLACKFIN_GPIOS - 1, + .flags = IORESOURCE_IRQ, +}; + +static struct platform_device bfin_gpios_device = { + .name = "simple-gpio", + .id = -1, + .num_resources = 1, + .resource = &bfin_gpios_resources, +}; + #if defined(CONFIG_I2C_GPIO) || defined(CONFIG_I2C_GPIO_MODULE) #include @@ -446,6 +459,7 @@ static struct platform_device *ezkit_devices[] __initdata = { &isp1362_hcd_device, #endif + &bfin_gpios_device, &ezkit_flash_device, }; diff --git a/arch/blackfin/mach-common/dpmc.S b/arch/blackfin/mach-common/dpmc.S index b80ddd8b232decc3203490c79ae04071d7a8cae4..9d45aa3265b19a399e403045c1cda8ad3cac5130 100644 --- a/arch/blackfin/mach-common/dpmc.S +++ b/arch/blackfin/mach-common/dpmc.S @@ -31,140 +31,6 @@ #include #include -.text - -ENTRY(_unmask_wdog_wakeup_evt) - [--SP] = ( R7:0, P5:0 ); -#if defined(CONFIG_BF561) - P0.H = hi(SICA_IWR1); - P0.L = lo(SICA_IWR1); -#elif defined(CONFIG_BF54x) || defined(CONFIG_BF52x) - P0.h = HI(SIC_IWR0); - P0.l = LO(SIC_IWR0); -#else - P0.h = HI(SIC_IWR); - P0.l = LO(SIC_IWR); -#endif - R7 = [P0]; -#if defined(CONFIG_BF561) - BITSET(R7, 27); -#else - BITSET(R7,(IRQ_WATCH - IVG7)); -#endif - [P0] = R7; - SSYNC; - - ( R7:0, P5:0 ) = [SP++]; - RTS; - -.LWRITE_TO_STAT: - /* When watch dog timer is enabled, a write to STAT will load the - * contents of CNT to STAT - */ - R7 = 0x0000(z); -#if defined(CONFIG_BF561) - P0.h = HI(WDOGA_STAT); - P0.l = LO(WDOGA_STAT); -#else - P0.h = HI(WDOG_STAT); - P0.l = LO(WDOG_STAT); -#endif - [P0] = R7; - SSYNC; - JUMP .LSKIP_WRITE_TO_STAT; - -ENTRY(_program_wdog_timer) - [--SP] = ( R7:0, P5:0 ); -#if defined(CONFIG_BF561) - P0.h = HI(WDOGA_CNT); - P0.l = LO(WDOGA_CNT); -#else - P0.h = HI(WDOG_CNT); - P0.l = LO(WDOG_CNT); -#endif - [P0] = R0; - SSYNC; - -#if defined(CONFIG_BF561) - P0.h = HI(WDOGA_CTL); - P0.l = LO(WDOGA_CTL); -#else - P0.h = HI(WDOG_CTL); - P0.l = LO(WDOG_CTL); -#endif - R7 = W[P0](Z); - CC = BITTST(R7,1); - if !CC JUMP .LWRITE_TO_STAT; - CC = BITTST(R7,2); - if !CC JUMP .LWRITE_TO_STAT; - -.LSKIP_WRITE_TO_STAT: -#if defined(CONFIG_BF561) - P0.h = HI(WDOGA_CTL); - P0.l = LO(WDOGA_CTL); -#else - P0.h = HI(WDOG_CTL); - P0.l = LO(WDOG_CTL); -#endif - R7 = W[P0](Z); - BITCLR(R7,1); /* Enable GP event */ - BITSET(R7,2); - W[P0] = R7.L; - SSYNC; - NOP; - - R7 = W[P0](Z); - BITCLR(R7,4); /* Enable the wdog counter */ - W[P0] = R7.L; - SSYNC; - - ( R7:0, P5:0 ) = [SP++]; - RTS; - -ENTRY(_clear_wdog_wakeup_evt) - [--SP] = ( R7:0, P5:0 ); - -#if defined(CONFIG_BF561) - P0.h = HI(WDOGA_CTL); - P0.l = LO(WDOGA_CTL); -#else - P0.h = HI(WDOG_CTL); - P0.l = LO(WDOG_CTL); -#endif - R7 = 0x0AD6(Z); - W[P0] = R7.L; - SSYNC; - - R7 = W[P0](Z); - BITSET(R7,15); - W[P0] = R7.L; - SSYNC; - - R7 = W[P0](Z); - BITSET(R7,1); - BITSET(R7,2); - W[P0] = R7.L; - SSYNC; - - ( R7:0, P5:0 ) = [SP++]; - RTS; - -ENTRY(_disable_wdog_timer) - [--SP] = ( R7:0, P5:0 ); -#if defined(CONFIG_BF561) - P0.h = HI(WDOGA_CTL); - P0.l = LO(WDOGA_CTL); -#else - P0.h = HI(WDOG_CTL); - P0.l = LO(WDOG_CTL); -#endif - R7 = 0xAD6(Z); - W[P0] = R7.L; - SSYNC; - ( R7:0, P5:0 ) = [SP++]; - RTS; - -#if !defined(CONFIG_BF561) .section .l1.text @@ -459,10 +325,12 @@ ENTRY(_set_sic_iwr) RTS; ENTRY(_set_rtc_istat) +#ifndef CONFIG_BF561 P0.H = hi(RTC_ISTAT); P0.L = lo(RTC_ISTAT); w[P0] = R0.L; SSYNC; +#endif RTS; ENTRY(_test_pll_locked) @@ -473,4 +341,3 @@ ENTRY(_test_pll_locked) CC = BITTST(R0,5); IF !CC JUMP 1b; RTS; -#endif diff --git a/arch/blackfin/mach-common/entry.S b/arch/blackfin/mach-common/entry.S index 2cbb7a0bc38efe28ca027876cb9ccd24c32950ed..cee54cebbc6592505e0ff2046a7cc94d2b792c15 100644 --- a/arch/blackfin/mach-common/entry.S +++ b/arch/blackfin/mach-common/entry.S @@ -1369,7 +1369,7 @@ ENTRY(_sys_call_table) .long _sys_epoll_pwait .long _sys_utimensat .long _sys_signalfd - .long _sys_ni_syscall + .long _sys_timerfd_create .long _sys_eventfd /* 350 */ .long _sys_pread64 .long _sys_pwrite64 @@ -1378,6 +1378,9 @@ ENTRY(_sys_call_table) .long _sys_get_robust_list /* 355 */ .long _sys_fallocate .long _sys_semtimedop + .long _sys_timerfd_settime + .long _sys_timerfd_gettime + .rept NR_syscalls-(.-_sys_call_table)/4 .long _sys_ni_syscall .endr diff --git a/arch/blackfin/mach-common/ints-priority.c b/arch/blackfin/mach-common/ints-priority.c index 880595afe98da61b2ade7323701b17de6b4070b6..225ef14af75eade0ef629575cc5ab646db063796 100644 --- a/arch/blackfin/mach-common/ints-priority.c +++ b/arch/blackfin/mach-common/ints-priority.c @@ -74,7 +74,7 @@ unsigned long bfin_sic_iwr[3]; /* Up to 3 SIC_IWRx registers */ #endif struct ivgx { - /* irq number for request_irq, available in mach-bf533/irq.h */ + /* irq number for request_irq, available in mach-bf5xx/irq.h */ unsigned int irqno; /* corresponding bit in the SIC_ISR register */ unsigned int isrflag; @@ -86,7 +86,6 @@ struct ivg_slice { struct ivgx *istop; } ivg7_13[IVG13 - IVG7 + 1]; -static void search_IAR(void); /* * Search SIC_IAR and fill tables with the irqvalues @@ -120,10 +119,10 @@ static void __init search_IAR(void) } /* - * This is for BF533 internal IRQs + * This is for core internal IRQs */ -static void ack_noop(unsigned int irq) +static void bfin_ack_noop(unsigned int irq) { /* Dummy function. */ } @@ -156,11 +155,11 @@ static void bfin_internal_mask_irq(unsigned int irq) { #ifdef CONFIG_BF53x bfin_write_SIC_IMASK(bfin_read_SIC_IMASK() & - ~(1 << (irq - (IRQ_CORETMR + 1)))); + ~(1 << SIC_SYSIRQ(irq))); #else unsigned mask_bank, mask_bit; - mask_bank = (irq - (IRQ_CORETMR + 1)) / 32; - mask_bit = (irq - (IRQ_CORETMR + 1)) % 32; + mask_bank = SIC_SYSIRQ(irq) / 32; + mask_bit = SIC_SYSIRQ(irq) % 32; bfin_write_SIC_IMASK(mask_bank, bfin_read_SIC_IMASK(mask_bank) & ~(1 << mask_bit)); #endif @@ -171,11 +170,11 @@ static void bfin_internal_unmask_irq(unsigned int irq) { #ifdef CONFIG_BF53x bfin_write_SIC_IMASK(bfin_read_SIC_IMASK() | - (1 << (irq - (IRQ_CORETMR + 1)))); + (1 << SIC_SYSIRQ(irq))); #else unsigned mask_bank, mask_bit; - mask_bank = (irq - (IRQ_CORETMR + 1)) / 32; - mask_bit = (irq - (IRQ_CORETMR + 1)) % 32; + mask_bank = SIC_SYSIRQ(irq) / 32; + mask_bit = SIC_SYSIRQ(irq) % 32; bfin_write_SIC_IMASK(mask_bank, bfin_read_SIC_IMASK(mask_bank) | (1 << mask_bit)); #endif @@ -187,8 +186,8 @@ int bfin_internal_set_wake(unsigned int irq, unsigned int state) { unsigned bank, bit; unsigned long flags; - bank = (irq - (IRQ_CORETMR + 1)) / 32; - bit = (irq - (IRQ_CORETMR + 1)) % 32; + bank = SIC_SYSIRQ(irq) / 32; + bit = SIC_SYSIRQ(irq) % 32; local_irq_save(flags); @@ -204,15 +203,18 @@ int bfin_internal_set_wake(unsigned int irq, unsigned int state) #endif static struct irq_chip bfin_core_irqchip = { - .ack = ack_noop, + .ack = bfin_ack_noop, .mask = bfin_core_mask_irq, .unmask = bfin_core_unmask_irq, }; static struct irq_chip bfin_internal_irqchip = { - .ack = ack_noop, + .ack = bfin_ack_noop, .mask = bfin_internal_mask_irq, .unmask = bfin_internal_unmask_irq, + .mask_ack = bfin_internal_mask_irq, + .disable = bfin_internal_mask_irq, + .enable = bfin_internal_unmask_irq, #ifdef CONFIG_PM .set_wake = bfin_internal_set_wake, #endif @@ -221,38 +223,23 @@ static struct irq_chip bfin_internal_irqchip = { #ifdef BF537_GENERIC_ERROR_INT_DEMUX static int error_int_mask; -static void bfin_generic_error_ack_irq(unsigned int irq) -{ - -} - static void bfin_generic_error_mask_irq(unsigned int irq) { error_int_mask &= ~(1L << (irq - IRQ_PPI_ERROR)); - if (!error_int_mask) { - local_irq_disable(); - bfin_write_SIC_IMASK(bfin_read_SIC_IMASK() & - ~(1 << (IRQ_GENERIC_ERROR - - (IRQ_CORETMR + 1)))); - SSYNC(); - local_irq_enable(); - } + if (!error_int_mask) + bfin_internal_mask_irq(IRQ_GENERIC_ERROR); } static void bfin_generic_error_unmask_irq(unsigned int irq) { - local_irq_disable(); - bfin_write_SIC_IMASK(bfin_read_SIC_IMASK() | 1 << - (IRQ_GENERIC_ERROR - (IRQ_CORETMR + 1))); - SSYNC(); - local_irq_enable(); - + bfin_internal_unmask_irq(IRQ_GENERIC_ERROR); error_int_mask |= 1L << (irq - IRQ_PPI_ERROR); } static struct irq_chip bfin_generic_error_irqchip = { - .ack = bfin_generic_error_ack_irq, + .ack = bfin_ack_noop, + .mask_ack = bfin_generic_error_mask_irq, .mask = bfin_generic_error_mask_irq, .unmask = bfin_generic_error_unmask_irq, }; @@ -608,7 +595,7 @@ static struct pin_int_t *pint[NR_PINT_SYS_IRQS] = { (struct pin_int_t *)PINT3_MASK_SET, }; -unsigned short get_irq_base(u8 bank, u8 bmap) +inline unsigned short get_irq_base(u8 bank, u8 bmap) { u16 irq_base; @@ -969,17 +956,12 @@ int __init init_arch_irq(void) #if defined(CONFIG_BF54x) || defined(CONFIG_BF52x) || defined(CONFIG_BF561) bfin_write_SIC_IMASK0(SIC_UNMASK_ALL); bfin_write_SIC_IMASK1(SIC_UNMASK_ALL); - bfin_write_SIC_IWR0(IWR_ENABLE_ALL); - bfin_write_SIC_IWR1(IWR_ENABLE_ALL); # ifdef CONFIG_BF54x bfin_write_SIC_IMASK2(SIC_UNMASK_ALL); - bfin_write_SIC_IWR2(IWR_ENABLE_ALL); # endif #else bfin_write_SIC_IMASK(SIC_UNMASK_ALL); - bfin_write_SIC_IWR(IWR_ENABLE_ALL); #endif - SSYNC(); local_irq_disable(); @@ -1001,90 +983,53 @@ int __init init_arch_irq(void) set_irq_chip(irq, &bfin_core_irqchip); else set_irq_chip(irq, &bfin_internal_irqchip); -#ifdef BF537_GENERIC_ERROR_INT_DEMUX - if (irq != IRQ_GENERIC_ERROR) { -#endif - switch (irq) { + switch (irq) { #if defined(CONFIG_BF53x) - case IRQ_PROG_INTA: - set_irq_chained_handler(irq, - bfin_demux_gpio_irq); - break; + case IRQ_PROG_INTA: # if defined(BF537_FAMILY) && !(defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE)) - case IRQ_MAC_RX: - set_irq_chained_handler(irq, - bfin_demux_gpio_irq); - break; + case IRQ_MAC_RX: # endif #elif defined(CONFIG_BF54x) - case IRQ_PINT0: - set_irq_chained_handler(irq, - bfin_demux_gpio_irq); - break; - case IRQ_PINT1: - set_irq_chained_handler(irq, - bfin_demux_gpio_irq); - break; - case IRQ_PINT2: - set_irq_chained_handler(irq, - bfin_demux_gpio_irq); - break; - case IRQ_PINT3: - set_irq_chained_handler(irq, - bfin_demux_gpio_irq); - break; + case IRQ_PINT0: + case IRQ_PINT1: + case IRQ_PINT2: + case IRQ_PINT3: #elif defined(CONFIG_BF52x) - case IRQ_PORTF_INTA: - set_irq_chained_handler(irq, - bfin_demux_gpio_irq); - break; - case IRQ_PORTG_INTA: - set_irq_chained_handler(irq, - bfin_demux_gpio_irq); - break; - case IRQ_PORTH_INTA: - set_irq_chained_handler(irq, - bfin_demux_gpio_irq); - break; + case IRQ_PORTF_INTA: + case IRQ_PORTG_INTA: + case IRQ_PORTH_INTA: #elif defined(CONFIG_BF561) - case IRQ_PROG0_INTA: - set_irq_chained_handler(irq, - bfin_demux_gpio_irq); - break; - case IRQ_PROG1_INTA: - set_irq_chained_handler(irq, - bfin_demux_gpio_irq); - break; - case IRQ_PROG2_INTA: - set_irq_chained_handler(irq, - bfin_demux_gpio_irq); - break; + case IRQ_PROG0_INTA: + case IRQ_PROG1_INTA: + case IRQ_PROG2_INTA: #endif - default: - set_irq_handler(irq, handle_simple_irq); - break; - } - + set_irq_chained_handler(irq, + bfin_demux_gpio_irq); + break; #ifdef BF537_GENERIC_ERROR_INT_DEMUX - } else { + case IRQ_GENERIC_ERROR: set_irq_handler(irq, bfin_demux_error_irq); - } + + break; #endif + default: + set_irq_handler(irq, handle_simple_irq); + break; + } } + #ifdef BF537_GENERIC_ERROR_INT_DEMUX - for (irq = IRQ_PPI_ERROR; irq <= IRQ_UART1_ERROR; irq++) { - set_irq_chip(irq, &bfin_generic_error_irqchip); - set_irq_handler(irq, handle_level_irq); - } + for (irq = IRQ_PPI_ERROR; irq <= IRQ_UART1_ERROR; irq++) + set_irq_chip_and_handler(irq, &bfin_generic_error_irqchip, + handle_level_irq); #endif - for (irq = GPIO_IRQ_BASE; irq < NR_IRQS; irq++) { + /* if configured as edge, then will be changed to do_edge_IRQ */ + for (irq = GPIO_IRQ_BASE; irq < NR_IRQS; irq++) + set_irq_chip_and_handler(irq, &bfin_gpio_irqchip, + handle_level_irq); - set_irq_chip(irq, &bfin_gpio_irqchip); - /* if configured as edge, then will be changed to do_edge_IRQ */ - set_irq_handler(irq, handle_level_irq); - } bfin_write_IMASK(0); CSYNC(); @@ -1106,6 +1051,16 @@ int __init init_arch_irq(void) IMASK_IVG14 | IMASK_IVG13 | IMASK_IVG12 | IMASK_IVG11 | IMASK_IVG10 | IMASK_IVG9 | IMASK_IVG8 | IMASK_IVG7 | IMASK_IVGHW; +#if defined(CONFIG_BF54x) || defined(CONFIG_BF52x) || defined(CONFIG_BF561) + bfin_write_SIC_IWR0(IWR_ENABLE_ALL); + bfin_write_SIC_IWR1(IWR_ENABLE_ALL); +# ifdef CONFIG_BF54x + bfin_write_SIC_IWR2(IWR_ENABLE_ALL); +# endif +#else + bfin_write_SIC_IWR(IWR_ENABLE_ALL); +#endif + return 0; } @@ -1122,7 +1077,6 @@ void do_irq(int vec, struct pt_regs *fp) #if defined(CONFIG_BF54x) || defined(CONFIG_BF52x) || defined(CONFIG_BF561) unsigned long sic_status[3]; - SSYNC(); sic_status[0] = bfin_read_SIC_ISR0() & bfin_read_SIC_IMASK0(); sic_status[1] = bfin_read_SIC_ISR1() & bfin_read_SIC_IMASK1(); #ifdef CONFIG_BF54x @@ -1138,7 +1092,7 @@ void do_irq(int vec, struct pt_regs *fp) } #else unsigned long sic_status; - SSYNC(); + sic_status = bfin_read_SIC_IMASK() & bfin_read_SIC_ISR(); for (;; ivg++) { diff --git a/arch/blackfin/mm/init.c b/arch/blackfin/mm/init.c index 1f516c55bde676e14f3ede42e5031cd2ff3a5d40..ec3141fefd20da1554e08d745a8a34f175a04b72 100644 --- a/arch/blackfin/mm/init.c +++ b/arch/blackfin/mm/init.c @@ -181,7 +181,7 @@ void __init mem_init(void) } } -static __init void free_init_pages(const char *what, unsigned long begin, unsigned long end) +static void __init free_init_pages(const char *what, unsigned long begin, unsigned long end) { unsigned long addr; /* next to check that the page we free is not a partial page */ @@ -203,7 +203,7 @@ void __init free_initrd_mem(unsigned long start, unsigned long end) } #endif -void __init free_initmem(void) +void __init_refok free_initmem(void) { #if defined CONFIG_RAMKERNEL && !defined CONFIG_MPU free_init_pages("unused kernel memory", diff --git a/arch/cris/arch-v10/kernel/time.c b/arch/cris/arch-v10/kernel/time.c index 9310a7b476e95cf6353180de4e88bc8ba4f9f592..525483f0ddf89f3ec0fe0d14136710f86bbd9d6c 100644 --- a/arch/cris/arch-v10/kernel/time.c +++ b/arch/cris/arch-v10/kernel/time.c @@ -13,7 +13,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/arch/cris/arch-v10/lib/string.c b/arch/cris/arch-v10/lib/string.c index 7161a2bef4fe341e694780106ced3cccac5421c3..c7bd6ebdc93c0b18aa6d2e9efe213f02d01ad98c 100644 --- a/arch/cris/arch-v10/lib/string.c +++ b/arch/cris/arch-v10/lib/string.c @@ -1,55 +1,59 @@ -/*#************************************************************************#*/ -/*#-------------------------------------------------------------------------*/ -/*# */ -/*# FUNCTION NAME: memcpy() */ -/*# */ -/*# PARAMETERS: void* dst; Destination address. */ -/*# void* src; Source address. */ -/*# int len; Number of bytes to copy. */ -/*# */ -/*# RETURNS: dst. */ -/*# */ -/*# DESCRIPTION: Copies len bytes of memory from src to dst. No guarantees */ -/*# about copying of overlapping memory areas. This routine is */ -/*# very sensitive to compiler changes in register allocation. */ -/*# Should really be rewritten to avoid this problem. */ -/*# */ -/*#-------------------------------------------------------------------------*/ -/*# */ -/*# HISTORY */ -/*# */ -/*# DATE NAME CHANGES */ -/*# ---- ---- ------- */ -/*# 941007 Kenny R Creation */ -/*# 941011 Kenny R Lots of optimizations and inlining. */ -/*# 941129 Ulf A Adapted for use in libc. */ -/*# 950216 HP N==0 forgotten if non-aligned src/dst. */ -/*# Added some optimizations. */ -/*# 001025 HP Make src and dst char *. Align dst to */ -/*# dword, not just word-if-both-src-and-dst- */ -/*# are-misaligned. */ -/*# */ -/*#-------------------------------------------------------------------------*/ - -#include - -void *memcpy(void *pdst, - const void *psrc, - size_t pn) +/* A memcpy for CRIS. + Copyright (C) 1994-2005 Axis Communications. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Neither the name of Axis Communications nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY AXIS COMMUNICATIONS AND ITS CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL AXIS + COMMUNICATIONS OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. */ + +/* FIXME: This file should really only be used for reference, as the + result is somewhat depending on gcc generating what we expect rather + than what we describe. An assembly file should be used instead. */ + +#include + +/* Break even between movem and move16 is really at 38.7 * 2, but + modulo 44, so up to the next multiple of 44, we use ordinary code. */ +#define MEMCPY_BY_BLOCK_THRESHOLD (44 * 2) + +/* No name ambiguities in this file. */ +__asm__ (".syntax no_register_prefix"); + +void * +memcpy(void *pdst, const void *psrc, size_t pn) { - /* Ok. Now we want the parameters put in special registers. + /* Now we want the parameters put in special registers. Make sure the compiler is able to make something useful of this. - As it is now: r10 -> r13; r11 -> r11 (nop); r12 -> r12 (nop). + As it is now: r10 -> r13; r11 -> r11 (nop); r12 -> r12 (nop). - If gcc was alright, it really would need no temporaries, and no - stack space to save stuff on. */ + If gcc was allright, it really would need no temporaries, and no + stack space to save stuff on. */ register void *return_dst __asm__ ("r10") = pdst; - register char *dst __asm__ ("r13") = pdst; - register const char *src __asm__ ("r11") = psrc; + register unsigned char *dst __asm__ ("r13") = pdst; + register unsigned const char *src __asm__ ("r11") = psrc; register int n __asm__ ("r12") = pn; - - + /* When src is aligned but not dst, this makes a few extra needless cycles. I believe it would take as many to check that the re-alignment was unnecessary. */ @@ -59,167 +63,174 @@ void *memcpy(void *pdst, && n >= 3) { if ((unsigned long) dst & 1) - { - n--; - *(char*)dst = *(char*)src; - src++; - dst++; - } + { + n--; + *dst = *src; + src++; + dst++; + } if ((unsigned long) dst & 2) - { - n -= 2; - *(short*)dst = *(short*)src; - src += 2; - dst += 2; - } + { + n -= 2; + *(short *) dst = *(short *) src; + src += 2; + dst += 2; + } } - /* Decide which copying method to use. */ - if (n >= 44*2) /* Break even between movem and - move16 is at 38.7*2, but modulo 44. */ - { - /* For large copies we use 'movem' */ - - /* It is not optimal to tell the compiler about clobbering any - registers; that will move the saving/restoring of those registers - to the function prologue/epilogue, and make non-movem sizes - suboptimal. - - This method is not foolproof; it assumes that the "asm reg" - declarations at the beginning of the function really are used - here (beware: they may be moved to temporary registers). - This way, we do not have to save/move the registers around into - temporaries; we can safely use them straight away. - - If you want to check that the allocation was right; then - check the equalities in the first comment. It should say - "r13=r13, r11=r11, r12=r12" */ - __asm__ volatile ("\n\ - ;; Check that the following is true (same register names on \n\ - ;; both sides of equal sign, as in r8=r8): \n\ - ;; %0=r13, %1=r11, %2=r12 \n\ - ;; \n\ - ;; Save the registers we'll use in the movem process \n\ - ;; on the stack. \n\ - subq 11*4,$sp \n\ - movem $r10,[$sp] \n\ + /* Decide which copying method to use. */ + if (n >= MEMCPY_BY_BLOCK_THRESHOLD) + { + /* It is not optimal to tell the compiler about clobbering any + registers; that will move the saving/restoring of those registers + to the function prologue/epilogue, and make non-movem sizes + suboptimal. */ + __asm__ volatile + ("\ + ;; GCC does promise correct register allocations, but let's \n\ + ;; make sure it keeps its promises. \n\ + .ifnc %0-%1-%2,$r13-$r11-$r12 \n\ + .error \"GCC reg alloc bug: %0-%1-%4 != $r13-$r12-$r11\" \n\ + .endif \n\ + \n\ + ;; Save the registers we'll use in the movem process \n\ + ;; on the stack. \n\ + subq 11*4,sp \n\ + movem r10,[sp] \n\ \n\ - ;; Now we've got this: \n\ - ;; r11 - src \n\ - ;; r13 - dst \n\ - ;; r12 - n \n\ + ;; Now we've got this: \n\ + ;; r11 - src \n\ + ;; r13 - dst \n\ + ;; r12 - n \n\ \n\ - ;; Update n for the first loop \n\ - subq 44,$r12 \n\ + ;; Update n for the first loop. \n\ + subq 44,r12 \n\ 0: \n\ - movem [$r11+],$r10 \n\ - subq 44,$r12 \n\ - bge 0b \n\ - movem $r10,[$r13+] \n\ +" +#ifdef __arch_common_v10_v32 + /* Cater to branch offset difference between v32 and v10. We + assume the branch below has an 8-bit offset. */ +" setf\n" +#endif +" movem [r11+],r10 \n\ + subq 44,r12 \n\ + bge 0b \n\ + movem r10,[r13+] \n\ \n\ - addq 44,$r12 ;; compensate for last loop underflowing n \n\ + ;; Compensate for last loop underflowing n. \n\ + addq 44,r12 \n\ \n\ - ;; Restore registers from stack \n\ - movem [$sp+],$r10" + ;; Restore registers from stack. \n\ + movem [sp+],r10" - /* Outputs */ : "=r" (dst), "=r" (src), "=r" (n) - /* Inputs */ : "0" (dst), "1" (src), "2" (n)); - - } + /* Outputs. */ + : "=r" (dst), "=r" (src), "=r" (n) - /* Either we directly starts copying, using dword copying - in a loop, or we copy as much as possible with 'movem' - and then the last block (<44 bytes) is copied here. - This will work since 'movem' will have updated src,dst,n. */ + /* Inputs. */ + : "0" (dst), "1" (src), "2" (n)); + } - while ( n >= 16 ) - { - *((long*)dst)++ = *((long*)src)++; - *((long*)dst)++ = *((long*)src)++; - *((long*)dst)++ = *((long*)src)++; - *((long*)dst)++ = *((long*)src)++; - n -= 16; - } + while (n >= 16) + { + *(long *) dst = *(long *) src; dst += 4; src += 4; + *(long *) dst = *(long *) src; dst += 4; src += 4; + *(long *) dst = *(long *) src; dst += 4; src += 4; + *(long *) dst = *(long *) src; dst += 4; src += 4; + + n -= 16; + } - /* A switch() is definitely the fastest although it takes a LOT of code. - * Particularly if you inline code this. - */ switch (n) - { + { case 0: break; + case 1: - *(char*)dst = *(char*)src; + *dst = *src; break; + case 2: - *(short*)dst = *(short*)src; + *(short *) dst = *(short *) src; break; + case 3: - *((short*)dst)++ = *((short*)src)++; - *(char*)dst = *(char*)src; + *(short *) dst = *(short *) src; dst += 2; src += 2; + *dst = *src; break; + case 4: - *((long*)dst)++ = *((long*)src)++; + *(long *) dst = *(long *) src; break; + case 5: - *((long*)dst)++ = *((long*)src)++; - *(char*)dst = *(char*)src; + *(long *) dst = *(long *) src; dst += 4; src += 4; + *dst = *src; break; + case 6: - *((long*)dst)++ = *((long*)src)++; - *(short*)dst = *(short*)src; + *(long *) dst = *(long *) src; dst += 4; src += 4; + *(short *) dst = *(short *) src; break; + case 7: - *((long*)dst)++ = *((long*)src)++; - *((short*)dst)++ = *((short*)src)++; - *(char*)dst = *(char*)src; + *(long *) dst = *(long *) src; dst += 4; src += 4; + *(short *) dst = *(short *) src; dst += 2; src += 2; + *dst = *src; break; + case 8: - *((long*)dst)++ = *((long*)src)++; - *((long*)dst)++ = *((long*)src)++; + *(long *) dst = *(long *) src; dst += 4; src += 4; + *(long *) dst = *(long *) src; break; + case 9: - *((long*)dst)++ = *((long*)src)++; - *((long*)dst)++ = *((long*)src)++; - *(char*)dst = *(char*)src; + *(long *) dst = *(long *) src; dst += 4; src += 4; + *(long *) dst = *(long *) src; dst += 4; src += 4; + *dst = *src; break; + case 10: - *((long*)dst)++ = *((long*)src)++; - *((long*)dst)++ = *((long*)src)++; - *(short*)dst = *(short*)src; + *(long *) dst = *(long *) src; dst += 4; src += 4; + *(long *) dst = *(long *) src; dst += 4; src += 4; + *(short *) dst = *(short *) src; break; + case 11: - *((long*)dst)++ = *((long*)src)++; - *((long*)dst)++ = *((long*)src)++; - *((short*)dst)++ = *((short*)src)++; - *(char*)dst = *(char*)src; + *(long *) dst = *(long *) src; dst += 4; src += 4; + *(long *) dst = *(long *) src; dst += 4; src += 4; + *(short *) dst = *(short *) src; dst += 2; src += 2; + *dst = *src; break; + case 12: - *((long*)dst)++ = *((long*)src)++; - *((long*)dst)++ = *((long*)src)++; - *((long*)dst)++ = *((long*)src)++; + *(long *) dst = *(long *) src; dst += 4; src += 4; + *(long *) dst = *(long *) src; dst += 4; src += 4; + *(long *) dst = *(long *) src; break; + case 13: - *((long*)dst)++ = *((long*)src)++; - *((long*)dst)++ = *((long*)src)++; - *((long*)dst)++ = *((long*)src)++; - *(char*)dst = *(char*)src; + *(long *) dst = *(long *) src; dst += 4; src += 4; + *(long *) dst = *(long *) src; dst += 4; src += 4; + *(long *) dst = *(long *) src; dst += 4; src += 4; + *dst = *src; break; + case 14: - *((long*)dst)++ = *((long*)src)++; - *((long*)dst)++ = *((long*)src)++; - *((long*)dst)++ = *((long*)src)++; - *(short*)dst = *(short*)src; + *(long *) dst = *(long *) src; dst += 4; src += 4; + *(long *) dst = *(long *) src; dst += 4; src += 4; + *(long *) dst = *(long *) src; dst += 4; src += 4; + *(short *) dst = *(short *) src; break; + case 15: - *((long*)dst)++ = *((long*)src)++; - *((long*)dst)++ = *((long*)src)++; - *((long*)dst)++ = *((long*)src)++; - *((short*)dst)++ = *((short*)src)++; - *(char*)dst = *(char*)src; + *(long *) dst = *(long *) src; dst += 4; src += 4; + *(long *) dst = *(long *) src; dst += 4; src += 4; + *(long *) dst = *(long *) src; dst += 4; src += 4; + *(short *) dst = *(short *) src; dst += 2; src += 2; + *dst = *src; break; - } + } - return return_dst; /* destination pointer. */ -} /* memcpy() */ + return return_dst; +} diff --git a/arch/cris/arch-v10/lib/usercopy.c b/arch/cris/arch-v10/lib/usercopy.c index b8e6c0430e5b8832b6c9a5314c4f21a371405e57..b0a608da7bd13d5eff6f2e925153dbd7c47eadb0 100644 --- a/arch/cris/arch-v10/lib/usercopy.c +++ b/arch/cris/arch-v10/lib/usercopy.c @@ -193,7 +193,7 @@ __copy_user (void __user *pdst, const void *psrc, unsigned long pn) inaccessible. */ unsigned long -__copy_user_zeroing (void __user *pdst, const void *psrc, unsigned long pn) +__copy_user_zeroing(void *pdst, const void __user *psrc, unsigned long pn) { /* We want the parameters put in special registers. Make sure the compiler is able to make something useful of this. diff --git a/arch/cris/arch-v32/lib/string.c b/arch/cris/arch-v32/lib/string.c index 6740b2cebae5169d05a09d69ad5f99851394d8bc..c7bd6ebdc93c0b18aa6d2e9efe213f02d01ad98c 100644 --- a/arch/cris/arch-v32/lib/string.c +++ b/arch/cris/arch-v32/lib/string.c @@ -1,55 +1,59 @@ -/*#************************************************************************#*/ -/*#-------------------------------------------------------------------------*/ -/*# */ -/*# FUNCTION NAME: memcpy() */ -/*# */ -/*# PARAMETERS: void* dst; Destination address. */ -/*# void* src; Source address. */ -/*# int len; Number of bytes to copy. */ -/*# */ -/*# RETURNS: dst. */ -/*# */ -/*# DESCRIPTION: Copies len bytes of memory from src to dst. No guarantees */ -/*# about copying of overlapping memory areas. This routine is */ -/*# very sensitive to compiler changes in register allocation. */ -/*# Should really be rewritten to avoid this problem. */ -/*# */ -/*#-------------------------------------------------------------------------*/ -/*# */ -/*# HISTORY */ -/*# */ -/*# DATE NAME CHANGES */ -/*# ---- ---- ------- */ -/*# 941007 Kenny R Creation */ -/*# 941011 Kenny R Lots of optimizations and inlining. */ -/*# 941129 Ulf A Adapted for use in libc. */ -/*# 950216 HP N==0 forgotten if non-aligned src/dst. */ -/*# Added some optimizations. */ -/*# 001025 HP Make src and dst char *. Align dst to */ -/*# dword, not just word-if-both-src-and-dst- */ -/*# are-misaligned. */ -/*# */ -/*#-------------------------------------------------------------------------*/ - -#include - -void *memcpy(void *pdst, - const void *psrc, - size_t pn) +/* A memcpy for CRIS. + Copyright (C) 1994-2005 Axis Communications. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Neither the name of Axis Communications nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY AXIS COMMUNICATIONS AND ITS CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL AXIS + COMMUNICATIONS OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. */ + +/* FIXME: This file should really only be used for reference, as the + result is somewhat depending on gcc generating what we expect rather + than what we describe. An assembly file should be used instead. */ + +#include + +/* Break even between movem and move16 is really at 38.7 * 2, but + modulo 44, so up to the next multiple of 44, we use ordinary code. */ +#define MEMCPY_BY_BLOCK_THRESHOLD (44 * 2) + +/* No name ambiguities in this file. */ +__asm__ (".syntax no_register_prefix"); + +void * +memcpy(void *pdst, const void *psrc, size_t pn) { - /* Ok. Now we want the parameters put in special registers. + /* Now we want the parameters put in special registers. Make sure the compiler is able to make something useful of this. - As it is now: r10 -> r13; r11 -> r11 (nop); r12 -> r12 (nop). + As it is now: r10 -> r13; r11 -> r11 (nop); r12 -> r12 (nop). - If gcc was alright, it really would need no temporaries, and no - stack space to save stuff on. */ + If gcc was allright, it really would need no temporaries, and no + stack space to save stuff on. */ register void *return_dst __asm__ ("r10") = pdst; - register char *dst __asm__ ("r13") = pdst; - register const char *src __asm__ ("r11") = psrc; + register unsigned char *dst __asm__ ("r13") = pdst; + register unsigned const char *src __asm__ ("r11") = psrc; register int n __asm__ ("r12") = pn; - /* When src is aligned but not dst, this makes a few extra needless cycles. I believe it would take as many to check that the re-alignment was unnecessary. */ @@ -59,161 +63,174 @@ void *memcpy(void *pdst, && n >= 3) { if ((unsigned long) dst & 1) - { - n--; - *(char*)dst = *(char*)src; - src++; - dst++; - } + { + n--; + *dst = *src; + src++; + dst++; + } if ((unsigned long) dst & 2) - { - n -= 2; - *(short*)dst = *(short*)src; - src += 2; - dst += 2; - } + { + n -= 2; + *(short *) dst = *(short *) src; + src += 2; + dst += 2; + } } - /* Decide which copying method to use. Movem is dirt cheap, so the - overheap is low enough to always use the minimum block size as the - threshold. */ - if (n >= 44) - { - /* For large copies we use 'movem' */ - - /* It is not optimal to tell the compiler about clobbering any - registers; that will move the saving/restoring of those registers - to the function prologue/epilogue, and make non-movem sizes - suboptimal. */ - __asm__ volatile (" \n\ - ;; Check that the register asm declaration got right. \n\ - ;; The GCC manual explicitly says TRT will happen. \n\ - .ifnc %0-%1-%2,$r13-$r11-$r12 \n\ - .err \n\ - .endif \n\ - \n\ - ;; Save the registers we'll use in the movem process \n\ + /* Decide which copying method to use. */ + if (n >= MEMCPY_BY_BLOCK_THRESHOLD) + { + /* It is not optimal to tell the compiler about clobbering any + registers; that will move the saving/restoring of those registers + to the function prologue/epilogue, and make non-movem sizes + suboptimal. */ + __asm__ volatile + ("\ + ;; GCC does promise correct register allocations, but let's \n\ + ;; make sure it keeps its promises. \n\ + .ifnc %0-%1-%2,$r13-$r11-$r12 \n\ + .error \"GCC reg alloc bug: %0-%1-%4 != $r13-$r12-$r11\" \n\ + .endif \n\ \n\ - ;; on the stack. \n\ - subq 11*4,$sp \n\ - movem $r10,[$sp] \n\ + ;; Save the registers we'll use in the movem process \n\ + ;; on the stack. \n\ + subq 11*4,sp \n\ + movem r10,[sp] \n\ \n\ - ;; Now we've got this: \n\ - ;; r11 - src \n\ - ;; r13 - dst \n\ - ;; r12 - n \n\ + ;; Now we've got this: \n\ + ;; r11 - src \n\ + ;; r13 - dst \n\ + ;; r12 - n \n\ \n\ - ;; Update n for the first loop \n\ - subq 44,$r12 \n\ + ;; Update n for the first loop. \n\ + subq 44,r12 \n\ 0: \n\ - movem [$r11+],$r10 \n\ - subq 44,$r12 \n\ - bge 0b \n\ - movem $r10,[$r13+] \n\ +" +#ifdef __arch_common_v10_v32 + /* Cater to branch offset difference between v32 and v10. We + assume the branch below has an 8-bit offset. */ +" setf\n" +#endif +" movem [r11+],r10 \n\ + subq 44,r12 \n\ + bge 0b \n\ + movem r10,[r13+] \n\ \n\ - addq 44,$r12 ;; compensate for last loop underflowing n \n\ + ;; Compensate for last loop underflowing n. \n\ + addq 44,r12 \n\ \n\ - ;; Restore registers from stack \n\ - movem [$sp+],$r10" + ;; Restore registers from stack. \n\ + movem [sp+],r10" - /* Outputs */ : "=r" (dst), "=r" (src), "=r" (n) - /* Inputs */ : "0" (dst), "1" (src), "2" (n)); + /* Outputs. */ + : "=r" (dst), "=r" (src), "=r" (n) - } + /* Inputs. */ + : "0" (dst), "1" (src), "2" (n)); + } - /* Either we directly starts copying, using dword copying - in a loop, or we copy as much as possible with 'movem' - and then the last block (<44 bytes) is copied here. - This will work since 'movem' will have updated src,dst,n. */ + while (n >= 16) + { + *(long *) dst = *(long *) src; dst += 4; src += 4; + *(long *) dst = *(long *) src; dst += 4; src += 4; + *(long *) dst = *(long *) src; dst += 4; src += 4; + *(long *) dst = *(long *) src; dst += 4; src += 4; - while ( n >= 16 ) - { - *((long*)dst)++ = *((long*)src)++; - *((long*)dst)++ = *((long*)src)++; - *((long*)dst)++ = *((long*)src)++; - *((long*)dst)++ = *((long*)src)++; - n -= 16; - } + n -= 16; + } - /* A switch() is definitely the fastest although it takes a LOT of code. - * Particularly if you inline code this. - */ switch (n) - { + { case 0: break; + case 1: - *(char*)dst = *(char*)src; + *dst = *src; break; + case 2: - *(short*)dst = *(short*)src; + *(short *) dst = *(short *) src; break; + case 3: - *((short*)dst)++ = *((short*)src)++; - *(char*)dst = *(char*)src; + *(short *) dst = *(short *) src; dst += 2; src += 2; + *dst = *src; break; + case 4: - *((long*)dst)++ = *((long*)src)++; + *(long *) dst = *(long *) src; break; + case 5: - *((long*)dst)++ = *((long*)src)++; - *(char*)dst = *(char*)src; + *(long *) dst = *(long *) src; dst += 4; src += 4; + *dst = *src; break; + case 6: - *((long*)dst)++ = *((long*)src)++; - *(short*)dst = *(short*)src; + *(long *) dst = *(long *) src; dst += 4; src += 4; + *(short *) dst = *(short *) src; break; + case 7: - *((long*)dst)++ = *((long*)src)++; - *((short*)dst)++ = *((short*)src)++; - *(char*)dst = *(char*)src; + *(long *) dst = *(long *) src; dst += 4; src += 4; + *(short *) dst = *(short *) src; dst += 2; src += 2; + *dst = *src; break; + case 8: - *((long*)dst)++ = *((long*)src)++; - *((long*)dst)++ = *((long*)src)++; + *(long *) dst = *(long *) src; dst += 4; src += 4; + *(long *) dst = *(long *) src; break; + case 9: - *((long*)dst)++ = *((long*)src)++; - *((long*)dst)++ = *((long*)src)++; - *(char*)dst = *(char*)src; + *(long *) dst = *(long *) src; dst += 4; src += 4; + *(long *) dst = *(long *) src; dst += 4; src += 4; + *dst = *src; break; + case 10: - *((long*)dst)++ = *((long*)src)++; - *((long*)dst)++ = *((long*)src)++; - *(short*)dst = *(short*)src; + *(long *) dst = *(long *) src; dst += 4; src += 4; + *(long *) dst = *(long *) src; dst += 4; src += 4; + *(short *) dst = *(short *) src; break; + case 11: - *((long*)dst)++ = *((long*)src)++; - *((long*)dst)++ = *((long*)src)++; - *((short*)dst)++ = *((short*)src)++; - *(char*)dst = *(char*)src; + *(long *) dst = *(long *) src; dst += 4; src += 4; + *(long *) dst = *(long *) src; dst += 4; src += 4; + *(short *) dst = *(short *) src; dst += 2; src += 2; + *dst = *src; break; + case 12: - *((long*)dst)++ = *((long*)src)++; - *((long*)dst)++ = *((long*)src)++; - *((long*)dst)++ = *((long*)src)++; + *(long *) dst = *(long *) src; dst += 4; src += 4; + *(long *) dst = *(long *) src; dst += 4; src += 4; + *(long *) dst = *(long *) src; break; + case 13: - *((long*)dst)++ = *((long*)src)++; - *((long*)dst)++ = *((long*)src)++; - *((long*)dst)++ = *((long*)src)++; - *(char*)dst = *(char*)src; + *(long *) dst = *(long *) src; dst += 4; src += 4; + *(long *) dst = *(long *) src; dst += 4; src += 4; + *(long *) dst = *(long *) src; dst += 4; src += 4; + *dst = *src; break; + case 14: - *((long*)dst)++ = *((long*)src)++; - *((long*)dst)++ = *((long*)src)++; - *((long*)dst)++ = *((long*)src)++; - *(short*)dst = *(short*)src; + *(long *) dst = *(long *) src; dst += 4; src += 4; + *(long *) dst = *(long *) src; dst += 4; src += 4; + *(long *) dst = *(long *) src; dst += 4; src += 4; + *(short *) dst = *(short *) src; break; + case 15: - *((long*)dst)++ = *((long*)src)++; - *((long*)dst)++ = *((long*)src)++; - *((long*)dst)++ = *((long*)src)++; - *((short*)dst)++ = *((short*)src)++; - *(char*)dst = *(char*)src; + *(long *) dst = *(long *) src; dst += 4; src += 4; + *(long *) dst = *(long *) src; dst += 4; src += 4; + *(long *) dst = *(long *) src; dst += 4; src += 4; + *(short *) dst = *(short *) src; dst += 2; src += 2; + *dst = *src; break; - } + } - return return_dst; /* destination pointer. */ -} /* memcpy() */ + return return_dst; +} diff --git a/arch/cris/arch-v32/lib/usercopy.c b/arch/cris/arch-v32/lib/usercopy.c index 04d0cf35a2761b531c1350c58ecf36e081961fb7..0b5b70d5f58a45ca2554daf64ccb4625c1ff725f 100644 --- a/arch/cris/arch-v32/lib/usercopy.c +++ b/arch/cris/arch-v32/lib/usercopy.c @@ -161,7 +161,7 @@ __copy_user (void __user *pdst, const void *psrc, unsigned long pn) inaccessible. */ unsigned long -__copy_user_zeroing (void __user *pdst, const void *psrc, unsigned long pn) +__copy_user_zeroing(void *pdst, const void __user *psrc, unsigned long pn) { /* We want the parameters put in special registers. Make sure the compiler is able to make something useful of this. diff --git a/arch/ia64/Kconfig b/arch/ia64/Kconfig index dff9edfc7465e9954bc5b16749eaa0068e88671a..8fa3faf5ef1bb0e91c32b54c6c5b7d197c920b79 100644 --- a/arch/ia64/Kconfig +++ b/arch/ia64/Kconfig @@ -18,6 +18,7 @@ config IA64 select HAVE_IDE select HAVE_OPROFILE select HAVE_KPROBES + select HAVE_KRETPROBES default y help The Itanium Processor Family is Intel's 64-bit successor to @@ -155,6 +156,8 @@ config IA64_HP_ZX1_SWIOTLB config IA64_SGI_SN2 bool "SGI-SN2" + select NUMA + select ACPI_NUMA help Selecting this option will optimize the kernel for use on sn2 based systems, but the resulting kernel binary will not run on other diff --git a/arch/ia64/Makefile b/arch/ia64/Makefile index b916ccfdef843f158f1814cc74d278d389dcec70..f1645c4f70393c5294ecc9148300c8368178d5f5 100644 --- a/arch/ia64/Makefile +++ b/arch/ia64/Makefile @@ -11,6 +11,8 @@ # Copyright (C) 1998-2004 by David Mosberger-Tang # +KBUILD_DEFCONFIG := generic_defconfig + NM := $(CROSS_COMPILE)nm -B READELF := $(CROSS_COMPILE)readelf diff --git a/arch/ia64/defconfig b/arch/ia64/configs/generic_defconfig similarity index 100% rename from arch/ia64/defconfig rename to arch/ia64/configs/generic_defconfig diff --git a/arch/ia64/hp/common/hwsw_iommu.c b/arch/ia64/hp/common/hwsw_iommu.c index 94e57109fad658d060542aea2ed9f51bd1d230db..8f6bcfe1dadaa0fab0ec16fd2734ddf87d916450 100644 --- a/arch/ia64/hp/common/hwsw_iommu.c +++ b/arch/ia64/hp/common/hwsw_iommu.c @@ -71,7 +71,7 @@ hwsw_init (void) #ifdef CONFIG_IA64_GENERIC /* Better to have normal DMA than panic */ printk(KERN_WARNING "%s: Failed to initialize software I/O TLB," - " reverting to hpzx1 platform vector\n", __FUNCTION__); + " reverting to hpzx1 platform vector\n", __func__); machvec_init("hpzx1"); #else panic("Unable to initialize software I/O TLB services"); diff --git a/arch/ia64/hp/common/sba_iommu.c b/arch/ia64/hp/common/sba_iommu.c index a94445422cc65d895eb76e4a417897bf067556d9..523eae6d3e49f1177a20c0d72ad8d3d8d4461a14 100644 --- a/arch/ia64/hp/common/sba_iommu.c +++ b/arch/ia64/hp/common/sba_iommu.c @@ -529,7 +529,7 @@ sba_search_bitmap(struct ioc *ioc, unsigned long bits_wanted, int use_hint) base_mask = RESMAP_MASK(bits_wanted); mask = base_mask << bitshiftcnt; - DBG_RES("%s() o %ld %p", __FUNCTION__, o, res_ptr); + DBG_RES("%s() o %ld %p", __func__, o, res_ptr); for(; res_ptr < res_end ; res_ptr++) { DBG_RES(" %p %lx %lx\n", res_ptr, mask, *res_ptr); @@ -679,7 +679,7 @@ sba_alloc_range(struct ioc *ioc, size_t size) #endif DBG_RES("%s(%x) %d -> %lx hint %x/%x\n", - __FUNCTION__, size, pages_needed, pide, + __func__, size, pages_needed, pide, (uint) ((unsigned long) ioc->res_hint - (unsigned long) ioc->res_map), ioc->res_bitshift ); @@ -722,8 +722,8 @@ sba_free_range(struct ioc *ioc, dma_addr_t iova, size_t size) m = RESMAP_MASK(bits_not_wanted) << (pide & (BITS_PER_LONG - 1)); bits_not_wanted = 0; - DBG_RES("%s( ,%x,%x) %x/%lx %x %p %lx\n", __FUNCTION__, (uint) iova, size, - bits_not_wanted, m, pide, res_ptr, *res_ptr); + DBG_RES("%s( ,%x,%x) %x/%lx %x %p %lx\n", __func__, (uint) iova, size, + bits_not_wanted, m, pide, res_ptr, *res_ptr); ASSERT(m != 0); ASSERT(bits_not_wanted); @@ -940,8 +940,7 @@ sba_map_single(struct device *dev, void *addr, size_t size, int dir) iovp = (dma_addr_t) pide << iovp_shift; - DBG_RUN("%s() 0x%p -> 0x%lx\n", - __FUNCTION__, addr, (long) iovp | offset); + DBG_RUN("%s() 0x%p -> 0x%lx\n", __func__, addr, (long) iovp | offset); pdir_start = &(ioc->pdir_base[pide]); @@ -1029,8 +1028,7 @@ void sba_unmap_single(struct device *dev, dma_addr_t iova, size_t size, int dir) #endif offset = iova & ~iovp_mask; - DBG_RUN("%s() iovp 0x%lx/%x\n", - __FUNCTION__, (long) iova, size); + DBG_RUN("%s() iovp 0x%lx/%x\n", __func__, (long) iova, size); iova ^= offset; /* clear offset bits */ size += offset; @@ -1404,7 +1402,7 @@ int sba_map_sg(struct device *dev, struct scatterlist *sglist, int nents, int di struct scatterlist *sg; #endif - DBG_RUN_SG("%s() START %d entries\n", __FUNCTION__, nents); + DBG_RUN_SG("%s() START %d entries\n", __func__, nents); ioc = GET_IOC(dev); ASSERT(ioc); @@ -1468,7 +1466,7 @@ int sba_map_sg(struct device *dev, struct scatterlist *sglist, int nents, int di #endif ASSERT(coalesced == filled); - DBG_RUN_SG("%s() DONE %d mappings\n", __FUNCTION__, filled); + DBG_RUN_SG("%s() DONE %d mappings\n", __func__, filled); return filled; } @@ -1491,7 +1489,7 @@ void sba_unmap_sg (struct device *dev, struct scatterlist *sglist, int nents, in #endif DBG_RUN_SG("%s() START %d entries, %p,%x\n", - __FUNCTION__, nents, sba_sg_address(sglist), sglist->length); + __func__, nents, sba_sg_address(sglist), sglist->length); #ifdef ASSERT_PDIR_SANITY ioc = GET_IOC(dev); @@ -1509,7 +1507,7 @@ void sba_unmap_sg (struct device *dev, struct scatterlist *sglist, int nents, in nents--; } - DBG_RUN_SG("%s() DONE (nents %d)\n", __FUNCTION__, nents); + DBG_RUN_SG("%s() DONE (nents %d)\n", __func__, nents); #ifdef ASSERT_PDIR_SANITY spin_lock_irqsave(&ioc->res_lock, flags); @@ -1546,7 +1544,7 @@ ioc_iova_init(struct ioc *ioc) ioc->iov_size = ~ioc->imask + 1; DBG_INIT("%s() hpa %p IOV base 0x%lx mask 0x%lx (%dMB)\n", - __FUNCTION__, ioc->ioc_hpa, ioc->ibase, ioc->imask, + __func__, ioc->ioc_hpa, ioc->ibase, ioc->imask, ioc->iov_size >> 20); switch (iovp_size) { @@ -1569,7 +1567,7 @@ ioc_iova_init(struct ioc *ioc) memset(ioc->pdir_base, 0, ioc->pdir_size); - DBG_INIT("%s() IOV page size %ldK pdir %p size %x\n", __FUNCTION__, + DBG_INIT("%s() IOV page size %ldK pdir %p size %x\n", __func__, iovp_size >> 10, ioc->pdir_base, ioc->pdir_size); ASSERT(ALIGN((unsigned long) ioc->pdir_base, 4*1024) == (unsigned long) ioc->pdir_base); @@ -1612,7 +1610,7 @@ ioc_iova_init(struct ioc *ioc) prefetch_spill_page = virt_to_phys(addr); - DBG_INIT("%s() prefetch spill addr: 0x%lx\n", __FUNCTION__, prefetch_spill_page); + DBG_INIT("%s() prefetch spill addr: 0x%lx\n", __func__, prefetch_spill_page); } /* ** Set all the PDIR entries valid w/ the spill page as the target @@ -1641,7 +1639,7 @@ ioc_resource_init(struct ioc *ioc) /* resource map size dictated by pdir_size */ ioc->res_size = ioc->pdir_size / PDIR_ENTRY_SIZE; /* entries */ ioc->res_size >>= 3; /* convert bit count to byte count */ - DBG_INIT("%s() res_size 0x%x\n", __FUNCTION__, ioc->res_size); + DBG_INIT("%s() res_size 0x%x\n", __func__, ioc->res_size); ioc->res_map = (char *) __get_free_pages(GFP_KERNEL, get_order(ioc->res_size)); @@ -1664,7 +1662,7 @@ ioc_resource_init(struct ioc *ioc) | prefetch_spill_page); #endif - DBG_INIT("%s() res_map %x %p\n", __FUNCTION__, + DBG_INIT("%s() res_map %x %p\n", __func__, ioc->res_size, (void *) ioc->res_map); } @@ -1767,7 +1765,7 @@ ioc_init(u64 hpa, void *handle) iovp_size = (1 << iovp_shift); iovp_mask = ~(iovp_size - 1); - DBG_INIT("%s: PAGE_SIZE %ldK, iovp_size %ldK\n", __FUNCTION__, + DBG_INIT("%s: PAGE_SIZE %ldK, iovp_size %ldK\n", __func__, PAGE_SIZE >> 10, iovp_size >> 10); if (!ioc->name) { @@ -2137,7 +2135,7 @@ sba_page_override(char *str) break; default: printk("%s: unknown/unsupported iommu page size %ld\n", - __FUNCTION__, page_size); + __func__, page_size); } return 1; diff --git a/arch/ia64/hp/sim/simeth.c b/arch/ia64/hp/sim/simeth.c index 9898febf609a34b8073f288295d1f24446931621..969fe9f443c4f69883949e6a3b64d74cb46da8ad 100644 --- a/arch/ia64/hp/sim/simeth.c +++ b/arch/ia64/hp/sim/simeth.c @@ -222,7 +222,7 @@ simeth_probe1(void) } if ((rc = assign_irq_vector(AUTO_ASSIGN)) < 0) - panic("%s: out of interrupt vectors!\n", __FUNCTION__); + panic("%s: out of interrupt vectors!\n", __func__); dev->irq = rc; /* diff --git a/arch/ia64/hp/sim/simserial.c b/arch/ia64/hp/sim/simserial.c index ef252df50e1e7a32097d881957e83b307cb167a2..eb0c32a85fd737c3154a016a609cd99b13216266 100644 --- a/arch/ia64/hp/sim/simserial.c +++ b/arch/ia64/hp/sim/simserial.c @@ -1000,7 +1000,7 @@ simrs_init (void) if (!state->irq) { if ((rc = assign_irq_vector(AUTO_ASSIGN)) < 0) panic("%s: out of interrupt vectors!\n", - __FUNCTION__); + __func__); state->irq = rc; ia64_ssc_connect_irq(KEYBOARD_INTR, state->irq); } diff --git a/arch/ia64/ia32/ia32_signal.c b/arch/ia64/ia32/ia32_signal.c index 85e82f32e480c4707de98d4fcdb73e801f2ebc95..256a7faeda0787fc7ba6df9f48d0899dc0add99a 100644 --- a/arch/ia64/ia32/ia32_signal.c +++ b/arch/ia64/ia32/ia32_signal.c @@ -766,8 +766,19 @@ get_sigframe (struct k_sigaction *ka, struct pt_regs * regs, size_t frame_size) /* This is the X/Open sanctioned signal stack switching. */ if (ka->sa.sa_flags & SA_ONSTACK) { - if (!on_sig_stack(esp)) + int onstack = sas_ss_flags(esp); + + if (onstack == 0) esp = current->sas_ss_sp + current->sas_ss_size; + else if (onstack == SS_ONSTACK) { + /* + * If we are on the alternate signal stack and would + * overflow it, don't. Return an always-bogus address + * instead so we will die with SIGSEGV. + */ + if (!likely(on_sig_stack(esp - frame_size))) + return (void __user *) -1L; + } } /* Legacy stack switching not supported */ diff --git a/arch/ia64/ia32/sys_ia32.c b/arch/ia64/ia32/sys_ia32.c index d025a22eb225f6bf455ec5a76b47434dc09a0977..b1bf51fe97b47cc66b32cd889431c5ae9af1b3b3 100644 --- a/arch/ia64/ia32/sys_ia32.c +++ b/arch/ia64/ia32/sys_ia32.c @@ -32,13 +32,8 @@ #include #include #include -#include +#include #include -#include -#include -#include -#include -#include #include #include #include diff --git a/arch/ia64/kernel/crash.c b/arch/ia64/kernel/crash.c index f1cf2df97a2d3f2602e2da6432f3e348567fe5f7..fbe742ad2fdeb2e26b3598abf00ae580ccae1aff 100644 --- a/arch/ia64/kernel/crash.c +++ b/arch/ia64/kernel/crash.c @@ -155,7 +155,7 @@ kdump_init_notifier(struct notifier_block *self, unsigned long val, void *data) if (val == DIE_INIT_MONARCH_LEAVE) ia64_mca_printk(KERN_NOTICE "%s: kdump not configured\n", - __FUNCTION__); + __func__); return NOTIFY_DONE; } diff --git a/arch/ia64/kernel/efi.c b/arch/ia64/kernel/efi.c index 919070a9aed7184c87ea43d83855963bb170d40e..728d7247a1a69688da32f12386d8fcb2165a1439 100644 --- a/arch/ia64/kernel/efi.c +++ b/arch/ia64/kernel/efi.c @@ -379,8 +379,8 @@ efi_get_pal_addr (void) * a dedicated ITR for the PAL code. */ if ((vaddr & mask) == (KERNEL_START & mask)) { - printk(KERN_INFO "%s: no need to install ITR for " - "PAL code\n", __FUNCTION__); + printk(KERN_INFO "%s: no need to install ITR for PAL code\n", + __func__); continue; } @@ -399,7 +399,7 @@ efi_get_pal_addr (void) return __va(md->phys_addr); } printk(KERN_WARNING "%s: no PAL-code memory-descriptor found\n", - __FUNCTION__); + __func__); return NULL; } @@ -543,12 +543,30 @@ efi_init (void) for (i = 0, p = efi_map_start; p < efi_map_end; ++i, p += efi_desc_size) { + const char *unit; + unsigned long size; + md = p; - printk("mem%02u: type=%u, attr=0x%lx, " - "range=[0x%016lx-0x%016lx) (%luMB)\n", + size = md->num_pages << EFI_PAGE_SHIFT; + + if ((size >> 40) > 0) { + size >>= 40; + unit = "TB"; + } else if ((size >> 30) > 0) { + size >>= 30; + unit = "GB"; + } else if ((size >> 20) > 0) { + size >>= 20; + unit = "MB"; + } else { + size >>= 10; + unit = "KB"; + } + + printk("mem%02d: type=%2u, attr=0x%016lx, " + "range=[0x%016lx-0x%016lx) (%4lu%s)\n", i, md->type, md->attribute, md->phys_addr, - md->phys_addr + efi_md_size(md), - md->num_pages >> (20 - EFI_PAGE_SHIFT)); + md->phys_addr + efi_md_size(md), size, unit); } } #endif diff --git a/arch/ia64/kernel/iosapic.c b/arch/ia64/kernel/iosapic.c index 398e2fd1cd2519ef2d6a2186308cd992073b0ec5..082c31dcfd998d83448d52559161805ca240be49 100644 --- a/arch/ia64/kernel/iosapic.c +++ b/arch/ia64/kernel/iosapic.c @@ -345,7 +345,7 @@ iosapic_set_affinity (unsigned int irq, cpumask_t mask) if (cpus_empty(mask)) return; - if (reassign_irq_vector(irq, first_cpu(mask))) + if (irq_prepare_move(irq, first_cpu(mask))) return; dest = cpu_physical_id(first_cpu(mask)); @@ -397,6 +397,7 @@ iosapic_end_level_irq (unsigned int irq) struct iosapic_rte_info *rte; int do_unmask_irq = 0; + irq_complete_move(irq); if (unlikely(irq_desc[irq].status & IRQ_MOVE_PENDING)) { do_unmask_irq = 1; mask_irq(irq); @@ -450,6 +451,7 @@ iosapic_ack_edge_irq (unsigned int irq) { irq_desc_t *idesc = irq_desc + irq; + irq_complete_move(irq); move_native_irq(irq); /* * Once we have recorded IRQ_PENDING already, we can mask the @@ -532,7 +534,7 @@ iosapic_reassign_vector (int irq) if (iosapic_intr_info[irq].count) { new_irq = create_irq(); if (new_irq < 0) - panic("%s: out of interrupt vectors!\n", __FUNCTION__); + panic("%s: out of interrupt vectors!\n", __func__); printk(KERN_INFO "Reassigning vector %d to %d\n", irq_to_vector(irq), irq_to_vector(new_irq)); memcpy(&iosapic_intr_info[new_irq], &iosapic_intr_info[irq], @@ -597,7 +599,7 @@ register_intr (unsigned int gsi, int irq, unsigned char delivery, index = find_iosapic(gsi); if (index < 0) { printk(KERN_WARNING "%s: No IOSAPIC for GSI %u\n", - __FUNCTION__, gsi); + __func__, gsi); return -ENODEV; } @@ -606,7 +608,7 @@ register_intr (unsigned int gsi, int irq, unsigned char delivery, rte = iosapic_alloc_rte(); if (!rte) { printk(KERN_WARNING "%s: cannot allocate memory\n", - __FUNCTION__); + __func__); return -ENOMEM; } @@ -623,7 +625,7 @@ register_intr (unsigned int gsi, int irq, unsigned char delivery, (info->trigger != trigger || info->polarity != polarity)){ printk (KERN_WARNING "%s: cannot override the interrupt\n", - __FUNCTION__); + __func__); return -EINVAL; } rte->refcnt++; @@ -645,7 +647,7 @@ register_intr (unsigned int gsi, int irq, unsigned char delivery, if (idesc->chip != &no_irq_type) printk(KERN_WARNING "%s: changing vector %d from %s to %s\n", - __FUNCTION__, irq_to_vector(irq), + __func__, irq_to_vector(irq), idesc->chip->name, irq_type->name); idesc->chip = irq_type; } @@ -918,7 +920,7 @@ iosapic_register_platform_intr (u32 int_type, unsigned int gsi, case ACPI_INTERRUPT_INIT: irq = create_irq(); if (irq < 0) - panic("%s: out of interrupt vectors!\n", __FUNCTION__); + panic("%s: out of interrupt vectors!\n", __func__); vector = irq_to_vector(irq); delivery = IOSAPIC_INIT; break; @@ -929,7 +931,7 @@ iosapic_register_platform_intr (u32 int_type, unsigned int gsi, mask = 1; break; default: - printk(KERN_ERR "%s: invalid int type 0x%x\n", __FUNCTION__, + printk(KERN_ERR "%s: invalid int type 0x%x\n", __func__, int_type); return -1; } @@ -994,7 +996,7 @@ iosapic_system_init (int system_pcat_compat) */ printk(KERN_INFO "%s: Disabling PC-AT compatible 8259 interrupts\n", - __FUNCTION__); + __func__); outb(0xff, 0xA1); outb(0xff, 0x21); } @@ -1009,7 +1011,7 @@ iosapic_alloc (void) if (!iosapic_lists[index].addr) return index; - printk(KERN_WARNING "%s: failed to allocate iosapic\n", __FUNCTION__); + printk(KERN_WARNING "%s: failed to allocate iosapic\n", __func__); return -1; } @@ -1107,14 +1109,14 @@ iosapic_remove (unsigned int gsi_base) index = find_iosapic(gsi_base); if (index < 0) { printk(KERN_WARNING "%s: No IOSAPIC for GSI base %u\n", - __FUNCTION__, gsi_base); + __func__, gsi_base); goto out; } if (iosapic_lists[index].rtes_inuse) { err = -EBUSY; printk(KERN_WARNING "%s: IOSAPIC for GSI base %u is busy\n", - __FUNCTION__, gsi_base); + __func__, gsi_base); goto out; } @@ -1135,7 +1137,7 @@ map_iosapic_to_node(unsigned int gsi_base, int node) index = find_iosapic(gsi_base); if (index < 0) { printk(KERN_WARNING "%s: No IOSAPIC for GSI %u\n", - __FUNCTION__, gsi_base); + __func__, gsi_base); return; } iosapic_lists[index].node = node; diff --git a/arch/ia64/kernel/irq_ia64.c b/arch/ia64/kernel/irq_ia64.c index 0b52f19ed04615b8f637e2ee496fa8c488b5546c..d8be23fbe6bc7bbf0668a01f55fe3dd7813a6f29 100644 --- a/arch/ia64/kernel/irq_ia64.c +++ b/arch/ia64/kernel/irq_ia64.c @@ -260,6 +260,8 @@ void __setup_vector_irq(int cpu) } #if defined(CONFIG_SMP) && (defined(CONFIG_IA64_GENERIC) || defined(CONFIG_IA64_DIG)) +#define IA64_IRQ_MOVE_VECTOR IA64_DEF_FIRST_DEVICE_VECTOR + static enum vector_domain_type { VECTOR_DOMAIN_NONE, VECTOR_DOMAIN_PERCPU @@ -272,6 +274,101 @@ static cpumask_t vector_allocation_domain(int cpu) return CPU_MASK_ALL; } +static int __irq_prepare_move(int irq, int cpu) +{ + struct irq_cfg *cfg = &irq_cfg[irq]; + int vector; + cpumask_t domain; + + if (cfg->move_in_progress || cfg->move_cleanup_count) + return -EBUSY; + if (cfg->vector == IRQ_VECTOR_UNASSIGNED || !cpu_online(cpu)) + return -EINVAL; + if (cpu_isset(cpu, cfg->domain)) + return 0; + domain = vector_allocation_domain(cpu); + vector = find_unassigned_vector(domain); + if (vector < 0) + return -ENOSPC; + cfg->move_in_progress = 1; + cfg->old_domain = cfg->domain; + cfg->vector = IRQ_VECTOR_UNASSIGNED; + cfg->domain = CPU_MASK_NONE; + BUG_ON(__bind_irq_vector(irq, vector, domain)); + return 0; +} + +int irq_prepare_move(int irq, int cpu) +{ + unsigned long flags; + int ret; + + spin_lock_irqsave(&vector_lock, flags); + ret = __irq_prepare_move(irq, cpu); + spin_unlock_irqrestore(&vector_lock, flags); + return ret; +} + +void irq_complete_move(unsigned irq) +{ + struct irq_cfg *cfg = &irq_cfg[irq]; + cpumask_t cleanup_mask; + int i; + + if (likely(!cfg->move_in_progress)) + return; + + if (unlikely(cpu_isset(smp_processor_id(), cfg->old_domain))) + return; + + cpus_and(cleanup_mask, cfg->old_domain, cpu_online_map); + cfg->move_cleanup_count = cpus_weight(cleanup_mask); + for_each_cpu_mask(i, cleanup_mask) + platform_send_ipi(i, IA64_IRQ_MOVE_VECTOR, IA64_IPI_DM_INT, 0); + cfg->move_in_progress = 0; +} + +static irqreturn_t smp_irq_move_cleanup_interrupt(int irq, void *dev_id) +{ + int me = smp_processor_id(); + ia64_vector vector; + unsigned long flags; + + for (vector = IA64_FIRST_DEVICE_VECTOR; + vector < IA64_LAST_DEVICE_VECTOR; vector++) { + int irq; + struct irq_desc *desc; + struct irq_cfg *cfg; + irq = __get_cpu_var(vector_irq)[vector]; + if (irq < 0) + continue; + + desc = irq_desc + irq; + cfg = irq_cfg + irq; + spin_lock(&desc->lock); + if (!cfg->move_cleanup_count) + goto unlock; + + if (!cpu_isset(me, cfg->old_domain)) + goto unlock; + + spin_lock_irqsave(&vector_lock, flags); + __get_cpu_var(vector_irq)[vector] = -1; + cpu_clear(me, vector_table[vector]); + spin_unlock_irqrestore(&vector_lock, flags); + cfg->move_cleanup_count--; + unlock: + spin_unlock(&desc->lock); + } + return IRQ_HANDLED; +} + +static struct irqaction irq_move_irqaction = { + .handler = smp_irq_move_cleanup_interrupt, + .flags = IRQF_DISABLED, + .name = "irq_move" +}; + static int __init parse_vector_domain(char *arg) { if (!arg) @@ -303,36 +400,6 @@ void destroy_and_reserve_irq(unsigned int irq) spin_unlock_irqrestore(&vector_lock, flags); } -static int __reassign_irq_vector(int irq, int cpu) -{ - struct irq_cfg *cfg = &irq_cfg[irq]; - int vector; - cpumask_t domain; - - if (cfg->vector == IRQ_VECTOR_UNASSIGNED || !cpu_online(cpu)) - return -EINVAL; - if (cpu_isset(cpu, cfg->domain)) - return 0; - domain = vector_allocation_domain(cpu); - vector = find_unassigned_vector(domain); - if (vector < 0) - return -ENOSPC; - __clear_irq_vector(irq); - BUG_ON(__bind_irq_vector(irq, vector, domain)); - return 0; -} - -int reassign_irq_vector(int irq, int cpu) -{ - unsigned long flags; - int ret; - - spin_lock_irqsave(&vector_lock, flags); - ret = __reassign_irq_vector(irq, cpu); - spin_unlock_irqrestore(&vector_lock, flags); - return ret; -} - /* * Dynamic irq allocate and deallocation for MSI */ @@ -440,7 +507,7 @@ ia64_handle_irq (ia64_vector vector, struct pt_regs *regs) if (unlikely(irq < 0)) { printk(KERN_ERR "%s: Unexpected interrupt " "vector %d on CPU %d is not mapped " - "to any IRQ!\n", __FUNCTION__, vector, + "to any IRQ!\n", __func__, vector, smp_processor_id()); } else generic_handle_irq(irq); @@ -505,7 +572,7 @@ void ia64_process_pending_intr(void) if (unlikely(irq < 0)) { printk(KERN_ERR "%s: Unexpected interrupt " "vector %d on CPU %d not being mapped " - "to any IRQ!!\n", __FUNCTION__, vector, + "to any IRQ!!\n", __func__, vector, smp_processor_id()); } else { vectors_in_migration[irq]=0; @@ -578,6 +645,13 @@ init_IRQ (void) register_percpu_irq(IA64_IPI_VECTOR, &ipi_irqaction); register_percpu_irq(IA64_IPI_RESCHEDULE, &resched_irqaction); register_percpu_irq(IA64_IPI_LOCAL_TLB_FLUSH, &tlb_irqaction); +#if defined(CONFIG_IA64_GENERIC) || defined(CONFIG_IA64_DIG) + if (vector_domain_type != VECTOR_DOMAIN_NONE) { + BUG_ON(IA64_FIRST_DEVICE_VECTOR != IA64_IRQ_MOVE_VECTOR); + IA64_FIRST_DEVICE_VECTOR++; + register_percpu_irq(IA64_IRQ_MOVE_VECTOR, &irq_move_irqaction); + } +#endif #endif #ifdef CONFIG_PERFMON pfm_init_percpu(); @@ -592,11 +666,7 @@ ia64_send_ipi (int cpu, int vector, int delivery_mode, int redirect) unsigned long ipi_data; unsigned long phys_cpu_id; -#ifdef CONFIG_SMP phys_cpu_id = cpu_physical_id(cpu); -#else - phys_cpu_id = (ia64_getreg(_IA64_REG_CR_LID) >> 16) & 0xffff; -#endif /* * cpu number is in 8bit ID and 8bit EID diff --git a/arch/ia64/kernel/kprobes.c b/arch/ia64/kernel/kprobes.c index b618487cdc858b836cee4adb044579bb5cb716f4..8d9a446a0d178e47a8ffad9a47711ee564680da3 100644 --- a/arch/ia64/kernel/kprobes.c +++ b/arch/ia64/kernel/kprobes.c @@ -838,7 +838,7 @@ out: return 1; } -int __kprobes kprobes_fault_handler(struct pt_regs *regs, int trapnr) +int __kprobes kprobe_fault_handler(struct pt_regs *regs, int trapnr) { struct kprobe *cur = kprobe_running(); struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); @@ -1001,6 +1001,11 @@ int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs) return 1; } +/* ia64 does not need this */ +void __kprobes jprobe_return(void) +{ +} + int __kprobes longjmp_break_handler(struct kprobe *p, struct pt_regs *regs) { struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); diff --git a/arch/ia64/kernel/mca.c b/arch/ia64/kernel/mca.c index 6e17aed5313521be82a8bf9f381f1b1a09307ea5..6c18221dba366776264d3f0251e14cd51a47d9dc 100644 --- a/arch/ia64/kernel/mca.c +++ b/arch/ia64/kernel/mca.c @@ -413,8 +413,8 @@ ia64_log_get(int sal_info_type, u8 **buffer, int irq_safe) IA64_LOG_INDEX_INC(sal_info_type); IA64_LOG_UNLOCK(sal_info_type); if (irq_safe) { - IA64_MCA_DEBUG("%s: SAL error record type %d retrieved. " - "Record length = %ld\n", __FUNCTION__, sal_info_type, total_len); + IA64_MCA_DEBUG("%s: SAL error record type %d retrieved. Record length = %ld\n", + __func__, sal_info_type, total_len); } *buffer = (u8 *) log_buffer; return total_len; @@ -518,7 +518,7 @@ ia64_mca_cpe_int_handler (int cpe_irq, void *arg) static DEFINE_SPINLOCK(cpe_history_lock); IA64_MCA_DEBUG("%s: received interrupt vector = %#x on CPU %d\n", - __FUNCTION__, cpe_irq, smp_processor_id()); + __func__, cpe_irq, smp_processor_id()); /* SAL spec states this should run w/ interrupts enabled */ local_irq_enable(); @@ -594,7 +594,7 @@ ia64_mca_register_cpev (int cpev) } IA64_MCA_DEBUG("%s: corrected platform error " - "vector %#x registered\n", __FUNCTION__, cpev); + "vector %#x registered\n", __func__, cpev); } #endif /* CONFIG_ACPI */ @@ -621,12 +621,11 @@ ia64_mca_cmc_vector_setup (void) cmcv.cmcv_vector = IA64_CMC_VECTOR; ia64_setreg(_IA64_REG_CR_CMCV, cmcv.cmcv_regval); - IA64_MCA_DEBUG("%s: CPU %d corrected " - "machine check vector %#x registered.\n", - __FUNCTION__, smp_processor_id(), IA64_CMC_VECTOR); + IA64_MCA_DEBUG("%s: CPU %d corrected machine check vector %#x registered.\n", + __func__, smp_processor_id(), IA64_CMC_VECTOR); IA64_MCA_DEBUG("%s: CPU %d CMCV = %#016lx\n", - __FUNCTION__, smp_processor_id(), ia64_getreg(_IA64_REG_CR_CMCV)); + __func__, smp_processor_id(), ia64_getreg(_IA64_REG_CR_CMCV)); } /* @@ -651,9 +650,8 @@ ia64_mca_cmc_vector_disable (void *dummy) cmcv.cmcv_mask = 1; /* Mask/disable interrupt */ ia64_setreg(_IA64_REG_CR_CMCV, cmcv.cmcv_regval); - IA64_MCA_DEBUG("%s: CPU %d corrected " - "machine check vector %#x disabled.\n", - __FUNCTION__, smp_processor_id(), cmcv.cmcv_vector); + IA64_MCA_DEBUG("%s: CPU %d corrected machine check vector %#x disabled.\n", + __func__, smp_processor_id(), cmcv.cmcv_vector); } /* @@ -678,9 +676,8 @@ ia64_mca_cmc_vector_enable (void *dummy) cmcv.cmcv_mask = 0; /* Unmask/enable interrupt */ ia64_setreg(_IA64_REG_CR_CMCV, cmcv.cmcv_regval); - IA64_MCA_DEBUG("%s: CPU %d corrected " - "machine check vector %#x enabled.\n", - __FUNCTION__, smp_processor_id(), cmcv.cmcv_vector); + IA64_MCA_DEBUG("%s: CPU %d corrected machine check vector %#x enabled.\n", + __func__, smp_processor_id(), cmcv.cmcv_vector); } /* @@ -767,7 +764,7 @@ ia64_mca_rendez_int_handler(int rendez_irq, void *arg) local_irq_save(flags); if (notify_die(DIE_MCA_RENDZVOUS_ENTER, "MCA", get_irq_regs(), (long)&nd, 0, 0) == NOTIFY_STOP) - ia64_mca_spin(__FUNCTION__); + ia64_mca_spin(__func__); ia64_mc_info.imi_rendez_checkin[cpu] = IA64_MCA_RENDEZ_CHECKIN_DONE; /* Register with the SAL monarch that the slave has @@ -777,7 +774,7 @@ ia64_mca_rendez_int_handler(int rendez_irq, void *arg) if (notify_die(DIE_MCA_RENDZVOUS_PROCESS, "MCA", get_irq_regs(), (long)&nd, 0, 0) == NOTIFY_STOP) - ia64_mca_spin(__FUNCTION__); + ia64_mca_spin(__func__); /* Wait for the monarch cpu to exit. */ while (monarch_cpu != -1) @@ -785,7 +782,7 @@ ia64_mca_rendez_int_handler(int rendez_irq, void *arg) if (notify_die(DIE_MCA_RENDZVOUS_LEAVE, "MCA", get_irq_regs(), (long)&nd, 0, 0) == NOTIFY_STOP) - ia64_mca_spin(__FUNCTION__); + ia64_mca_spin(__func__); ia64_mc_info.imi_rendez_checkin[cpu] = IA64_MCA_RENDEZ_CHECKIN_NOTDONE; /* Enable all interrupts */ @@ -1230,7 +1227,7 @@ ia64_mca_handler(struct pt_regs *regs, struct switch_stack *sw, if (notify_die(DIE_MCA_MONARCH_ENTER, "MCA", regs, (long)&nd, 0, 0) == NOTIFY_STOP) - ia64_mca_spin(__FUNCTION__); + ia64_mca_spin(__func__); ia64_mc_info.imi_rendez_checkin[cpu] = IA64_MCA_RENDEZ_CHECKIN_CONCURRENT_MCA; if (sos->monarch) { @@ -1246,7 +1243,7 @@ ia64_mca_handler(struct pt_regs *regs, struct switch_stack *sw, ia64_mca_wakeup_all(); if (notify_die(DIE_MCA_MONARCH_PROCESS, "MCA", regs, (long)&nd, 0, 0) == NOTIFY_STOP) - ia64_mca_spin(__FUNCTION__); + ia64_mca_spin(__func__); } else { while (cpu_isset(cpu, mca_cpu)) cpu_relax(); /* spin until monarch wakes us */ @@ -1276,7 +1273,7 @@ ia64_mca_handler(struct pt_regs *regs, struct switch_stack *sw, } if (notify_die(DIE_MCA_MONARCH_LEAVE, "MCA", regs, (long)&nd, 0, recover) == NOTIFY_STOP) - ia64_mca_spin(__FUNCTION__); + ia64_mca_spin(__func__); if (atomic_dec_return(&mca_count) > 0) { @@ -1328,7 +1325,7 @@ ia64_mca_cmc_int_handler(int cmc_irq, void *arg) static DEFINE_SPINLOCK(cmc_history_lock); IA64_MCA_DEBUG("%s: received interrupt vector = %#x on CPU %d\n", - __FUNCTION__, cmc_irq, smp_processor_id()); + __func__, cmc_irq, smp_processor_id()); /* SAL spec states this should run w/ interrupts enabled */ local_irq_enable(); @@ -1614,7 +1611,7 @@ ia64_init_handler(struct pt_regs *regs, struct switch_stack *sw, */ if (!sos->monarch && atomic_add_return(1, &slaves) == num_online_cpus()) { mprintk(KERN_WARNING "%s: Promoting cpu %d to monarch.\n", - __FUNCTION__, cpu); + __func__, cpu); atomic_dec(&slaves); sos->monarch = 1; } @@ -1626,7 +1623,7 @@ ia64_init_handler(struct pt_regs *regs, struct switch_stack *sw, */ if (sos->monarch && atomic_add_return(1, &monarchs) > 1) { mprintk(KERN_WARNING "%s: Demoting cpu %d to slave.\n", - __FUNCTION__, cpu); + __func__, cpu); atomic_dec(&monarchs); sos->monarch = 0; } @@ -1637,15 +1634,15 @@ ia64_init_handler(struct pt_regs *regs, struct switch_stack *sw, cpu_relax(); /* spin until monarch enters */ if (notify_die(DIE_INIT_SLAVE_ENTER, "INIT", regs, (long)&nd, 0, 0) == NOTIFY_STOP) - ia64_mca_spin(__FUNCTION__); + ia64_mca_spin(__func__); if (notify_die(DIE_INIT_SLAVE_PROCESS, "INIT", regs, (long)&nd, 0, 0) == NOTIFY_STOP) - ia64_mca_spin(__FUNCTION__); + ia64_mca_spin(__func__); while (monarch_cpu != -1) cpu_relax(); /* spin until monarch leaves */ if (notify_die(DIE_INIT_SLAVE_LEAVE, "INIT", regs, (long)&nd, 0, 0) == NOTIFY_STOP) - ia64_mca_spin(__FUNCTION__); + ia64_mca_spin(__func__); mprintk("Slave on cpu %d returning to normal service.\n", cpu); set_curr_task(cpu, previous_current); ia64_mc_info.imi_rendez_checkin[cpu] = IA64_MCA_RENDEZ_CHECKIN_NOTDONE; @@ -1656,7 +1653,7 @@ ia64_init_handler(struct pt_regs *regs, struct switch_stack *sw, monarch_cpu = cpu; if (notify_die(DIE_INIT_MONARCH_ENTER, "INIT", regs, (long)&nd, 0, 0) == NOTIFY_STOP) - ia64_mca_spin(__FUNCTION__); + ia64_mca_spin(__func__); /* * Wait for a bit. On some machines (e.g., HP's zx2000 and zx6000, INIT can be @@ -1673,10 +1670,10 @@ ia64_init_handler(struct pt_regs *regs, struct switch_stack *sw, */ if (notify_die(DIE_INIT_MONARCH_PROCESS, "INIT", regs, (long)&nd, 0, 0) == NOTIFY_STOP) - ia64_mca_spin(__FUNCTION__); + ia64_mca_spin(__func__); if (notify_die(DIE_INIT_MONARCH_LEAVE, "INIT", regs, (long)&nd, 0, 0) == NOTIFY_STOP) - ia64_mca_spin(__FUNCTION__); + ia64_mca_spin(__func__); mprintk("\nINIT dump complete. Monarch on cpu %d returning to normal service.\n", cpu); atomic_dec(&monarchs); set_curr_task(cpu, previous_current); @@ -1884,7 +1881,7 @@ ia64_mca_init(void) .priority = 0/* we need to notified last */ }; - IA64_MCA_DEBUG("%s: begin\n", __FUNCTION__); + IA64_MCA_DEBUG("%s: begin\n", __func__); /* Clear the Rendez checkin flag for all cpus */ for(i = 0 ; i < NR_CPUS; i++) @@ -1928,7 +1925,7 @@ ia64_mca_init(void) return; } - IA64_MCA_DEBUG("%s: registered MCA rendezvous spinloop and wakeup mech.\n", __FUNCTION__); + IA64_MCA_DEBUG("%s: registered MCA rendezvous spinloop and wakeup mech.\n", __func__); ia64_mc_info.imi_mca_handler = ia64_tpa(mca_hldlr_ptr->fp); /* @@ -1949,7 +1946,7 @@ ia64_mca_init(void) return; } - IA64_MCA_DEBUG("%s: registered OS MCA handler with SAL at 0x%lx, gp = 0x%lx\n", __FUNCTION__, + IA64_MCA_DEBUG("%s: registered OS MCA handler with SAL at 0x%lx, gp = 0x%lx\n", __func__, ia64_mc_info.imi_mca_handler, ia64_tpa(mca_hldlr_ptr->gp)); /* @@ -1961,7 +1958,7 @@ ia64_mca_init(void) ia64_mc_info.imi_slave_init_handler = ia64_tpa(init_hldlr_ptr_slave->fp); ia64_mc_info.imi_slave_init_handler_size = 0; - IA64_MCA_DEBUG("%s: OS INIT handler at %lx\n", __FUNCTION__, + IA64_MCA_DEBUG("%s: OS INIT handler at %lx\n", __func__, ia64_mc_info.imi_monarch_init_handler); /* Register the os init handler with SAL */ @@ -1982,7 +1979,7 @@ ia64_mca_init(void) return; } - IA64_MCA_DEBUG("%s: registered OS INIT handler with SAL\n", __FUNCTION__); + IA64_MCA_DEBUG("%s: registered OS INIT handler with SAL\n", __func__); /* * Configure the CMCI/P vector and handler. Interrupts for CMC are @@ -2042,7 +2039,7 @@ ia64_mca_late_init(void) cmc_polling_enabled = 0; schedule_work(&cmc_enable_work); - IA64_MCA_DEBUG("%s: CMCI/P setup and enabled.\n", __FUNCTION__); + IA64_MCA_DEBUG("%s: CMCI/P setup and enabled.\n", __func__); #ifdef CONFIG_ACPI /* Setup the CPEI/P vector and handler */ @@ -2065,17 +2062,17 @@ ia64_mca_late_init(void) ia64_cpe_irq = irq; ia64_mca_register_cpev(cpe_vector); IA64_MCA_DEBUG("%s: CPEI/P setup and enabled.\n", - __FUNCTION__); + __func__); return 0; } printk(KERN_ERR "%s: Failed to find irq for CPE " "interrupt handler, vector %d\n", - __FUNCTION__, cpe_vector); + __func__, cpe_vector); } /* If platform doesn't support CPEI, get the timer going. */ if (cpe_poll_enabled) { ia64_mca_cpe_poll(0UL); - IA64_MCA_DEBUG("%s: CPEP setup and enabled.\n", __FUNCTION__); + IA64_MCA_DEBUG("%s: CPEP setup and enabled.\n", __func__); } } #endif diff --git a/arch/ia64/kernel/module.c b/arch/ia64/kernel/module.c index e58f4367cf11db4ad4cca80fed0785f7283d5b15..e83e2ea3b3e0787ea673ae7451ae2855196f1c38 100644 --- a/arch/ia64/kernel/module.c +++ b/arch/ia64/kernel/module.c @@ -493,7 +493,7 @@ module_frob_arch_sections (Elf_Ehdr *ehdr, Elf_Shdr *sechdrs, char *secstrings, mod->arch.opd->sh_addralign = 8; mod->arch.opd->sh_size = fdescs * sizeof(struct fdesc); DEBUGP("%s: core.plt=%lx, init.plt=%lx, got=%lx, fdesc=%lx\n", - __FUNCTION__, mod->arch.core_plt->sh_size, mod->arch.init_plt->sh_size, + __func__, mod->arch.core_plt->sh_size, mod->arch.init_plt->sh_size, mod->arch.got->sh_size, mod->arch.opd->sh_size); return 0; } @@ -585,7 +585,7 @@ get_plt (struct module *mod, const struct insn *insn, uint64_t value, int *okp) #if ARCH_MODULE_DEBUG if (plt_target(plt) != target_ip) { printk("%s: mistargeted PLT: wanted %lx, got %lx\n", - __FUNCTION__, target_ip, plt_target(plt)); + __func__, target_ip, plt_target(plt)); *okp = 0; return 0; } @@ -703,7 +703,7 @@ do_reloc (struct module *mod, uint8_t r_type, Elf64_Sym *sym, uint64_t addend, if (r_type == R_IA64_PCREL21BI) { if (!is_internal(mod, val)) { printk(KERN_ERR "%s: %s reloc against non-local symbol (%lx)\n", - __FUNCTION__, reloc_name[r_type], val); + __func__, reloc_name[r_type], val); return -ENOEXEC; } format = RF_INSN21B; @@ -737,7 +737,7 @@ do_reloc (struct module *mod, uint8_t r_type, Elf64_Sym *sym, uint64_t addend, case R_IA64_LDXMOV: if (gp_addressable(mod, val)) { /* turn "ld8" into "mov": */ - DEBUGP("%s: patching ld8 at %p to mov\n", __FUNCTION__, location); + DEBUGP("%s: patching ld8 at %p to mov\n", __func__, location); ia64_patch((u64) location, 0x1fff80fe000UL, 0x10000000000UL); } return 0; @@ -771,7 +771,7 @@ do_reloc (struct module *mod, uint8_t r_type, Elf64_Sym *sym, uint64_t addend, if (!ok) return -ENOEXEC; - DEBUGP("%s: [%p]<-%016lx = %s(%lx)\n", __FUNCTION__, location, val, + DEBUGP("%s: [%p]<-%016lx = %s(%lx)\n", __func__, location, val, reloc_name[r_type] ? reloc_name[r_type] : "?", sym->st_value + addend); switch (format) { @@ -807,7 +807,7 @@ apply_relocate_add (Elf64_Shdr *sechdrs, const char *strtab, unsigned int symind Elf64_Shdr *target_sec; int ret; - DEBUGP("%s: applying section %u (%u relocs) to %u\n", __FUNCTION__, + DEBUGP("%s: applying section %u (%u relocs) to %u\n", __func__, relsec, n, sechdrs[relsec].sh_info); target_sec = sechdrs + sechdrs[relsec].sh_info; @@ -835,7 +835,7 @@ apply_relocate_add (Elf64_Shdr *sechdrs, const char *strtab, unsigned int symind gp = mod->core_size / 2; gp = (uint64_t) mod->module_core + ((gp + 7) & -8); mod->arch.gp = gp; - DEBUGP("%s: placing gp at 0x%lx\n", __FUNCTION__, gp); + DEBUGP("%s: placing gp at 0x%lx\n", __func__, gp); } for (i = 0; i < n; i++) { @@ -903,7 +903,7 @@ register_unwind_table (struct module *mod) init = start + num_core; } - DEBUGP("%s: name=%s, gp=%lx, num_init=%lu, num_core=%lu\n", __FUNCTION__, + DEBUGP("%s: name=%s, gp=%lx, num_init=%lu, num_core=%lu\n", __func__, mod->name, mod->arch.gp, num_init, num_core); /* @@ -912,13 +912,13 @@ register_unwind_table (struct module *mod) if (num_core > 0) { mod->arch.core_unw_table = unw_add_unwind_table(mod->name, 0, mod->arch.gp, core, core + num_core); - DEBUGP("%s: core: handle=%p [%p-%p)\n", __FUNCTION__, + DEBUGP("%s: core: handle=%p [%p-%p)\n", __func__, mod->arch.core_unw_table, core, core + num_core); } if (num_init > 0) { mod->arch.init_unw_table = unw_add_unwind_table(mod->name, 0, mod->arch.gp, init, init + num_init); - DEBUGP("%s: init: handle=%p [%p-%p)\n", __FUNCTION__, + DEBUGP("%s: init: handle=%p [%p-%p)\n", __func__, mod->arch.init_unw_table, init, init + num_init); } } @@ -926,7 +926,7 @@ register_unwind_table (struct module *mod) int module_finalize (const Elf_Ehdr *hdr, const Elf_Shdr *sechdrs, struct module *mod) { - DEBUGP("%s: init: entry=%p\n", __FUNCTION__, mod->init); + DEBUGP("%s: init: entry=%p\n", __func__, mod->init); if (mod->arch.unwind) register_unwind_table(mod); return 0; diff --git a/arch/ia64/kernel/msi_ia64.c b/arch/ia64/kernel/msi_ia64.c index e86d0295979465a56c257298028d5fc9798fb249..60c6ef67ebb215267c79eae647984893d0684f66 100644 --- a/arch/ia64/kernel/msi_ia64.c +++ b/arch/ia64/kernel/msi_ia64.c @@ -57,7 +57,7 @@ static void ia64_set_msi_irq_affinity(unsigned int irq, cpumask_t cpu_mask) if (!cpu_online(cpu)) return; - if (reassign_irq_vector(irq, cpu)) + if (irq_prepare_move(irq, cpu)) return; read_msi_msg(irq, &msg); @@ -119,6 +119,7 @@ void ia64_teardown_msi_irq(unsigned int irq) static void ia64_ack_msi_irq(unsigned int irq) { + irq_complete_move(irq); move_native_irq(irq); ia64_eoi(); } diff --git a/arch/ia64/kernel/perfmon.c b/arch/ia64/kernel/perfmon.c index f6b99719f10f0b4c1ef4893e3e8999f0d4ca75df..a2aabfdc80d9ecaf4a8d1f4853956ca765e73f64 100644 --- a/arch/ia64/kernel/perfmon.c +++ b/arch/ia64/kernel/perfmon.c @@ -227,12 +227,12 @@ #ifdef PFM_DEBUGGING #define DPRINT(a) \ do { \ - if (unlikely(pfm_sysctl.debug >0)) { printk("%s.%d: CPU%d [%d] ", __FUNCTION__, __LINE__, smp_processor_id(), task_pid_nr(current)); printk a; } \ + if (unlikely(pfm_sysctl.debug >0)) { printk("%s.%d: CPU%d [%d] ", __func__, __LINE__, smp_processor_id(), task_pid_nr(current)); printk a; } \ } while (0) #define DPRINT_ovfl(a) \ do { \ - if (unlikely(pfm_sysctl.debug > 0 && pfm_sysctl.debug_ovfl >0)) { printk("%s.%d: CPU%d [%d] ", __FUNCTION__, __LINE__, smp_processor_id(), task_pid_nr(current)); printk a; } \ + if (unlikely(pfm_sysctl.debug > 0 && pfm_sysctl.debug_ovfl >0)) { printk("%s.%d: CPU%d [%d] ", __func__, __LINE__, smp_processor_id(), task_pid_nr(current)); printk a; } \ } while (0) #endif diff --git a/arch/ia64/kernel/perfmon_default_smpl.c b/arch/ia64/kernel/perfmon_default_smpl.c index a7af1cb419f921490991a2d29c3a6e6bc69d6012..5f637bbfcccdd6f5a09bdfe6a9266859f5cc4e63 100644 --- a/arch/ia64/kernel/perfmon_default_smpl.c +++ b/arch/ia64/kernel/perfmon_default_smpl.c @@ -24,12 +24,12 @@ MODULE_LICENSE("GPL"); #ifdef DEFAULT_DEBUG #define DPRINT(a) \ do { \ - if (unlikely(pfm_sysctl.debug >0)) { printk("%s.%d: CPU%d ", __FUNCTION__, __LINE__, smp_processor_id()); printk a; } \ + if (unlikely(pfm_sysctl.debug >0)) { printk("%s.%d: CPU%d ", __func__, __LINE__, smp_processor_id()); printk a; } \ } while (0) #define DPRINT_ovfl(a) \ do { \ - if (unlikely(pfm_sysctl.debug > 0 && pfm_sysctl.debug_ovfl >0)) { printk("%s.%d: CPU%d ", __FUNCTION__, __LINE__, smp_processor_id()); printk a; } \ + if (unlikely(pfm_sysctl.debug > 0 && pfm_sysctl.debug_ovfl >0)) { printk("%s.%d: CPU%d ", __func__, __LINE__, smp_processor_id()); printk a; } \ } while (0) #else diff --git a/arch/ia64/kernel/ptrace.c b/arch/ia64/kernel/ptrace.c index 331d6768b5d50f7257cb6c389929fdfb989800c9..ab784ec4319dbd2eea568a5a6cbc566e829eb358 100644 --- a/arch/ia64/kernel/ptrace.c +++ b/arch/ia64/kernel/ptrace.c @@ -697,52 +697,6 @@ thread_matches (struct task_struct *thread, unsigned long addr) return 1; /* looks like we've got a winner */ } -/* - * GDB apparently wants to be able to read the register-backing store - * of any thread when attached to a given process. If we are peeking - * or poking an address that happens to reside in the kernel-backing - * store of another thread, we need to attach to that thread, because - * otherwise we end up accessing stale data. - * - * task_list_lock must be read-locked before calling this routine! - */ -static struct task_struct * -find_thread_for_addr (struct task_struct *child, unsigned long addr) -{ - struct task_struct *p; - struct mm_struct *mm; - struct list_head *this, *next; - int mm_users; - - if (!(mm = get_task_mm(child))) - return child; - - /* -1 because of our get_task_mm(): */ - mm_users = atomic_read(&mm->mm_users) - 1; - if (mm_users <= 1) - goto out; /* not multi-threaded */ - - /* - * Traverse the current process' children list. Every task that - * one attaches to becomes a child. And it is only attached children - * of the debugger that are of interest (ptrace_check_attach checks - * for this). - */ - list_for_each_safe(this, next, ¤t->children) { - p = list_entry(this, struct task_struct, sibling); - if (p->tgid != child->tgid) - continue; - if (thread_matches(p, addr)) { - child = p; - goto out; - } - } - - out: - mmput(mm); - return child; -} - /* * Write f32-f127 back to task->thread.fph if it has been modified. */ @@ -826,14 +780,14 @@ convert_to_non_syscall (struct task_struct *child, struct pt_regs *pt, if ((long)((unsigned long)child + IA64_STK_OFFSET - sp) < IA64_PT_REGS_SIZE) { dprintk("ptrace.%s: ran off the top of the kernel " - "stack\n", __FUNCTION__); + "stack\n", __func__); return; } if (unw_get_pr (&prev_info, &pr) < 0) { unw_get_rp(&prev_info, &ip); dprintk("ptrace.%s: failed to read " "predicate register (ip=0x%lx)\n", - __FUNCTION__, ip); + __func__, ip); return; } if (unw_is_intr_frame(&info) @@ -908,7 +862,7 @@ static int access_uarea (struct task_struct *child, unsigned long addr, unsigned long *data, int write_access) { - unsigned long *ptr, regnum, urbs_end, rnat_addr, cfm; + unsigned long *ptr, regnum, urbs_end, cfm; struct switch_stack *sw; struct pt_regs *pt; # define pt_reg_addr(pt, reg) ((void *) \ @@ -1011,14 +965,9 @@ access_uarea (struct task_struct *child, unsigned long addr, * the kernel was entered. * * Furthermore, when changing the contents of - * PT_AR_BSP (or PT_CFM) we MUST copy any - * users-level stacked registers that are - * stored on the kernel stack back to - * user-space because otherwise, we might end - * up clobbering kernel stacked registers. - * Also, if this happens while the task is - * blocked in a system call, which convert the - * state such that the non-system-call exit + * PT_AR_BSP (or PT_CFM) while the task is + * blocked in a system call, convert the state + * so that the non-system-call exit * path is used. This ensures that the proper * state will be picked up when resuming * execution. However, it *also* means that @@ -1035,10 +984,6 @@ access_uarea (struct task_struct *child, unsigned long addr, urbs_end = ia64_get_user_rbs_end(child, pt, &cfm); if (write_access) { if (*data != urbs_end) { - if (ia64_sync_user_rbs(child, sw, - pt->ar_bspstore, - urbs_end) < 0) - return -1; if (in_syscall(pt)) convert_to_non_syscall(child, pt, @@ -1058,10 +1003,6 @@ access_uarea (struct task_struct *child, unsigned long addr, urbs_end = ia64_get_user_rbs_end(child, pt, &cfm); if (write_access) { if (((cfm ^ *data) & PFM_MASK) != 0) { - if (ia64_sync_user_rbs(child, sw, - pt->ar_bspstore, - urbs_end) < 0) - return -1; if (in_syscall(pt)) convert_to_non_syscall(child, pt, @@ -1093,16 +1034,8 @@ access_uarea (struct task_struct *child, unsigned long addr, return 0; case PT_AR_RNAT: - urbs_end = ia64_get_user_rbs_end(child, pt, NULL); - rnat_addr = (long) ia64_rse_rnat_addr((long *) - urbs_end); - if (write_access) - return ia64_poke(child, sw, urbs_end, - rnat_addr, *data); - else - return ia64_peek(child, sw, urbs_end, - rnat_addr, data); - + ptr = pt_reg_addr(pt, ar_rnat); + break; case PT_R1: ptr = pt_reg_addr(pt, r1); break; @@ -1521,215 +1454,97 @@ ptrace_setregs (struct task_struct *child, struct pt_all_user_regs __user *ppr) return ret; } -/* - * Called by kernel/ptrace.c when detaching.. - * - * Make sure the single step bit is not set. - */ void -ptrace_disable (struct task_struct *child) +user_enable_single_step (struct task_struct *child) { struct ia64_psr *child_psr = ia64_psr(task_pt_regs(child)); - /* make sure the single step/taken-branch trap bits are not set: */ - clear_tsk_thread_flag(child, TIF_SINGLESTEP); - child_psr->ss = 0; - child_psr->tb = 0; + set_tsk_thread_flag(child, TIF_SINGLESTEP); + child_psr->ss = 1; } -asmlinkage long -sys_ptrace (long request, pid_t pid, unsigned long addr, unsigned long data) +void +user_enable_block_step (struct task_struct *child) { - struct pt_regs *pt; - unsigned long urbs_end, peek_or_poke; - struct task_struct *child; - struct switch_stack *sw; - long ret; - struct unw_frame_info info; + struct ia64_psr *child_psr = ia64_psr(task_pt_regs(child)); - lock_kernel(); - ret = -EPERM; - if (request == PTRACE_TRACEME) { - ret = ptrace_traceme(); - goto out; - } + set_tsk_thread_flag(child, TIF_SINGLESTEP); + child_psr->tb = 1; +} - peek_or_poke = (request == PTRACE_PEEKTEXT - || request == PTRACE_PEEKDATA - || request == PTRACE_POKETEXT - || request == PTRACE_POKEDATA); - ret = -ESRCH; - read_lock(&tasklist_lock); - { - child = find_task_by_pid(pid); - if (child) { - if (peek_or_poke) - child = find_thread_for_addr(child, addr); - get_task_struct(child); - } - } - read_unlock(&tasklist_lock); - if (!child) - goto out; - ret = -EPERM; - if (pid == 1) /* no messing around with init! */ - goto out_tsk; - - if (request == PTRACE_ATTACH) { - ret = ptrace_attach(child); - if (!ret) - arch_ptrace_attach(child); - goto out_tsk; - } +void +user_disable_single_step (struct task_struct *child) +{ + struct ia64_psr *child_psr = ia64_psr(task_pt_regs(child)); - ret = ptrace_check_attach(child, request == PTRACE_KILL); - if (ret < 0) - goto out_tsk; + /* make sure the single step/taken-branch trap bits are not set: */ + clear_tsk_thread_flag(child, TIF_SINGLESTEP); + child_psr->ss = 0; + child_psr->tb = 0; +} - pt = task_pt_regs(child); - sw = (struct switch_stack *) (child->thread.ksp + 16); +/* + * Called by kernel/ptrace.c when detaching.. + * + * Make sure the single step bit is not set. + */ +void +ptrace_disable (struct task_struct *child) +{ + user_disable_single_step(child); +} +long +arch_ptrace (struct task_struct *child, long request, long addr, long data) +{ switch (request) { - case PTRACE_PEEKTEXT: - case PTRACE_PEEKDATA: + case PTRACE_PEEKTEXT: + case PTRACE_PEEKDATA: /* read word at location addr */ - urbs_end = ia64_get_user_rbs_end(child, pt, NULL); - ret = ia64_peek(child, sw, urbs_end, addr, &data); - if (ret == 0) { - ret = data; - /* ensure "ret" is not mistaken as an error code: */ - force_successful_syscall_return(); - } - goto out_tsk; - - case PTRACE_POKETEXT: - case PTRACE_POKEDATA: - /* write the word at location addr */ - urbs_end = ia64_get_user_rbs_end(child, pt, NULL); - ret = ia64_poke(child, sw, urbs_end, addr, data); - - /* Make sure user RBS has the latest data */ - unw_init_from_blocked_task(&info, child); - do_sync_rbs(&info, ia64_sync_user_rbs); + if (access_process_vm(child, addr, &data, sizeof(data), 0) + != sizeof(data)) + return -EIO; + /* ensure return value is not mistaken for error code */ + force_successful_syscall_return(); + return data; - goto out_tsk; + /* PTRACE_POKETEXT and PTRACE_POKEDATA is handled + * by the generic ptrace_request(). + */ - case PTRACE_PEEKUSR: + case PTRACE_PEEKUSR: /* read the word at addr in the USER area */ - if (access_uarea(child, addr, &data, 0) < 0) { - ret = -EIO; - goto out_tsk; - } - ret = data; - /* ensure "ret" is not mistaken as an error code */ + if (access_uarea(child, addr, &data, 0) < 0) + return -EIO; + /* ensure return value is not mistaken for error code */ force_successful_syscall_return(); - goto out_tsk; + return data; - case PTRACE_POKEUSR: + case PTRACE_POKEUSR: /* write the word at addr in the USER area */ - if (access_uarea(child, addr, &data, 1) < 0) { - ret = -EIO; - goto out_tsk; - } - ret = 0; - goto out_tsk; + if (access_uarea(child, addr, &data, 1) < 0) + return -EIO; + return 0; - case PTRACE_OLD_GETSIGINFO: + case PTRACE_OLD_GETSIGINFO: /* for backwards-compatibility */ - ret = ptrace_request(child, PTRACE_GETSIGINFO, addr, data); - goto out_tsk; + return ptrace_request(child, PTRACE_GETSIGINFO, addr, data); - case PTRACE_OLD_SETSIGINFO: + case PTRACE_OLD_SETSIGINFO: /* for backwards-compatibility */ - ret = ptrace_request(child, PTRACE_SETSIGINFO, addr, data); - goto out_tsk; - - case PTRACE_SYSCALL: - /* continue and stop at next (return from) syscall */ - case PTRACE_CONT: - /* restart after signal. */ - ret = -EIO; - if (!valid_signal(data)) - goto out_tsk; - if (request == PTRACE_SYSCALL) - set_tsk_thread_flag(child, TIF_SYSCALL_TRACE); - else - clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); - child->exit_code = data; + return ptrace_request(child, PTRACE_SETSIGINFO, addr, data); - /* - * Make sure the single step/taken-branch trap bits - * are not set: - */ - clear_tsk_thread_flag(child, TIF_SINGLESTEP); - ia64_psr(pt)->ss = 0; - ia64_psr(pt)->tb = 0; + case PTRACE_GETREGS: + return ptrace_getregs(child, + (struct pt_all_user_regs __user *) data); - wake_up_process(child); - ret = 0; - goto out_tsk; + case PTRACE_SETREGS: + return ptrace_setregs(child, + (struct pt_all_user_regs __user *) data); - case PTRACE_KILL: - /* - * Make the child exit. Best I can do is send it a - * sigkill. Perhaps it should be put in the status - * that it wants to exit. - */ - if (child->exit_state == EXIT_ZOMBIE) - /* already dead */ - goto out_tsk; - child->exit_code = SIGKILL; - - ptrace_disable(child); - wake_up_process(child); - ret = 0; - goto out_tsk; - - case PTRACE_SINGLESTEP: - /* let child execute for one instruction */ - case PTRACE_SINGLEBLOCK: - ret = -EIO; - if (!valid_signal(data)) - goto out_tsk; - - clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); - set_tsk_thread_flag(child, TIF_SINGLESTEP); - if (request == PTRACE_SINGLESTEP) { - ia64_psr(pt)->ss = 1; - } else { - ia64_psr(pt)->tb = 1; - } - child->exit_code = data; - - /* give it a chance to run. */ - wake_up_process(child); - ret = 0; - goto out_tsk; - - case PTRACE_DETACH: - /* detach a process that was attached. */ - ret = ptrace_detach(child, data); - goto out_tsk; - - case PTRACE_GETREGS: - ret = ptrace_getregs(child, - (struct pt_all_user_regs __user *) data); - goto out_tsk; - - case PTRACE_SETREGS: - ret = ptrace_setregs(child, - (struct pt_all_user_regs __user *) data); - goto out_tsk; - - default: - ret = ptrace_request(child, request, addr, data); - goto out_tsk; + default: + return ptrace_request(child, request, addr, data); } - out_tsk: - put_task_struct(child); - out: - unlock_kernel(); - return ret; } diff --git a/arch/ia64/kernel/sal.c b/arch/ia64/kernel/sal.c index f44fe8412162c55b73b80663d8bb3e8d4d3d50a9..a3022dc48ef8432a437256948d5a25080b1cf24d 100644 --- a/arch/ia64/kernel/sal.c +++ b/arch/ia64/kernel/sal.c @@ -109,6 +109,13 @@ check_versions (struct ia64_sal_systab *systab) sal_revision = SAL_VERSION_CODE(2, 8); sal_version = SAL_VERSION_CODE(0, 0); } + + if (ia64_platform_is("sn2") && (sal_revision == SAL_VERSION_CODE(2, 9))) + /* + * SGI Altix has hard-coded version 2.9 in their prom + * but they actually implement 3.2, so let's fix it here. + */ + sal_revision = SAL_VERSION_CODE(3, 2); } static void __init diff --git a/arch/ia64/kernel/setup.c b/arch/ia64/kernel/setup.c index ebd1a09f32016b870ccb758dac93f1ade566f866..4aa9eaea76c373bcab89dfa1d058984272030456 100644 --- a/arch/ia64/kernel/setup.c +++ b/arch/ia64/kernel/setup.c @@ -690,7 +690,7 @@ get_model_name(__u8 family, __u8 model) if (overflow++ == 0) printk(KERN_ERR "%s: Table overflow. Some processor model information will be missing\n", - __FUNCTION__); + __func__); return "Unknown"; } @@ -785,7 +785,7 @@ get_max_cacheline_size (void) status = ia64_pal_cache_summary(&levels, &unique_caches); if (status != 0) { printk(KERN_ERR "%s: ia64_pal_cache_summary() failed (status=%ld)\n", - __FUNCTION__, status); + __func__, status); max = SMP_CACHE_BYTES; /* Safest setup for "flush_icache_range()" */ ia64_i_cache_stride_shift = I_CACHE_STRIDE_SHIFT; @@ -798,7 +798,7 @@ get_max_cacheline_size (void) if (status != 0) { printk(KERN_ERR "%s: ia64_pal_cache_config_info(l=%lu, 2) failed (status=%ld)\n", - __FUNCTION__, l, status); + __func__, l, status); max = SMP_CACHE_BYTES; /* The safest setup for "flush_icache_range()" */ cci.pcci_stride = I_CACHE_STRIDE_SHIFT; @@ -814,7 +814,7 @@ get_max_cacheline_size (void) if (status != 0) { printk(KERN_ERR "%s: ia64_pal_cache_config_info(l=%lu, 1) failed (status=%ld)\n", - __FUNCTION__, l, status); + __func__, l, status); /* The safest setup for "flush_icache_range()" */ cci.pcci_stride = I_CACHE_STRIDE_SHIFT; } diff --git a/arch/ia64/kernel/signal.c b/arch/ia64/kernel/signal.c index 309da3567bc851966e8a7ad27e01eccac2e26ff2..5740296c35afa3d597e8fd041db4385ff628f268 100644 --- a/arch/ia64/kernel/signal.c +++ b/arch/ia64/kernel/signal.c @@ -342,15 +342,33 @@ setup_frame (int sig, struct k_sigaction *ka, siginfo_t *info, sigset_t *set, new_sp = scr->pt.r12; tramp_addr = (unsigned long) __kernel_sigtramp; - if ((ka->sa.sa_flags & SA_ONSTACK) && sas_ss_flags(new_sp) == 0) { - new_sp = current->sas_ss_sp + current->sas_ss_size; - /* - * We need to check for the register stack being on the signal stack - * separately, because it's switched separately (memory stack is switched - * in the kernel, register stack is switched in the signal trampoline). - */ - if (!rbs_on_sig_stack(scr->pt.ar_bspstore)) - new_rbs = (current->sas_ss_sp + sizeof(long) - 1) & ~(sizeof(long) - 1); + if (ka->sa.sa_flags & SA_ONSTACK) { + int onstack = sas_ss_flags(new_sp); + + if (onstack == 0) { + new_sp = current->sas_ss_sp + current->sas_ss_size; + /* + * We need to check for the register stack being on the + * signal stack separately, because it's switched + * separately (memory stack is switched in the kernel, + * register stack is switched in the signal trampoline). + */ + if (!rbs_on_sig_stack(scr->pt.ar_bspstore)) + new_rbs = ALIGN(current->sas_ss_sp, + sizeof(long)); + } else if (onstack == SS_ONSTACK) { + unsigned long check_sp; + + /* + * If we are on the alternate signal stack and would + * overflow it, don't. Return an always-bogus address + * instead so we will die with SIGSEGV. + */ + check_sp = (new_sp - sizeof(*frame)) & -STACK_ALIGN; + if (!likely(on_sig_stack(check_sp))) + return force_sigsegv_info(sig, (void __user *) + check_sp); + } } frame = (void __user *) ((new_sp - sizeof(*frame)) & -STACK_ALIGN); diff --git a/arch/ia64/kernel/unaligned.c b/arch/ia64/kernel/unaligned.c index 52f70bbc192a6faa68ad87bd76bde20b37a6bb73..6903361d11a5766e54f2b8b0e64f5a4d892e2538 100644 --- a/arch/ia64/kernel/unaligned.c +++ b/arch/ia64/kernel/unaligned.c @@ -28,7 +28,7 @@ extern int die_if_kernel(char *str, struct pt_regs *regs, long err); #undef DEBUG_UNALIGNED_TRAP #ifdef DEBUG_UNALIGNED_TRAP -# define DPRINT(a...) do { printk("%s %u: ", __FUNCTION__, __LINE__); printk (a); } while (0) +# define DPRINT(a...) do { printk("%s %u: ", __func__, __LINE__); printk (a); } while (0) # define DDUMP(str,vp,len) dump(str, vp, len) static void @@ -674,7 +674,7 @@ emulate_load_updates (update_t type, load_store_t ld, struct pt_regs *regs, unsi * just in case. */ if (ld.x6_op == 1 || ld.x6_op == 3) { - printk(KERN_ERR "%s: register update on speculative load, error\n", __FUNCTION__); + printk(KERN_ERR "%s: register update on speculative load, error\n", __func__); if (die_if_kernel("unaligned reference on speculative load with register update\n", regs, 30)) return; @@ -1104,7 +1104,7 @@ emulate_load_floatpair (unsigned long ifa, load_store_t ld, struct pt_regs *regs */ if (ld.x6_op == 1 || ld.x6_op == 3) printk(KERN_ERR "%s: register update on speculative load pair, error\n", - __FUNCTION__); + __func__); setreg(ld.r3, ifa, 0, regs); } diff --git a/arch/ia64/kernel/unwind.c b/arch/ia64/kernel/unwind.c index c1bdb5131814c8f9f24e01cc51eae54e4df35666..67810b77d998768199b3978d288130968e837865 100644 --- a/arch/ia64/kernel/unwind.c +++ b/arch/ia64/kernel/unwind.c @@ -257,7 +257,7 @@ pt_regs_off (unsigned long reg) off = unw.pt_regs_offsets[reg]; if (off < 0) { - UNW_DPRINT(0, "unwind.%s: bad scratch reg r%lu\n", __FUNCTION__, reg); + UNW_DPRINT(0, "unwind.%s: bad scratch reg r%lu\n", __func__, reg); off = 0; } return (unsigned long) off; @@ -268,13 +268,13 @@ get_scratch_regs (struct unw_frame_info *info) { if (!info->pt) { /* This should not happen with valid unwind info. */ - UNW_DPRINT(0, "unwind.%s: bad unwind info: resetting info->pt\n", __FUNCTION__); + UNW_DPRINT(0, "unwind.%s: bad unwind info: resetting info->pt\n", __func__); if (info->flags & UNW_FLAG_INTERRUPT_FRAME) info->pt = (unsigned long) ((struct pt_regs *) info->psp - 1); else info->pt = info->sp - 16; } - UNW_DPRINT(3, "unwind.%s: sp 0x%lx pt 0x%lx\n", __FUNCTION__, info->sp, info->pt); + UNW_DPRINT(3, "unwind.%s: sp 0x%lx pt 0x%lx\n", __func__, info->sp, info->pt); return (struct pt_regs *) info->pt; } @@ -294,7 +294,7 @@ unw_access_gr (struct unw_frame_info *info, int regnum, unsigned long *val, char return 0; } UNW_DPRINT(0, "unwind.%s: trying to access non-existent r%u\n", - __FUNCTION__, regnum); + __func__, regnum); return -1; } @@ -341,7 +341,7 @@ unw_access_gr (struct unw_frame_info *info, int regnum, unsigned long *val, char { UNW_DPRINT(0, "unwind.%s: %p outside of regstk " "[0x%lx-0x%lx)\n", - __FUNCTION__, (void *) addr, + __func__, (void *) addr, info->regstk.limit, info->regstk.top); return -1; @@ -374,7 +374,7 @@ unw_access_gr (struct unw_frame_info *info, int regnum, unsigned long *val, char || (unsigned long) addr >= info->regstk.top) { UNW_DPRINT(0, "unwind.%s: ignoring attempt to access register outside " - "of rbs\n", __FUNCTION__); + "of rbs\n", __func__); return -1; } if ((unsigned long) nat_addr >= info->regstk.top) @@ -385,7 +385,7 @@ unw_access_gr (struct unw_frame_info *info, int regnum, unsigned long *val, char if (write) { if (read_only(addr)) { UNW_DPRINT(0, "unwind.%s: ignoring attempt to write read-only location\n", - __FUNCTION__); + __func__); } else { *addr = *val; if (*nat) @@ -427,13 +427,13 @@ unw_access_br (struct unw_frame_info *info, int regnum, unsigned long *val, int default: UNW_DPRINT(0, "unwind.%s: trying to access non-existent b%u\n", - __FUNCTION__, regnum); + __func__, regnum); return -1; } if (write) if (read_only(addr)) { UNW_DPRINT(0, "unwind.%s: ignoring attempt to write read-only location\n", - __FUNCTION__); + __func__); } else *addr = *val; else @@ -450,7 +450,7 @@ unw_access_fr (struct unw_frame_info *info, int regnum, struct ia64_fpreg *val, if ((unsigned) (regnum - 2) >= 126) { UNW_DPRINT(0, "unwind.%s: trying to access non-existent f%u\n", - __FUNCTION__, regnum); + __func__, regnum); return -1; } @@ -482,7 +482,7 @@ unw_access_fr (struct unw_frame_info *info, int regnum, struct ia64_fpreg *val, if (write) if (read_only(addr)) { UNW_DPRINT(0, "unwind.%s: ignoring attempt to write read-only location\n", - __FUNCTION__); + __func__); } else *addr = *val; else @@ -572,14 +572,14 @@ unw_access_ar (struct unw_frame_info *info, int regnum, unsigned long *val, int default: UNW_DPRINT(0, "unwind.%s: trying to access non-existent ar%u\n", - __FUNCTION__, regnum); + __func__, regnum); return -1; } if (write) { if (read_only(addr)) { UNW_DPRINT(0, "unwind.%s: ignoring attempt to write read-only location\n", - __FUNCTION__); + __func__); } else *addr = *val; } else @@ -600,7 +600,7 @@ unw_access_pr (struct unw_frame_info *info, unsigned long *val, int write) if (write) { if (read_only(addr)) { UNW_DPRINT(0, "unwind.%s: ignoring attempt to write read-only location\n", - __FUNCTION__); + __func__); } else *addr = *val; } else @@ -699,7 +699,7 @@ decode_abreg (unsigned char abreg, int memory) default: break; } - UNW_DPRINT(0, "unwind.%s: bad abreg=0x%x\n", __FUNCTION__, abreg); + UNW_DPRINT(0, "unwind.%s: bad abreg=0x%x\n", __func__, abreg); return UNW_REG_LC; } @@ -739,7 +739,7 @@ spill_next_when (struct unw_reg_info **regp, struct unw_reg_info *lim, unw_word return; } } - UNW_DPRINT(0, "unwind.%s: excess spill!\n", __FUNCTION__); + UNW_DPRINT(0, "unwind.%s: excess spill!\n", __func__); } static inline void @@ -855,11 +855,11 @@ desc_abi (unsigned char abi, unsigned char context, struct unw_state_record *sr) { if (abi == 3 && context == 'i') { sr->flags |= UNW_FLAG_INTERRUPT_FRAME; - UNW_DPRINT(3, "unwind.%s: interrupt frame\n", __FUNCTION__); + UNW_DPRINT(3, "unwind.%s: interrupt frame\n", __func__); } else UNW_DPRINT(0, "unwind%s: ignoring unwabi(abi=0x%x,context=0x%x)\n", - __FUNCTION__, abi, context); + __func__, abi, context); } static inline void @@ -1347,7 +1347,7 @@ script_emit (struct unw_script *script, struct unw_insn insn) { if (script->count >= UNW_MAX_SCRIPT_LEN) { UNW_DPRINT(0, "unwind.%s: script exceeds maximum size of %u instructions!\n", - __FUNCTION__, UNW_MAX_SCRIPT_LEN); + __func__, UNW_MAX_SCRIPT_LEN); return; } script->insn[script->count++] = insn; @@ -1389,7 +1389,7 @@ emit_nat_info (struct unw_state_record *sr, int i, struct unw_script *script) default: UNW_DPRINT(0, "unwind.%s: don't know how to emit nat info for where = %u\n", - __FUNCTION__, r->where); + __func__, r->where); return; } insn.opc = opc; @@ -1446,7 +1446,7 @@ compile_reg (struct unw_state_record *sr, int i, struct unw_script *script) val = offsetof(struct pt_regs, f6) + 16*(rval - 6); else UNW_DPRINT(0, "unwind.%s: kernel may not touch f%lu\n", - __FUNCTION__, rval); + __func__, rval); } break; @@ -1474,7 +1474,7 @@ compile_reg (struct unw_state_record *sr, int i, struct unw_script *script) default: UNW_DPRINT(0, "unwind%s: register %u has unexpected `where' value of %u\n", - __FUNCTION__, i, r->where); + __func__, i, r->where); break; } insn.opc = opc; @@ -1547,10 +1547,10 @@ build_script (struct unw_frame_info *info) r->when = UNW_WHEN_NEVER; sr.pr_val = info->pr; - UNW_DPRINT(3, "unwind.%s: ip 0x%lx\n", __FUNCTION__, ip); + UNW_DPRINT(3, "unwind.%s: ip 0x%lx\n", __func__, ip); script = script_new(ip); if (!script) { - UNW_DPRINT(0, "unwind.%s: failed to create unwind script\n", __FUNCTION__); + UNW_DPRINT(0, "unwind.%s: failed to create unwind script\n", __func__); STAT(unw.stat.script.build_time += ia64_get_itc() - start); return NULL; } @@ -1569,7 +1569,7 @@ build_script (struct unw_frame_info *info) if (!e) { /* no info, return default unwinder (leaf proc, no mem stack, no saved regs) */ UNW_DPRINT(1, "unwind.%s: no unwind info for ip=0x%lx (prev ip=0x%lx)\n", - __FUNCTION__, ip, unw.cache[info->prev_script].ip); + __func__, ip, unw.cache[info->prev_script].ip); sr.curr.reg[UNW_REG_RP].where = UNW_WHERE_BR; sr.curr.reg[UNW_REG_RP].when = -1; sr.curr.reg[UNW_REG_RP].val = 0; @@ -1618,13 +1618,13 @@ build_script (struct unw_frame_info *info) sr.curr.reg[UNW_REG_RP].when = -1; sr.curr.reg[UNW_REG_RP].val = sr.return_link_reg; UNW_DPRINT(1, "unwind.%s: using default for rp at ip=0x%lx where=%d val=0x%lx\n", - __FUNCTION__, ip, sr.curr.reg[UNW_REG_RP].where, + __func__, ip, sr.curr.reg[UNW_REG_RP].where, sr.curr.reg[UNW_REG_RP].val); } #ifdef UNW_DEBUG UNW_DPRINT(1, "unwind.%s: state record for func 0x%lx, t=%u:\n", - __FUNCTION__, table->segment_base + e->start_offset, sr.when_target); + __func__, table->segment_base + e->start_offset, sr.when_target); for (r = sr.curr.reg; r < sr.curr.reg + UNW_NUM_REGS; ++r) { if (r->where != UNW_WHERE_NONE || r->when != UNW_WHEN_NEVER) { UNW_DPRINT(1, " %s <- ", unw.preg_name[r - sr.curr.reg]); @@ -1746,7 +1746,7 @@ run_script (struct unw_script *script, struct unw_frame_info *state) } else { s[dst] = 0; UNW_DPRINT(0, "unwind.%s: no state->pt, dst=%ld, val=%ld\n", - __FUNCTION__, dst, val); + __func__, dst, val); } break; @@ -1756,7 +1756,7 @@ run_script (struct unw_script *script, struct unw_frame_info *state) else { s[dst] = 0; UNW_DPRINT(0, "unwind.%s: UNW_INSN_MOVE_CONST bad val=%ld\n", - __FUNCTION__, val); + __func__, val); } break; @@ -1791,7 +1791,7 @@ run_script (struct unw_script *script, struct unw_frame_info *state) || s[val] < TASK_SIZE) { UNW_DPRINT(0, "unwind.%s: rejecting bad psp=0x%lx\n", - __FUNCTION__, s[val]); + __func__, s[val]); break; } #endif @@ -1825,7 +1825,7 @@ find_save_locs (struct unw_frame_info *info) if ((info->ip & (local_cpu_data->unimpl_va_mask | 0xf)) || info->ip < TASK_SIZE) { /* don't let obviously bad addresses pollute the cache */ /* FIXME: should really be level 0 but it occurs too often. KAO */ - UNW_DPRINT(1, "unwind.%s: rejecting bad ip=0x%lx\n", __FUNCTION__, info->ip); + UNW_DPRINT(1, "unwind.%s: rejecting bad ip=0x%lx\n", __func__, info->ip); info->rp_loc = NULL; return -1; } @@ -1838,7 +1838,7 @@ find_save_locs (struct unw_frame_info *info) spin_unlock_irqrestore(&unw.lock, flags); UNW_DPRINT(0, "unwind.%s: failed to locate/build unwind script for ip %lx\n", - __FUNCTION__, info->ip); + __func__, info->ip); return -1; } have_write_lock = 1; @@ -1882,21 +1882,21 @@ unw_unwind (struct unw_frame_info *info) if (!unw_valid(info, info->rp_loc)) { /* FIXME: should really be level 0 but it occurs too often. KAO */ UNW_DPRINT(1, "unwind.%s: failed to locate return link (ip=0x%lx)!\n", - __FUNCTION__, info->ip); + __func__, info->ip); STAT(unw.stat.api.unwind_time += ia64_get_itc() - start; local_irq_restore(flags)); return -1; } /* restore the ip */ ip = info->ip = *info->rp_loc; if (ip < GATE_ADDR) { - UNW_DPRINT(2, "unwind.%s: reached user-space (ip=0x%lx)\n", __FUNCTION__, ip); + UNW_DPRINT(2, "unwind.%s: reached user-space (ip=0x%lx)\n", __func__, ip); STAT(unw.stat.api.unwind_time += ia64_get_itc() - start; local_irq_restore(flags)); return -1; } /* validate the previous stack frame pointer */ if (!unw_valid(info, info->pfs_loc)) { - UNW_DPRINT(0, "unwind.%s: failed to locate ar.pfs!\n", __FUNCTION__); + UNW_DPRINT(0, "unwind.%s: failed to locate ar.pfs!\n", __func__); STAT(unw.stat.api.unwind_time += ia64_get_itc() - start; local_irq_restore(flags)); return -1; } @@ -1912,13 +1912,13 @@ unw_unwind (struct unw_frame_info *info) num_regs = *info->cfm_loc & 0x7f; /* size of frame */ info->pfs_loc = (unsigned long *) (info->pt + offsetof(struct pt_regs, ar_pfs)); - UNW_DPRINT(3, "unwind.%s: interrupt_frame pt 0x%lx\n", __FUNCTION__, info->pt); + UNW_DPRINT(3, "unwind.%s: interrupt_frame pt 0x%lx\n", __func__, info->pt); } else num_regs = (*info->cfm_loc >> 7) & 0x7f; /* size of locals */ info->bsp = (unsigned long) ia64_rse_skip_regs((unsigned long *) info->bsp, -num_regs); if (info->bsp < info->regstk.limit || info->bsp > info->regstk.top) { UNW_DPRINT(0, "unwind.%s: bsp (0x%lx) out of range [0x%lx-0x%lx]\n", - __FUNCTION__, info->bsp, info->regstk.limit, info->regstk.top); + __func__, info->bsp, info->regstk.limit, info->regstk.top); STAT(unw.stat.api.unwind_time += ia64_get_itc() - start; local_irq_restore(flags)); return -1; } @@ -1927,14 +1927,14 @@ unw_unwind (struct unw_frame_info *info) info->sp = info->psp; if (info->sp < info->memstk.top || info->sp > info->memstk.limit) { UNW_DPRINT(0, "unwind.%s: sp (0x%lx) out of range [0x%lx-0x%lx]\n", - __FUNCTION__, info->sp, info->memstk.top, info->memstk.limit); + __func__, info->sp, info->memstk.top, info->memstk.limit); STAT(unw.stat.api.unwind_time += ia64_get_itc() - start; local_irq_restore(flags)); return -1; } if (info->ip == prev_ip && info->sp == prev_sp && info->bsp == prev_bsp) { UNW_DPRINT(0, "unwind.%s: ip, sp, bsp unchanged; stopping here (ip=0x%lx)\n", - __FUNCTION__, ip); + __func__, ip); STAT(unw.stat.api.unwind_time += ia64_get_itc() - start; local_irq_restore(flags)); return -1; } @@ -1961,7 +1961,7 @@ unw_unwind_to_user (struct unw_frame_info *info) if ((long)((unsigned long)info->task + IA64_STK_OFFSET - sp) < IA64_PT_REGS_SIZE) { UNW_DPRINT(0, "unwind.%s: ran off the top of the kernel stack\n", - __FUNCTION__); + __func__); break; } if (unw_is_intr_frame(info) && @@ -1971,13 +1971,13 @@ unw_unwind_to_user (struct unw_frame_info *info) unw_get_rp(info, &ip); UNW_DPRINT(0, "unwind.%s: failed to read " "predicate register (ip=0x%lx)\n", - __FUNCTION__, ip); + __func__, ip); return -1; } } while (unw_unwind(info) >= 0); unw_get_ip(info, &ip); UNW_DPRINT(0, "unwind.%s: failed to unwind to user-level (ip=0x%lx)\n", - __FUNCTION__, ip); + __func__, ip); return -1; } EXPORT_SYMBOL(unw_unwind_to_user); @@ -2028,7 +2028,7 @@ init_frame_info (struct unw_frame_info *info, struct task_struct *t, " pr 0x%lx\n" " sw 0x%lx\n" " sp 0x%lx\n", - __FUNCTION__, (unsigned long) t, rbslimit, rbstop, stktop, stklimit, + __func__, (unsigned long) t, rbslimit, rbstop, stktop, stklimit, info->pr, (unsigned long) info->sw, info->sp); STAT(unw.stat.api.init_time += ia64_get_itc() - start; local_irq_restore(flags)); } @@ -2047,7 +2047,7 @@ unw_init_frame_info (struct unw_frame_info *info, struct task_struct *t, struct " bsp 0x%lx\n" " sol 0x%lx\n" " ip 0x%lx\n", - __FUNCTION__, info->bsp, sol, info->ip); + __func__, info->bsp, sol, info->ip); find_save_locs(info); } @@ -2058,7 +2058,7 @@ unw_init_from_blocked_task (struct unw_frame_info *info, struct task_struct *t) { struct switch_stack *sw = (struct switch_stack *) (t->thread.ksp + 16); - UNW_DPRINT(1, "unwind.%s\n", __FUNCTION__); + UNW_DPRINT(1, "unwind.%s\n", __func__); unw_init_frame_info(info, t, sw); } EXPORT_SYMBOL(unw_init_from_blocked_task); @@ -2088,7 +2088,7 @@ unw_add_unwind_table (const char *name, unsigned long segment_base, unsigned lon if (end - start <= 0) { UNW_DPRINT(0, "unwind.%s: ignoring attempt to insert empty unwind table\n", - __FUNCTION__); + __func__); return NULL; } @@ -2119,14 +2119,14 @@ unw_remove_unwind_table (void *handle) if (!handle) { UNW_DPRINT(0, "unwind.%s: ignoring attempt to remove non-existent unwind table\n", - __FUNCTION__); + __func__); return; } table = handle; if (table == &unw.kernel_table) { UNW_DPRINT(0, "unwind.%s: sorry, freeing the kernel's unwind table is a " - "no-can-do!\n", __FUNCTION__); + "no-can-do!\n", __func__); return; } @@ -2139,7 +2139,7 @@ unw_remove_unwind_table (void *handle) break; if (!prev) { UNW_DPRINT(0, "unwind.%s: failed to find unwind table %p\n", - __FUNCTION__, (void *) table); + __func__, (void *) table); spin_unlock_irqrestore(&unw.lock, flags); return; } @@ -2185,7 +2185,7 @@ create_gate_table (void) } if (!punw) { - printk("%s: failed to find gate DSO's unwind table!\n", __FUNCTION__); + printk("%s: failed to find gate DSO's unwind table!\n", __func__); return 0; } @@ -2202,7 +2202,7 @@ create_gate_table (void) unw.gate_table = kmalloc(size, GFP_KERNEL); if (!unw.gate_table) { unw.gate_table_size = 0; - printk(KERN_ERR "%s: unable to create unwind data for gate page!\n", __FUNCTION__); + printk(KERN_ERR "%s: unable to create unwind data for gate page!\n", __func__); return 0; } unw.gate_table_size = size; diff --git a/arch/ia64/mm/fault.c b/arch/ia64/mm/fault.c index 3e69881648a35ea1b91536b52eeb9387de9fd8d6..23088bed111ec229c4df3b1315da0e0fce7411a3 100644 --- a/arch/ia64/mm/fault.c +++ b/arch/ia64/mm/fault.c @@ -26,7 +26,7 @@ static inline int notify_page_fault(struct pt_regs *regs, int trap) if (!user_mode(regs)) { /* kprobe_running() needs smp_processor_id() */ preempt_disable(); - if (kprobe_running() && kprobes_fault_handler(regs, trap)) + if (kprobe_running() && kprobe_fault_handler(regs, trap)) ret = 1; preempt_enable(); } diff --git a/arch/ia64/mm/init.c b/arch/ia64/mm/init.c index 25aef6211a54be964778e5e42165bb2d0e3738f1..a4ca657c72c6905a10f9f59be54e7bb260d2922b 100644 --- a/arch/ia64/mm/init.c +++ b/arch/ia64/mm/init.c @@ -714,7 +714,7 @@ int arch_add_memory(int nid, u64 start, u64 size) if (ret) printk("%s: Problem encountered in __add_pages() as ret=%d\n", - __FUNCTION__, ret); + __func__, ret); return ret; } diff --git a/arch/ia64/pci/fixup.c b/arch/ia64/pci/fixup.c index 245dc1fedc24cea6de45d8fb6faee3fae77bac6c..f5959c0c1810422358f48498b29e44dcc743b4b5 100644 --- a/arch/ia64/pci/fixup.c +++ b/arch/ia64/pci/fixup.c @@ -63,7 +63,7 @@ static void __devinit pci_fixup_video(struct pci_dev *pdev) pci_read_config_word(pdev, PCI_COMMAND, &config); if (config & (PCI_COMMAND_IO | PCI_COMMAND_MEMORY)) { pdev->resource[PCI_ROM_RESOURCE].flags |= IORESOURCE_ROM_SHADOW; - printk(KERN_DEBUG "Boot video device is %s\n", pci_name(pdev)); + dev_printk(KERN_DEBUG, &pdev->dev, "Boot video device\n"); } } DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, pci_fixup_video); diff --git a/arch/ia64/pci/pci.c b/arch/ia64/pci/pci.c index 8fd7e825192b60160bf82215ed3004d22da075eb..e282c348dcde0b9a4a6b04b0d7a5077f449518b1 100644 --- a/arch/ia64/pci/pci.c +++ b/arch/ia64/pci/pci.c @@ -765,7 +765,7 @@ static void __init set_pci_cacheline_size(void) status = ia64_pal_cache_summary(&levels, &unique_caches); if (status != 0) { printk(KERN_ERR "%s: ia64_pal_cache_summary() failed " - "(status=%ld)\n", __FUNCTION__, status); + "(status=%ld)\n", __func__, status); return; } @@ -773,7 +773,7 @@ static void __init set_pci_cacheline_size(void) /* cache_type (data_or_unified)= */ 2, &cci); if (status != 0) { printk(KERN_ERR "%s: ia64_pal_cache_config_info() failed " - "(status=%ld)\n", __FUNCTION__, status); + "(status=%ld)\n", __func__, status); return; } pci_cache_line_size = (1 << cci.pcci_line_size) / 4; diff --git a/arch/ia64/sn/kernel/huberror.c b/arch/ia64/sn/kernel/huberror.c index b663168da55c5f32f1114b446fa0dd0244f4faea..0101c7924a4d4943dc4c4a4823967e1477dbbf54 100644 --- a/arch/ia64/sn/kernel/huberror.c +++ b/arch/ia64/sn/kernel/huberror.c @@ -37,7 +37,7 @@ static irqreturn_t hub_eint_handler(int irq, void *arg) (u64) nasid, 0, 0, 0, 0, 0, 0); if ((int)ret_stuff.v0) - panic("%s: Fatal %s Error", __FUNCTION__, + panic("%s: Fatal %s Error", __func__, ((nasid & 1) ? "TIO" : "HUBII")); if (!(nasid & 1)) /* Not a TIO, handle CRB errors */ @@ -48,7 +48,7 @@ static irqreturn_t hub_eint_handler(int irq, void *arg) (u64) nasid, 0, 0, 0, 0, 0, 0); if ((int)ret_stuff.v0) - panic("%s: Fatal TIO Error", __FUNCTION__); + panic("%s: Fatal TIO Error", __func__); } else bte_error_handler((unsigned long)NODEPDA(nasid_to_cnodeid(nasid))); diff --git a/arch/ia64/sn/kernel/io_acpi_init.c b/arch/ia64/sn/kernel/io_acpi_init.c index 3c7178f5dce82bad1492cbc006579db7f18ad98e..6568942a95f074514d28a96e7ab5b0acffff5173 100644 --- a/arch/ia64/sn/kernel/io_acpi_init.c +++ b/arch/ia64/sn/kernel/io_acpi_init.c @@ -133,7 +133,7 @@ sn_get_bussoft_ptr(struct pci_bus *bus) if (ACPI_FAILURE(status)) { printk(KERN_ERR "%s: " "acpi_get_vendor_resource() failed (0x%x) for: ", - __FUNCTION__, status); + __func__, status); acpi_ns_print_node_pathname(handle, NULL); printk("\n"); return NULL; @@ -145,7 +145,7 @@ sn_get_bussoft_ptr(struct pci_bus *bus) sizeof(struct pcibus_bussoft *)) { printk(KERN_ERR "%s: Invalid vendor data length %d\n", - __FUNCTION__, vendor->byte_length); + __func__, vendor->byte_length); kfree(buffer.pointer); return NULL; } @@ -184,7 +184,7 @@ sn_extract_device_info(acpi_handle handle, struct pcidev_info **pcidev_info, if (ACPI_FAILURE(status)) { printk(KERN_ERR "%s: acpi_get_vendor_resource() failed (0x%x) for: ", - __FUNCTION__, status); + __func__, status); acpi_ns_print_node_pathname(handle, NULL); printk("\n"); return 1; @@ -196,7 +196,7 @@ sn_extract_device_info(acpi_handle handle, struct pcidev_info **pcidev_info, sizeof(struct pci_devdev_info *)) { printk(KERN_ERR "%s: Invalid vendor data length: %d for: ", - __FUNCTION__, vendor->byte_length); + __func__, vendor->byte_length); acpi_ns_print_node_pathname(handle, NULL); printk("\n"); ret = 1; @@ -205,7 +205,7 @@ sn_extract_device_info(acpi_handle handle, struct pcidev_info **pcidev_info, pcidev_ptr = kzalloc(sizeof(struct pcidev_info), GFP_KERNEL); if (!pcidev_ptr) - panic("%s: Unable to alloc memory for pcidev_info", __FUNCTION__); + panic("%s: Unable to alloc memory for pcidev_info", __func__); memcpy(&addr, vendor->byte_data, sizeof(struct pcidev_info *)); pcidev_prom_ptr = __va(addr); @@ -214,7 +214,7 @@ sn_extract_device_info(acpi_handle handle, struct pcidev_info **pcidev_info, /* Get the IRQ info */ irq_info = kzalloc(sizeof(struct sn_irq_info), GFP_KERNEL); if (!irq_info) - panic("%s: Unable to alloc memory for sn_irq_info", __FUNCTION__); + panic("%s: Unable to alloc memory for sn_irq_info", __func__); if (pcidev_ptr->pdi_sn_irq_info) { irq_info_prom = __va(pcidev_ptr->pdi_sn_irq_info); @@ -249,10 +249,10 @@ get_host_devfn(acpi_handle device_handle, acpi_handle rootbus_handle) status = acpi_get_parent(child, &parent); if (ACPI_FAILURE(status)) { printk(KERN_ERR "%s: acpi_get_parent() failed " - "(0x%x) for: ", __FUNCTION__, status); + "(0x%x) for: ", __func__, status); acpi_ns_print_node_pathname(child, NULL); printk("\n"); - panic("%s: Unable to find host devfn\n", __FUNCTION__); + panic("%s: Unable to find host devfn\n", __func__); } if (parent == rootbus_handle) break; @@ -260,7 +260,7 @@ get_host_devfn(acpi_handle device_handle, acpi_handle rootbus_handle) } if (!child) { printk(KERN_ERR "%s: Unable to find root bus for: ", - __FUNCTION__); + __func__); acpi_ns_print_node_pathname(device_handle, NULL); printk("\n"); BUG(); @@ -269,10 +269,10 @@ get_host_devfn(acpi_handle device_handle, acpi_handle rootbus_handle) status = acpi_evaluate_integer(child, METHOD_NAME__ADR, NULL, &adr); if (ACPI_FAILURE(status)) { printk(KERN_ERR "%s: Unable to get _ADR (0x%x) for: ", - __FUNCTION__, status); + __func__, status); acpi_ns_print_node_pathname(child, NULL); printk("\n"); - panic("%s: Unable to find host devfn\n", __FUNCTION__); + panic("%s: Unable to find host devfn\n", __func__); } slot = (adr >> 16) & 0xffff; @@ -308,7 +308,7 @@ find_matching_device(acpi_handle handle, u32 lvl, void *context, void **rv) if (ACPI_FAILURE(status)) { printk(KERN_ERR "%s: acpi_get_parent() failed (0x%x) for: ", - __FUNCTION__, status); + __func__, status); acpi_ns_print_node_pathname(handle, NULL); printk("\n"); return AE_OK; @@ -318,7 +318,7 @@ find_matching_device(acpi_handle handle, u32 lvl, void *context, void **rv) if (ACPI_FAILURE(status)) { printk(KERN_ERR "%s: Failed to find _BBN in parent of: ", - __FUNCTION__); + __func__); acpi_ns_print_node_pathname(handle, NULL); printk("\n"); return AE_OK; @@ -358,14 +358,14 @@ sn_acpi_get_pcidev_info(struct pci_dev *dev, struct pcidev_info **pcidev_info, if (segment != pci_domain_nr(dev)) { printk(KERN_ERR "%s: Segment number mismatch, 0x%lx vs 0x%x for: ", - __FUNCTION__, segment, pci_domain_nr(dev)); + __func__, segment, pci_domain_nr(dev)); acpi_ns_print_node_pathname(rootbus_handle, NULL); printk("\n"); return 1; } } else { printk(KERN_ERR "%s: Unable to get __SEG from: ", - __FUNCTION__); + __func__); acpi_ns_print_node_pathname(rootbus_handle, NULL); printk("\n"); return 1; @@ -386,7 +386,7 @@ sn_acpi_get_pcidev_info(struct pci_dev *dev, struct pcidev_info **pcidev_info, if (!pcidev_match.handle) { printk(KERN_ERR "%s: Could not find matching ACPI device for %s.\n", - __FUNCTION__, pci_name(dev)); + __func__, pci_name(dev)); return 1; } @@ -422,7 +422,7 @@ sn_acpi_slot_fixup(struct pci_dev *dev) if (sn_acpi_get_pcidev_info(dev, &pcidev_info, &sn_irq_info)) { panic("%s: Failure obtaining pcidev_info for %s\n", - __FUNCTION__, pci_name(dev)); + __func__, pci_name(dev)); } if (pcidev_info->pdi_pio_mapped_addr[PCI_ROM_RESOURCE]) { @@ -463,7 +463,7 @@ sn_acpi_bus_fixup(struct pci_bus *bus) printk(KERN_ERR "%s: 0x%04x:0x%02x Unable to " "obtain prom_bussoft_ptr\n", - __FUNCTION__, pci_domain_nr(bus), bus->number); + __func__, pci_domain_nr(bus), bus->number); return; } sn_common_bus_fixup(bus, prom_bussoft_ptr); diff --git a/arch/ia64/sn/kernel/io_common.c b/arch/ia64/sn/kernel/io_common.c index c4eb84f9e78119c624889e02b43bbfbcca489730..8a924a5661ddffff994bb59a74762b9f5bd5555a 100644 --- a/arch/ia64/sn/kernel/io_common.c +++ b/arch/ia64/sn/kernel/io_common.c @@ -364,7 +364,7 @@ void sn_bus_store_sysdata(struct pci_dev *dev) element = kzalloc(sizeof(struct sysdata_el), GFP_KERNEL); if (!element) { - dev_dbg(&dev->dev, "%s: out of memory!\n", __FUNCTION__); + dev_dbg(&dev->dev, "%s: out of memory!\n", __func__); return; } element->sysdata = SN_PCIDEV_INFO(dev); diff --git a/arch/ia64/sn/kernel/io_init.c b/arch/ia64/sn/kernel/io_init.c index 906b93674b7604e236099c42f68cd8228a1876ed..c3aa851d1ca60278c9897859ba9a6740976ae6c9 100644 --- a/arch/ia64/sn/kernel/io_init.c +++ b/arch/ia64/sn/kernel/io_init.c @@ -209,11 +209,11 @@ sn_io_slot_fixup(struct pci_dev *dev) pcidev_info = kzalloc(sizeof(struct pcidev_info), GFP_KERNEL); if (!pcidev_info) - panic("%s: Unable to alloc memory for pcidev_info", __FUNCTION__); + panic("%s: Unable to alloc memory for pcidev_info", __func__); sn_irq_info = kzalloc(sizeof(struct sn_irq_info), GFP_KERNEL); if (!sn_irq_info) - panic("%s: Unable to alloc memory for sn_irq_info", __FUNCTION__); + panic("%s: Unable to alloc memory for sn_irq_info", __func__); /* Call to retrieve pci device information needed by kernel. */ status = sal_get_pcidev_info((u64) pci_domain_nr(dev), diff --git a/arch/ia64/sn/kernel/mca.c b/arch/ia64/sn/kernel/mca.c index 868c9aa64fe2db7af71a78016ab637b9b0a18a12..27793f7aa99c3c406b5547511a59347b05dd0210 100644 --- a/arch/ia64/sn/kernel/mca.c +++ b/arch/ia64/sn/kernel/mca.c @@ -100,7 +100,7 @@ sn_platform_plat_specific_err_print(const u8 * sect_header, u8 ** oemdata, if (!newbuf) { mutex_unlock(&sn_oemdata_mutex); printk(KERN_ERR "%s: unable to extend sn_oemdata\n", - __FUNCTION__); + __func__); return 1; } vfree(*sn_oemdata); diff --git a/arch/ia64/sn/pci/pci_dma.c b/arch/ia64/sn/pci/pci_dma.c index 511db2fd7bff9ad50dd92b7af192c486e73ad27b..18b94b792d5491bad4ccf3f650ce0feecfaed073 100644 --- a/arch/ia64/sn/pci/pci_dma.c +++ b/arch/ia64/sn/pci/pci_dma.c @@ -116,7 +116,7 @@ void *sn_dma_alloc_coherent(struct device *dev, size_t size, *dma_handle = provider->dma_map_consistent(pdev, phys_addr, size, SN_DMA_ADDR_PHYS); if (!*dma_handle) { - printk(KERN_ERR "%s: out of ATEs\n", __FUNCTION__); + printk(KERN_ERR "%s: out of ATEs\n", __func__); free_pages((unsigned long)cpuaddr, get_order(size)); return NULL; } @@ -179,7 +179,7 @@ dma_addr_t sn_dma_map_single(struct device *dev, void *cpu_addr, size_t size, phys_addr = __pa(cpu_addr); dma_addr = provider->dma_map(pdev, phys_addr, size, SN_DMA_ADDR_PHYS); if (!dma_addr) { - printk(KERN_ERR "%s: out of ATEs\n", __FUNCTION__); + printk(KERN_ERR "%s: out of ATEs\n", __func__); return 0; } return dma_addr; @@ -266,7 +266,7 @@ int sn_dma_map_sg(struct device *dev, struct scatterlist *sgl, int nhwentries, SN_DMA_ADDR_PHYS); if (!sg->dma_address) { - printk(KERN_ERR "%s: out of ATEs\n", __FUNCTION__); + printk(KERN_ERR "%s: out of ATEs\n", __func__); /* * Free any successfully allocated entries. diff --git a/arch/ia64/sn/pci/tioca_provider.c b/arch/ia64/sn/pci/tioca_provider.c index ef048a67477266925db3ce45a562bc318287b06d..529462c01570437aafdc8c9198ad394b8904e238 100644 --- a/arch/ia64/sn/pci/tioca_provider.c +++ b/arch/ia64/sn/pci/tioca_provider.c @@ -88,7 +88,7 @@ tioca_gart_init(struct tioca_kernel *tioca_kern) break; default: printk(KERN_ERR "%s: Invalid CA_APERATURE_SIZE " - "0x%lx\n", __FUNCTION__, (ulong) CA_APERATURE_SIZE); + "0x%lx\n", __func__, (ulong) CA_APERATURE_SIZE); return -1; } @@ -124,7 +124,7 @@ tioca_gart_init(struct tioca_kernel *tioca_kern) if (!tmp) { printk(KERN_ERR "%s: Could not allocate " "%lu bytes (order %d) for GART\n", - __FUNCTION__, + __func__, tioca_kern->ca_gart_size, get_order(tioca_kern->ca_gart_size)); return -ENOMEM; @@ -341,7 +341,7 @@ tioca_dma_d48(struct pci_dev *pdev, u64 paddr) if (node_upper > 64) { printk(KERN_ERR "%s: coretalk addr 0x%p node id out " - "of range\n", __FUNCTION__, (void *)ct_addr); + "of range\n", __func__, (void *)ct_addr); return 0; } @@ -349,7 +349,7 @@ tioca_dma_d48(struct pci_dev *pdev, u64 paddr) if (node_upper != (agp_dma_extn >> CA_AGP_DMA_NODE_ID_SHFT)) { printk(KERN_ERR "%s: coretalk upper node (%u) " "mismatch with ca_agp_dma_addr_extn (%lu)\n", - __FUNCTION__, + __func__, node_upper, (agp_dma_extn >> CA_AGP_DMA_NODE_ID_SHFT)); return 0; } @@ -597,7 +597,7 @@ tioca_bus_fixup(struct pcibus_bussoft *prom_bussoft, struct pci_controller *cont if (is_shub1() && sn_sal_rev() < 0x0406) { printk (KERN_ERR "%s: SGI prom rev 4.06 or greater required " - "for tioca support\n", __FUNCTION__); + "for tioca support\n", __func__); return NULL; } @@ -651,7 +651,7 @@ tioca_bus_fixup(struct pcibus_bussoft *prom_bussoft, struct pci_controller *cont printk(KERN_WARNING "%s: Unable to get irq %d. " "Error interrupts won't be routed for TIOCA bus %d\n", - __FUNCTION__, SGI_TIOCA_ERROR, + __func__, SGI_TIOCA_ERROR, (int)tioca_common->ca_common.bs_persist_busnum); sn_set_err_irq_affinity(SGI_TIOCA_ERROR); diff --git a/arch/ia64/sn/pci/tioce_provider.c b/arch/ia64/sn/pci/tioce_provider.c index 999f14f986e2cc99c8f6204d598092e2e942d4ea..9b3c11373022d2bd1319836b05eb92b97a06e4d7 100644 --- a/arch/ia64/sn/pci/tioce_provider.c +++ b/arch/ia64/sn/pci/tioce_provider.c @@ -494,7 +494,7 @@ tioce_dma_unmap(struct pci_dev *pdev, dma_addr_t bus_addr, int dir) if (&map->ce_dmamap_list == &ce_kern->ce_dmamap_list) { printk(KERN_WARNING "%s: %s - no map found for bus_addr 0x%lx\n", - __FUNCTION__, pci_name(pdev), bus_addr); + __func__, pci_name(pdev), bus_addr); } else if (--map->refcnt == 0) { for (i = 0; i < map->ate_count; i++) { map->ate_shadow[i] = 0; @@ -1030,7 +1030,7 @@ tioce_bus_fixup(struct pcibus_bussoft *prom_bussoft, struct pci_controller *cont "%s: Unable to get irq %d. " "Error interrupts won't be routed for " "TIOCE bus %04x:%02x\n", - __FUNCTION__, SGI_PCIASIC_ERROR, + __func__, SGI_PCIASIC_ERROR, tioce_common->ce_pcibus.bs_persist_segment, tioce_common->ce_pcibus.bs_persist_busnum); diff --git a/arch/m68k/kernel/entry.S b/arch/m68k/kernel/entry.S index 6dfa3b3c0e2a737d0b128e33cc1e6965e1aa8d00..18a9c5f4b00d4745dc8dfadb6c33c113ca705b37 100644 --- a/arch/m68k/kernel/entry.S +++ b/arch/m68k/kernel/entry.S @@ -742,7 +742,9 @@ sys_call_table: .long sys_epoll_pwait /* 315 */ .long sys_utimensat .long sys_signalfd - .long sys_ni_syscall + .long sys_timerfd_create .long sys_eventfd .long sys_fallocate /* 320 */ + .long sys_timerfd_settime + .long sys_timerfd_gettime diff --git a/arch/m68knommu/defconfig b/arch/m68knommu/defconfig index 648113075f9722cf0be3c657c7fc28554d533028..670b0a99cfa096424b131e2005a970cfc311b72c 100644 --- a/arch/m68knommu/defconfig +++ b/arch/m68knommu/defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.23 -# Thu Oct 18 13:17:38 2007 +# Linux kernel version: 2.6.25-rc3 +# Mon Feb 25 15:03:00 2008 # CONFIG_M68K=y # CONFIG_MMU is not set @@ -15,8 +15,10 @@ CONFIG_GENERIC_FIND_NEXT_BIT=y CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_HARDIRQS=y CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_GENERIC_TIME=y CONFIG_TIME_LOW_RES=y CONFIG_NO_IOPORT=y +CONFIG_ARCH_SUPPORTS_AOUT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # @@ -31,12 +33,14 @@ CONFIG_LOCALVERSION_AUTO=y # CONFIG_POSIX_MQUEUE is not set # CONFIG_BSD_PROCESS_ACCT is not set # CONFIG_TASKSTATS is not set -# CONFIG_USER_NS is not set # CONFIG_AUDIT is not set # CONFIG_IKCONFIG is not set CONFIG_LOG_BUF_SHIFT=14 +# CONFIG_CGROUPS is not set +# CONFIG_GROUP_SCHED is not set # CONFIG_SYSFS_DEPRECATED is not set # CONFIG_RELAY is not set +# CONFIG_NAMESPACES is not set # CONFIG_BLK_DEV_INITRD is not set # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set CONFIG_SYSCTL=y @@ -48,15 +52,22 @@ CONFIG_SYSCTL_SYSCALL=y CONFIG_PRINTK=y CONFIG_BUG=y CONFIG_ELF_CORE=y +CONFIG_COMPAT_BRK=y CONFIG_BASE_FULL=y # CONFIG_FUTEX is not set # CONFIG_EPOLL is not set # CONFIG_SIGNALFD is not set +# CONFIG_TIMERFD is not set # CONFIG_EVENTFD is not set # CONFIG_VM_EVENT_COUNTERS is not set CONFIG_SLAB=y # CONFIG_SLUB is not set # CONFIG_SLOB is not set +# CONFIG_PROFILING is not set +# CONFIG_MARKERS is not set +# CONFIG_HAVE_OPROFILE is not set +# CONFIG_HAVE_KPROBES is not set +CONFIG_SLABINFO=y CONFIG_TINY_SHMEM=y CONFIG_BASE_SMALL=0 CONFIG_MODULES=y @@ -83,6 +94,8 @@ CONFIG_IOSCHED_NOOP=y # CONFIG_DEFAULT_CFQ is not set CONFIG_DEFAULT_NOOP=y CONFIG_DEFAULT_IOSCHED="noop" +CONFIG_CLASSIC_RCU=y +# CONFIG_PREEMPT_RCU is not set # # Processor type and features @@ -121,6 +134,7 @@ CONFIG_M5272C3=y # CONFIG_MOD5272 is not set CONFIG_FREESCALE=y CONFIG_4KSTACKS=y +CONFIG_HZ=100 # # RAM configuration @@ -147,6 +161,7 @@ CONFIG_FLATMEM_MANUAL=y CONFIG_FLATMEM=y CONFIG_FLAT_NODE_MEM_MAP=y # CONFIG_SPARSEMEM_STATIC is not set +# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set CONFIG_SPLIT_PTLOCK_CPUS=4 # CONFIG_RESOURCES_64BIT is not set CONFIG_ZONE_DMA_FLAG=1 @@ -158,10 +173,6 @@ CONFIG_VIRT_TO_BUS=y # CONFIG_PCI is not set # CONFIG_ARCH_SUPPORTS_MSI is not set -# -# PCCARD (PCMCIA/CardBus) support -# - # # Executable file formats # @@ -205,6 +216,7 @@ CONFIG_IP_FIB_HASH=y # CONFIG_INET_XFRM_MODE_TRANSPORT is not set # CONFIG_INET_XFRM_MODE_TUNNEL is not set # CONFIG_INET_XFRM_MODE_BEET is not set +# CONFIG_INET_LRO is not set # CONFIG_INET_DIAG is not set # CONFIG_TCP_CONG_ADVANCED is not set CONFIG_TCP_CONG_CUBIC=y @@ -229,10 +241,6 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # CONFIG_LAPB 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 # @@ -240,6 +248,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # # CONFIG_NET_PKTGEN is not set # CONFIG_HAMRADIO is not set +# CONFIG_CAN is not set # CONFIG_IRDA is not set # CONFIG_BT is not set # CONFIG_AF_RXRPC is not set @@ -283,6 +292,7 @@ CONFIG_MTD_BLOCK=y # CONFIG_INFTL is not set # CONFIG_RFD_FTL is not set # CONFIG_SSFDC is not set +# CONFIG_MTD_OOPS is not set # # RAM/ROM/Flash chip drivers @@ -339,10 +349,11 @@ CONFIG_BLK_DEV=y CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_COUNT=16 CONFIG_BLK_DEV_RAM_SIZE=4096 -CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 +# CONFIG_BLK_DEV_XIP is not set # CONFIG_CDROM_PKTCDVD is not set # CONFIG_ATA_OVER_ETH is not set # CONFIG_MISC_DEVICES is not set +CONFIG_HAVE_IDE=y # CONFIG_IDE is not set # @@ -360,9 +371,15 @@ CONFIG_NETDEVICES=y # CONFIG_MACVLAN is not set # CONFIG_EQUALIZER is not set # CONFIG_TUN is not set +# CONFIG_VETH is not set # CONFIG_PHYLIB is not set CONFIG_NET_ETHERNET=y # CONFIG_MII is not set +# CONFIG_IBM_NEW_EMAC_ZMII is not set +# CONFIG_IBM_NEW_EMAC_RGMII is not set +# CONFIG_IBM_NEW_EMAC_TAH is not set +# CONFIG_IBM_NEW_EMAC_EMAC4 is not set +# CONFIG_B44 is not set CONFIG_FEC=y # CONFIG_FEC2 is not set # CONFIG_NETDEV_1000 is not set @@ -377,7 +394,7 @@ CONFIG_FEC=y CONFIG_PPP=y # CONFIG_PPP_MULTILINK is not set # CONFIG_PPP_FILTER is not set -# CONFIG_PPP_ASYNC 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 @@ -386,7 +403,6 @@ CONFIG_PPP=y # CONFIG_PPPOL2TP is not set # CONFIG_SLIP is not set CONFIG_SLHC=y -# CONFIG_SHAPER is not set # CONFIG_NETCONSOLE is not set # CONFIG_NETPOLL is not set # CONFIG_NET_POLL_CONTROLLER is not set @@ -418,12 +434,16 @@ CONFIG_SLHC=y # # Non-8250 serial port support # -CONFIG_SERIAL_COLDFIRE=y +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +# CONFIG_SERIAL_COLDFIRE is not set +CONFIG_SERIAL_MCF=y +CONFIG_SERIAL_MCF_BAUDRATE=19200 +CONFIG_SERIAL_MCF_CONSOLE=y # CONFIG_UNIX98_PTYS is not set CONFIG_LEGACY_PTYS=y CONFIG_LEGACY_PTY_COUNT=256 # CONFIG_IPMI_HANDLER is not set -# CONFIG_WATCHDOG is not set # CONFIG_HW_RANDOM is not set # CONFIG_GEN_RTC is not set # CONFIG_R3964 is not set @@ -439,6 +459,14 @@ CONFIG_LEGACY_PTY_COUNT=256 # CONFIG_W1 is not set # CONFIG_POWER_SUPPLY is not set # CONFIG_HWMON is not set +# CONFIG_THERMAL is not set +# CONFIG_WATCHDOG is not set + +# +# Sonics Silicon Backplane +# +CONFIG_SSB_POSSIBLE=y +# CONFIG_SSB is not set # # Multifunction device drivers @@ -450,20 +478,20 @@ CONFIG_LEGACY_PTY_COUNT=256 # # CONFIG_VIDEO_DEV is not set # CONFIG_DVB_CORE is not set -CONFIG_DAB=y +# CONFIG_DAB is not set # # Graphics support # +# CONFIG_VGASTATE is not set +# CONFIG_VIDEO_OUTPUT_CONTROL is not set +# CONFIG_FB is not set # CONFIG_BACKLIGHT_LCD_SUPPORT is not set # # Display device support # # CONFIG_DISPLAY_SUPPORT is not set -# CONFIG_VGASTATE is not set -CONFIG_VIDEO_OUTPUT_CONTROL=y -# CONFIG_FB is not set # # Sound @@ -471,22 +499,10 @@ CONFIG_VIDEO_OUTPUT_CONTROL=y # CONFIG_SOUND is not set # CONFIG_USB_SUPPORT is not set # CONFIG_MMC is not set +# CONFIG_MEMSTICK is not set # CONFIG_NEW_LEDS is not set # CONFIG_RTC_CLASS is not set -# -# DMA Engine support -# -# CONFIG_DMA_ENGINE is not set - -# -# DMA Clients -# - -# -# DMA Devices -# - # # Userspace I/O # @@ -505,11 +521,9 @@ CONFIG_EXT2_FS=y # CONFIG_XFS_FS is not set # CONFIG_GFS2_FS is not set # CONFIG_OCFS2_FS is not set -# CONFIG_MINIX_FS is not set -CONFIG_ROMFS_FS=y +# CONFIG_DNOTIFY is not set # CONFIG_INOTIFY is not set # CONFIG_QUOTA is not set -# CONFIG_DNOTIFY is not set # CONFIG_AUTOFS_FS is not set # CONFIG_AUTOFS4_FS is not set # CONFIG_FUSE_FS is not set @@ -535,7 +549,6 @@ CONFIG_PROC_SYSCTL=y CONFIG_SYSFS=y # CONFIG_TMPFS is not set # CONFIG_HUGETLB_PAGE is not set -CONFIG_RAMFS=y # CONFIG_CONFIGFS_FS is not set # @@ -551,42 +564,27 @@ CONFIG_RAMFS=y # CONFIG_JFFS2_FS is not set # CONFIG_CRAMFS is not set # CONFIG_VXFS_FS is not set +# CONFIG_MINIX_FS is not set # CONFIG_HPFS_FS is not set # CONFIG_QNX4FS_FS is not set +CONFIG_ROMFS_FS=y # CONFIG_SYSV_FS is not set # CONFIG_UFS_FS is not set - -# -# Network File Systems -# -# CONFIG_NFS_FS is not set -# CONFIG_NFSD is not set -# CONFIG_SMB_FS is not set -# CONFIG_CIFS is not set -# CONFIG_NCP_FS is not set -# CONFIG_CODA_FS is not set -# CONFIG_AFS_FS is not set +# CONFIG_NETWORK_FILESYSTEMS is not set # # Partition Types # # CONFIG_PARTITION_ADVANCED is not set CONFIG_MSDOS_PARTITION=y - -# -# Native Language Support -# # CONFIG_NLS is not set - -# -# Distributed Lock Manager -# # CONFIG_DLM is not set # # Kernel hacking # # CONFIG_PRINTK_TIME is not set +CONFIG_ENABLE_WARN_DEPRECATED=y # CONFIG_ENABLE_MUST_CHECK is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_UNUSED_SYMBOLS is not set @@ -594,6 +592,7 @@ CONFIG_MSDOS_PARTITION=y # CONFIG_HEADERS_CHECK is not set # CONFIG_DEBUG_KERNEL is not set # CONFIG_DEBUG_BUGVERBOSE is not set +# CONFIG_SAMPLES is not set # CONFIG_FULLDEBUG is not set # CONFIG_HIGHPROFILE is not set # CONFIG_BOOTPARAM is not set @@ -605,6 +604,7 @@ CONFIG_MSDOS_PARTITION=y # # CONFIG_KEYS is not set # CONFIG_SECURITY is not set +# CONFIG_SECURITY_FILE_CAPABILITIES is not set # CONFIG_CRYPTO is not set # diff --git a/arch/m68knommu/kernel/syscalltable.S b/arch/m68knommu/kernel/syscalltable.S index 1b02b88200680c8ebbec377d4c67b56622bc1595..fca2e49917a37179bb0d99646d011edf52dc96e2 100644 --- a/arch/m68knommu/kernel/syscalltable.S +++ b/arch/m68knommu/kernel/syscalltable.S @@ -336,9 +336,11 @@ ENTRY(sys_call_table) .long sys_epoll_pwait /* 315 */ .long sys_utimensat .long sys_signalfd - .long sys_ni_syscall + .long sys_timerfd_create .long sys_eventfd .long sys_fallocate /* 320 */ + .long sys_timerfd_settime + .long sys_timerfd_gettime .rept NR_syscalls-(.-sys_call_table)/4 .long sys_ni_syscall diff --git a/arch/m68knommu/platform/68328/timers.c b/arch/m68knommu/platform/68328/timers.c index 9159fd05c9ac7638e64af74f8f9502936142d721..6bafefa546e5cd810531ff654fd1d8192a3749b1 100644 --- a/arch/m68knommu/platform/68328/timers.c +++ b/arch/m68knommu/platform/68328/timers.c @@ -67,16 +67,6 @@ static irqreturn_t hw_tick(int irq, void *dummy) /***************************************************************************/ -static irqreturn_t hw_tick(int irq, void *dummy) -{ - /* Reset Timer1 */ - TSTAT &= 0; - - return arch_timer_interrupt(irq, dummy); -} - -/***************************************************************************/ - static struct irqaction m68328_timer_irq = { .name = "timer", .flags = IRQF_DISABLED | IRQF_TIMER, diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index ade230d445d9fd1ed952bc191720e60c679d9073..8724ed3298d31f9de2dad9521126a75bb8d51298 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -1824,7 +1824,7 @@ choice Allows the configuration of the timer frequency. config HZ_48 - bool "48 HZ" if SYS_SUPPORTS_48HZ + bool "48 HZ" if SYS_SUPPORTS_48HZ || SYS_SUPPORTS_ARBIT_HZ config HZ_100 bool "100 HZ" if SYS_SUPPORTS_100HZ || SYS_SUPPORTS_ARBIT_HZ diff --git a/arch/mips/Makefile b/arch/mips/Makefile index 3fb7f3065c92d4a523001aba19731f36e3e76435..72097dacabd3fe68dbae4296199aba7f21c2c6ec 100644 --- a/arch/mips/Makefile +++ b/arch/mips/Makefile @@ -12,6 +12,8 @@ # for "archclean" cleaning up for this architecture. # +KBUILD_DEFCONFIG := ip22_defconfig + cflags-y := # diff --git a/arch/mips/au1000/common/dbdma.c b/arch/mips/au1000/common/dbdma.c index 428ed275a0f60bb2131bdba50f0fe818690c2a9e..57f17b41098dfa8134a9b7b500ea1f66547abb8b 100644 --- a/arch/mips/au1000/common/dbdma.c +++ b/arch/mips/au1000/common/dbdma.c @@ -161,22 +161,22 @@ static dbdev_tab_t dbdev_tab[] = { { DSCR_CMD0_ALWAYS, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 }, /* Provide 16 user definable device types */ - { 0, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0 }, + { ~0, 0, 0, 0, 0, 0, 0 }, + { ~0, 0, 0, 0, 0, 0, 0 }, + { ~0, 0, 0, 0, 0, 0, 0 }, + { ~0, 0, 0, 0, 0, 0, 0 }, + { ~0, 0, 0, 0, 0, 0, 0 }, + { ~0, 0, 0, 0, 0, 0, 0 }, + { ~0, 0, 0, 0, 0, 0, 0 }, + { ~0, 0, 0, 0, 0, 0, 0 }, + { ~0, 0, 0, 0, 0, 0, 0 }, + { ~0, 0, 0, 0, 0, 0, 0 }, + { ~0, 0, 0, 0, 0, 0, 0 }, + { ~0, 0, 0, 0, 0, 0, 0 }, + { ~0, 0, 0, 0, 0, 0, 0 }, + { ~0, 0, 0, 0, 0, 0, 0 }, + { ~0, 0, 0, 0, 0, 0, 0 }, + { ~0, 0, 0, 0, 0, 0, 0 }, }; #define DBDEV_TAB_SIZE ARRAY_SIZE(dbdev_tab) @@ -209,7 +209,7 @@ au1xxx_ddma_add_device(dbdev_tab_t *dev) dbdev_tab_t *p=NULL; static u16 new_id=0x1000; - p = find_dbdev_id(0); + p = find_dbdev_id(~0); if ( NULL != p ) { memcpy(p, dev, sizeof(dbdev_tab_t)); diff --git a/arch/mips/defconfig b/arch/mips/defconfig deleted file mode 100644 index 4f5e56c9335e42014eb9f8fc081a55f18b8af178..0000000000000000000000000000000000000000 --- a/arch/mips/defconfig +++ /dev/null @@ -1,1158 +0,0 @@ -# -# Automatically generated make config: don't edit -# Linux kernel version: 2.6.23-rc2 -# Tue Aug 7 12:39:49 2007 -# -CONFIG_MIPS=y - -# -# Machine selection -# -CONFIG_ZONE_DMA=y -# CONFIG_MACH_ALCHEMY is not set -# CONFIG_BASLER_EXCITE is not set -# CONFIG_MIPS_COBALT is not set -# CONFIG_MACH_DECSTATION is not set -# CONFIG_MACH_JAZZ is not set -# CONFIG_LEMOTE_FULONG is not set -# CONFIG_MIPS_ATLAS is not set -# CONFIG_MIPS_MALTA is not set -# CONFIG_MIPS_SEAD is not set -# CONFIG_MIPS_SIM is not set -# CONFIG_MARKEINS is not set -# CONFIG_MACH_VR41XX is not set -# CONFIG_PNX8550_JBS is not set -# CONFIG_PNX8550_STB810 is not set -# CONFIG_PMC_MSP is not set -# CONFIG_PMC_YOSEMITE is not set -CONFIG_SGI_IP22=y -# CONFIG_SGI_IP27 is not set -# CONFIG_SGI_IP32 is not set -# CONFIG_SIBYTE_CRHINE is not set -# CONFIG_SIBYTE_CARMEL is not set -# CONFIG_SIBYTE_CRHONE is not set -# CONFIG_SIBYTE_RHONE is not set -# CONFIG_SIBYTE_SWARM is not set -# CONFIG_SIBYTE_LITTLESUR is not set -# CONFIG_SIBYTE_SENTOSA is not set -# CONFIG_SIBYTE_BIGSUR is not set -# CONFIG_SNI_RM is not set -# CONFIG_TOSHIBA_JMR3927 is not set -# CONFIG_TOSHIBA_RBTX4927 is not set -# CONFIG_TOSHIBA_RBTX4938 is not set -# CONFIG_WR_PPMC is not set -CONFIG_RWSEM_GENERIC_SPINLOCK=y -# CONFIG_ARCH_HAS_ILOG2_U32 is not set -# CONFIG_ARCH_HAS_ILOG2_U64 is not set -CONFIG_GENERIC_FIND_NEXT_BIT=y -CONFIG_GENERIC_HWEIGHT=y -CONFIG_GENERIC_CALIBRATE_DELAY=y -CONFIG_GENERIC_TIME=y -CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y -# CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ is not set -CONFIG_ARC=y -CONFIG_DMA_NONCOHERENT=y -CONFIG_DMA_NEED_PCI_MAP_STATE=y -CONFIG_EARLY_PRINTK=y -CONFIG_SYS_HAS_EARLY_PRINTK=y -# CONFIG_NO_IOPORT is not set -CONFIG_GENERIC_ISA_DMA_SUPPORT_BROKEN=y -CONFIG_CPU_BIG_ENDIAN=y -# CONFIG_CPU_LITTLE_ENDIAN is not set -CONFIG_SYS_SUPPORTS_BIG_ENDIAN=y -CONFIG_IRQ_CPU=y -CONFIG_SWAP_IO_SPACE=y -CONFIG_ARC32=y -CONFIG_BOOT_ELF32=y -CONFIG_MIPS_L1_CACHE_SHIFT=5 -CONFIG_ARC_CONSOLE=y -CONFIG_ARC_PROMLIB=y - -# -# CPU selection -# -# CONFIG_CPU_LOONGSON2 is not set -# CONFIG_CPU_MIPS32_R1 is not set -# CONFIG_CPU_MIPS32_R2 is not set -# CONFIG_CPU_MIPS64_R1 is not set -# CONFIG_CPU_MIPS64_R2 is not set -# CONFIG_CPU_R3000 is not set -# CONFIG_CPU_TX39XX is not set -# CONFIG_CPU_VR41XX is not set -# CONFIG_CPU_R4300 is not set -# CONFIG_CPU_R4X00 is not set -# CONFIG_CPU_TX49XX is not set -CONFIG_CPU_R5000=y -# CONFIG_CPU_R5432 is not set -# CONFIG_CPU_R6000 is not set -# CONFIG_CPU_NEVADA is not set -# CONFIG_CPU_R8000 is not set -# CONFIG_CPU_R10000 is not set -# CONFIG_CPU_RM7000 is not set -# CONFIG_CPU_RM9000 is not set -# CONFIG_CPU_SB1 is not set -CONFIG_SYS_HAS_CPU_R4X00=y -CONFIG_SYS_HAS_CPU_R5000=y -CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y -CONFIG_SYS_SUPPORTS_64BIT_KERNEL=y -CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y -CONFIG_CPU_SUPPORTS_64BIT_KERNEL=y - -# -# Kernel type -# -CONFIG_32BIT=y -# CONFIG_64BIT is not set -CONFIG_PAGE_SIZE_4KB=y -# CONFIG_PAGE_SIZE_8KB is not set -# CONFIG_PAGE_SIZE_16KB is not set -# CONFIG_PAGE_SIZE_64KB is not set -CONFIG_BOARD_SCACHE=y -CONFIG_IP22_CPU_SCACHE=y -CONFIG_MIPS_MT_DISABLED=y -# CONFIG_MIPS_MT_SMP is not set -# CONFIG_MIPS_MT_SMTC is not set -CONFIG_CPU_HAS_LLSC=y -CONFIG_CPU_HAS_SYNC=y -CONFIG_GENERIC_HARDIRQS=y -CONFIG_GENERIC_IRQ_PROBE=y -CONFIG_ARCH_FLATMEM_ENABLE=y -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=4 -# CONFIG_RESOURCES_64BIT is not set -CONFIG_ZONE_DMA_FLAG=1 -CONFIG_BOUNCE=y -CONFIG_VIRT_TO_BUS=y -# CONFIG_HZ_48 is not set -# CONFIG_HZ_100 is not set -# CONFIG_HZ_128 is not set -# CONFIG_HZ_250 is not set -# CONFIG_HZ_256 is not set -CONFIG_HZ_1000=y -# CONFIG_HZ_1024 is not set -CONFIG_SYS_SUPPORTS_ARBIT_HZ=y -CONFIG_HZ=1000 -# CONFIG_PREEMPT_NONE is not set -CONFIG_PREEMPT_VOLUNTARY=y -# CONFIG_PREEMPT is not set -# CONFIG_KEXEC is not set -CONFIG_SECCOMP=y -CONFIG_LOCKDEP_SUPPORT=y -CONFIG_STACKTRACE_SUPPORT=y -CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" - -# -# General setup -# -CONFIG_EXPERIMENTAL=y -CONFIG_BROKEN_ON_SMP=y -CONFIG_INIT_ENV_ARG_LIMIT=32 -CONFIG_LOCALVERSION="" -CONFIG_LOCALVERSION_AUTO=y -CONFIG_SWAP=y -CONFIG_SYSVIPC=y -CONFIG_SYSVIPC_SYSCTL=y -# CONFIG_POSIX_MQUEUE is not set -# CONFIG_BSD_PROCESS_ACCT is not set -# CONFIG_TASKSTATS is not set -# CONFIG_USER_NS is not set -# CONFIG_AUDIT is not set -CONFIG_IKCONFIG=y -CONFIG_IKCONFIG_PROC=y -CONFIG_LOG_BUF_SHIFT=14 -CONFIG_SYSFS_DEPRECATED=y -CONFIG_RELAY=y -# CONFIG_BLK_DEV_INITRD is not set -# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set -CONFIG_SYSCTL=y -CONFIG_EMBEDDED=y -CONFIG_SYSCTL_SYSCALL=y -CONFIG_KALLSYMS=y -# CONFIG_KALLSYMS_EXTRA_PASS is not set -# CONFIG_HOTPLUG is not set -CONFIG_PRINTK=y -CONFIG_BUG=y -CONFIG_ELF_CORE=y -CONFIG_BASE_FULL=y -CONFIG_FUTEX=y -CONFIG_ANON_INODES=y -CONFIG_EPOLL=y -CONFIG_SIGNALFD=y -CONFIG_TIMERFD=y -CONFIG_EVENTFD=y -CONFIG_SHMEM=y -CONFIG_VM_EVENT_COUNTERS=y -CONFIG_SLAB=y -# CONFIG_SLUB is not set -# CONFIG_SLOB is not set -CONFIG_RT_MUTEXES=y -# CONFIG_TINY_SHMEM is not set -CONFIG_BASE_SMALL=0 -CONFIG_MODULES=y -CONFIG_MODULE_UNLOAD=y -# CONFIG_MODULE_FORCE_UNLOAD is not set -CONFIG_MODVERSIONS=y -CONFIG_MODULE_SRCVERSION_ALL=y -CONFIG_KMOD=y -CONFIG_BLOCK=y -# CONFIG_LBD is not set -# CONFIG_BLK_DEV_IO_TRACE is not set -# CONFIG_LSF is not set -# CONFIG_BLK_DEV_BSG 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" - -# -# Bus options (PCI, PCMCIA, EISA, ISA, TC) -# -CONFIG_HW_HAS_EISA=y -# CONFIG_ARCH_SUPPORTS_MSI is not set -# CONFIG_EISA is not set -CONFIG_MMU=y - -# -# PCCARD (PCMCIA/CardBus) support -# - -# -# Executable file formats -# -CONFIG_BINFMT_ELF=y -CONFIG_BINFMT_MISC=m -CONFIG_TRAD_SIGNALS=y - -# -# Power management options -# -CONFIG_PM=y -# CONFIG_PM_LEGACY is not set -# CONFIG_PM_DEBUG is not set -# CONFIG_SUSPEND is not set - -# -# Networking -# -CONFIG_NET=y - -# -# Networking options -# -CONFIG_PACKET=y -CONFIG_PACKET_MMAP=y -CONFIG_UNIX=y -CONFIG_XFRM=y -CONFIG_XFRM_USER=m -# CONFIG_XFRM_SUB_POLICY is not set -CONFIG_XFRM_MIGRATE=y -CONFIG_NET_KEY=y -CONFIG_NET_KEY_MIGRATE=y -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=m -CONFIG_INET_ESP=m -CONFIG_INET_IPCOMP=m -CONFIG_INET_XFRM_TUNNEL=m -CONFIG_INET_TUNNEL=m -CONFIG_INET_XFRM_MODE_TRANSPORT=m -CONFIG_INET_XFRM_MODE_TUNNEL=m -CONFIG_INET_XFRM_MODE_BEET=m -CONFIG_INET_DIAG=y -CONFIG_INET_TCP_DIAG=y -# CONFIG_TCP_CONG_ADVANCED is not set -CONFIG_TCP_CONG_CUBIC=y -CONFIG_DEFAULT_TCP_CONG="cubic" -CONFIG_TCP_MD5SIG=y -CONFIG_IP_VS=m -# CONFIG_IP_VS_DEBUG is not set -CONFIG_IP_VS_TAB_BITS=12 - -# -# IPVS transport protocol load balancing support -# -CONFIG_IP_VS_PROTO_TCP=y -CONFIG_IP_VS_PROTO_UDP=y -CONFIG_IP_VS_PROTO_ESP=y -CONFIG_IP_VS_PROTO_AH=y - -# -# IPVS scheduler -# -CONFIG_IP_VS_RR=m -CONFIG_IP_VS_WRR=m -CONFIG_IP_VS_LC=m -CONFIG_IP_VS_WLC=m -CONFIG_IP_VS_LBLC=m -CONFIG_IP_VS_LBLCR=m -CONFIG_IP_VS_DH=m -CONFIG_IP_VS_SH=m -CONFIG_IP_VS_SED=m -CONFIG_IP_VS_NQ=m - -# -# IPVS application helper -# -CONFIG_IP_VS_FTP=m -CONFIG_IPV6=m -CONFIG_IPV6_PRIVACY=y -CONFIG_IPV6_ROUTER_PREF=y -CONFIG_IPV6_ROUTE_INFO=y -CONFIG_IPV6_OPTIMISTIC_DAD=y -CONFIG_INET6_AH=m -CONFIG_INET6_ESP=m -CONFIG_INET6_IPCOMP=m -CONFIG_IPV6_MIP6=m -CONFIG_INET6_XFRM_TUNNEL=m -CONFIG_INET6_TUNNEL=m -CONFIG_INET6_XFRM_MODE_TRANSPORT=m -CONFIG_INET6_XFRM_MODE_TUNNEL=m -CONFIG_INET6_XFRM_MODE_BEET=m -CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m -CONFIG_IPV6_SIT=m -CONFIG_IPV6_TUNNEL=m -CONFIG_IPV6_MULTIPLE_TABLES=y -CONFIG_IPV6_SUBTREES=y -CONFIG_NETWORK_SECMARK=y -CONFIG_NETFILTER=y -# CONFIG_NETFILTER_DEBUG is not set - -# -# Core Netfilter Configuration -# -CONFIG_NETFILTER_NETLINK=m -CONFIG_NETFILTER_NETLINK_QUEUE=m -CONFIG_NETFILTER_NETLINK_LOG=m -CONFIG_NF_CONNTRACK_ENABLED=m -CONFIG_NF_CONNTRACK=m -CONFIG_NF_CT_ACCT=y -CONFIG_NF_CONNTRACK_MARK=y -CONFIG_NF_CONNTRACK_SECMARK=y -CONFIG_NF_CONNTRACK_EVENTS=y -CONFIG_NF_CT_PROTO_GRE=m -CONFIG_NF_CT_PROTO_SCTP=m -CONFIG_NF_CT_PROTO_UDPLITE=m -CONFIG_NF_CONNTRACK_AMANDA=m -CONFIG_NF_CONNTRACK_FTP=m -CONFIG_NF_CONNTRACK_H323=m -CONFIG_NF_CONNTRACK_IRC=m -# CONFIG_NF_CONNTRACK_NETBIOS_NS is not set -CONFIG_NF_CONNTRACK_PPTP=m -CONFIG_NF_CONNTRACK_SANE=m -CONFIG_NF_CONNTRACK_SIP=m -CONFIG_NF_CONNTRACK_TFTP=m -CONFIG_NF_CT_NETLINK=m -CONFIG_NETFILTER_XTABLES=m -CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m -CONFIG_NETFILTER_XT_TARGET_CONNMARK=m -CONFIG_NETFILTER_XT_TARGET_DSCP=m -CONFIG_NETFILTER_XT_TARGET_MARK=m -CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m -CONFIG_NETFILTER_XT_TARGET_NFLOG=m -CONFIG_NETFILTER_XT_TARGET_NOTRACK=m -CONFIG_NETFILTER_XT_TARGET_TRACE=m -CONFIG_NETFILTER_XT_TARGET_SECMARK=m -CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=m -CONFIG_NETFILTER_XT_TARGET_TCPMSS=m -CONFIG_NETFILTER_XT_MATCH_COMMENT=m -CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m -CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m -CONFIG_NETFILTER_XT_MATCH_CONNMARK=m -CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m -CONFIG_NETFILTER_XT_MATCH_DCCP=m -CONFIG_NETFILTER_XT_MATCH_DSCP=m -CONFIG_NETFILTER_XT_MATCH_ESP=m -CONFIG_NETFILTER_XT_MATCH_HELPER=m -CONFIG_NETFILTER_XT_MATCH_LENGTH=m -CONFIG_NETFILTER_XT_MATCH_LIMIT=m -CONFIG_NETFILTER_XT_MATCH_MAC=m -CONFIG_NETFILTER_XT_MATCH_MARK=m -CONFIG_NETFILTER_XT_MATCH_POLICY=m -CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m -CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m -CONFIG_NETFILTER_XT_MATCH_QUOTA=m -CONFIG_NETFILTER_XT_MATCH_REALM=m -CONFIG_NETFILTER_XT_MATCH_SCTP=m -CONFIG_NETFILTER_XT_MATCH_STATE=m -CONFIG_NETFILTER_XT_MATCH_STATISTIC=m -CONFIG_NETFILTER_XT_MATCH_STRING=m -CONFIG_NETFILTER_XT_MATCH_TCPMSS=m -CONFIG_NETFILTER_XT_MATCH_U32=m -CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m - -# -# IP: Netfilter Configuration -# -CONFIG_NF_CONNTRACK_IPV4=m -CONFIG_NF_CONNTRACK_PROC_COMPAT=y -CONFIG_IP_NF_QUEUE=m -CONFIG_IP_NF_IPTABLES=m -CONFIG_IP_NF_MATCH_IPRANGE=m -CONFIG_IP_NF_MATCH_TOS=m -CONFIG_IP_NF_MATCH_RECENT=m -CONFIG_IP_NF_MATCH_ECN=m -CONFIG_IP_NF_MATCH_AH=m -CONFIG_IP_NF_MATCH_TTL=m -CONFIG_IP_NF_MATCH_OWNER=m -CONFIG_IP_NF_MATCH_ADDRTYPE=m -CONFIG_IP_NF_FILTER=m -CONFIG_IP_NF_TARGET_REJECT=m -CONFIG_IP_NF_TARGET_LOG=m -CONFIG_IP_NF_TARGET_ULOG=m -CONFIG_NF_NAT=m -CONFIG_NF_NAT_NEEDED=y -CONFIG_IP_NF_TARGET_MASQUERADE=m -CONFIG_IP_NF_TARGET_REDIRECT=m -CONFIG_IP_NF_TARGET_NETMAP=m -CONFIG_IP_NF_TARGET_SAME=m -CONFIG_NF_NAT_SNMP_BASIC=m -CONFIG_NF_NAT_PROTO_GRE=m -CONFIG_NF_NAT_FTP=m -CONFIG_NF_NAT_IRC=m -CONFIG_NF_NAT_TFTP=m -CONFIG_NF_NAT_AMANDA=m -CONFIG_NF_NAT_PPTP=m -CONFIG_NF_NAT_H323=m -CONFIG_NF_NAT_SIP=m -CONFIG_IP_NF_MANGLE=m -CONFIG_IP_NF_TARGET_TOS=m -CONFIG_IP_NF_TARGET_ECN=m -CONFIG_IP_NF_TARGET_TTL=m -CONFIG_IP_NF_TARGET_CLUSTERIP=m -CONFIG_IP_NF_RAW=m -CONFIG_IP_NF_ARPTABLES=m -CONFIG_IP_NF_ARPFILTER=m -CONFIG_IP_NF_ARP_MANGLE=m - -# -# IPv6: Netfilter Configuration (EXPERIMENTAL) -# -CONFIG_NF_CONNTRACK_IPV6=m -CONFIG_IP6_NF_QUEUE=m -CONFIG_IP6_NF_IPTABLES=m -CONFIG_IP6_NF_MATCH_RT=m -CONFIG_IP6_NF_MATCH_OPTS=m -CONFIG_IP6_NF_MATCH_FRAG=m -CONFIG_IP6_NF_MATCH_HL=m -CONFIG_IP6_NF_MATCH_OWNER=m -CONFIG_IP6_NF_MATCH_IPV6HEADER=m -CONFIG_IP6_NF_MATCH_AH=m -CONFIG_IP6_NF_MATCH_MH=m -CONFIG_IP6_NF_MATCH_EUI64=m -CONFIG_IP6_NF_FILTER=m -CONFIG_IP6_NF_TARGET_LOG=m -CONFIG_IP6_NF_TARGET_REJECT=m -CONFIG_IP6_NF_MANGLE=m -CONFIG_IP6_NF_TARGET_HL=m -CONFIG_IP6_NF_RAW=m -# CONFIG_IP_DCCP is not set -CONFIG_IP_SCTP=m -# CONFIG_SCTP_DBG_MSG is not set -# CONFIG_SCTP_DBG_OBJCNT is not set -# CONFIG_SCTP_HMAC_NONE is not set -# CONFIG_SCTP_HMAC_SHA1 is not set -CONFIG_SCTP_HMAC_MD5=y -# 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_ECONET is not set -# CONFIG_WAN_ROUTER is not set - -# -# QoS and/or fair queueing -# -CONFIG_NET_SCHED=y -CONFIG_NET_SCH_FIFO=y - -# -# Queueing/Scheduling -# -CONFIG_NET_SCH_CBQ=m -CONFIG_NET_SCH_HTB=m -CONFIG_NET_SCH_HFSC=m -CONFIG_NET_SCH_PRIO=m -CONFIG_NET_SCH_RR=m -CONFIG_NET_SCH_RED=m -CONFIG_NET_SCH_SFQ=m -CONFIG_NET_SCH_TEQL=m -CONFIG_NET_SCH_TBF=m -CONFIG_NET_SCH_GRED=m -CONFIG_NET_SCH_DSMARK=m -CONFIG_NET_SCH_NETEM=m -CONFIG_NET_SCH_INGRESS=m - -# -# Classification -# -CONFIG_NET_CLS=y -CONFIG_NET_CLS_BASIC=m -CONFIG_NET_CLS_TCINDEX=m -CONFIG_NET_CLS_ROUTE4=m -CONFIG_NET_CLS_ROUTE=y -CONFIG_NET_CLS_FW=m -CONFIG_NET_CLS_U32=m -# CONFIG_CLS_U32_PERF is not set -# CONFIG_CLS_U32_MARK is not set -CONFIG_NET_CLS_RSVP=m -CONFIG_NET_CLS_RSVP6=m -# CONFIG_NET_EMATCH is not set -CONFIG_NET_CLS_ACT=y -CONFIG_NET_ACT_POLICE=y -CONFIG_NET_ACT_GACT=m -CONFIG_GACT_PROB=y -CONFIG_NET_ACT_MIRRED=m -CONFIG_NET_ACT_IPT=m -CONFIG_NET_ACT_PEDIT=m -CONFIG_NET_ACT_SIMP=m -CONFIG_NET_CLS_POLICE=y -# CONFIG_NET_CLS_IND 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_AF_RXRPC is not set -CONFIG_FIB_RULES=y - -# -# Wireless -# -CONFIG_CFG80211=m -CONFIG_WIRELESS_EXT=y -CONFIG_MAC80211=m -# CONFIG_MAC80211_DEBUG is not set -CONFIG_IEEE80211=m -# CONFIG_IEEE80211_DEBUG is not set -CONFIG_IEEE80211_CRYPT_WEP=m -CONFIG_IEEE80211_CRYPT_CCMP=m -CONFIG_IEEE80211_CRYPT_TKIP=m -CONFIG_IEEE80211_SOFTMAC=m -# CONFIG_IEEE80211_SOFTMAC_DEBUG is not set -CONFIG_RFKILL=m -CONFIG_RFKILL_INPUT=m -# CONFIG_NET_9P is not set - -# -# Device Drivers -# - -# -# Generic Driver Options -# -CONFIG_STANDALONE=y -CONFIG_PREVENT_FIRMWARE_BUILD=y -# CONFIG_SYS_HYPERVISOR is not set -CONFIG_CONNECTOR=m -# CONFIG_MTD is not set -# CONFIG_PARPORT is not set -CONFIG_BLK_DEV=y -# CONFIG_BLK_DEV_COW_COMMON is not set -# CONFIG_BLK_DEV_LOOP is not set -# CONFIG_BLK_DEV_NBD is not set -# CONFIG_BLK_DEV_RAM is not set -CONFIG_CDROM_PKTCDVD=m -CONFIG_CDROM_PKTCDVD_BUFFERS=8 -# CONFIG_CDROM_PKTCDVD_WCACHE is not set -CONFIG_ATA_OVER_ETH=m -# CONFIG_MISC_DEVICES is not set -# CONFIG_IDE is not set - -# -# SCSI device support -# -CONFIG_RAID_ATTRS=m -CONFIG_SCSI=y -CONFIG_SCSI_DMA=y -CONFIG_SCSI_TGT=m -# CONFIG_SCSI_NETLINK is not set -CONFIG_SCSI_PROC_FS=y - -# -# SCSI support type (disk, tape, CD-ROM) -# -CONFIG_BLK_DEV_SD=y -CONFIG_CHR_DEV_ST=y -# CONFIG_CHR_DEV_OSST is not set -CONFIG_BLK_DEV_SR=y -# CONFIG_BLK_DEV_SR_VENDOR is not set -# CONFIG_CHR_DEV_SG is not set -CONFIG_CHR_DEV_SCH=m - -# -# Some SCSI devices (e.g. CD jukebox) support multiple LUNs -# -# CONFIG_SCSI_MULTI_LUN is not set -CONFIG_SCSI_CONSTANTS=y -# CONFIG_SCSI_LOGGING is not set -CONFIG_SCSI_SCAN_ASYNC=y -CONFIG_SCSI_WAIT_SCAN=m - -# -# SCSI Transports -# -CONFIG_SCSI_SPI_ATTRS=m -# CONFIG_SCSI_FC_ATTRS is not set -CONFIG_SCSI_ISCSI_ATTRS=m -# CONFIG_SCSI_SAS_LIBSAS is not set -CONFIG_SCSI_LOWLEVEL=y -CONFIG_ISCSI_TCP=m -CONFIG_SGIWD93_SCSI=y -# CONFIG_SCSI_DEBUG is not set -# CONFIG_ATA is not set -# CONFIG_MD is not set -CONFIG_NETDEVICES=y -# CONFIG_NETDEVICES_MULTIQUEUE is not set -# CONFIG_IFB is not set -CONFIG_DUMMY=m -CONFIG_BONDING=m -CONFIG_MACVLAN=m -CONFIG_EQUALIZER=m -CONFIG_TUN=m -CONFIG_PHYLIB=m - -# -# MII PHY device drivers -# -CONFIG_MARVELL_PHY=m -CONFIG_DAVICOM_PHY=m -CONFIG_QSEMI_PHY=m -CONFIG_LXT_PHY=m -CONFIG_CICADA_PHY=m -# CONFIG_VITESSE_PHY is not set -# CONFIG_SMSC_PHY is not set -# CONFIG_BROADCOM_PHY is not set -# CONFIG_ICPLUS_PHY is not set -# CONFIG_FIXED_PHY is not set -CONFIG_NET_ETHERNET=y -# CONFIG_MII is not set -# CONFIG_AX88796 is not set -# CONFIG_DM9000 is not set -CONFIG_SGISEEQ=y -# CONFIG_NETDEV_1000 is not set -# CONFIG_NETDEV_10000 is not set - -# -# Wireless LAN -# -CONFIG_WLAN_PRE80211=y -CONFIG_STRIP=m -CONFIG_WLAN_80211=y -# CONFIG_LIBERTAS is not set -CONFIG_HOSTAP=m -# CONFIG_HOSTAP_FIRMWARE is not set -# CONFIG_WAN is not set -# CONFIG_PPP 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 -# CONFIG_ISDN is not set -# CONFIG_PHONE is not set - -# -# Input device support -# -CONFIG_INPUT=y -# CONFIG_INPUT_FF_MEMLESS is not set -# CONFIG_INPUT_POLLDEV is not set - -# -# Userland interfaces -# -CONFIG_INPUT_MOUSEDEV=m -CONFIG_INPUT_MOUSEDEV_PSAUX=y -CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 -CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 -# CONFIG_INPUT_JOYDEV is not set -# CONFIG_INPUT_TSDEV is not set -# CONFIG_INPUT_EVDEV is not set -# CONFIG_INPUT_EVBUG is not set - -# -# Input Device Drivers -# -CONFIG_INPUT_KEYBOARD=y -CONFIG_KEYBOARD_ATKBD=y -# CONFIG_KEYBOARD_SUNKBD is not set -# CONFIG_KEYBOARD_LKKBD is not set -# CONFIG_KEYBOARD_XTKBD is not set -# CONFIG_KEYBOARD_NEWTON is not set -# CONFIG_KEYBOARD_STOWAWAY is not set -CONFIG_INPUT_MOUSE=y -CONFIG_MOUSE_PS2=m -# CONFIG_MOUSE_PS2_ALPS is not set -CONFIG_MOUSE_PS2_LOGIPS2PP=y -# CONFIG_MOUSE_PS2_SYNAPTICS is not set -# CONFIG_MOUSE_PS2_LIFEBOOK is not set -CONFIG_MOUSE_PS2_TRACKPOINT=y -# CONFIG_MOUSE_PS2_TOUCHKIT is not set -CONFIG_MOUSE_SERIAL=m -# CONFIG_MOUSE_VSXXXAA is not set -# CONFIG_INPUT_JOYSTICK is not set -# CONFIG_INPUT_TABLET is not set -# CONFIG_INPUT_TOUCHSCREEN is not set -# CONFIG_INPUT_MISC is not set - -# -# Hardware I/O ports -# -CONFIG_SERIO=y -CONFIG_SERIO_I8042=y -CONFIG_SERIO_SERPORT=y -CONFIG_SERIO_LIBPS2=y -CONFIG_SERIO_RAW=m -# CONFIG_GAMEPORT is not set - -# -# Character devices -# -CONFIG_VT=y -CONFIG_VT_CONSOLE=y -CONFIG_HW_CONSOLE=y -CONFIG_VT_HW_CONSOLE_BINDING=y -# CONFIG_SERIAL_NONSTANDARD is not set - -# -# Serial drivers -# -# CONFIG_SERIAL_8250 is not set - -# -# Non-8250 serial port support -# -CONFIG_SERIAL_IP22_ZILOG=m -CONFIG_SERIAL_CORE=m -CONFIG_UNIX98_PTYS=y -CONFIG_LEGACY_PTYS=y -CONFIG_LEGACY_PTY_COUNT=256 -# CONFIG_IPMI_HANDLER is not set -CONFIG_WATCHDOG=y -# CONFIG_WATCHDOG_NOWAYOUT is not set - -# -# Watchdog Device Drivers -# -# CONFIG_SOFT_WATCHDOG is not set -CONFIG_INDYDOG=m -# CONFIG_HW_RANDOM is not set -# CONFIG_RTC is not set -CONFIG_SGI_DS1286=m -# CONFIG_R3964 is not set -CONFIG_RAW_DRIVER=m -CONFIG_MAX_RAW_DEVS=256 -# CONFIG_TCG_TPM is not set -# CONFIG_I2C is not set - -# -# SPI support -# -# CONFIG_SPI is not set -# CONFIG_SPI_MASTER is not set -# CONFIG_W1 is not set -# CONFIG_POWER_SUPPLY is not set -# CONFIG_HWMON is not set - -# -# Multifunction device drivers -# -# CONFIG_MFD_SM501 is not set - -# -# Multimedia devices -# -# CONFIG_VIDEO_DEV is not set -# CONFIG_DVB_CORE is not set -# CONFIG_DAB is not set - -# -# Graphics support -# -# CONFIG_BACKLIGHT_LCD_SUPPORT is not set - -# -# Display device support -# -# CONFIG_DISPLAY_SUPPORT is not set -# CONFIG_VGASTATE is not set -# CONFIG_VIDEO_OUTPUT_CONTROL is not set -# CONFIG_FB is not set - -# -# Console display driver support -# -# CONFIG_VGA_CONSOLE is not set -CONFIG_SGI_NEWPORT_CONSOLE=y -CONFIG_DUMMY_CONSOLE=y -CONFIG_FONT_8x16=y -CONFIG_LOGO=y -# CONFIG_LOGO_LINUX_MONO is not set -# CONFIG_LOGO_LINUX_VGA16 is not set -# CONFIG_LOGO_LINUX_CLUT224 is not set -CONFIG_LOGO_SGI_CLUT224=y - -# -# Sound -# -# CONFIG_SOUND is not set -CONFIG_HID_SUPPORT=y -CONFIG_HID=y -# CONFIG_HID_DEBUG is not set -CONFIG_USB_SUPPORT=y -# CONFIG_USB_ARCH_HAS_HCD is not set -# CONFIG_USB_ARCH_HAS_OHCI is not set -# CONFIG_USB_ARCH_HAS_EHCI is not set - -# -# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' -# - -# -# USB Gadget Support -# -# CONFIG_USB_GADGET is not set -# CONFIG_MMC is not set -# CONFIG_NEW_LEDS is not set -# CONFIG_RTC_CLASS is not set - -# -# DMA Engine support -# -# CONFIG_DMA_ENGINE is not set - -# -# DMA Clients -# - -# -# DMA Devices -# - -# -# Userspace I/O -# -# CONFIG_UIO is not set - -# -# File systems -# -CONFIG_EXT2_FS=m -# CONFIG_EXT2_FS_XATTR is not set -# CONFIG_EXT2_FS_XIP is not set -CONFIG_EXT3_FS=y -CONFIG_EXT3_FS_XATTR=y -CONFIG_EXT3_FS_POSIX_ACL=y -CONFIG_EXT3_FS_SECURITY=y -# CONFIG_EXT4DEV_FS is not set -CONFIG_JBD=y -# CONFIG_JBD_DEBUG 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_XFS_FS=m -CONFIG_XFS_QUOTA=y -CONFIG_XFS_SECURITY=y -# CONFIG_XFS_POSIX_ACL is not set -# CONFIG_XFS_RT is not set -# CONFIG_GFS2_FS is not set -# CONFIG_OCFS2_FS is not set -CONFIG_MINIX_FS=m -# CONFIG_ROMFS_FS is not set -CONFIG_INOTIFY=y -CONFIG_INOTIFY_USER=y -CONFIG_QUOTA=y -# CONFIG_QFMT_V1 is not set -CONFIG_QFMT_V2=m -CONFIG_QUOTACTL=y -CONFIG_DNOTIFY=y -CONFIG_AUTOFS_FS=m -CONFIG_AUTOFS4_FS=m -CONFIG_FUSE_FS=m -CONFIG_GENERIC_ACL=y - -# -# CD-ROM/DVD Filesystems -# -CONFIG_ISO9660_FS=m -CONFIG_JOLIET=y -CONFIG_ZISOFS=y -CONFIG_UDF_FS=m -CONFIG_UDF_NLS=y - -# -# DOS/FAT/NT Filesystems -# -CONFIG_FAT_FS=m -CONFIG_MSDOS_FS=m -CONFIG_VFAT_FS=m -CONFIG_FAT_DEFAULT_CODEPAGE=437 -CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" -# CONFIG_NTFS_FS is not set - -# -# Pseudo filesystems -# -CONFIG_PROC_FS=y -CONFIG_PROC_KCORE=y -CONFIG_PROC_SYSCTL=y -CONFIG_SYSFS=y -CONFIG_TMPFS=y -CONFIG_TMPFS_POSIX_ACL=y -# CONFIG_HUGETLB_PAGE is not set -CONFIG_RAMFS=y -CONFIG_CONFIGFS_FS=m - -# -# Miscellaneous filesystems -# -# CONFIG_ADFS_FS is not set -# CONFIG_AFFS_FS is not set -# CONFIG_ECRYPT_FS is not set -# CONFIG_HFS_FS is not set -# CONFIG_HFSPLUS_FS is not set -# CONFIG_BEFS_FS is not set -# CONFIG_BFS_FS is not set -CONFIG_EFS_FS=m -# CONFIG_CRAMFS is not set -# CONFIG_VXFS_FS is not set -# CONFIG_HPFS_FS is not set -# CONFIG_QNX4FS_FS is not set -# CONFIG_SYSV_FS is not set -CONFIG_UFS_FS=m -# CONFIG_UFS_FS_WRITE is not set -# CONFIG_UFS_DEBUG is not set - -# -# Network File Systems -# -CONFIG_NFS_FS=m -CONFIG_NFS_V3=y -CONFIG_NFS_V3_ACL=y -# CONFIG_NFS_V4 is not set -# CONFIG_NFS_DIRECTIO is not set -CONFIG_NFSD=m -CONFIG_NFSD_V2_ACL=y -CONFIG_NFSD_V3=y -CONFIG_NFSD_V3_ACL=y -# CONFIG_NFSD_V4 is not set -CONFIG_NFSD_TCP=y -CONFIG_LOCKD=m -CONFIG_LOCKD_V4=y -CONFIG_EXPORTFS=m -CONFIG_NFS_ACL_SUPPORT=m -CONFIG_NFS_COMMON=y -CONFIG_SUNRPC=m -CONFIG_SUNRPC_GSS=m -# CONFIG_SUNRPC_BIND34 is not set -CONFIG_RPCSEC_GSS_KRB5=m -# CONFIG_RPCSEC_GSS_SPKM3 is not set -CONFIG_SMB_FS=m -CONFIG_SMB_NLS_DEFAULT=y -CONFIG_SMB_NLS_REMOTE="cp437" -CONFIG_CIFS=m -# CONFIG_CIFS_STATS is not set -# CONFIG_CIFS_WEAK_PW_HASH is not set -# CONFIG_CIFS_XATTR is not set -# CONFIG_CIFS_DEBUG2 is not set -# CONFIG_CIFS_EXPERIMENTAL is not set -# CONFIG_NCP_FS is not set -CONFIG_CODA_FS=m -# CONFIG_CODA_FS_OLD_API is not set -# CONFIG_AFS_FS is not set - -# -# Partition Types -# -CONFIG_PARTITION_ADVANCED=y -# CONFIG_ACORN_PARTITION is not set -# CONFIG_OSF_PARTITION is not set -# CONFIG_AMIGA_PARTITION is not set -# CONFIG_ATARI_PARTITION is not set -# CONFIG_MAC_PARTITION is not set -CONFIG_MSDOS_PARTITION=y -# CONFIG_BSD_DISKLABEL is not set -# CONFIG_MINIX_SUBPARTITION is not set -# CONFIG_SOLARIS_X86_PARTITION is not set -# CONFIG_UNIXWARE_DISKLABEL is not set -# CONFIG_LDM_PARTITION is not set -CONFIG_SGI_PARTITION=y -# CONFIG_ULTRIX_PARTITION is not set -# CONFIG_SUN_PARTITION is not set -# CONFIG_KARMA_PARTITION is not set -# CONFIG_EFI_PARTITION is not set -# CONFIG_SYSV68_PARTITION is not set - -# -# Native Language Support -# -CONFIG_NLS=m -CONFIG_NLS_DEFAULT="iso8859-1" -CONFIG_NLS_CODEPAGE_437=m -CONFIG_NLS_CODEPAGE_737=m -CONFIG_NLS_CODEPAGE_775=m -CONFIG_NLS_CODEPAGE_850=m -CONFIG_NLS_CODEPAGE_852=m -CONFIG_NLS_CODEPAGE_855=m -CONFIG_NLS_CODEPAGE_857=m -CONFIG_NLS_CODEPAGE_860=m -CONFIG_NLS_CODEPAGE_861=m -CONFIG_NLS_CODEPAGE_862=m -CONFIG_NLS_CODEPAGE_863=m -CONFIG_NLS_CODEPAGE_864=m -CONFIG_NLS_CODEPAGE_865=m -CONFIG_NLS_CODEPAGE_866=m -CONFIG_NLS_CODEPAGE_869=m -CONFIG_NLS_CODEPAGE_936=m -CONFIG_NLS_CODEPAGE_950=m -CONFIG_NLS_CODEPAGE_932=m -CONFIG_NLS_CODEPAGE_949=m -CONFIG_NLS_CODEPAGE_874=m -CONFIG_NLS_ISO8859_8=m -CONFIG_NLS_CODEPAGE_1250=m -CONFIG_NLS_CODEPAGE_1251=m -CONFIG_NLS_ASCII=m -CONFIG_NLS_ISO8859_1=m -CONFIG_NLS_ISO8859_2=m -CONFIG_NLS_ISO8859_3=m -CONFIG_NLS_ISO8859_4=m -CONFIG_NLS_ISO8859_5=m -CONFIG_NLS_ISO8859_6=m -CONFIG_NLS_ISO8859_7=m -CONFIG_NLS_ISO8859_9=m -CONFIG_NLS_ISO8859_13=m -CONFIG_NLS_ISO8859_14=m -CONFIG_NLS_ISO8859_15=m -CONFIG_NLS_KOI8_R=m -CONFIG_NLS_KOI8_U=m -CONFIG_NLS_UTF8=m - -# -# Distributed Lock Manager -# -CONFIG_DLM=m -# CONFIG_DLM_DEBUG is not set - -# -# Profiling support -# -# CONFIG_PROFILING is not set - -# -# Kernel hacking -# -CONFIG_TRACE_IRQFLAGS_SUPPORT=y -# CONFIG_PRINTK_TIME is not set -CONFIG_ENABLE_MUST_CHECK=y -# CONFIG_MAGIC_SYSRQ is not set -# CONFIG_UNUSED_SYMBOLS is not set -# CONFIG_DEBUG_FS is not set -# CONFIG_HEADERS_CHECK is not set -# CONFIG_DEBUG_KERNEL is not set -CONFIG_CROSSCOMPILE=y -CONFIG_CMDLINE="" - -# -# Security options -# -CONFIG_KEYS=y -CONFIG_KEYS_DEBUG_PROC_KEYS=y -# CONFIG_SECURITY is not set -CONFIG_CRYPTO=y -CONFIG_CRYPTO_ALGAPI=y -CONFIG_CRYPTO_ABLKCIPHER=m -CONFIG_CRYPTO_BLKCIPHER=m -CONFIG_CRYPTO_HASH=y -CONFIG_CRYPTO_MANAGER=y -CONFIG_CRYPTO_HMAC=y -CONFIG_CRYPTO_XCBC=m -CONFIG_CRYPTO_NULL=m -CONFIG_CRYPTO_MD4=m -CONFIG_CRYPTO_MD5=y -CONFIG_CRYPTO_SHA1=m -CONFIG_CRYPTO_SHA256=m -CONFIG_CRYPTO_SHA512=m -CONFIG_CRYPTO_WP512=m -CONFIG_CRYPTO_TGR192=m -CONFIG_CRYPTO_GF128MUL=m -CONFIG_CRYPTO_ECB=m -CONFIG_CRYPTO_CBC=m -CONFIG_CRYPTO_PCBC=m -CONFIG_CRYPTO_LRW=m -CONFIG_CRYPTO_CRYPTD=m -CONFIG_CRYPTO_DES=m -CONFIG_CRYPTO_FCRYPT=m -CONFIG_CRYPTO_BLOWFISH=m -CONFIG_CRYPTO_TWOFISH=m -CONFIG_CRYPTO_TWOFISH_COMMON=m -CONFIG_CRYPTO_SERPENT=m -CONFIG_CRYPTO_AES=m -CONFIG_CRYPTO_CAST5=m -CONFIG_CRYPTO_CAST6=m -CONFIG_CRYPTO_TEA=m -CONFIG_CRYPTO_ARC4=m -CONFIG_CRYPTO_KHAZAD=m -CONFIG_CRYPTO_ANUBIS=m -CONFIG_CRYPTO_DEFLATE=m -CONFIG_CRYPTO_MICHAEL_MIC=m -CONFIG_CRYPTO_CRC32C=m -CONFIG_CRYPTO_CAMELLIA=m -# CONFIG_CRYPTO_TEST is not set -# CONFIG_CRYPTO_HW is not set - -# -# Library routines -# -CONFIG_BITREVERSE=m -# CONFIG_CRC_CCITT is not set -CONFIG_CRC16=m -# CONFIG_CRC_ITU_T is not set -CONFIG_CRC32=m -# CONFIG_CRC7 is not set -CONFIG_LIBCRC32C=m -CONFIG_ZLIB_INFLATE=m -CONFIG_ZLIB_DEFLATE=m -CONFIG_TEXTSEARCH=y -CONFIG_TEXTSEARCH_KMP=m -CONFIG_TEXTSEARCH_BM=m -CONFIG_TEXTSEARCH_FSM=m -CONFIG_PLIST=y -CONFIG_HAS_IOMEM=y -CONFIG_HAS_IOPORT=y -CONFIG_HAS_DMA=y diff --git a/arch/mips/kernel/Makefile b/arch/mips/kernel/Makefile index ffa08362de170d3c09790b4511c6cdd5f973f6bc..9e78e1a4ca179f8004b9cf47aa2fa5815c086f3a 100644 --- a/arch/mips/kernel/Makefile +++ b/arch/mips/kernel/Makefile @@ -76,7 +76,6 @@ obj-$(CONFIG_PROC_FS) += proc.o obj-$(CONFIG_64BIT) += cpu-bugs64.o obj-$(CONFIG_I8253) += i8253.o -obj-$(CONFIG_PCSPEAKER) += pcspeaker.o obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o obj-$(CONFIG_EARLY_PRINTK) += early_printk.o diff --git a/arch/mips/kernel/cpu-bugs64.c b/arch/mips/kernel/cpu-bugs64.c index 417bb3e336ac811d33a0f9b43092e44e146a5b8f..a1b48af0992ffb297c588c1a2cc5ae22de826871 100644 --- a/arch/mips/kernel/cpu-bugs64.c +++ b/arch/mips/kernel/cpu-bugs64.c @@ -167,7 +167,7 @@ static inline void check_mult_sh(void) panic(bug64hit, !R4000_WAR ? r4kwar : nowar); } -static volatile int daddi_ov __initdata = 0; +static volatile int daddi_ov __cpuinitdata = 0; asmlinkage void __init do_daddi_ov(struct pt_regs *regs) { @@ -239,7 +239,7 @@ static inline void check_daddi(void) panic(bug64hit, !DADDI_WAR ? daddiwar : nowar); } -int daddiu_bug __initdata = -1; +int daddiu_bug __cpuinitdata = -1; static inline void check_daddiu(void) { diff --git a/arch/mips/kernel/cpu-probe.c b/arch/mips/kernel/cpu-probe.c index 5861a432a52f93bb2feeb76724311922f6b57c76..89c3304cb93c391903f0178de2bd796a48e24c5d 100644 --- a/arch/mips/kernel/cpu-probe.c +++ b/arch/mips/kernel/cpu-probe.c @@ -550,7 +550,7 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c) } } -static char unknown_isa[] __initdata = KERN_ERR \ +static char unknown_isa[] __cpuinitdata = KERN_ERR \ "Unsupported ISA type, c0.config0: %d."; static inline unsigned int decode_config0(struct cpuinfo_mips *c) @@ -656,7 +656,7 @@ static inline unsigned int decode_config3(struct cpuinfo_mips *c) return config3 & MIPS_CONF_M; } -static void __init decode_configs(struct cpuinfo_mips *c) +static void __cpuinit decode_configs(struct cpuinfo_mips *c) { /* MIPS32 or MIPS64 compliant CPU. */ c->options = MIPS_CPU_4KEX | MIPS_CPU_4K_CACHE | MIPS_CPU_COUNTER | @@ -814,7 +814,7 @@ const char *__cpu_name[NR_CPUS]; /* * Name a CPU */ -static __init const char *cpu_to_name(struct cpuinfo_mips *c) +static __cpuinit const char *cpu_to_name(struct cpuinfo_mips *c) { const char *name = NULL; @@ -896,7 +896,7 @@ static __init const char *cpu_to_name(struct cpuinfo_mips *c) return name; } -__init void cpu_probe(void) +__cpuinit void cpu_probe(void) { struct cpuinfo_mips *c = ¤t_cpu_data; unsigned int cpu = smp_processor_id(); @@ -959,7 +959,7 @@ __init void cpu_probe(void) c->srsets = 1; } -__init void cpu_report(void) +__cpuinit void cpu_report(void) { struct cpuinfo_mips *c = ¤t_cpu_data; diff --git a/arch/mips/kernel/csrc-r4k.c b/arch/mips/kernel/csrc-r4k.c index 0e2b5cd81f67dbdd4e48bd83846e074d6c17ea0c..86e026f067bc566c2bbd9620763e2ab6428e836a 100644 --- a/arch/mips/kernel/csrc-r4k.c +++ b/arch/mips/kernel/csrc-r4k.c @@ -22,12 +22,17 @@ static struct clocksource clocksource_mips = { .flags = CLOCK_SOURCE_IS_CONTINUOUS, }; -void __init init_mips_clocksource(void) +int __init init_mips_clocksource(void) { + if (!cpu_has_counter || !mips_hpt_frequency) + return -ENXIO; + /* Calclate a somewhat reasonable rating value */ clocksource_mips.rating = 200 + mips_hpt_frequency / 10000000; clocksource_set_clock(&clocksource_mips, mips_hpt_frequency); clocksource_register(&clocksource_mips); + + return 0; } diff --git a/arch/mips/kernel/head.S b/arch/mips/kernel/head.S index a24fb790090113eef1fc650b677ce70c80d79c53..361364501d34926deea6d59456cce24f0674e538 100644 --- a/arch/mips/kernel/head.S +++ b/arch/mips/kernel/head.S @@ -195,7 +195,7 @@ NESTED(kernel_entry, 16, sp) # kernel entry point j start_kernel END(kernel_entry) - __INIT + __CPUINIT #ifdef CONFIG_SMP /* diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c index fcae6675297273839812a4977c329ee6cb9e5899..984c0d0a7b4d72d2f0ff49c6dcf450220ba061c4 100644 --- a/arch/mips/kernel/traps.c +++ b/arch/mips/kernel/traps.c @@ -534,8 +534,7 @@ static int simulate_llsc(struct pt_regs *regs, unsigned int opcode) /* * Simulate trapping 'rdhwr' instructions to provide user accessible - * registers not implemented in hardware. The only current use of this - * is the thread area pointer. + * registers not implemented in hardware. */ static int simulate_rdhwr(struct pt_regs *regs, unsigned int opcode) { @@ -545,11 +544,31 @@ static int simulate_rdhwr(struct pt_regs *regs, unsigned int opcode) int rd = (opcode & RD) >> 11; int rt = (opcode & RT) >> 16; switch (rd) { - case 29: - regs->regs[rt] = ti->tp_value; - return 0; + case 0: /* CPU number */ + regs->regs[rt] = smp_processor_id(); + return 0; + case 1: /* SYNCI length */ + regs->regs[rt] = min(current_cpu_data.dcache.linesz, + current_cpu_data.icache.linesz); + return 0; + case 2: /* Read count register */ + regs->regs[rt] = read_c0_count(); + return 0; + case 3: /* Count register resolution */ + switch (current_cpu_data.cputype) { + case CPU_20KC: + case CPU_25KF: + regs->regs[rt] = 1; + break; default: - return -1; + regs->regs[rt] = 2; + } + return 0; + case 29: + regs->regs[rt] = ti->tp_value; + return 0; + default: + return -1; } } @@ -1287,7 +1306,7 @@ int cp0_compare_irq; int cp0_perfcount_irq; EXPORT_SYMBOL_GPL(cp0_perfcount_irq); -void __init per_cpu_trap_init(void) +void __cpuinit per_cpu_trap_init(void) { unsigned int cpu = smp_processor_id(); unsigned int status_set = ST0_CU0; @@ -1404,11 +1423,12 @@ void __init set_handler(unsigned long offset, void *addr, unsigned long size) flush_icache_range(ebase + offset, ebase + offset + size); } -static char panic_null_cerr[] __initdata = +static char panic_null_cerr[] __cpuinitdata = "Trying to set NULL cache error exception handler"; /* Install uncached CPU exception handler */ -void __init set_uncached_handler(unsigned long offset, void *addr, unsigned long size) +void __cpuinit set_uncached_handler(unsigned long offset, void *addr, + unsigned long size) { #ifdef CONFIG_32BIT unsigned long uncached_ebase = KSEG1ADDR(ebase); diff --git a/arch/mips/lib/ucmpdi2.c b/arch/mips/lib/ucmpdi2.c index b33d8569bcb0a0f71ee3838b72f1f92df113f657..bb4cb2f828ea9ae86090a06b859caf299f1a5c29 100644 --- a/arch/mips/lib/ucmpdi2.c +++ b/arch/mips/lib/ucmpdi2.c @@ -17,3 +17,5 @@ word_type __ucmpdi2(unsigned long long a, unsigned long long b) return 2; return 1; } + +EXPORT_SYMBOL(__ucmpdi2); diff --git a/arch/mips/lib/uncached.c b/arch/mips/lib/uncached.c index 27b012d4341c2ad6f259ac33b4557b7360bc0a9b..a6d1c77034d5ea351bd140c7ee78fd86cdf515dd 100644 --- a/arch/mips/lib/uncached.c +++ b/arch/mips/lib/uncached.c @@ -36,7 +36,7 @@ * values, so we can avoid sharing the same stack area between a cached * and the uncached mode. */ -unsigned long __init run_uncached(void *func) +unsigned long __cpuinit run_uncached(void *func) { register long sp __asm__("$sp"); register long ret __asm__("$2"); diff --git a/arch/mips/mips-boards/generic/time.c b/arch/mips/mips-boards/generic/time.c index f02ce6308e51d839dd9e366a7cbdea60cc4e7625..b50e0fc406ac9d04fa50b64ad87e8f6666d800a0 100644 --- a/arch/mips/mips-boards/generic/time.c +++ b/arch/mips/mips-boards/generic/time.c @@ -146,7 +146,7 @@ void __init plat_perf_setup(void) } } -unsigned int __init get_c0_compare_int(void) +unsigned int __cpuinit get_c0_compare_int(void) { #ifdef MSC01E_INT_BASE if (cpu_has_veic) { diff --git a/arch/mips/mipssim/sim_time.c b/arch/mips/mipssim/sim_time.c index e39bbe989da34b85a0ec7dbe703efdbef4e5270a..881ecbc1fa238d62790bcf9dcd946137cad7639f 100644 --- a/arch/mips/mipssim/sim_time.c +++ b/arch/mips/mipssim/sim_time.c @@ -83,7 +83,7 @@ static void mips_timer_dispatch(void) } -unsigned __init get_c0_compare_int(void) +unsigned __cpuinit get_c0_compare_int(void) { #ifdef MSC01E_INT_BASE if (cpu_has_veic) { diff --git a/arch/mips/mm/c-r3k.c b/arch/mips/mm/c-r3k.c index 562abb77d1d543864a80b2a09318aadf1c464733..76935e320214bf200106b78bd4b8ed7037c1f72c 100644 --- a/arch/mips/mm/c-r3k.c +++ b/arch/mips/mm/c-r3k.c @@ -307,7 +307,7 @@ static void r3k_dma_cache_wback_inv(unsigned long start, unsigned long size) r3k_flush_dcache_range(start, start + size); } -void __init r3k_cache_init(void) +void __cpuinit r3k_cache_init(void) { extern void build_clear_page(void); extern void build_copy_page(void); diff --git a/arch/mips/mm/c-r4k.c b/arch/mips/mm/c-r4k.c index 2c4f7e11f0d55fe746d142f764b0e4024f78d686..6496925b5e290ab1ec837a785baf065438ae346c 100644 --- a/arch/mips/mm/c-r4k.c +++ b/arch/mips/mm/c-r4k.c @@ -93,7 +93,7 @@ static inline void r4k_blast_dcache_page_dc32(unsigned long addr) blast_dcache32_page(addr); } -static void __init r4k_blast_dcache_page_setup(void) +static void __cpuinit r4k_blast_dcache_page_setup(void) { unsigned long dc_lsize = cpu_dcache_line_size(); @@ -107,7 +107,7 @@ static void __init r4k_blast_dcache_page_setup(void) static void (* r4k_blast_dcache_page_indexed)(unsigned long addr); -static void __init r4k_blast_dcache_page_indexed_setup(void) +static void __cpuinit r4k_blast_dcache_page_indexed_setup(void) { unsigned long dc_lsize = cpu_dcache_line_size(); @@ -121,7 +121,7 @@ static void __init r4k_blast_dcache_page_indexed_setup(void) static void (* r4k_blast_dcache)(void); -static void __init r4k_blast_dcache_setup(void) +static void __cpuinit r4k_blast_dcache_setup(void) { unsigned long dc_lsize = cpu_dcache_line_size(); @@ -206,7 +206,7 @@ static inline void tx49_blast_icache32_page_indexed(unsigned long page) static void (* r4k_blast_icache_page)(unsigned long addr); -static void __init r4k_blast_icache_page_setup(void) +static void __cpuinit r4k_blast_icache_page_setup(void) { unsigned long ic_lsize = cpu_icache_line_size(); @@ -223,7 +223,7 @@ static void __init r4k_blast_icache_page_setup(void) static void (* r4k_blast_icache_page_indexed)(unsigned long addr); -static void __init r4k_blast_icache_page_indexed_setup(void) +static void __cpuinit r4k_blast_icache_page_indexed_setup(void) { unsigned long ic_lsize = cpu_icache_line_size(); @@ -247,7 +247,7 @@ static void __init r4k_blast_icache_page_indexed_setup(void) static void (* r4k_blast_icache)(void); -static void __init r4k_blast_icache_setup(void) +static void __cpuinit r4k_blast_icache_setup(void) { unsigned long ic_lsize = cpu_icache_line_size(); @@ -268,7 +268,7 @@ static void __init r4k_blast_icache_setup(void) static void (* r4k_blast_scache_page)(unsigned long addr); -static void __init r4k_blast_scache_page_setup(void) +static void __cpuinit r4k_blast_scache_page_setup(void) { unsigned long sc_lsize = cpu_scache_line_size(); @@ -286,7 +286,7 @@ static void __init r4k_blast_scache_page_setup(void) static void (* r4k_blast_scache_page_indexed)(unsigned long addr); -static void __init r4k_blast_scache_page_indexed_setup(void) +static void __cpuinit r4k_blast_scache_page_indexed_setup(void) { unsigned long sc_lsize = cpu_scache_line_size(); @@ -304,7 +304,7 @@ static void __init r4k_blast_scache_page_indexed_setup(void) static void (* r4k_blast_scache)(void); -static void __init r4k_blast_scache_setup(void) +static void __cpuinit r4k_blast_scache_setup(void) { unsigned long sc_lsize = cpu_scache_line_size(); @@ -691,11 +691,11 @@ static inline void rm7k_erratum31(void) } } -static char *way_string[] __initdata = { NULL, "direct mapped", "2-way", +static char *way_string[] __cpuinitdata = { NULL, "direct mapped", "2-way", "3-way", "4-way", "5-way", "6-way", "7-way", "8-way" }; -static void __init probe_pcache(void) +static void __cpuinit probe_pcache(void) { struct cpuinfo_mips *c = ¤t_cpu_data; unsigned int config = read_c0_config(); @@ -1016,7 +1016,7 @@ static void __init probe_pcache(void) * executes in KSEG1 space or else you will crash and burn badly. You have * been warned. */ -static int __init probe_scache(void) +static int __cpuinit probe_scache(void) { unsigned long flags, addr, begin, end, pow2; unsigned int config = read_c0_config(); @@ -1095,7 +1095,7 @@ extern int r5k_sc_init(void); extern int rm7k_sc_init(void); extern int mips_sc_init(void); -static void __init setup_scache(void) +static void __cpuinit setup_scache(void) { struct cpuinfo_mips *c = ¤t_cpu_data; unsigned int config = read_c0_config(); @@ -1206,7 +1206,7 @@ void au1x00_fixup_config_od(void) } } -static void __init coherency_setup(void) +static void __cpuinit coherency_setup(void) { change_c0_config(CONF_CM_CMASK, CONF_CM_DEFAULT); @@ -1238,7 +1238,7 @@ static void __init coherency_setup(void) } } -void __init r4k_cache_init(void) +void __cpuinit r4k_cache_init(void) { extern void build_clear_page(void); extern void build_copy_page(void); diff --git a/arch/mips/mm/c-tx39.c b/arch/mips/mm/c-tx39.c index 9ea121e8cdceb39245d922154dde44ce239d40e5..b09d56981d53cfcf7d99da747f8225a8915ade2f 100644 --- a/arch/mips/mm/c-tx39.c +++ b/arch/mips/mm/c-tx39.c @@ -329,7 +329,7 @@ static __init void tx39_probe_cache(void) } } -void __init tx39_cache_init(void) +void __cpuinit tx39_cache_init(void) { extern void build_clear_page(void); extern void build_copy_page(void); diff --git a/arch/mips/mm/cache.c b/arch/mips/mm/cache.c index 6a24651971df0f6e361d110419c65ee46f5f241a..51ab1faa027d86b6c2b5c832ea518942bd0e33e8 100644 --- a/arch/mips/mm/cache.c +++ b/arch/mips/mm/cache.c @@ -127,9 +127,10 @@ void __update_cache(struct vm_area_struct *vma, unsigned long address, } } -static char cache_panic[] __initdata = "Yeee, unsupported cache architecture."; +static char cache_panic[] __cpuinitdata = + "Yeee, unsupported cache architecture."; -void __init cpu_cache_init(void) +void __devinit cpu_cache_init(void) { if (cpu_has_3k_cache) { extern void __weak r3k_cache_init(void); diff --git a/arch/mips/mm/cex-sb1.S b/arch/mips/mm/cex-sb1.S index e54a62f2807c93754e9c4b05d97442b812d5d626..2d08268bb705f19f29c2a708f5a25a8f6d571369 100644 --- a/arch/mips/mm/cex-sb1.S +++ b/arch/mips/mm/cex-sb1.S @@ -34,8 +34,6 @@ * is changed. */ - __INIT - .set mips64 .set noreorder .set noat @@ -51,6 +49,8 @@ * (0x170-0x17f) are used to preserve k0, k1, and ra. */ + __CPUINIT + LEAF(except_vec2_sb1) /* * If this error is recoverable, we need to exit the handler diff --git a/arch/mips/mm/pg-r4k.c b/arch/mips/mm/pg-r4k.c index 9185fbf37c0d5b9655e914b446d2d9e3ae70f5d4..455dedb5b39e8379703246bc3a158fdafb0ca83e 100644 --- a/arch/mips/mm/pg-r4k.c +++ b/arch/mips/mm/pg-r4k.c @@ -66,21 +66,21 @@ EXPORT_SYMBOL(copy_page); * with 64-bit kernels. The prefetch offsets have been experimentally tuned * an Origin 200. */ -static int pref_offset_clear __initdata = 512; -static int pref_offset_copy __initdata = 256; +static int pref_offset_clear __cpuinitdata = 512; +static int pref_offset_copy __cpuinitdata = 256; -static unsigned int pref_src_mode __initdata; -static unsigned int pref_dst_mode __initdata; +static unsigned int pref_src_mode __cpuinitdata; +static unsigned int pref_dst_mode __cpuinitdata; -static int load_offset __initdata; -static int store_offset __initdata; +static int load_offset __cpuinitdata; +static int store_offset __cpuinitdata; -static unsigned int __initdata *dest, *epc; +static unsigned int __cpuinitdata *dest, *epc; static unsigned int instruction_pending; static union mips_instruction delayed_mi; -static void __init emit_instruction(union mips_instruction mi) +static void __cpuinit emit_instruction(union mips_instruction mi) { if (instruction_pending) *epc++ = delayed_mi.word; @@ -222,7 +222,7 @@ static inline void build_cdex_p(void) emit_instruction(mi); } -static void __init __build_store_reg(int reg) +static void __cpuinit __build_store_reg(int reg) { union mips_instruction mi; unsigned int width; @@ -339,7 +339,7 @@ static inline void build_jr_ra(void) flush_delay_slot_or_nop(); } -void __init build_clear_page(void) +void __cpuinit build_clear_page(void) { unsigned int loop_start; unsigned long off; @@ -442,7 +442,7 @@ dest = label(); pr_debug("\t.set pop\n"); } -void __init build_copy_page(void) +void __cpuinit build_copy_page(void) { unsigned int loop_start; unsigned long off; diff --git a/arch/mips/mm/pg-sb1.c b/arch/mips/mm/pg-sb1.c index 89925ec57d6a83e80b8657dc2fb038996bea90ac..49e289d05414fe333287ba2d0377170c0849071f 100644 --- a/arch/mips/mm/pg-sb1.c +++ b/arch/mips/mm/pg-sb1.c @@ -293,10 +293,10 @@ void copy_page(void *to, void *from) EXPORT_SYMBOL(clear_page); EXPORT_SYMBOL(copy_page); -void __init build_clear_page(void) +void __cpuinit build_clear_page(void) { } -void __init build_copy_page(void) +void __cpuinit build_copy_page(void) { } diff --git a/arch/mips/mm/sc-ip22.c b/arch/mips/mm/sc-ip22.c index d236cf8b7374720e2beb555c66aad84becec69c7..1f602a110e101e9e54bcd4c1426cec9659eaaa23 100644 --- a/arch/mips/mm/sc-ip22.c +++ b/arch/mips/mm/sc-ip22.c @@ -168,7 +168,7 @@ struct bcache_ops indy_sc_ops = { .bc_inv = indy_sc_wback_invalidate }; -void __init indy_sc_init(void) +void __cpuinit indy_sc_init(void) { if (indy_sc_probe()) { indy_sc_enable(); diff --git a/arch/mips/mm/sc-mips.c b/arch/mips/mm/sc-mips.c index c13170bc675c6f3483221ced2a7d34a28d0081bf..b55c2d1b998fee54a905b4cc816d3c7196209673 100644 --- a/arch/mips/mm/sc-mips.c +++ b/arch/mips/mm/sc-mips.c @@ -100,7 +100,7 @@ static inline int __init mips_sc_probe(void) return 1; } -int __init mips_sc_init(void) +int __cpuinit mips_sc_init(void) { int found = mips_sc_probe(); if (found) { @@ -109,4 +109,3 @@ int __init mips_sc_init(void) } return found; } - diff --git a/arch/mips/mm/sc-r5k.c b/arch/mips/mm/sc-r5k.c index d35b6c1103a393d8f52994ec66ee59859c59e90a..f330d38e55753b057c9647c031215c8fb2feb7d0 100644 --- a/arch/mips/mm/sc-r5k.c +++ b/arch/mips/mm/sc-r5k.c @@ -99,7 +99,7 @@ static struct bcache_ops r5k_sc_ops = { .bc_inv = r5k_dma_cache_inv_sc }; -void __init r5k_sc_init(void) +void __cpuinit r5k_sc_init(void) { if (r5k_sc_probe()) { r5k_sc_enable(); diff --git a/arch/mips/mm/sc-rm7k.c b/arch/mips/mm/sc-rm7k.c index 31ec730524239dcc9de7c22dd2cda845daa8b963..fc227f3b1199750bfbdb6fb350274b4d51fef915 100644 --- a/arch/mips/mm/sc-rm7k.c +++ b/arch/mips/mm/sc-rm7k.c @@ -128,7 +128,7 @@ struct bcache_ops rm7k_sc_ops = { .bc_inv = rm7k_sc_inv }; -void __init rm7k_sc_init(void) +void __cpuinit rm7k_sc_init(void) { struct cpuinfo_mips *c = ¤t_cpu_data; unsigned int config = read_c0_config(); diff --git a/arch/mips/mm/tlb-r3k.c b/arch/mips/mm/tlb-r3k.c index 7948e9a5e37212bccc6da9bce7d4829429169dc9..a782549ac80eaa02069e40a18f6e0d98527be9b2 100644 --- a/arch/mips/mm/tlb-r3k.c +++ b/arch/mips/mm/tlb-r3k.c @@ -281,7 +281,7 @@ void __init add_wired_entry(unsigned long entrylo0, unsigned long entrylo1, } } -void __init tlb_init(void) +void __cpuinit tlb_init(void) { local_flush_tlb_all(); diff --git a/arch/mips/mm/tlb-r4k.c b/arch/mips/mm/tlb-r4k.c index 74ae0348cc92533d483f0f2597d8429bfb4d07b7..63065d6e806397202e93628db4dc0142e1ce642a 100644 --- a/arch/mips/mm/tlb-r4k.c +++ b/arch/mips/mm/tlb-r4k.c @@ -388,7 +388,7 @@ void __init add_wired_entry(unsigned long entrylo0, unsigned long entrylo1, * lifetime of the system */ -static int temp_tlb_entry __initdata; +static int temp_tlb_entry __cpuinitdata; __init int add_temporary_entry(unsigned long entrylo0, unsigned long entrylo1, unsigned long entryhi, unsigned long pagemask) @@ -427,7 +427,7 @@ out: return ret; } -static void __init probe_tlb(unsigned long config) +static void __cpuinit probe_tlb(unsigned long config) { struct cpuinfo_mips *c = ¤t_cpu_data; unsigned int reg; @@ -455,7 +455,7 @@ static void __init probe_tlb(unsigned long config) c->tlbsize = ((reg >> 25) & 0x3f) + 1; } -static int __initdata ntlb = 0; +static int __cpuinitdata ntlb = 0; static int __init set_ntlb(char *str) { get_option(&str, &ntlb); @@ -464,7 +464,7 @@ static int __init set_ntlb(char *str) __setup("ntlb=", set_ntlb); -void __init tlb_init(void) +void __cpuinit tlb_init(void) { unsigned int config = read_c0_config(); @@ -473,7 +473,7 @@ void __init tlb_init(void) * - On R4600 1.7 the tlbp never hits for pages smaller than * the value in the c0_pagemask register. * - The entire mm handling assumes the c0_pagemask register to - * be set for 4kb pages. + * be set to fixed-size pages. */ probe_tlb(config); write_c0_pagemask(PM_DEFAULT_MASK); diff --git a/arch/mips/mm/tlb-r8k.c b/arch/mips/mm/tlb-r8k.c index bd8409d8ff626c64b62ed271cb11ab1bf82a125d..4f01a3be215cf142434fbe91fbaf3edee0a6884f 100644 --- a/arch/mips/mm/tlb-r8k.c +++ b/arch/mips/mm/tlb-r8k.c @@ -214,14 +214,14 @@ void __update_tlb(struct vm_area_struct * vma, unsigned long address, pte_t pte) local_irq_restore(flags); } -static void __init probe_tlb(unsigned long config) +static void __cpuinit probe_tlb(unsigned long config) { struct cpuinfo_mips *c = ¤t_cpu_data; c->tlbsize = 3 * 128; /* 3 sets each 128 entries */ } -void __init tlb_init(void) +void __cpuinit tlb_init(void) { unsigned int config = read_c0_config(); unsigned long status; diff --git a/arch/mips/mm/tlbex.c b/arch/mips/mm/tlbex.c index 218a6cc415e8865cbdb83b59889666fd4f2d8dc7..3a93d4ce270320501acf029da9a5036e4d4d3d26 100644 --- a/arch/mips/mm/tlbex.c +++ b/arch/mips/mm/tlbex.c @@ -60,7 +60,7 @@ static inline int __maybe_unused r10000_llsc_war(void) * why; it's not an issue caused by the core RTL. * */ -static int __init m4kc_tlbp_war(void) +static int __cpuinit m4kc_tlbp_war(void) { return (current_cpu_data.processor_id & 0xffff00) == (PRID_COMP_MIPS | PRID_IMP_4KC); @@ -144,16 +144,16 @@ static inline void dump_handler(const u32 *handler, int count) * We deliberately chose a buffer size of 128, so we won't scribble * over anything important on overflow before we panic. */ -static u32 tlb_handler[128] __initdata; +static u32 tlb_handler[128] __cpuinitdata; /* simply assume worst case size for labels and relocs */ -static struct uasm_label labels[128] __initdata; -static struct uasm_reloc relocs[128] __initdata; +static struct uasm_label labels[128] __cpuinitdata; +static struct uasm_reloc relocs[128] __cpuinitdata; /* * The R3000 TLB handler is simple. */ -static void __init build_r3000_tlb_refill_handler(void) +static void __cpuinit build_r3000_tlb_refill_handler(void) { long pgdc = (long)pgd_current; u32 *p; @@ -197,7 +197,7 @@ static void __init build_r3000_tlb_refill_handler(void) * other one.To keep things simple, we first assume linear space, * then we relocate it to the final handler layout as needed. */ -static u32 final_handler[64] __initdata; +static u32 final_handler[64] __cpuinitdata; /* * Hazards @@ -221,7 +221,7 @@ static u32 final_handler[64] __initdata; * * As if we MIPS hackers wouldn't know how to nop pipelines happy ... */ -static void __init __maybe_unused build_tlb_probe_entry(u32 **p) +static void __cpuinit __maybe_unused build_tlb_probe_entry(u32 **p) { switch (current_cpu_type()) { /* Found by experiment: R4600 v2.0 needs this, too. */ @@ -245,7 +245,7 @@ static void __init __maybe_unused build_tlb_probe_entry(u32 **p) */ enum tlb_write_entry { tlb_random, tlb_indexed }; -static void __init build_tlb_write_entry(u32 **p, struct uasm_label **l, +static void __cpuinit build_tlb_write_entry(u32 **p, struct uasm_label **l, struct uasm_reloc **r, enum tlb_write_entry wmode) { @@ -389,7 +389,7 @@ static void __init build_tlb_write_entry(u32 **p, struct uasm_label **l, * TMP and PTR are scratch. * TMP will be clobbered, PTR will hold the pmd entry. */ -static void __init +static void __cpuinit build_get_pmde64(u32 **p, struct uasm_label **l, struct uasm_reloc **r, unsigned int tmp, unsigned int ptr) { @@ -450,7 +450,7 @@ build_get_pmde64(u32 **p, struct uasm_label **l, struct uasm_reloc **r, * BVADDR is the faulting address, PTR is scratch. * PTR will hold the pgd for vmalloc. */ -static void __init +static void __cpuinit build_get_pgd_vmalloc64(u32 **p, struct uasm_label **l, struct uasm_reloc **r, unsigned int bvaddr, unsigned int ptr) { @@ -522,7 +522,7 @@ build_get_pgd_vmalloc64(u32 **p, struct uasm_label **l, struct uasm_reloc **r, * TMP and PTR are scratch. * TMP will be clobbered, PTR will hold the pgd entry. */ -static void __init __maybe_unused +static void __cpuinit __maybe_unused build_get_pgde32(u32 **p, unsigned int tmp, unsigned int ptr) { long pgdc = (long)pgd_current; @@ -557,7 +557,7 @@ build_get_pgde32(u32 **p, unsigned int tmp, unsigned int ptr) #endif /* !CONFIG_64BIT */ -static void __init build_adjust_context(u32 **p, unsigned int ctx) +static void __cpuinit build_adjust_context(u32 **p, unsigned int ctx) { unsigned int shift = 4 - (PTE_T_LOG2 + 1) + PAGE_SHIFT - 12; unsigned int mask = (PTRS_PER_PTE / 2 - 1) << (PTE_T_LOG2 + 1); @@ -583,7 +583,7 @@ static void __init build_adjust_context(u32 **p, unsigned int ctx) uasm_i_andi(p, ctx, ctx, mask); } -static void __init build_get_ptep(u32 **p, unsigned int tmp, unsigned int ptr) +static void __cpuinit build_get_ptep(u32 **p, unsigned int tmp, unsigned int ptr) { /* * Bug workaround for the Nevada. It seems as if under certain @@ -608,7 +608,7 @@ static void __init build_get_ptep(u32 **p, unsigned int tmp, unsigned int ptr) UASM_i_ADDU(p, ptr, ptr, tmp); /* add in offset */ } -static void __init build_update_entries(u32 **p, unsigned int tmp, +static void __cpuinit build_update_entries(u32 **p, unsigned int tmp, unsigned int ptep) { /* @@ -651,7 +651,7 @@ static void __init build_update_entries(u32 **p, unsigned int tmp, #endif } -static void __init build_r4000_tlb_refill_handler(void) +static void __cpuinit build_r4000_tlb_refill_handler(void) { u32 *p = tlb_handler; struct uasm_label *l = labels; @@ -783,7 +783,7 @@ u32 handle_tlbl[FASTPATH_SIZE] __cacheline_aligned; u32 handle_tlbs[FASTPATH_SIZE] __cacheline_aligned; u32 handle_tlbm[FASTPATH_SIZE] __cacheline_aligned; -static void __init +static void __cpuinit iPTE_LW(u32 **p, struct uasm_label **l, unsigned int pte, unsigned int ptr) { #ifdef CONFIG_SMP @@ -803,7 +803,7 @@ iPTE_LW(u32 **p, struct uasm_label **l, unsigned int pte, unsigned int ptr) #endif } -static void __init +static void __cpuinit iPTE_SW(u32 **p, struct uasm_reloc **r, unsigned int pte, unsigned int ptr, unsigned int mode) { @@ -863,7 +863,7 @@ iPTE_SW(u32 **p, struct uasm_reloc **r, unsigned int pte, unsigned int ptr, * the page table where this PTE is located, PTE will be re-loaded * with it's original value. */ -static void __init +static void __cpuinit build_pte_present(u32 **p, struct uasm_label **l, struct uasm_reloc **r, unsigned int pte, unsigned int ptr, enum label_id lid) { @@ -874,7 +874,7 @@ build_pte_present(u32 **p, struct uasm_label **l, struct uasm_reloc **r, } /* Make PTE valid, store result in PTR. */ -static void __init +static void __cpuinit build_make_valid(u32 **p, struct uasm_reloc **r, unsigned int pte, unsigned int ptr) { @@ -887,7 +887,7 @@ build_make_valid(u32 **p, struct uasm_reloc **r, unsigned int pte, * Check if PTE can be written to, if not branch to LABEL. Regardless * restore PTE with value from PTR when done. */ -static void __init +static void __cpuinit build_pte_writable(u32 **p, struct uasm_label **l, struct uasm_reloc **r, unsigned int pte, unsigned int ptr, enum label_id lid) { @@ -900,7 +900,7 @@ build_pte_writable(u32 **p, struct uasm_label **l, struct uasm_reloc **r, /* Make PTE writable, update software status bits as well, then store * at PTR. */ -static void __init +static void __cpuinit build_make_write(u32 **p, struct uasm_reloc **r, unsigned int pte, unsigned int ptr) { @@ -914,7 +914,7 @@ build_make_write(u32 **p, struct uasm_reloc **r, unsigned int pte, * Check if PTE can be modified, if not branch to LABEL. Regardless * restore PTE with value from PTR when done. */ -static void __init +static void __cpuinit build_pte_modifiable(u32 **p, struct uasm_label **l, struct uasm_reloc **r, unsigned int pte, unsigned int ptr, enum label_id lid) { @@ -931,7 +931,7 @@ build_pte_modifiable(u32 **p, struct uasm_label **l, struct uasm_reloc **r, * This places the pte into ENTRYLO0 and writes it with tlbwi. * Then it returns. */ -static void __init +static void __cpuinit build_r3000_pte_reload_tlbwi(u32 **p, unsigned int pte, unsigned int tmp) { uasm_i_mtc0(p, pte, C0_ENTRYLO0); /* cp0 delay */ @@ -947,7 +947,7 @@ build_r3000_pte_reload_tlbwi(u32 **p, unsigned int pte, unsigned int tmp) * may have the probe fail bit set as a result of a trap on a * kseg2 access, i.e. without refill. Then it returns. */ -static void __init +static void __cpuinit build_r3000_tlb_reload_write(u32 **p, struct uasm_label **l, struct uasm_reloc **r, unsigned int pte, unsigned int tmp) @@ -965,7 +965,7 @@ build_r3000_tlb_reload_write(u32 **p, struct uasm_label **l, uasm_i_rfe(p); /* branch delay */ } -static void __init +static void __cpuinit build_r3000_tlbchange_handler_head(u32 **p, unsigned int pte, unsigned int ptr) { @@ -985,7 +985,7 @@ build_r3000_tlbchange_handler_head(u32 **p, unsigned int pte, uasm_i_tlbp(p); /* load delay */ } -static void __init build_r3000_tlb_load_handler(void) +static void __cpuinit build_r3000_tlb_load_handler(void) { u32 *p = handle_tlbl; struct uasm_label *l = labels; @@ -1015,7 +1015,7 @@ static void __init build_r3000_tlb_load_handler(void) dump_handler(handle_tlbl, ARRAY_SIZE(handle_tlbl)); } -static void __init build_r3000_tlb_store_handler(void) +static void __cpuinit build_r3000_tlb_store_handler(void) { u32 *p = handle_tlbs; struct uasm_label *l = labels; @@ -1045,7 +1045,7 @@ static void __init build_r3000_tlb_store_handler(void) dump_handler(handle_tlbs, ARRAY_SIZE(handle_tlbs)); } -static void __init build_r3000_tlb_modify_handler(void) +static void __cpuinit build_r3000_tlb_modify_handler(void) { u32 *p = handle_tlbm; struct uasm_label *l = labels; @@ -1078,7 +1078,7 @@ static void __init build_r3000_tlb_modify_handler(void) /* * R4000 style TLB load/store/modify handlers. */ -static void __init +static void __cpuinit build_r4000_tlbchange_handler_head(u32 **p, struct uasm_label **l, struct uasm_reloc **r, unsigned int pte, unsigned int ptr) @@ -1103,7 +1103,7 @@ build_r4000_tlbchange_handler_head(u32 **p, struct uasm_label **l, build_tlb_probe_entry(p); } -static void __init +static void __cpuinit build_r4000_tlbchange_handler_tail(u32 **p, struct uasm_label **l, struct uasm_reloc **r, unsigned int tmp, unsigned int ptr) @@ -1120,7 +1120,7 @@ build_r4000_tlbchange_handler_tail(u32 **p, struct uasm_label **l, #endif } -static void __init build_r4000_tlb_load_handler(void) +static void __cpuinit build_r4000_tlb_load_handler(void) { u32 *p = handle_tlbl; struct uasm_label *l = labels; @@ -1160,7 +1160,7 @@ static void __init build_r4000_tlb_load_handler(void) dump_handler(handle_tlbl, ARRAY_SIZE(handle_tlbl)); } -static void __init build_r4000_tlb_store_handler(void) +static void __cpuinit build_r4000_tlb_store_handler(void) { u32 *p = handle_tlbs; struct uasm_label *l = labels; @@ -1191,7 +1191,7 @@ static void __init build_r4000_tlb_store_handler(void) dump_handler(handle_tlbs, ARRAY_SIZE(handle_tlbs)); } -static void __init build_r4000_tlb_modify_handler(void) +static void __cpuinit build_r4000_tlb_modify_handler(void) { u32 *p = handle_tlbm; struct uasm_label *l = labels; @@ -1223,7 +1223,7 @@ static void __init build_r4000_tlb_modify_handler(void) dump_handler(handle_tlbm, ARRAY_SIZE(handle_tlbm)); } -void __init build_tlb_refill_handler(void) +void __cpuinit build_tlb_refill_handler(void) { /* * The refill handler is generated per-CPU, multi-node systems @@ -1269,7 +1269,7 @@ void __init build_tlb_refill_handler(void) } } -void __init flush_tlb_handlers(void) +void __cpuinit flush_tlb_handlers(void) { flush_icache_range((unsigned long)handle_tlbl, (unsigned long)handle_tlbl + sizeof(handle_tlbl)); diff --git a/arch/mips/mm/uasm.c b/arch/mips/mm/uasm.c index e3f74ed5f704113cd55dfc76a14c5d21bb79b130..1a6f7704cc894276dda1b6ce6dcc3d6edb225382 100644 --- a/arch/mips/mm/uasm.c +++ b/arch/mips/mm/uasm.c @@ -82,7 +82,7 @@ struct insn { | (e) << RE_SH \ | (f) << FUNC_SH) -static struct insn insn_table[] __initdata = { +static struct insn insn_table[] __cpuinitdata = { { insn_addiu, M(addiu_op, 0, 0, 0, 0, 0), RS | RT | SIMM }, { insn_addu, M(spec_op, 0, 0, 0, 0, addu_op), RS | RT | RD }, { insn_and, M(spec_op, 0, 0, 0, 0, and_op), RS | RT | RD }, @@ -135,7 +135,7 @@ static struct insn insn_table[] __initdata = { #undef M -static inline __init u32 build_rs(u32 arg) +static inline __cpuinit u32 build_rs(u32 arg) { if (arg & ~RS_MASK) printk(KERN_WARNING "Micro-assembler field overflow\n"); @@ -143,7 +143,7 @@ static inline __init u32 build_rs(u32 arg) return (arg & RS_MASK) << RS_SH; } -static inline __init u32 build_rt(u32 arg) +static inline __cpuinit u32 build_rt(u32 arg) { if (arg & ~RT_MASK) printk(KERN_WARNING "Micro-assembler field overflow\n"); @@ -151,7 +151,7 @@ static inline __init u32 build_rt(u32 arg) return (arg & RT_MASK) << RT_SH; } -static inline __init u32 build_rd(u32 arg) +static inline __cpuinit u32 build_rd(u32 arg) { if (arg & ~RD_MASK) printk(KERN_WARNING "Micro-assembler field overflow\n"); @@ -159,7 +159,7 @@ static inline __init u32 build_rd(u32 arg) return (arg & RD_MASK) << RD_SH; } -static inline __init u32 build_re(u32 arg) +static inline __cpuinit u32 build_re(u32 arg) { if (arg & ~RE_MASK) printk(KERN_WARNING "Micro-assembler field overflow\n"); @@ -167,7 +167,7 @@ static inline __init u32 build_re(u32 arg) return (arg & RE_MASK) << RE_SH; } -static inline __init u32 build_simm(s32 arg) +static inline __cpuinit u32 build_simm(s32 arg) { if (arg > 0x7fff || arg < -0x8000) printk(KERN_WARNING "Micro-assembler field overflow\n"); @@ -175,7 +175,7 @@ static inline __init u32 build_simm(s32 arg) return arg & 0xffff; } -static inline __init u32 build_uimm(u32 arg) +static inline __cpuinit u32 build_uimm(u32 arg) { if (arg & ~IMM_MASK) printk(KERN_WARNING "Micro-assembler field overflow\n"); @@ -183,7 +183,7 @@ static inline __init u32 build_uimm(u32 arg) return arg & IMM_MASK; } -static inline __init u32 build_bimm(s32 arg) +static inline __cpuinit u32 build_bimm(s32 arg) { if (arg > 0x1ffff || arg < -0x20000) printk(KERN_WARNING "Micro-assembler field overflow\n"); @@ -194,7 +194,7 @@ static inline __init u32 build_bimm(s32 arg) return ((arg < 0) ? (1 << 15) : 0) | ((arg >> 2) & 0x7fff); } -static inline __init u32 build_jimm(u32 arg) +static inline __cpuinit u32 build_jimm(u32 arg) { if (arg & ~((JIMM_MASK) << 2)) printk(KERN_WARNING "Micro-assembler field overflow\n"); @@ -202,7 +202,7 @@ static inline __init u32 build_jimm(u32 arg) return (arg >> 2) & JIMM_MASK; } -static inline __init u32 build_func(u32 arg) +static inline __cpuinit u32 build_func(u32 arg) { if (arg & ~FUNC_MASK) printk(KERN_WARNING "Micro-assembler field overflow\n"); @@ -210,7 +210,7 @@ static inline __init u32 build_func(u32 arg) return arg & FUNC_MASK; } -static inline __init u32 build_set(u32 arg) +static inline __cpuinit u32 build_set(u32 arg) { if (arg & ~SET_MASK) printk(KERN_WARNING "Micro-assembler field overflow\n"); @@ -222,7 +222,7 @@ static inline __init u32 build_set(u32 arg) * The order of opcode arguments is implicitly left to right, * starting with RS and ending with FUNC or IMM. */ -static void __init build_insn(u32 **buf, enum opcode opc, ...) +static void __cpuinit build_insn(u32 **buf, enum opcode opc, ...) { struct insn *ip = NULL; unsigned int i; @@ -375,14 +375,14 @@ I_u3u1u2(_xor) I_u2u1u3(_xori) /* Handle labels. */ -void __init uasm_build_label(struct uasm_label **lab, u32 *addr, int lid) +void __cpuinit uasm_build_label(struct uasm_label **lab, u32 *addr, int lid) { (*lab)->addr = addr; (*lab)->lab = lid; (*lab)++; } -int __init uasm_in_compat_space_p(long addr) +int __cpuinit uasm_in_compat_space_p(long addr) { /* Is this address in 32bit compat space? */ #ifdef CONFIG_64BIT @@ -392,7 +392,7 @@ int __init uasm_in_compat_space_p(long addr) #endif } -int __init uasm_rel_highest(long val) +int __cpuinit uasm_rel_highest(long val) { #ifdef CONFIG_64BIT return ((((val + 0x800080008000L) >> 48) & 0xffff) ^ 0x8000) - 0x8000; @@ -401,7 +401,7 @@ int __init uasm_rel_highest(long val) #endif } -int __init uasm_rel_higher(long val) +int __cpuinit uasm_rel_higher(long val) { #ifdef CONFIG_64BIT return ((((val + 0x80008000L) >> 32) & 0xffff) ^ 0x8000) - 0x8000; @@ -410,17 +410,17 @@ int __init uasm_rel_higher(long val) #endif } -int __init uasm_rel_hi(long val) +int __cpuinit uasm_rel_hi(long val) { return ((((val + 0x8000L) >> 16) & 0xffff) ^ 0x8000) - 0x8000; } -int __init uasm_rel_lo(long val) +int __cpuinit uasm_rel_lo(long val) { return ((val & 0xffff) ^ 0x8000) - 0x8000; } -void __init UASM_i_LA_mostly(u32 **buf, unsigned int rs, long addr) +void __cpuinit UASM_i_LA_mostly(u32 **buf, unsigned int rs, long addr) { if (!uasm_in_compat_space_p(addr)) { uasm_i_lui(buf, rs, uasm_rel_highest(addr)); @@ -436,7 +436,7 @@ void __init UASM_i_LA_mostly(u32 **buf, unsigned int rs, long addr) uasm_i_lui(buf, rs, uasm_rel_hi(addr)); } -void __init UASM_i_LA(u32 **buf, unsigned int rs, long addr) +void __cpuinit UASM_i_LA(u32 **buf, unsigned int rs, long addr) { UASM_i_LA_mostly(buf, rs, addr); if (uasm_rel_lo(addr)) { @@ -448,7 +448,7 @@ void __init UASM_i_LA(u32 **buf, unsigned int rs, long addr) } /* Handle relocations. */ -void __init +void __cpuinit uasm_r_mips_pc16(struct uasm_reloc **rel, u32 *addr, int lid) { (*rel)->addr = addr; @@ -457,7 +457,7 @@ uasm_r_mips_pc16(struct uasm_reloc **rel, u32 *addr, int lid) (*rel)++; } -static inline void __init +static inline void __cpuinit __resolve_relocs(struct uasm_reloc *rel, struct uasm_label *lab) { long laddr = (long)lab->addr; @@ -474,7 +474,7 @@ __resolve_relocs(struct uasm_reloc *rel, struct uasm_label *lab) } } -void __init +void __cpuinit uasm_resolve_relocs(struct uasm_reloc *rel, struct uasm_label *lab) { struct uasm_label *l; @@ -485,7 +485,7 @@ uasm_resolve_relocs(struct uasm_reloc *rel, struct uasm_label *lab) __resolve_relocs(rel, l); } -void __init +void __cpuinit uasm_move_relocs(struct uasm_reloc *rel, u32 *first, u32 *end, long off) { for (; rel->lab != UASM_LABEL_INVALID; rel++) @@ -493,7 +493,7 @@ uasm_move_relocs(struct uasm_reloc *rel, u32 *first, u32 *end, long off) rel->addr += off; } -void __init +void __cpuinit uasm_move_labels(struct uasm_label *lab, u32 *first, u32 *end, long off) { for (; lab->lab != UASM_LABEL_INVALID; lab++) @@ -501,7 +501,7 @@ uasm_move_labels(struct uasm_label *lab, u32 *first, u32 *end, long off) lab->addr += off; } -void __init +void __cpuinit uasm_copy_handler(struct uasm_reloc *rel, struct uasm_label *lab, u32 *first, u32 *end, u32 *target) { @@ -513,7 +513,7 @@ uasm_copy_handler(struct uasm_reloc *rel, struct uasm_label *lab, u32 *first, uasm_move_labels(lab, first, end, off); } -int __init uasm_insn_has_bdelay(struct uasm_reloc *rel, u32 *addr) +int __cpuinit uasm_insn_has_bdelay(struct uasm_reloc *rel, u32 *addr) { for (; rel->lab != UASM_LABEL_INVALID; rel++) { if (rel->addr == addr @@ -526,49 +526,49 @@ int __init uasm_insn_has_bdelay(struct uasm_reloc *rel, u32 *addr) } /* Convenience functions for labeled branches. */ -void __init +void __cpuinit uasm_il_bltz(u32 **p, struct uasm_reloc **r, unsigned int reg, int lid) { uasm_r_mips_pc16(r, *p, lid); uasm_i_bltz(p, reg, 0); } -void __init +void __cpuinit uasm_il_b(u32 **p, struct uasm_reloc **r, int lid) { uasm_r_mips_pc16(r, *p, lid); uasm_i_b(p, 0); } -void __init +void __cpuinit uasm_il_beqz(u32 **p, struct uasm_reloc **r, unsigned int reg, int lid) { uasm_r_mips_pc16(r, *p, lid); uasm_i_beqz(p, reg, 0); } -void __init +void __cpuinit uasm_il_beqzl(u32 **p, struct uasm_reloc **r, unsigned int reg, int lid) { uasm_r_mips_pc16(r, *p, lid); uasm_i_beqzl(p, reg, 0); } -void __init +void __cpuinit uasm_il_bnez(u32 **p, struct uasm_reloc **r, unsigned int reg, int lid) { uasm_r_mips_pc16(r, *p, lid); uasm_i_bnez(p, reg, 0); } -void __init +void __cpuinit uasm_il_bgezl(u32 **p, struct uasm_reloc **r, unsigned int reg, int lid) { uasm_r_mips_pc16(r, *p, lid); uasm_i_bgezl(p, reg, 0); } -void __init +void __cpuinit uasm_il_bgez(u32 **p, struct uasm_reloc **r, unsigned int reg, int lid) { uasm_r_mips_pc16(r, *p, lid); diff --git a/arch/mips/mm/uasm.h b/arch/mips/mm/uasm.h index a10fc1135c76bb24abecbc5e57554fa713e3673c..fe0574f6e77ddcec84847b6e4028540022982646 100644 --- a/arch/mips/mm/uasm.h +++ b/arch/mips/mm/uasm.h @@ -11,38 +11,38 @@ #include #define Ip_u1u2u3(op) \ -void __init \ +void __cpuinit \ uasm_i##op(u32 **buf, unsigned int a, unsigned int b, unsigned int c) #define Ip_u2u1u3(op) \ -void __init \ +void __cpuinit \ uasm_i##op(u32 **buf, unsigned int a, unsigned int b, unsigned int c) #define Ip_u3u1u2(op) \ -void __init \ +void __cpuinit \ uasm_i##op(u32 **buf, unsigned int a, unsigned int b, unsigned int c) #define Ip_u1u2s3(op) \ -void __init \ +void __cpuinit \ uasm_i##op(u32 **buf, unsigned int a, unsigned int b, signed int c) #define Ip_u2s3u1(op) \ -void __init \ +void __cpuinit \ uasm_i##op(u32 **buf, unsigned int a, signed int b, unsigned int c) #define Ip_u2u1s3(op) \ -void __init \ +void __cpuinit \ uasm_i##op(u32 **buf, unsigned int a, unsigned int b, signed int c) #define Ip_u1u2(op) \ -void __init uasm_i##op(u32 **buf, unsigned int a, unsigned int b) +void __cpuinit uasm_i##op(u32 **buf, unsigned int a, unsigned int b) #define Ip_u1s2(op) \ -void __init uasm_i##op(u32 **buf, unsigned int a, signed int b) +void __cpuinit uasm_i##op(u32 **buf, unsigned int a, signed int b) -#define Ip_u1(op) void __init uasm_i##op(u32 **buf, unsigned int a) +#define Ip_u1(op) void __cpuinit uasm_i##op(u32 **buf, unsigned int a) -#define Ip_0(op) void __init uasm_i##op(u32 **buf) +#define Ip_0(op) void __cpuinit uasm_i##op(u32 **buf) Ip_u2u1s3(_addiu); Ip_u3u1u2(_addu); @@ -98,19 +98,19 @@ struct uasm_label { int lab; }; -void __init uasm_build_label(struct uasm_label **lab, u32 *addr, int lid); +void __cpuinit uasm_build_label(struct uasm_label **lab, u32 *addr, int lid); #ifdef CONFIG_64BIT -int __init uasm_in_compat_space_p(long addr); -int __init uasm_rel_highest(long val); -int __init uasm_rel_higher(long val); +int uasm_in_compat_space_p(long addr); +int uasm_rel_highest(long val); +int uasm_rel_higher(long val); #endif -int __init uasm_rel_hi(long val); -int __init uasm_rel_lo(long val); -void __init UASM_i_LA_mostly(u32 **buf, unsigned int rs, long addr); -void __init UASM_i_LA(u32 **buf, unsigned int rs, long addr); +int uasm_rel_hi(long val); +int uasm_rel_lo(long val); +void UASM_i_LA_mostly(u32 **buf, unsigned int rs, long addr); +void UASM_i_LA(u32 **buf, unsigned int rs, long addr); #define UASM_L_LA(lb) \ -static inline void __init uasm_l##lb(struct uasm_label **lab, u32 *addr) \ +static inline void __cpuinit uasm_l##lb(struct uasm_label **lab, u32 *addr) \ { \ uasm_build_label(lab, addr, label##lb); \ } @@ -164,29 +164,19 @@ struct uasm_reloc { /* This is zero so we can use zeroed label arrays. */ #define UASM_LABEL_INVALID 0 -void __init uasm_r_mips_pc16(struct uasm_reloc **rel, u32 *addr, int lid); -void __init -uasm_resolve_relocs(struct uasm_reloc *rel, struct uasm_label *lab); -void __init -uasm_move_relocs(struct uasm_reloc *rel, u32 *first, u32 *end, long off); -void __init -uasm_move_labels(struct uasm_label *lab, u32 *first, u32 *end, long off); -void __init -uasm_copy_handler(struct uasm_reloc *rel, struct uasm_label *lab, u32 *first, - u32 *end, u32 *target); -int __init uasm_insn_has_bdelay(struct uasm_reloc *rel, u32 *addr); +void uasm_r_mips_pc16(struct uasm_reloc **rel, u32 *addr, int lid); +void uasm_resolve_relocs(struct uasm_reloc *rel, struct uasm_label *lab); +void uasm_move_relocs(struct uasm_reloc *rel, u32 *first, u32 *end, long off); +void uasm_move_labels(struct uasm_label *lab, u32 *first, u32 *end, long off); +void uasm_copy_handler(struct uasm_reloc *rel, struct uasm_label *lab, + u32 *first, u32 *end, u32 *target); +int uasm_insn_has_bdelay(struct uasm_reloc *rel, u32 *addr); /* Convenience functions for labeled branches. */ -void __init -uasm_il_bltz(u32 **p, struct uasm_reloc **r, unsigned int reg, int lid); -void __init uasm_il_b(u32 **p, struct uasm_reloc **r, int lid); -void __init -uasm_il_beqz(u32 **p, struct uasm_reloc **r, unsigned int reg, int lid); -void __init -uasm_il_beqzl(u32 **p, struct uasm_reloc **r, unsigned int reg, int lid); -void __init -uasm_il_bnez(u32 **p, struct uasm_reloc **r, unsigned int reg, int lid); -void __init -uasm_il_bgezl(u32 **p, struct uasm_reloc **r, unsigned int reg, int lid); -void __init -uasm_il_bgez(u32 **p, struct uasm_reloc **r, unsigned int reg, int lid); +void uasm_il_bltz(u32 **p, struct uasm_reloc **r, unsigned int reg, int lid); +void uasm_il_b(u32 **p, struct uasm_reloc **r, int lid); +void uasm_il_beqz(u32 **p, struct uasm_reloc **r, unsigned int reg, int lid); +void uasm_il_beqzl(u32 **p, struct uasm_reloc **r, unsigned int reg, int lid); +void uasm_il_bnez(u32 **p, struct uasm_reloc **r, unsigned int reg, int lid); +void uasm_il_bgezl(u32 **p, struct uasm_reloc **r, unsigned int reg, int lid); +void uasm_il_bgez(u32 **p, struct uasm_reloc **r, unsigned int reg, int lid); diff --git a/arch/mips/pci/pci-bcm1480.c b/arch/mips/pci/pci-bcm1480.c index 30ed36125bcdb73173f859823a77c3dbffce6d01..ab68c4318a308554dd3a598cbee493d9096ac08c 100644 --- a/arch/mips/pci/pci-bcm1480.c +++ b/arch/mips/pci/pci-bcm1480.c @@ -249,8 +249,9 @@ static int __init bcm1480_pcibios_init(void) * XXX ehs: Should this happen in PCI Device mode? */ - set_io_port_base((unsigned long) - ioremap(A_BCM1480_PHYS_PCI_IO_MATCH_BYTES, 65536)); + bcm1480_controller.io_map_base = (unsigned long) + ioremap(A_BCM1480_PHYS_PCI_IO_MATCH_BYTES, 65536); + set_io_port_base(bcm1480_controller.io_map_base); isa_slot_offset = (unsigned long) ioremap(A_BCM1480_PHYS_PCI_MEM_MATCH_BYTES, 1024*1024); diff --git a/arch/mips/pci/pci-ip27.c b/arch/mips/pci/pci-ip27.c index a322543ac34e257223f66cb4f3bd684c60eb9537..bb64828a92fece6bcab023b1fd50cbcaf814231e 100644 --- a/arch/mips/pci/pci-ip27.c +++ b/arch/mips/pci/pci-ip27.c @@ -40,7 +40,7 @@ int irq_to_slot[MAX_PCI_BUSSES * MAX_DEVICES_PER_PCIBUS]; extern struct pci_ops bridge_pci_ops; -int __init bridge_probe(nasid_t nasid, int widget_id, int masterwid) +int __cpuinit bridge_probe(nasid_t nasid, int widget_id, int masterwid) { unsigned long offset = NODE_OFFSET(nasid); struct bridge_controller *bc; diff --git a/arch/mips/pci/pci.c b/arch/mips/pci/pci.c index f9471d77c09673f9c1e4252a404b95fea1abeecf..358ad6210949113211fa80b8e27995b20d1d1f56 100644 --- a/arch/mips/pci/pci.c +++ b/arch/mips/pci/pci.c @@ -260,7 +260,7 @@ static void pcibios_fixup_device_resources(struct pci_dev *dev, } } -void pcibios_fixup_bus(struct pci_bus *bus) +void __devinit pcibios_fixup_bus(struct pci_bus *bus) { /* Propagate hose info into the subordinate devices. */ diff --git a/arch/mips/pmc-sierra/yosemite/smp.c b/arch/mips/pmc-sierra/yosemite/smp.c index 653f3ec61cababae9a75320da0ec6fa8b96a8ea2..3a7df647ca7739b9336cc22ade77c34d883d5252 100644 --- a/arch/mips/pmc-sierra/yosemite/smp.c +++ b/arch/mips/pmc-sierra/yosemite/smp.c @@ -7,10 +7,10 @@ #define LAUNCHSTACK_SIZE 256 -static __initdata DEFINE_SPINLOCK(launch_lock); +static __cpuinitdata DEFINE_SPINLOCK(launch_lock); -static unsigned long secondary_sp __initdata; -static unsigned long secondary_gp __initdata; +static unsigned long secondary_sp __cpuinitdata; +static unsigned long secondary_gp __cpuinitdata; static unsigned char launchstack[LAUNCHSTACK_SIZE] __initdata __attribute__((aligned(2 * sizeof(long)))); diff --git a/arch/mips/sgi-ip27/ip27-init.c b/arch/mips/sgi-ip27/ip27-init.c index a49e7c85f7241adce41c47eab083d41c267544c5..7093e7c573a42d0f06b689417792490ef37ee5f6 100644 --- a/arch/mips/sgi-ip27/ip27-init.c +++ b/arch/mips/sgi-ip27/ip27-init.c @@ -53,7 +53,7 @@ extern void pcibr_setup(cnodeid_t); extern void xtalk_probe_node(cnodeid_t nid); -static void __init per_hub_init(cnodeid_t cnode) +static void __cpuinit per_hub_init(cnodeid_t cnode) { struct hub_data *hub = hub_data(cnode); nasid_t nasid = COMPACT_TO_NASID_NODEID(cnode); diff --git a/arch/mips/sgi-ip27/ip27-timer.c b/arch/mips/sgi-ip27/ip27-timer.c index 08d45369be45c40a4895a00c9c831e109de9fd7f..25d3baf0ebc4362a8c6cb02fa11468759c0f0b28 100644 --- a/arch/mips/sgi-ip27/ip27-timer.c +++ b/arch/mips/sgi-ip27/ip27-timer.c @@ -285,7 +285,7 @@ void __cpuinit cpu_time_init(void) set_c0_status(SRB_TIMOCLK); } -void __init hub_rtc_init(cnodeid_t cnode) +void __cpuinit hub_rtc_init(cnodeid_t cnode) { /* * We only need to initialize the current node. diff --git a/arch/mips/sgi-ip27/ip27-xtalk.c b/arch/mips/sgi-ip27/ip27-xtalk.c index fc82f34a32ceead327291ec709988fc3d4943b34..6ae64e8dfc408473ddd9f34ee569886f8c0abac3 100644 --- a/arch/mips/sgi-ip27/ip27-xtalk.c +++ b/arch/mips/sgi-ip27/ip27-xtalk.c @@ -22,7 +22,7 @@ extern int bridge_probe(nasid_t nasid, int widget, int masterwid); -static int __init probe_one_port(nasid_t nasid, int widget, int masterwid) +static int __cpuinit probe_one_port(nasid_t nasid, int widget, int masterwid) { widgetreg_t widget_id; xwidget_part_num_t partnum; @@ -46,7 +46,7 @@ static int __init probe_one_port(nasid_t nasid, int widget, int masterwid) return 0; } -static int __init xbow_probe(nasid_t nasid) +static int __cpuinit xbow_probe(nasid_t nasid) { lboard_t *brd; klxbow_t *xbow_p; @@ -99,7 +99,7 @@ static int __init xbow_probe(nasid_t nasid) return 0; } -void __init xtalk_probe_node(cnodeid_t nid) +void __cpuinit xtalk_probe_node(cnodeid_t nid) { volatile u64 hubreg; nasid_t nasid; diff --git a/arch/parisc/Makefile b/arch/parisc/Makefile index e574de4efb36c2e588ad93d8ab6c5637551bdff1..5ddad7bd60ac8740de6712aabd6c274fc1fb435d 100644 --- a/arch/parisc/Makefile +++ b/arch/parisc/Makefile @@ -16,6 +16,9 @@ # Modified for PA-RISC Linux by Paul Lahaie, Alex deVries, # Mike Shaver, Helge Deller and Martin K. Petersen # + +KBUILD_DEFCONFIG := default_defconfig + NM = sh $(srctree)/arch/parisc/nm CHECKFLAGS += -D__hppa__=1 diff --git a/arch/parisc/defconfig b/arch/parisc/configs/default_defconfig similarity index 100% rename from arch/parisc/defconfig rename to arch/parisc/configs/default_defconfig diff --git a/arch/parisc/kernel/firmware.c b/arch/parisc/kernel/firmware.c index 4ab83d56974dcc88381ea4267c5ebb71fb69ddac..7177a6cd1b7f58b0fcc83f60ea5c11cf1bd96e1a 100644 --- a/arch/parisc/kernel/firmware.c +++ b/arch/parisc/kernel/firmware.c @@ -1080,6 +1080,9 @@ void pdc_io_reset_devices(void) spin_unlock_irqrestore(&pdc_lock, flags); } +/* locked by pdc_console_lock */ +static int __attribute__((aligned(8))) iodc_retbuf[32]; +static char __attribute__((aligned(64))) iodc_dbuf[4096]; /** * pdc_iodc_print - Console print using IODC. @@ -1091,24 +1094,20 @@ void pdc_io_reset_devices(void) * Since the HP console requires CR+LF to perform a 'newline', we translate * "\n" to "\r\n". */ -int pdc_iodc_print(unsigned char *str, unsigned count) +int pdc_iodc_print(const unsigned char *str, unsigned count) { - /* XXX Should we spinlock posx usage */ static int posx; /* for simple TAB-Simulation... */ - int __attribute__((aligned(8))) iodc_retbuf[32]; - char __attribute__((aligned(64))) iodc_dbuf[4096]; unsigned int i; unsigned long flags; - memset(iodc_dbuf, 0, 4096); - for (i = 0; i < count && i < 2048;) { + for (i = 0; i < count && i < 79;) { switch(str[i]) { case '\n': iodc_dbuf[i+0] = '\r'; iodc_dbuf[i+1] = '\n'; i += 2; posx = 0; - break; + goto print; case '\t': while (posx & 7) { iodc_dbuf[i] = ' '; @@ -1124,6 +1123,16 @@ int pdc_iodc_print(unsigned char *str, unsigned count) } } + /* if we're at the end of line, and not already inserting a newline, + * insert one anyway. iodc console doesn't claim to support >79 char + * lines. don't account for this in the return value. + */ + if (i == 79 && iodc_dbuf[i-1] != '\n') { + iodc_dbuf[i+0] = '\r'; + iodc_dbuf[i+1] = '\n'; + } + +print: spin_lock_irqsave(&pdc_lock, flags); real32_call(PAGE0->mem_cons.iodc_io, (unsigned long)PAGE0->mem_cons.hpa, ENTRY_IO_COUT, @@ -1142,11 +1151,9 @@ int pdc_iodc_print(unsigned char *str, unsigned count) */ int pdc_iodc_getc(void) { - unsigned long flags; - static int __attribute__((aligned(8))) iodc_retbuf[32]; - static char __attribute__((aligned(64))) iodc_dbuf[4096]; int ch; int status; + unsigned long flags; /* Bail if no console input device. */ if (!PAGE0->mem_kbd.iodc_io) diff --git a/arch/parisc/kernel/hardware.c b/arch/parisc/kernel/hardware.c index 84b9611a92285b8edcbab9fffc20fdbca6662d7c..f48a640b55fbe553fd191eace94be5a8d66aa0cf 100644 --- a/arch/parisc/kernel/hardware.c +++ b/arch/parisc/kernel/hardware.c @@ -274,7 +274,18 @@ static struct hp_hardware hp_hardware_list[] __devinitdata = { {HPHW_NPROC,0x887,0x4,0x91,"Storm Peak Slow"}, {HPHW_NPROC,0x888,0x4,0x91,"Storm Peak Fast DC-"}, {HPHW_NPROC,0x889,0x4,0x91,"Storm Peak Fast"}, - {HPHW_NPROC,0x88A,0x4,0x91,"Crestone Peak"}, + {HPHW_NPROC,0x88A,0x4,0x91,"Crestone Peak Slow"}, + {HPHW_NPROC,0x88C,0x4,0x91,"Orca Mako+"}, + {HPHW_NPROC,0x88D,0x4,0x91,"Rainier/Medel Mako+ Slow"}, + {HPHW_NPROC,0x88E,0x4,0x91,"Rainier/Medel Mako+ Fast"}, + {HPHW_NPROC,0x894,0x4,0x91,"Mt. Hamilton Fast Mako+"}, + {HPHW_NPROC,0x895,0x4,0x91,"Storm Peak Slow Mako+"}, + {HPHW_NPROC,0x896,0x4,0x91,"Storm Peak Fast Mako+"}, + {HPHW_NPROC,0x897,0x4,0x91,"Storm Peak DC- Slow Mako+"}, + {HPHW_NPROC,0x898,0x4,0x91,"Storm Peak DC- Fast Mako+"}, + {HPHW_NPROC,0x899,0x4,0x91,"Mt. Hamilton Slow Mako+"}, + {HPHW_NPROC,0x89B,0x4,0x91,"Crestone Peak Mako+ Slow"}, + {HPHW_NPROC,0x89C,0x4,0x91,"Crestone Peak Mako+ Fast"}, {HPHW_A_DIRECT, 0x004, 0x0000D, 0x00, "Arrakis MUX"}, {HPHW_A_DIRECT, 0x005, 0x0000D, 0x00, "Dyun Kiuh MUX"}, {HPHW_A_DIRECT, 0x006, 0x0000D, 0x00, "Baat Kiuh AP/MUX (40299B)"}, diff --git a/arch/parisc/kernel/head.S b/arch/parisc/kernel/head.S index a7b8859488bb9ca7014746151a8d1f2a766a71be..ec2482dc1beb39f4a62a7e17c28b7238d8291709 100644 --- a/arch/parisc/kernel/head.S +++ b/arch/parisc/kernel/head.S @@ -20,10 +20,11 @@ #include #include +#include .level LEVEL - .data + __INITDATA ENTRY(boot_args) .word 0 /* arg0 */ .word 0 /* arg1 */ @@ -31,7 +32,7 @@ ENTRY(boot_args) .word 0 /* arg3 */ END(boot_args) - .text + .section .text.head .align 4 .import init_thread_union,data .import fault_vector_20,code /* IVA parisc 2.0 32 bit */ @@ -343,7 +344,7 @@ smp_slave_stext: ENDPROC(stext) #ifndef CONFIG_64BIT - .data + .section .data.read_mostly .align 4 .export $global$,data diff --git a/arch/parisc/kernel/pdc_cons.c b/arch/parisc/kernel/pdc_cons.c index 33b1f84441b14e4076e077432c1212cd74b681a3..ccb68090781efdc24b553ce9e6162899ed349c03 100644 --- a/arch/parisc/kernel/pdc_cons.c +++ b/arch/parisc/kernel/pdc_cons.c @@ -52,28 +52,30 @@ #include #include /* for iodc_call() proto and friends */ +static spinlock_t pdc_console_lock = SPIN_LOCK_UNLOCKED; static void pdc_console_write(struct console *co, const char *s, unsigned count) { - pdc_iodc_print(s, count); + int i = 0; + unsigned long flags; + + spin_lock_irqsave(&pdc_console_lock, flags); + do { + i += pdc_iodc_print(s + i, count - i); + } while (i < count); + spin_unlock_irqrestore(&pdc_console_lock, flags); } -void pdc_printf(const char *fmt, ...) +int pdc_console_poll_key(struct console *co) { - va_list args; - char buf[1024]; - int i, len; - - va_start(args, fmt); - len = vscnprintf(buf, sizeof(buf), fmt, args); - va_end(args); + int c; + unsigned long flags; - pdc_iodc_print(buf, len); -} + spin_lock_irqsave(&pdc_console_lock, flags); + c = pdc_iodc_getc(); + spin_unlock_irqrestore(&pdc_console_lock, flags); -int pdc_console_poll_key(struct console *co) -{ - return pdc_iodc_getc(); + return c; } static int pdc_console_setup(struct console *co, char *options) diff --git a/arch/parisc/kernel/syscall_table.S b/arch/parisc/kernel/syscall_table.S index 117438e9eb2a8329a932c17b5b184095982c39dc..6b5ac38f5a9916017473d3174bb6f3d047f72cb8 100644 --- a/arch/parisc/kernel/syscall_table.S +++ b/arch/parisc/kernel/syscall_table.S @@ -401,9 +401,12 @@ ENTRY_COMP(kexec_load) /* 300 */ ENTRY_COMP(utimensat) ENTRY_COMP(signalfd) - ENTRY_COMP(timerfd) + ENTRY_SAME(ni_syscall) /* was timerfd */ ENTRY_SAME(eventfd) ENTRY_COMP(fallocate) /* 305 */ + ENTRY_SAME(timerfd_create) + ENTRY_COMP(timerfd_settime) + ENTRY_COMP(timerfd_gettime) /* Nothing yet */ diff --git a/arch/parisc/kernel/traps.c b/arch/parisc/kernel/traps.c index 99fd56939afa73909f4aabbe9fe88a490afa3748..9dc6dc42f9cfb151e5d827338c9e27431e40c58d 100644 --- a/arch/parisc/kernel/traps.c +++ b/arch/parisc/kernel/traps.c @@ -51,6 +51,9 @@ DEFINE_SPINLOCK(pa_dbit_lock); #endif +void parisc_show_stack(struct task_struct *t, unsigned long *sp, + struct pt_regs *regs); + static int printbinary(char *buf, unsigned long x, int nbits) { unsigned long mask = 1UL << (nbits - 1); @@ -148,6 +151,8 @@ void show_regs(struct pt_regs *regs) print_symbol(" IAOQ[1]: %s\n", regs->iaoq[1]); printk(level); print_symbol(" RP(r2): %s\n", regs->gr[2]); + + parisc_show_stack(current, NULL, regs); } @@ -181,11 +186,19 @@ static void do_show_stack(struct unwind_frame_info *info) printk("\n"); } -void show_stack(struct task_struct *task, unsigned long *s) +void parisc_show_stack(struct task_struct *task, unsigned long *sp, + struct pt_regs *regs) { struct unwind_frame_info info; + struct task_struct *t; + + t = task ? task : current; + if (regs) { + unwind_frame_init(&info, t, regs); + goto show_stack; + } - if (!task) { + if (t == current) { unsigned long sp; HERE: @@ -201,12 +214,18 @@ HERE: unwind_frame_init(&info, current, &r); } } else { - unwind_frame_init_from_blocked_task(&info, task); + unwind_frame_init_from_blocked_task(&info, t); } +show_stack: do_show_stack(&info); } +void show_stack(struct task_struct *t, unsigned long *sp) +{ + return parisc_show_stack(t, sp, NULL); +} + int is_valid_bugaddr(unsigned long iaoq) { return 1; diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index 5b8d8382b7629e93ccdb07a7d86b96049f587e38..1189d8d6170d252013ddcf112903073297308da7 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig @@ -90,6 +90,7 @@ config PPC select HAVE_IDE select HAVE_OPROFILE select HAVE_KPROBES + select HAVE_KRETPROBES config EARLY_PRINTK bool diff --git a/arch/powerpc/Makefile b/arch/powerpc/Makefile index 1c6ce3536e4cf15e88d1a0138bd26daada9251f5..ab5cfe8ef988f53361b42c418e477f36eb94b32d 100644 --- a/arch/powerpc/Makefile +++ b/arch/powerpc/Makefile @@ -155,7 +155,7 @@ all: zImage CPPFLAGS_vmlinux.lds := -Upowerpc -BOOT_TARGETS = zImage zImage.initrd uImage treeImage.% cuImage.% +BOOT_TARGETS = zImage zImage.initrd uImage zImage% dtbImage% treeImage.% cuImage.% PHONY += $(BOOT_TARGETS) diff --git a/arch/powerpc/boot/Makefile b/arch/powerpc/boot/Makefile index e3993a607584825fafffc5d5043c5f6599be4b2f..4974d9e56ead1d02176111e5de1e2de6ea3f31b3 100644 --- a/arch/powerpc/boot/Makefile +++ b/arch/powerpc/boot/Makefile @@ -186,7 +186,7 @@ quiet_cmd_wrap = WRAP $@ image-$(CONFIG_PPC_PSERIES) += zImage.pseries image-$(CONFIG_PPC_MAPLE) += zImage.pseries image-$(CONFIG_PPC_IBM_CELL_BLADE) += zImage.pseries -image-$(CONFIG_PPC_PS3) += zImage-dtb.ps3 +image-$(CONFIG_PPC_PS3) += dtbImage.ps3 image-$(CONFIG_PPC_CELLEB) += zImage.pseries image-$(CONFIG_PPC_CHRP) += zImage.chrp image-$(CONFIG_PPC_EFIKA) += zImage.chrp @@ -205,7 +205,7 @@ image-$(CONFIG_DEFAULT_UIMAGE) += uImage # # Board ports in arch/powerpc/platform/40x/Kconfig -image-$(CONFIG_EP405) += zImage-dtb.ep405 +image-$(CONFIG_EP405) += dtbImage.ep405 image-$(CONFIG_WALNUT) += treeImage.walnut # Board ports in arch/powerpc/platform/44x/Kconfig @@ -220,9 +220,9 @@ image-$(CONFIG_WARP) += cuImage.warp # Board ports in arch/powerpc/platform/8xx/Kconfig image-$(CONFIG_PPC_MPC86XADS) += cuImage.mpc866ads image-$(CONFIG_PPC_MPC885ADS) += cuImage.mpc885ads -image-$(CONFIG_PPC_EP88XC) += zImage-dtb.ep88xc +image-$(CONFIG_PPC_EP88XC) += dtbImage.ep88xc image-$(CONFIG_PPC_ADDER875) += cuImage.adder875-uboot \ - zImage-dtb.adder875-redboot + dtbImage.adder875-redboot # Board ports in arch/powerpc/platform/52xx/Kconfig image-$(CONFIG_PPC_LITE5200) += cuImage.lite5200 cuImage.lite5200b @@ -230,7 +230,7 @@ image-$(CONFIG_PPC_LITE5200) += cuImage.lite5200 cuImage.lite5200b # Board ports in arch/powerpc/platform/82xx/Kconfig image-$(CONFIG_MPC8272_ADS) += cuImage.mpc8272ads image-$(CONFIG_PQ2FADS) += cuImage.pq2fads -image-$(CONFIG_EP8248E) += zImage-dtb.ep8248e +image-$(CONFIG_EP8248E) += dtbImage.ep8248e # Board ports in arch/powerpc/platform/83xx/Kconfig image-$(CONFIG_MPC832x_MDS) += cuImage.mpc832x_mds @@ -268,7 +268,8 @@ endif initrd- := $(patsubst zImage%, zImage.initrd%, $(image-n) $(image-)) initrd-y := $(patsubst zImage%, zImage.initrd%, \ - $(patsubst treeImage%, treeImage.initrd%, $(image-y))) + $(patsubst dtbImage%, dtbImage.initrd%, \ + $(patsubst treeImage%, treeImage.initrd%, $(image-y)))) initrd-y := $(filter-out $(image-y), $(initrd-y)) targets += $(image-y) $(initrd-y) @@ -283,10 +284,11 @@ $(obj)/zImage.initrd.%: vmlinux $(wrapperbits) $(obj)/zImage.%: vmlinux $(wrapperbits) $(call if_changed,wrap,$*) -$(obj)/zImage-dtb.initrd.%: vmlinux $(wrapperbits) $(dtstree)/%.dts +# dtbImage% - a dtbImage is a zImage with an embedded device tree blob +$(obj)/dtbImage.initrd.%: vmlinux $(wrapperbits) $(dtstree)/%.dts $(call if_changed,wrap,$*,$(dtstree)/$*.dts,,$(obj)/ramdisk.image.gz) -$(obj)/zImage-dtb.%: vmlinux $(wrapperbits) $(dtstree)/%.dts +$(obj)/dtbImage.%: vmlinux $(wrapperbits) $(dtstree)/%.dts $(call if_changed,wrap,$*,$(dtstree)/$*.dts) # This cannot be in the root of $(src) as the zImage rule always adds a $(obj) diff --git a/arch/powerpc/boot/cuboot-bamboo.c b/arch/powerpc/boot/cuboot-bamboo.c index 900c7ff2b7e985d4aa679fccb1fa230a480cbf29..b5c30f766c401fa0828e61fd10d0c0c8b48a6e80 100644 --- a/arch/powerpc/boot/cuboot-bamboo.c +++ b/arch/powerpc/boot/cuboot-bamboo.c @@ -17,6 +17,7 @@ #include "44x.h" #include "cuboot.h" +#define TARGET_4xx #define TARGET_44x #include "ppcboot.h" diff --git a/arch/powerpc/boot/cuboot-ebony.c b/arch/powerpc/boot/cuboot-ebony.c index c5f37ce172ea92654a7509c72680de4bf55c26ef..56564ba37f62d1d7a7aba46ff94362627c8f8f69 100644 --- a/arch/powerpc/boot/cuboot-ebony.c +++ b/arch/powerpc/boot/cuboot-ebony.c @@ -17,6 +17,7 @@ #include "44x.h" #include "cuboot.h" +#define TARGET_4xx #define TARGET_44x #include "ppcboot.h" diff --git a/arch/powerpc/boot/cuboot-katmai.c b/arch/powerpc/boot/cuboot-katmai.c index c021167f938122078f3c4081f626c8482099df07..5434d70b56605670e041834d326ab9cb72a561f5 100644 --- a/arch/powerpc/boot/cuboot-katmai.c +++ b/arch/powerpc/boot/cuboot-katmai.c @@ -22,6 +22,7 @@ #include "44x.h" #include "cuboot.h" +#define TARGET_4xx #define TARGET_44x #include "ppcboot.h" diff --git a/arch/powerpc/boot/cuboot-taishan.c b/arch/powerpc/boot/cuboot-taishan.c index f66455a45ab1cfcbf17f5bfbd391f0fb3e37cd37..b55b80467eed9b23e70d7347e134745723116af1 100644 --- a/arch/powerpc/boot/cuboot-taishan.c +++ b/arch/powerpc/boot/cuboot-taishan.c @@ -21,7 +21,9 @@ #include "dcr.h" #include "4xx.h" +#define TARGET_4xx #define TARGET_44x +#define TARGET_440GX #include "ppcboot.h" static bd_t bd; diff --git a/arch/powerpc/boot/cuboot-warp.c b/arch/powerpc/boot/cuboot-warp.c index bdedebe1bc1434180527101c5085f386d9b12dc4..3db93e85e9eaa65cc954bfdf0384d3e273b761f0 100644 --- a/arch/powerpc/boot/cuboot-warp.c +++ b/arch/powerpc/boot/cuboot-warp.c @@ -11,6 +11,7 @@ #include "4xx.h" #include "cuboot.h" +#define TARGET_4xx #define TARGET_44x #include "ppcboot.h" diff --git a/arch/powerpc/boot/dts/haleakala.dts b/arch/powerpc/boot/dts/haleakala.dts index 5dd3d15f0febabfaf212ad2b4fd5ad8433e53171..ae68fefc01b6a054b62eaaaffde5930e983e72dc 100644 --- a/arch/powerpc/boot/dts/haleakala.dts +++ b/arch/powerpc/boot/dts/haleakala.dts @@ -235,7 +235,7 @@ #interrupt-cells = <1>; #size-cells = <2>; #address-cells = <3>; - compatible = "ibm,plb-pciex-405exr", "ibm,plb-pciex"; + compatible = "ibm,plb-pciex-405ex", "ibm,plb-pciex"; primary; port = <0>; /* port number */ reg = ; /* Filled in by zImage */ i-cache-line-size = <20>; d-cache-line-size = <20>; - i-cache-size = <20000>; - d-cache-size = <20000>; + i-cache-size = <8000>; + d-cache-size = <8000>; dcr-controller; dcr-access-method = "native"; }; @@ -136,11 +136,11 @@ }; POB0: opb { - compatible = "ibm,opb-440spe", "ibm,opb-440gp", "ibm,opb"; + compatible = "ibm,opb-440spe", "ibm,opb-440gp", "ibm,opb"; #address-cells = <1>; #size-cells = <1>; - ranges = <00000000 4 e0000000 20000000>; - clock-frequency = <0>; /* Filled in by zImage */ + ranges = <00000000 4 e0000000 20000000>; + clock-frequency = <0>; /* Filled in by zImage */ EBC0: ebc { compatible = "ibm,ebc-440spe", "ibm,ebc-440gp", "ibm,ebc"; @@ -153,38 +153,38 @@ }; UART0: serial@10000200 { - device_type = "serial"; - compatible = "ns16550"; - reg = <10000200 8>; + device_type = "serial"; + compatible = "ns16550"; + reg = <10000200 8>; virtual-reg = ; - clock-frequency = <0>; /* Filled in by zImage */ - current-speed = <1c200>; - interrupt-parent = <&UIC0>; - interrupts = <0 4>; - }; + clock-frequency = <0>; /* Filled in by zImage */ + current-speed = <1c200>; + interrupt-parent = <&UIC0>; + interrupts = <0 4>; + }; UART1: serial@10000300 { - device_type = "serial"; - compatible = "ns16550"; - reg = <10000300 8>; + device_type = "serial"; + compatible = "ns16550"; + reg = <10000300 8>; virtual-reg = ; - clock-frequency = <0>; - current-speed = <0>; - interrupt-parent = <&UIC0>; - interrupts = <1 4>; - }; + clock-frequency = <0>; + current-speed = <0>; + interrupt-parent = <&UIC0>; + interrupts = <1 4>; + }; UART2: serial@10000600 { - device_type = "serial"; - compatible = "ns16550"; - reg = <10000600 8>; + device_type = "serial"; + compatible = "ns16550"; + reg = <10000600 8>; virtual-reg = ; - clock-frequency = <0>; - current-speed = <0>; - interrupt-parent = <&UIC1>; - interrupts = <5 4>; - }; + clock-frequency = <0>; + current-speed = <0>; + interrupt-parent = <&UIC1>; + interrupts = <5 4>; + }; IIC0: i2c@10000400 { compatible = "ibm,iic-440spe", "ibm,iic-440gp", "ibm,iic"; diff --git a/arch/powerpc/boot/dts/mpc8377_mds.dts b/arch/powerpc/boot/dts/mpc8377_mds.dts index a3637fff73ccea43951ccca804d4e62e4452a376..49c05e97386cfccfd520e3ab17de4d0c2b787bba 100644 --- a/arch/powerpc/boot/dts/mpc8377_mds.dts +++ b/arch/powerpc/boot/dts/mpc8377_mds.dts @@ -47,6 +47,72 @@ reg = <0x00000000 0x20000000>; // 512MB at 0 }; + localbus@e0005000 { + #address-cells = <2>; + #size-cells = <1>; + compatible = "fsl,mpc8377-elbc", "fsl,elbc", "simple-bus"; + reg = <0xe0005000 0x1000>; + interrupts = <77 0x8>; + interrupt-parent = <&ipic>; + + // booting from NOR flash + ranges = <0 0x0 0xfe000000 0x02000000 + 1 0x0 0xf8000000 0x00008000 + 3 0x0 0xe0600000 0x00008000>; + + flash@0,0 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "cfi-flash"; + reg = <0 0x0 0x2000000>; + bank-width = <2>; + device-width = <1>; + + u-boot@0 { + reg = <0x0 0x100000>; + read-only; + }; + + fs@100000 { + reg = <0x100000 0x800000>; + }; + + kernel@1d00000 { + reg = <0x1d00000 0x200000>; + }; + + dtb@1f00000 { + reg = <0x1f00000 0x100000>; + }; + }; + + bcsr@1,0 { + reg = <1 0x0 0x8000>; + compatible = "fsl,mpc837xmds-bcsr"; + }; + + nand@3,0 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "fsl,mpc8377-fcm-nand", + "fsl,elbc-fcm-nand"; + reg = <3 0x0 0x8000>; + + u-boot@0 { + reg = <0x0 0x100000>; + read-only; + }; + + kernel@100000 { + reg = <0x100000 0x300000>; + }; + + fs@400000 { + reg = <0x400000 0x1c00000>; + }; + }; + }; + soc@e0000000 { #address-cells = <1>; #size-cells = <1>; @@ -91,7 +157,6 @@ mode = "cpu"; }; - /* phy type (ULPI, UTMI, UTMI_WIDE, SERIAL) */ usb@23000 { compatible = "fsl-usb2-dr"; reg = <0x23000 0x1000>; @@ -99,7 +164,8 @@ #size-cells = <0>; interrupt-parent = <&ipic>; interrupts = <38 0x8>; - phy_type = "utmi_wide"; + dr_mode = "host"; + phy_type = "ulpi"; }; mdio@24520 { diff --git a/arch/powerpc/boot/dts/mpc8378_mds.dts b/arch/powerpc/boot/dts/mpc8378_mds.dts index 533e9b06cc8f7f11a62ce17e2e81ed291d62fa85..1d6ea080ad730d6224caecf1d185a9b69e1aeea0 100644 --- a/arch/powerpc/boot/dts/mpc8378_mds.dts +++ b/arch/powerpc/boot/dts/mpc8378_mds.dts @@ -47,6 +47,72 @@ reg = <0x00000000 0x20000000>; // 512MB at 0 }; + localbus@e0005000 { + #address-cells = <2>; + #size-cells = <1>; + compatible = "fsl,mpc8378-elbc", "fsl,elbc", "simple-bus"; + reg = <0xe0005000 0x1000>; + interrupts = <77 0x8>; + interrupt-parent = <&ipic>; + + // booting from NOR flash + ranges = <0 0x0 0xfe000000 0x02000000 + 1 0x0 0xf8000000 0x00008000 + 3 0x0 0xe0600000 0x00008000>; + + flash@0,0 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "cfi-flash"; + reg = <0 0x0 0x2000000>; + bank-width = <2>; + device-width = <1>; + + u-boot@0 { + reg = <0x0 0x100000>; + read-only; + }; + + fs@100000 { + reg = <0x100000 0x800000>; + }; + + kernel@1d00000 { + reg = <0x1d00000 0x200000>; + }; + + dtb@1f00000 { + reg = <0x1f00000 0x100000>; + }; + }; + + bcsr@1,0 { + reg = <1 0x0 0x8000>; + compatible = "fsl,mpc837xmds-bcsr"; + }; + + nand@3,0 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "fsl,mpc8378-fcm-nand", + "fsl,elbc-fcm-nand"; + reg = <3 0x0 0x8000>; + + u-boot@0 { + reg = <0x0 0x100000>; + read-only; + }; + + kernel@100000 { + reg = <0x100000 0x300000>; + }; + + fs@400000 { + reg = <0x400000 0x1c00000>; + }; + }; + }; + soc@e0000000 { #address-cells = <1>; #size-cells = <1>; @@ -91,7 +157,6 @@ mode = "cpu"; }; - /* phy type (ULPI, UTMI, UTMI_WIDE, SERIAL) */ usb@23000 { compatible = "fsl-usb2-dr"; reg = <0x23000 0x1000>; @@ -99,7 +164,8 @@ #size-cells = <0>; interrupt-parent = <&ipic>; interrupts = <38 0x8>; - phy_type = "utmi_wide"; + dr_mode = "host"; + phy_type = "ulpi"; }; mdio@24520 { diff --git a/arch/powerpc/boot/dts/mpc8379_mds.dts b/arch/powerpc/boot/dts/mpc8379_mds.dts index c270685bbde4d26e53a12a0bc6bf43282997501b..fdb4a9255b24ab5a3070a578f03f427d1b27055b 100644 --- a/arch/powerpc/boot/dts/mpc8379_mds.dts +++ b/arch/powerpc/boot/dts/mpc8379_mds.dts @@ -47,6 +47,72 @@ reg = <0x00000000 0x20000000>; // 512MB at 0 }; + localbus@e0005000 { + #address-cells = <2>; + #size-cells = <1>; + compatible = "fsl,mpc8379-elbc", "fsl,elbc", "simple-bus"; + reg = <0xe0005000 0x1000>; + interrupts = <77 0x8>; + interrupt-parent = <&ipic>; + + // booting from NOR flash + ranges = <0 0x0 0xfe000000 0x02000000 + 1 0x0 0xf8000000 0x00008000 + 3 0x0 0xe0600000 0x00008000>; + + flash@0,0 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "cfi-flash"; + reg = <0 0x0 0x2000000>; + bank-width = <2>; + device-width = <1>; + + u-boot@0 { + reg = <0x0 0x100000>; + read-only; + }; + + fs@100000 { + reg = <0x100000 0x800000>; + }; + + kernel@1d00000 { + reg = <0x1d00000 0x200000>; + }; + + dtb@1f00000 { + reg = <0x1f00000 0x100000>; + }; + }; + + bcsr@1,0 { + reg = <1 0x0 0x8000>; + compatible = "fsl,mpc837xmds-bcsr"; + }; + + nand@3,0 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "fsl,mpc8379-fcm-nand", + "fsl,elbc-fcm-nand"; + reg = <3 0x0 0x8000>; + + u-boot@0 { + reg = <0x0 0x100000>; + read-only; + }; + + kernel@100000 { + reg = <0x100000 0x300000>; + }; + + fs@400000 { + reg = <0x400000 0x1c00000>; + }; + }; + }; + soc@e0000000 { #address-cells = <1>; #size-cells = <1>; @@ -91,7 +157,6 @@ mode = "cpu"; }; - /* phy type (ULPI, UTMI, UTMI_WIDE, SERIAL) */ usb@23000 { compatible = "fsl-usb2-dr"; reg = <0x23000 0x1000>; @@ -99,7 +164,8 @@ #size-cells = <0>; interrupt-parent = <&ipic>; interrupts = <38 0x8>; - phy_type = "utmi_wide"; + dr_mode = "host"; + phy_type = "ulpi"; }; mdio@24520 { diff --git a/arch/powerpc/boot/dts/sbc8548.dts b/arch/powerpc/boot/dts/sbc8548.dts index 14be38ad5d4b30f4ff3fcaa0a118680a68ba5df5..b86e65d926c16e40acffd304193018075deffa88 100644 --- a/arch/powerpc/boot/dts/sbc8548.dts +++ b/arch/powerpc/boot/dts/sbc8548.dts @@ -184,11 +184,17 @@ cell-index = <0>; interrupt-map-mask = <0xf800 0x0 0x0 0x7>; interrupt-map = < - /* IDSEL 0x01 (PCI-X slot) */ - 0x0800 0x0 0x0 0x1 &mpic 0x0 0x1 - 0x0800 0x0 0x0 0x2 &mpic 0x1 0x1 - 0x0800 0x0 0x0 0x3 &mpic 0x2 0x1 - 0x0800 0x0 0x0 0x4 &mpic 0x3 0x1>; + /* IDSEL 0x01 (PCI-X slot) @66MHz */ + 0x0800 0x0 0x0 0x1 &mpic 0x2 0x1 + 0x0800 0x0 0x0 0x2 &mpic 0x3 0x1 + 0x0800 0x0 0x0 0x3 &mpic 0x4 0x1 + 0x0800 0x0 0x0 0x4 &mpic 0x1 0x1 + + /* IDSEL 0x11 (PCI, 3.3V 32bit) @33MHz */ + 0x8800 0x0 0x0 0x1 &mpic 0x2 0x1 + 0x8800 0x0 0x0 0x2 &mpic 0x3 0x1 + 0x8800 0x0 0x0 0x3 &mpic 0x4 0x1 + 0x8800 0x0 0x0 0x4 &mpic 0x1 0x1>; interrupt-parent = <&mpic>; interrupts = <0x18 0x2>; diff --git a/arch/powerpc/boot/wrapper b/arch/powerpc/boot/wrapper index c3178155311ba1f565e8af685f61f83046b02db1..d50e498a072b99cd50af01960655a8edae9af27e 100755 --- a/arch/powerpc/boot/wrapper +++ b/arch/powerpc/boot/wrapper @@ -191,10 +191,14 @@ ps3) ksection=.kernel:vmlinux.bin isection=.kernel:initrd ;; -ep88xc|ep405|redboot*|ep8248e) +ep88xc|ep405|ep8248e) platformo="$object/fixed-head.o $object/$platform.o" binary=y ;; +adder875-redboot) + platformo="$object/fixed-head.o $object/redboot-8xx.o" + binary=y + ;; esac vmz="$tmpdir/`basename \"$kernel\"`.$ext" diff --git a/arch/powerpc/configs/adder875-uboot_defconfig b/arch/powerpc/configs/adder875-uboot_defconfig deleted file mode 100644 index 1faf7ef59a23a48730af1bff560e069d81e3b5d0..0000000000000000000000000000000000000000 --- a/arch/powerpc/configs/adder875-uboot_defconfig +++ /dev/null @@ -1,798 +0,0 @@ -# -# Automatically generated make config: don't edit -# Linux kernel version: 2.6.24-rc6 -# Thu Jan 17 16:17:18 2008 -# -# CONFIG_PPC64 is not set - -# -# Processor support -# -# CONFIG_6xx is not set -# CONFIG_PPC_85xx is not set -CONFIG_PPC_8xx=y -# CONFIG_40x is not set -# CONFIG_44x is not set -# CONFIG_E200 is not set -CONFIG_8xx=y -# CONFIG_PPC_MM_SLICES is not set -CONFIG_NOT_COHERENT_CACHE=y -CONFIG_PPC32=y -CONFIG_WORD_SIZE=32 -CONFIG_PPC_MERGE=y -CONFIG_MMU=y -CONFIG_GENERIC_CMOS_UPDATE=y -CONFIG_GENERIC_TIME=y -CONFIG_GENERIC_TIME_VSYSCALL=y -CONFIG_GENERIC_CLOCKEVENTS=y -CONFIG_GENERIC_HARDIRQS=y -CONFIG_IRQ_PER_CPU=y -CONFIG_RWSEM_XCHGADD_ALGORITHM=y -CONFIG_ARCH_HAS_ILOG2_U32=y -CONFIG_GENERIC_HWEIGHT=y -CONFIG_GENERIC_CALIBRATE_DELAY=y -CONFIG_GENERIC_FIND_NEXT_BIT=y -# CONFIG_ARCH_NO_VIRT_TO_BUS is not set -CONFIG_PPC=y -CONFIG_EARLY_PRINTK=y -CONFIG_GENERIC_NVRAM=y -CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y -CONFIG_ARCH_MAY_HAVE_PC_FDC=y -CONFIG_PPC_OF=y -CONFIG_OF=y -# CONFIG_PPC_UDBG_16550 is not set -# CONFIG_GENERIC_TBSYNC is not set -CONFIG_AUDIT_ARCH=y -CONFIG_GENERIC_BUG=y -# CONFIG_DEFAULT_UIMAGE is not set -CONFIG_REDBOOT=y -# CONFIG_PPC_DCR_NATIVE is not set -# CONFIG_PPC_DCR_MMIO is not set -CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" - -# -# General setup -# -CONFIG_EXPERIMENTAL=y -CONFIG_BROKEN_ON_SMP=y -CONFIG_INIT_ENV_ARG_LIMIT=32 -CONFIG_LOCALVERSION="" -CONFIG_LOCALVERSION_AUTO=y -# CONFIG_SWAP is not set -CONFIG_SYSVIPC=y -CONFIG_SYSVIPC_SYSCTL=y -# CONFIG_POSIX_MQUEUE is not set -# CONFIG_BSD_PROCESS_ACCT is not set -# CONFIG_TASKSTATS is not set -# CONFIG_USER_NS is not set -# CONFIG_PID_NS is not set -# CONFIG_AUDIT is not set -# CONFIG_IKCONFIG is not set -CONFIG_LOG_BUF_SHIFT=14 -# CONFIG_CGROUPS is not set -CONFIG_FAIR_GROUP_SCHED=y -CONFIG_FAIR_USER_SCHED=y -# CONFIG_FAIR_CGROUP_SCHED is not set -CONFIG_SYSFS_DEPRECATED=y -# CONFIG_RELAY is not set -# CONFIG_BLK_DEV_INITRD is not set -# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set -CONFIG_SYSCTL=y -CONFIG_EMBEDDED=y -# CONFIG_SYSCTL_SYSCALL 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 is not set -# CONFIG_BASE_FULL is not set -# CONFIG_FUTEX is not set -CONFIG_ANON_INODES=y -CONFIG_EPOLL=y -CONFIG_SIGNALFD=y -CONFIG_EVENTFD=y -CONFIG_SHMEM=y -# CONFIG_VM_EVENT_COUNTERS is not set -CONFIG_SLUB_DEBUG=y -# CONFIG_SLAB is not set -CONFIG_SLUB=y -# CONFIG_SLOB is not set -# CONFIG_TINY_SHMEM is not set -CONFIG_BASE_SMALL=1 -# CONFIG_MODULES is not set -CONFIG_BLOCK=y -# CONFIG_LBD is not set -# CONFIG_BLK_DEV_IO_TRACE is not set -# CONFIG_LSF is not set -# CONFIG_BLK_DEV_BSG is not set - -# -# IO Schedulers -# -CONFIG_IOSCHED_NOOP=y -# CONFIG_IOSCHED_AS is not set -CONFIG_IOSCHED_DEADLINE=y -# CONFIG_IOSCHED_CFQ is not set -# CONFIG_DEFAULT_AS is not set -CONFIG_DEFAULT_DEADLINE=y -# CONFIG_DEFAULT_CFQ is not set -# CONFIG_DEFAULT_NOOP is not set -CONFIG_DEFAULT_IOSCHED="deadline" - -# -# Platform support -# -# CONFIG_PPC_MPC52xx is not set -# CONFIG_PPC_MPC5200 is not set -# CONFIG_PPC_CELL is not set -# CONFIG_PPC_CELL_NATIVE is not set -CONFIG_CPM1=y -# CONFIG_MPC8XXFADS is not set -# CONFIG_MPC86XADS is not set -# CONFIG_MPC885ADS is not set -# CONFIG_PPC_EP88XC is not set -CONFIG_PPC_ADDER875=y - -# -# MPC8xx CPM Options -# - -# -# Generic MPC8xx Options -# -CONFIG_8xx_COPYBACK=y -# CONFIG_8xx_CPU6 is not set -CONFIG_8xx_CPU15=y -CONFIG_NO_UCODE_PATCH=y -# CONFIG_USB_SOF_UCODE_PATCH is not set -# CONFIG_I2C_SPI_UCODE_PATCH is not set -# CONFIG_I2C_SPI_SMC1_UCODE_PATCH is not set -# CONFIG_PQ2ADS is not set -# CONFIG_MPIC is not set -# CONFIG_MPIC_WEIRD is not set -# CONFIG_PPC_I8259 is not set -# CONFIG_PPC_RTAS is not set -# CONFIG_MMIO_NVRAM is not set -# CONFIG_PPC_MPC106 is not set -# CONFIG_PPC_970_NAP is not set -# CONFIG_PPC_INDIRECT_IO is not set -# CONFIG_GENERIC_IOMAP is not set -# CONFIG_CPU_FREQ is not set -# CONFIG_CPM2 is not set -CONFIG_PPC_CPM_NEW_BINDING=y -# CONFIG_FSL_ULI1575 is not set -CONFIG_CPM=y - -# -# Kernel options -# -# CONFIG_HIGHMEM is not set -# CONFIG_TICK_ONESHOT is not set -# CONFIG_NO_HZ is not set -# CONFIG_HIGH_RES_TIMERS is not set -CONFIG_GENERIC_CLOCKEVENTS_BUILD=y -# CONFIG_HZ_100 is not set -# CONFIG_HZ_250 is not set -# CONFIG_HZ_300 is not set -CONFIG_HZ_1000=y -CONFIG_HZ=1000 -CONFIG_PREEMPT_NONE=y -# CONFIG_PREEMPT_VOLUNTARY is not set -# CONFIG_PREEMPT is not set -CONFIG_BINFMT_ELF=y -# CONFIG_BINFMT_MISC is not set -# CONFIG_MATH_EMULATION is not set -# CONFIG_8XX_MINIMAL_FPEMU is not set -CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y -CONFIG_ARCH_FLATMEM_ENABLE=y -CONFIG_ARCH_POPULATES_NODE_MAP=y -CONFIG_SELECT_MEMORY_MODEL=y -CONFIG_FLATMEM_MANUAL=y -# CONFIG_DISCONTIGMEM_MANUAL is not set -# CONFIG_SPARSEMEM_MANUAL is not set -CONFIG_FLATMEM=y -CONFIG_FLAT_NODE_MEM_MAP=y -# CONFIG_SPARSEMEM_STATIC is not set -# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set -CONFIG_SPLIT_PTLOCK_CPUS=4 -# CONFIG_RESOURCES_64BIT is not set -CONFIG_ZONE_DMA_FLAG=1 -CONFIG_BOUNCE=y -CONFIG_VIRT_TO_BUS=y -# CONFIG_PROC_DEVICETREE is not set -# CONFIG_CMDLINE_BOOL is not set -# CONFIG_PM is not set -CONFIG_SUSPEND_UP_POSSIBLE=y -CONFIG_HIBERNATION_UP_POSSIBLE=y -# CONFIG_SECCOMP is not set -CONFIG_WANT_DEVICE_TREE=y -CONFIG_DEVICE_TREE="adder875-uboot.dts" -CONFIG_ISA_DMA_API=y - -# -# Bus options -# -CONFIG_ZONE_DMA=y -CONFIG_FSL_SOC=y -# CONFIG_PCI is not set -# CONFIG_PCI_DOMAINS is not set -# CONFIG_PCI_SYSCALL is not set -# CONFIG_PCI_QSPAN is not set -# CONFIG_ARCH_SUPPORTS_MSI is not set -# CONFIG_PCCARD is not set - -# -# Advanced setup -# -# CONFIG_ADVANCED_OPTIONS is not set - -# -# Default settings for advanced configuration options are used -# -CONFIG_HIGHMEM_START=0xfe000000 -CONFIG_LOWMEM_SIZE=0x30000000 -CONFIG_KERNEL_START=0xc0000000 -CONFIG_TASK_SIZE=0x80000000 -CONFIG_CONSISTENT_START=0xfd000000 -CONFIG_CONSISTENT_SIZE=0x00200000 -CONFIG_BOOT_LOAD=0x00400000 - -# -# Networking -# -CONFIG_NET=y - -# -# Networking options -# -CONFIG_PACKET=y -# CONFIG_PACKET_MMAP 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_FIB_HASH=y -CONFIG_IP_PNP=y -# CONFIG_IP_PNP_DHCP is not set -# CONFIG_IP_PNP_BOOTP is not set -# 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=y -# 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_XFRM_MODE_TRANSPORT is not set -# CONFIG_INET_XFRM_MODE_TUNNEL is not set -# CONFIG_INET_XFRM_MODE_BEET is not set -# CONFIG_INET_LRO is not set -CONFIG_INET_DIAG=y -CONFIG_INET_TCP_DIAG=y -# CONFIG_TCP_CONG_ADVANCED is not set -CONFIG_TCP_CONG_CUBIC=y -CONFIG_DEFAULT_TCP_CONG="cubic" -# CONFIG_TCP_MD5SIG is not set -# CONFIG_IPV6 is not set -# CONFIG_INET6_XFRM_TUNNEL is not set -# CONFIG_INET6_TUNNEL is not set -# CONFIG_NETWORK_SECMARK is not set -# CONFIG_NETFILTER is not set -# CONFIG_IP_DCCP is not set -# CONFIG_IP_SCTP is not set -# 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_ECONET is not set -# CONFIG_WAN_ROUTER is not set -# 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_AF_RXRPC is not set - -# -# Wireless -# -# CONFIG_CFG80211 is not set -# CONFIG_WIRELESS_EXT is not set -# CONFIG_MAC80211 is not set -# CONFIG_IEEE80211 is not set -# CONFIG_RFKILL is not set -# CONFIG_NET_9P is not set - -# -# Device Drivers -# - -# -# Generic Driver Options -# -CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" -CONFIG_STANDALONE=y -CONFIG_PREVENT_FIRMWARE_BUILD=y -# CONFIG_FW_LOADER is not set -# CONFIG_DEBUG_DRIVER is not set -# CONFIG_DEBUG_DEVRES is not set -# CONFIG_SYS_HYPERVISOR is not set -# CONFIG_CONNECTOR is not set -CONFIG_MTD=y -# CONFIG_MTD_DEBUG is not set -# CONFIG_MTD_CONCAT is not set -# CONFIG_MTD_PARTITIONS is not set - -# -# User Modules And Translation Layers -# -CONFIG_MTD_CHAR=y -CONFIG_MTD_BLKDEVS=y -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 -# CONFIG_SSFDC is not set -# CONFIG_MTD_OOPS is not set - -# -# RAM/ROM/Flash chip drivers -# -CONFIG_MTD_CFI=y -# CONFIG_MTD_JEDECPROBE is not set -CONFIG_MTD_GEN_PROBE=y -# CONFIG_MTD_CFI_ADV_OPTIONS is not set -CONFIG_MTD_MAP_BANK_WIDTH_1=y -CONFIG_MTD_MAP_BANK_WIDTH_2=y -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_I8 is not set -# CONFIG_MTD_CFI_INTELEXT is not set -CONFIG_MTD_CFI_AMDSTD=y -# 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 - -# -# Mapping drivers for chip access -# -# CONFIG_MTD_COMPLEX_MAPPINGS is not set -# CONFIG_MTD_PHYSMAP is not set -CONFIG_MTD_PHYSMAP_OF=y -# CONFIG_MTD_CFI_FLAGADM is not set -# CONFIG_MTD_PLATRAM is not set - -# -# Self-contained MTD device drivers -# -# CONFIG_MTD_SLRAM is not set -# CONFIG_MTD_PHRAM is not set -# CONFIG_MTD_MTDRAM is not set -# CONFIG_MTD_BLOCK2MTD is not set - -# -# Disk-On-Chip Device Drivers -# -# CONFIG_MTD_DOC2000 is not set -# CONFIG_MTD_DOC2001 is not set -# CONFIG_MTD_DOC2001PLUS is not set -# CONFIG_MTD_NAND is not set -# CONFIG_MTD_ONENAND is not set - -# -# UBI - Unsorted block images -# -# CONFIG_MTD_UBI is not set -CONFIG_OF_DEVICE=y -# CONFIG_PARPORT is not set -# CONFIG_BLK_DEV is not set -# CONFIG_MISC_DEVICES is not set -# CONFIG_IDE is not set - -# -# SCSI device support -# -# CONFIG_RAID_ATTRS is not set -# CONFIG_SCSI is not set -# CONFIG_SCSI_DMA is not set -# CONFIG_SCSI_NETLINK is not set -# CONFIG_ATA is not set -# CONFIG_MD is not set -# CONFIG_MACINTOSH_DRIVERS is not set -CONFIG_NETDEVICES=y -# CONFIG_NETDEVICES_MULTIQUEUE is not set -# CONFIG_DUMMY is not set -# CONFIG_BONDING is not set -# CONFIG_MACVLAN is not set -# CONFIG_EQUALIZER is not set -# CONFIG_TUN is not set -# CONFIG_VETH is not set -CONFIG_PHYLIB=y - -# -# MII PHY device drivers -# -# CONFIG_MARVELL_PHY is not set -CONFIG_DAVICOM_PHY=y -# CONFIG_QSEMI_PHY is not set -# CONFIG_LXT_PHY is not set -# CONFIG_CICADA_PHY is not set -# CONFIG_VITESSE_PHY is not set -# CONFIG_SMSC_PHY is not set -# CONFIG_BROADCOM_PHY is not set -# CONFIG_ICPLUS_PHY is not set -# CONFIG_FIXED_PHY is not set -# CONFIG_MDIO_BITBANG is not set -CONFIG_NET_ETHERNET=y -CONFIG_MII=y -# CONFIG_IBM_NEW_EMAC_ZMII is not set -# CONFIG_IBM_NEW_EMAC_RGMII is not set -# CONFIG_IBM_NEW_EMAC_TAH is not set -# CONFIG_IBM_NEW_EMAC_EMAC4 is not set -# CONFIG_B44 is not set -CONFIG_FS_ENET=y -# CONFIG_FS_ENET_HAS_SCC is not set -CONFIG_FS_ENET_HAS_FEC=y -CONFIG_FS_ENET_MDIO_FEC=y -# CONFIG_NETDEV_1000 is not set -# CONFIG_NETDEV_10000 is not set - -# -# Wireless LAN -# -# CONFIG_WLAN_PRE80211 is not set -# CONFIG_WLAN_80211 is not set -# CONFIG_WAN is not set -# CONFIG_PPP 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 -# CONFIG_ISDN is not set -# CONFIG_PHONE is not set - -# -# Input device support -# -CONFIG_INPUT=y -# CONFIG_INPUT_FF_MEMLESS is not set -# CONFIG_INPUT_POLLDEV is not set - -# -# Userland interfaces -# -CONFIG_INPUT_MOUSEDEV=y -CONFIG_INPUT_MOUSEDEV_PSAUX=y -CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 -CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 -# CONFIG_INPUT_JOYDEV is not set -# CONFIG_INPUT_EVDEV is not set -# CONFIG_INPUT_EVBUG is not set - -# -# Input Device Drivers -# -CONFIG_INPUT_KEYBOARD=y -CONFIG_KEYBOARD_ATKBD=y -# CONFIG_KEYBOARD_SUNKBD is not set -# CONFIG_KEYBOARD_LKKBD is not set -# CONFIG_KEYBOARD_XTKBD is not set -# CONFIG_KEYBOARD_NEWTON is not set -# CONFIG_KEYBOARD_STOWAWAY is not set -CONFIG_INPUT_MOUSE=y -CONFIG_MOUSE_PS2=y -CONFIG_MOUSE_PS2_ALPS=y -CONFIG_MOUSE_PS2_LOGIPS2PP=y -CONFIG_MOUSE_PS2_SYNAPTICS=y -CONFIG_MOUSE_PS2_LIFEBOOK=y -CONFIG_MOUSE_PS2_TRACKPOINT=y -# CONFIG_MOUSE_PS2_TOUCHKIT is not set -# CONFIG_MOUSE_SERIAL is not set -# CONFIG_MOUSE_VSXXXAA is not set -# CONFIG_INPUT_JOYSTICK is not set -# CONFIG_INPUT_TABLET is not set -# CONFIG_INPUT_TOUCHSCREEN is not set -# CONFIG_INPUT_MISC is not set - -# -# Hardware I/O ports -# -CONFIG_SERIO=y -CONFIG_SERIO_I8042=y -CONFIG_SERIO_SERPORT=y -CONFIG_SERIO_LIBPS2=y -# CONFIG_SERIO_RAW is not set -# CONFIG_GAMEPORT is not set - -# -# Character devices -# -# CONFIG_VT is not set -# CONFIG_SERIAL_NONSTANDARD is not set - -# -# Serial drivers -# -# CONFIG_SERIAL_8250 is not set - -# -# Non-8250 serial port support -# -# CONFIG_SERIAL_UARTLITE is not set -CONFIG_SERIAL_CORE=y -CONFIG_SERIAL_CORE_CONSOLE=y -CONFIG_SERIAL_CPM=y -CONFIG_SERIAL_CPM_CONSOLE=y -# CONFIG_SERIAL_CPM_SCC1 is not set -# CONFIG_SERIAL_CPM_SCC2 is not set -# CONFIG_SERIAL_CPM_SCC3 is not set -# CONFIG_SERIAL_CPM_SCC4 is not set -CONFIG_SERIAL_CPM_SMC1=y -CONFIG_SERIAL_CPM_SMC2=y -CONFIG_UNIX98_PTYS=y -# CONFIG_LEGACY_PTYS is not set -# CONFIG_IPMI_HANDLER is not set -CONFIG_HW_RANDOM=y -# CONFIG_NVRAM is not set -CONFIG_GEN_RTC=y -# CONFIG_GEN_RTC_X is not set -# CONFIG_R3964 is not set -# CONFIG_RAW_DRIVER is not set -# CONFIG_TCG_TPM is not set -# CONFIG_I2C is not set - -# -# SPI support -# -# CONFIG_SPI is not set -# CONFIG_SPI_MASTER is not set -# CONFIG_W1 is not set -# CONFIG_POWER_SUPPLY is not set -# CONFIG_HWMON is not set -# CONFIG_WATCHDOG is not set - -# -# Sonics Silicon Backplane -# -CONFIG_SSB_POSSIBLE=y -# CONFIG_SSB is not set - -# -# Multifunction device drivers -# -# CONFIG_MFD_SM501 is not set - -# -# Multimedia devices -# -# CONFIG_VIDEO_DEV is not set -# CONFIG_DVB_CORE is not set -CONFIG_DAB=y - -# -# Graphics support -# -# CONFIG_VGASTATE is not set -CONFIG_VIDEO_OUTPUT_CONTROL=y -# CONFIG_FB is not set -# CONFIG_BACKLIGHT_LCD_SUPPORT is not set - -# -# Display device support -# -# CONFIG_DISPLAY_SUPPORT is not set - -# -# Sound -# -# CONFIG_SOUND is not set -# CONFIG_HID_SUPPORT is not set -# CONFIG_USB_SUPPORT is not set -# CONFIG_MMC is not set -# CONFIG_NEW_LEDS is not set -# CONFIG_EDAC is not set -# CONFIG_RTC_CLASS is not set - -# -# Userspace I/O -# -# CONFIG_UIO is not set - -# -# File systems -# -# CONFIG_EXT2_FS is not set -# CONFIG_EXT3_FS is not set -# CONFIG_EXT4DEV_FS is not set -# CONFIG_REISERFS_FS is not set -# CONFIG_JFS_FS is not set -# CONFIG_FS_POSIX_ACL is not set -# CONFIG_XFS_FS is not set -# CONFIG_GFS2_FS is not set -# CONFIG_OCFS2_FS is not set -# CONFIG_MINIX_FS is not set -# CONFIG_ROMFS_FS is not set -# CONFIG_INOTIFY is not set -# CONFIG_QUOTA is not set -# CONFIG_DNOTIFY is not set -# CONFIG_AUTOFS_FS is not set -# CONFIG_AUTOFS4_FS is not set -# CONFIG_FUSE_FS is not set - -# -# CD-ROM/DVD Filesystems -# -# CONFIG_ISO9660_FS is not set -# CONFIG_UDF_FS is not set - -# -# DOS/FAT/NT Filesystems -# -# CONFIG_MSDOS_FS is not set -# CONFIG_VFAT_FS is not set -# CONFIG_NTFS_FS is not set - -# -# Pseudo filesystems -# -CONFIG_PROC_FS=y -# CONFIG_PROC_KCORE is not set -CONFIG_PROC_SYSCTL=y -CONFIG_SYSFS=y -CONFIG_TMPFS=y -# CONFIG_TMPFS_POSIX_ACL is not set -# CONFIG_HUGETLB_PAGE is not set -# CONFIG_CONFIGFS_FS is not set - -# -# Miscellaneous filesystems -# -# CONFIG_ADFS_FS is not set -# CONFIG_AFFS_FS is not set -# CONFIG_HFS_FS is not set -# CONFIG_HFSPLUS_FS is not set -# CONFIG_BEFS_FS is not set -# CONFIG_BFS_FS is not set -# CONFIG_EFS_FS is not set -# CONFIG_JFFS2_FS is not set -CONFIG_CRAMFS=y -# CONFIG_VXFS_FS is not set -# CONFIG_HPFS_FS is not set -# CONFIG_QNX4FS_FS is not set -# CONFIG_SYSV_FS is not set -# CONFIG_UFS_FS is not set -CONFIG_NETWORK_FILESYSTEMS=y -CONFIG_NFS_FS=y -CONFIG_NFS_V3=y -# CONFIG_NFS_V3_ACL is not set -# CONFIG_NFS_V4 is not set -# CONFIG_NFS_DIRECTIO is not set -# CONFIG_NFSD is not set -CONFIG_ROOT_NFS=y -CONFIG_LOCKD=y -CONFIG_LOCKD_V4=y -CONFIG_NFS_COMMON=y -CONFIG_SUNRPC=y -# CONFIG_SUNRPC_BIND34 is not set -# CONFIG_RPCSEC_GSS_KRB5 is not set -# CONFIG_RPCSEC_GSS_SPKM3 is not set -# CONFIG_SMB_FS is not set -# CONFIG_CIFS is not set -# CONFIG_NCP_FS is not set -# CONFIG_CODA_FS is not set -# CONFIG_AFS_FS is not set - -# -# Partition Types -# -CONFIG_PARTITION_ADVANCED=y -# CONFIG_ACORN_PARTITION is not set -# CONFIG_OSF_PARTITION is not set -# CONFIG_AMIGA_PARTITION is not set -# CONFIG_ATARI_PARTITION is not set -# CONFIG_MAC_PARTITION is not set -CONFIG_MSDOS_PARTITION=y -# CONFIG_BSD_DISKLABEL is not set -# CONFIG_MINIX_SUBPARTITION is not set -# CONFIG_SOLARIS_X86_PARTITION is not set -# CONFIG_UNIXWARE_DISKLABEL is not set -# CONFIG_LDM_PARTITION is not set -# 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 -# CONFIG_SYSV68_PARTITION is not set -# CONFIG_NLS is not set -# CONFIG_DLM is not set -# CONFIG_UCC_SLOW is not set - -# -# Library routines -# -# CONFIG_CRC_CCITT is not set -# CONFIG_CRC16 is not set -# CONFIG_CRC_ITU_T is not set -# CONFIG_CRC32 is not set -# CONFIG_CRC7 is not set -# CONFIG_LIBCRC32C is not set -CONFIG_ZLIB_INFLATE=y -CONFIG_HAS_IOMEM=y -CONFIG_HAS_IOPORT=y -CONFIG_HAS_DMA=y -CONFIG_INSTRUMENTATION=y -# CONFIG_PROFILING is not set -# CONFIG_MARKERS is not set - -# -# Kernel hacking -# -# CONFIG_PRINTK_TIME is not set -CONFIG_ENABLE_WARN_DEPRECATED=y -CONFIG_ENABLE_MUST_CHECK=y -CONFIG_MAGIC_SYSRQ=y -# CONFIG_UNUSED_SYMBOLS is not set -# CONFIG_DEBUG_FS is not set -# CONFIG_HEADERS_CHECK is not set -CONFIG_DEBUG_KERNEL=y -# CONFIG_DEBUG_SHIRQ is not set -CONFIG_DETECT_SOFTLOCKUP=y -CONFIG_SCHED_DEBUG=y -# CONFIG_SCHEDSTATS is not set -# CONFIG_TIMER_STATS is not set -# CONFIG_SLUB_DEBUG_ON is not set -# CONFIG_DEBUG_SPINLOCK is not set -# CONFIG_DEBUG_MUTEXES is not set -# CONFIG_DEBUG_SPINLOCK_SLEEP is not set -# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set -# CONFIG_DEBUG_KOBJECT is not set -CONFIG_DEBUG_BUGVERBOSE=y -CONFIG_DEBUG_INFO=y -# CONFIG_DEBUG_VM is not set -# CONFIG_DEBUG_LIST is not set -# CONFIG_DEBUG_SG is not set -CONFIG_FORCED_INLINING=y -# CONFIG_BOOT_PRINTK_DELAY is not set -# CONFIG_FAULT_INJECTION is not set -# CONFIG_SAMPLES is not set -# CONFIG_DEBUG_STACKOVERFLOW is not set -# CONFIG_DEBUG_STACK_USAGE is not set -# CONFIG_DEBUG_PAGEALLOC is not set -# CONFIG_DEBUGGER is not set -# CONFIG_BDI_SWITCH is not set -# CONFIG_PPC_EARLY_DEBUG is not set - -# -# Security options -# -# CONFIG_KEYS is not set -# CONFIG_SECURITY is not set -# CONFIG_SECURITY_FILE_CAPABILITIES is not set -# CONFIG_CRYPTO is not set -# CONFIG_PPC_CLOCK is not set -CONFIG_PPC_LIB_RHEAP=y diff --git a/arch/powerpc/configs/adder875-redboot_defconfig b/arch/powerpc/configs/adder875_defconfig similarity index 95% rename from arch/powerpc/configs/adder875-redboot_defconfig rename to arch/powerpc/configs/adder875_defconfig index cab5f9b64567c654c89250a2b2b38bb47737e4d3..a3cc94a2ff06a40104d6ddaea804b13aeb8c6a4f 100644 --- a/arch/powerpc/configs/adder875-redboot_defconfig +++ b/arch/powerpc/configs/adder875_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.24-rc6 -# Thu Jan 17 16:17:38 2008 +# Linux kernel version: 2.6.25-rc2 +# Wed Feb 20 12:26:07 2008 # # CONFIG_PPC64 is not set @@ -26,6 +26,7 @@ CONFIG_GENERIC_TIME=y CONFIG_GENERIC_TIME_VSYSCALL=y CONFIG_GENERIC_CLOCKEVENTS=y CONFIG_GENERIC_HARDIRQS=y +# CONFIG_HAVE_SETUP_PER_CPU_AREA is not set CONFIG_IRQ_PER_CPU=y CONFIG_RWSEM_XCHGADD_ALGORITHM=y CONFIG_ARCH_HAS_ILOG2_U32=y @@ -64,17 +65,18 @@ CONFIG_SYSVIPC_SYSCTL=y # CONFIG_POSIX_MQUEUE is not set # CONFIG_BSD_PROCESS_ACCT is not set # CONFIG_TASKSTATS is not set -# CONFIG_USER_NS is not set -# CONFIG_PID_NS is not set # CONFIG_AUDIT is not set # CONFIG_IKCONFIG is not set CONFIG_LOG_BUF_SHIFT=14 # CONFIG_CGROUPS is not set +CONFIG_GROUP_SCHED=y CONFIG_FAIR_GROUP_SCHED=y -CONFIG_FAIR_USER_SCHED=y -# CONFIG_FAIR_CGROUP_SCHED is not set +# CONFIG_RT_GROUP_SCHED is not set +CONFIG_USER_SCHED=y +# CONFIG_CGROUP_SCHED is not set CONFIG_SYSFS_DEPRECATED=y # CONFIG_RELAY is not set +# CONFIG_NAMESPACES is not set # CONFIG_BLK_DEV_INITRD is not set # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set CONFIG_SYSCTL=y @@ -87,11 +89,13 @@ CONFIG_HOTPLUG=y CONFIG_PRINTK=y CONFIG_BUG=y # CONFIG_ELF_CORE is not set +CONFIG_COMPAT_BRK=y # CONFIG_BASE_FULL is not set # CONFIG_FUTEX is not set CONFIG_ANON_INODES=y CONFIG_EPOLL=y CONFIG_SIGNALFD=y +CONFIG_TIMERFD=y CONFIG_EVENTFD=y CONFIG_SHMEM=y # CONFIG_VM_EVENT_COUNTERS is not set @@ -99,6 +103,12 @@ CONFIG_SLUB_DEBUG=y # CONFIG_SLAB is not set CONFIG_SLUB=y # CONFIG_SLOB is not set +# CONFIG_PROFILING is not set +# CONFIG_MARKERS is not set +CONFIG_HAVE_OPROFILE=y +CONFIG_HAVE_KPROBES=y +CONFIG_PROC_PAGE_MONITOR=y +CONFIG_SLABINFO=y # CONFIG_TINY_SHMEM is not set CONFIG_BASE_SMALL=1 # CONFIG_MODULES is not set @@ -120,12 +130,14 @@ CONFIG_DEFAULT_DEADLINE=y # CONFIG_DEFAULT_CFQ is not set # CONFIG_DEFAULT_NOOP is not set CONFIG_DEFAULT_IOSCHED="deadline" +CONFIG_CLASSIC_RCU=y +# CONFIG_PREEMPT_RCU is not set # # Platform support # -# CONFIG_PPC_MPC52xx is not set -# CONFIG_PPC_MPC5200 is not set +# CONFIG_PPC_MPC512x is not set +# CONFIG_PPC_MPC5121 is not set # CONFIG_PPC_CELL is not set # CONFIG_PPC_CELL_NATIVE is not set CONFIG_CPM1=y @@ -150,6 +162,7 @@ CONFIG_NO_UCODE_PATCH=y # CONFIG_I2C_SPI_UCODE_PATCH is not set # CONFIG_I2C_SPI_SMC1_UCODE_PATCH is not set # CONFIG_PQ2ADS is not set +# CONFIG_IPIC is not set # CONFIG_MPIC is not set # CONFIG_MPIC_WEIRD is not set # CONFIG_PPC_I8259 is not set @@ -160,7 +173,6 @@ CONFIG_NO_UCODE_PATCH=y # CONFIG_PPC_INDIRECT_IO is not set # CONFIG_GENERIC_IOMAP is not set # CONFIG_CPU_FREQ is not set -# CONFIG_CPM2 is not set CONFIG_PPC_CPM_NEW_BINDING=y # CONFIG_FSL_ULI1575 is not set CONFIG_CPM=y @@ -178,14 +190,19 @@ CONFIG_GENERIC_CLOCKEVENTS_BUILD=y # CONFIG_HZ_300 is not set CONFIG_HZ_1000=y CONFIG_HZ=1000 +# CONFIG_SCHED_HRTICK is not set CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT_VOLUNTARY is not set # CONFIG_PREEMPT is not set +CONFIG_RCU_TRACE=y CONFIG_BINFMT_ELF=y # CONFIG_BINFMT_MISC is not set # CONFIG_MATH_EMULATION is not set # CONFIG_8XX_MINIMAL_FPEMU is not set +# CONFIG_IOMMU_HELPER is not set CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y +CONFIG_ARCH_HAS_WALK_MEMORY=y +CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y CONFIG_ARCH_FLATMEM_ENABLE=y CONFIG_ARCH_POPULATES_NODE_MAP=y CONFIG_SELECT_MEMORY_MODEL=y @@ -204,11 +221,7 @@ CONFIG_VIRT_TO_BUS=y # CONFIG_PROC_DEVICETREE is not set # CONFIG_CMDLINE_BOOL is not set # CONFIG_PM is not set -CONFIG_SUSPEND_UP_POSSIBLE=y -CONFIG_HIBERNATION_UP_POSSIBLE=y # CONFIG_SECCOMP is not set -CONFIG_WANT_DEVICE_TREE=y -CONFIG_DEVICE_TREE="adder875-redboot.dts" CONFIG_ISA_DMA_API=y # @@ -305,6 +318,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # # CONFIG_NET_PKTGEN is not set # CONFIG_HAMRADIO is not set +# CONFIG_CAN is not set # CONFIG_IRDA is not set # CONFIG_BT is not set # CONFIG_AF_RXRPC is not set @@ -411,6 +425,7 @@ CONFIG_OF_DEVICE=y # CONFIG_PARPORT is not set # CONFIG_BLK_DEV is not set # CONFIG_MISC_DEVICES is not set +CONFIG_HAVE_IDE=y # CONFIG_IDE is not set # @@ -445,6 +460,7 @@ CONFIG_DAVICOM_PHY=y # CONFIG_SMSC_PHY is not set # CONFIG_BROADCOM_PHY is not set # CONFIG_ICPLUS_PHY is not set +# CONFIG_REALTEK_PHY is not set # CONFIG_FIXED_PHY is not set # CONFIG_MDIO_BITBANG is not set CONFIG_NET_ETHERNET=y @@ -469,7 +485,6 @@ CONFIG_FS_ENET_MDIO_FEC=y # CONFIG_WAN is not set # CONFIG_PPP 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 @@ -574,6 +589,7 @@ CONFIG_GEN_RTC=y # CONFIG_W1 is not set # CONFIG_POWER_SUPPLY is not set # CONFIG_HWMON is not set +CONFIG_THERMAL=y # CONFIG_WATCHDOG is not set # @@ -614,6 +630,7 @@ CONFIG_VIDEO_OUTPUT_CONTROL=y # CONFIG_HID_SUPPORT is not set # CONFIG_USB_SUPPORT is not set # CONFIG_MMC is not set +# CONFIG_MEMSTICK is not set # CONFIG_NEW_LEDS is not set # CONFIG_EDAC is not set # CONFIG_RTC_CLASS is not set @@ -635,11 +652,9 @@ CONFIG_VIDEO_OUTPUT_CONTROL=y # CONFIG_XFS_FS is not set # CONFIG_GFS2_FS is not set # CONFIG_OCFS2_FS is not set -# CONFIG_MINIX_FS is not set -# CONFIG_ROMFS_FS is not set +# CONFIG_DNOTIFY is not set # CONFIG_INOTIFY is not set # CONFIG_QUOTA is not set -# CONFIG_DNOTIFY is not set # CONFIG_AUTOFS_FS is not set # CONFIG_AUTOFS4_FS is not set # CONFIG_FUSE_FS is not set @@ -682,8 +697,10 @@ CONFIG_TMPFS=y # CONFIG_JFFS2_FS is not set CONFIG_CRAMFS=y # CONFIG_VXFS_FS is not set +# CONFIG_MINIX_FS is not set # CONFIG_HPFS_FS is not set # CONFIG_QNX4FS_FS is not set +# CONFIG_ROMFS_FS is not set # CONFIG_SYSV_FS is not set # CONFIG_UFS_FS is not set CONFIG_NETWORK_FILESYSTEMS=y @@ -730,7 +747,6 @@ CONFIG_MSDOS_PARTITION=y # CONFIG_SYSV68_PARTITION is not set # CONFIG_NLS is not set # CONFIG_DLM is not set -# CONFIG_UCC_SLOW is not set # # Library routines @@ -745,9 +761,6 @@ CONFIG_ZLIB_INFLATE=y CONFIG_HAS_IOMEM=y CONFIG_HAS_IOPORT=y CONFIG_HAS_DMA=y -CONFIG_INSTRUMENTATION=y -# CONFIG_PROFILING is not set -# CONFIG_MARKERS is not set # # Kernel hacking @@ -757,7 +770,7 @@ CONFIG_ENABLE_WARN_DEPRECATED=y CONFIG_ENABLE_MUST_CHECK=y CONFIG_MAGIC_SYSRQ=y # CONFIG_UNUSED_SYMBOLS is not set -# CONFIG_DEBUG_FS is not set +CONFIG_DEBUG_FS=y # CONFIG_HEADERS_CHECK is not set CONFIG_DEBUG_KERNEL=y # CONFIG_DEBUG_SHIRQ is not set @@ -766,6 +779,7 @@ CONFIG_SCHED_DEBUG=y # CONFIG_SCHEDSTATS is not set # CONFIG_TIMER_STATS is not set # CONFIG_SLUB_DEBUG_ON is not set +# CONFIG_SLUB_STATS is not set # CONFIG_DEBUG_SPINLOCK is not set # CONFIG_DEBUG_MUTEXES is not set # CONFIG_DEBUG_SPINLOCK_SLEEP is not set @@ -776,14 +790,15 @@ CONFIG_DEBUG_INFO=y # CONFIG_DEBUG_VM is not set # CONFIG_DEBUG_LIST is not set # CONFIG_DEBUG_SG is not set -CONFIG_FORCED_INLINING=y # CONFIG_BOOT_PRINTK_DELAY is not set +# CONFIG_BACKTRACE_SELF_TEST is not set # CONFIG_FAULT_INJECTION is not set # CONFIG_SAMPLES is not set # CONFIG_DEBUG_STACKOVERFLOW is not set # CONFIG_DEBUG_STACK_USAGE is not set # CONFIG_DEBUG_PAGEALLOC is not set # CONFIG_DEBUGGER is not set +# CONFIG_VIRQ_DEBUG is not set # CONFIG_BDI_SWITCH is not set # CONFIG_PPC_EARLY_DEBUG is not set diff --git a/arch/powerpc/kernel/head_8xx.S b/arch/powerpc/kernel/head_8xx.S index f7458396cd7c022968abb231d1fdf62cb5ec2c67..3c9452d4308b8d245f1c85816b62d971948c6d44 100644 --- a/arch/powerpc/kernel/head_8xx.S +++ b/arch/powerpc/kernel/head_8xx.S @@ -332,8 +332,18 @@ InstructionTLBMiss: mfspr r11, SPRN_MD_TWC /* ....and get the pte address */ lwz r10, 0(r11) /* Get the pte */ +#ifdef CONFIG_SWAP + /* do not set the _PAGE_ACCESSED bit of a non-present page */ + andi. r11, r10, _PAGE_PRESENT + beq 4f + ori r10, r10, _PAGE_ACCESSED + mfspr r11, SPRN_MD_TWC /* get the pte address again */ + stw r10, 0(r11) +4: +#else ori r10, r10, _PAGE_ACCESSED stw r10, 0(r11) +#endif /* The Linux PTE won't go exactly into the MMU TLB. * Software indicator bits 21, 22 and 28 must be clear. @@ -398,8 +408,17 @@ DataStoreTLBMiss: DO_8xx_CPU6(0x3b80, r3) mtspr SPRN_MD_TWC, r11 - mfspr r11, SPRN_MD_TWC /* get the pte address again */ +#ifdef CONFIG_SWAP + /* do not set the _PAGE_ACCESSED bit of a non-present page */ + andi. r11, r10, _PAGE_PRESENT + beq 4f ori r10, r10, _PAGE_ACCESSED +4: + /* and update pte in table */ +#else + ori r10, r10, _PAGE_ACCESSED +#endif + mfspr r11, SPRN_MD_TWC /* get the pte address again */ stw r10, 0(r11) /* The Linux PTE won't go exactly into the MMU TLB. @@ -507,7 +526,16 @@ DataTLBError: /* Update 'changed', among others. */ +#ifdef CONFIG_SWAP + ori r10, r10, _PAGE_DIRTY|_PAGE_HWWRITE + /* do not set the _PAGE_ACCESSED bit of a non-present page */ + andi. r11, r10, _PAGE_PRESENT + beq 4f + ori r10, r10, _PAGE_ACCESSED +4: +#else ori r10, r10, _PAGE_DIRTY|_PAGE_ACCESSED|_PAGE_HWWRITE +#endif mfspr r11, SPRN_MD_TWC /* Get pte address again */ stw r10, 0(r11) /* and update pte in table */ diff --git a/arch/powerpc/kernel/misc_32.S b/arch/powerpc/kernel/misc_32.S index 5c2e253ddfb1a8eec7efbc582a8017724def45bb..9d2c56621f1ea0ad18ee1a0d89e46931ece7e7a5 100644 --- a/arch/powerpc/kernel/misc_32.S +++ b/arch/powerpc/kernel/misc_32.S @@ -785,6 +785,21 @@ _GLOBAL(__lshrdi3) or r4,r4,r7 # LSW |= t2 blr +/* + * 64-bit comparison: __ucmpdi2(u64 a, u64 b) + * Returns 0 if a < b, 1 if a == b, 2 if a > b. + */ +_GLOBAL(__ucmpdi2) + cmplw r3,r5 + li r3,1 + bne 1f + cmplw r4,r6 + beqlr +1: li r3,0 + bltlr + li r3,2 + blr + _GLOBAL(abs) srawi r4,r3,31 xor r3,r3,r4 diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c index 980fe32895c0af5aed4e97142ef479dc234ff88f..89c83ccb85c10e07d5fe29375d26fb624377567d 100644 --- a/arch/powerpc/kernel/pci-common.c +++ b/arch/powerpc/kernel/pci-common.c @@ -748,7 +748,13 @@ static void __devinit pcibios_fixup_resources(struct pci_dev *dev) struct resource *res = dev->resource + i; if (!res->flags) continue; - if (res->end == 0xffffffff) { + /* On platforms that have PPC_PCI_PROBE_ONLY set, we don't + * consider 0 as an unassigned BAR value. It's technically + * a valid value, but linux doesn't like it... so when we can + * re-assign things, we do so, but if we can't, we keep it + * around and hope for the best... + */ + if (res->start == 0 && !(ppc_pci_flags & PPC_PCI_PROBE_ONLY)) { pr_debug("PCI:%s Resource %d %016llx-%016llx [%x] is unassigned\n", pci_name(dev), i, (unsigned long long)res->start, diff --git a/arch/powerpc/kernel/ppc_ksyms.c b/arch/powerpc/kernel/ppc_ksyms.c index aa9ff35b0e630e86d04ef5611188570c5ed5b958..9c98424277a8660373549eb5d3d3c664556694ea 100644 --- a/arch/powerpc/kernel/ppc_ksyms.c +++ b/arch/powerpc/kernel/ppc_ksyms.c @@ -58,6 +58,7 @@ extern void program_check_exception(struct pt_regs *regs); extern void single_step_exception(struct pt_regs *regs); extern int sys_sigreturn(struct pt_regs *regs); +EXPORT_SYMBOL(empty_zero_page); EXPORT_SYMBOL(clear_pages); EXPORT_SYMBOL(copy_page); EXPORT_SYMBOL(ISA_DMA_THRESHOLD); @@ -149,6 +150,8 @@ long long __lshrdi3(long long, int); EXPORT_SYMBOL(__ashrdi3); EXPORT_SYMBOL(__ashldi3); EXPORT_SYMBOL(__lshrdi3); +int __ucmpdi2(unsigned long long, unsigned long long); +EXPORT_SYMBOL(__ucmpdi2); #endif EXPORT_SYMBOL(memcpy); diff --git a/arch/powerpc/mm/hash_utils_64.c b/arch/powerpc/mm/hash_utils_64.c index 32f416175db10f9c6266ea48c56bf5b69becb952..590f1f67c87403df6db3f878c800a7c37bf992b4 100644 --- a/arch/powerpc/mm/hash_utils_64.c +++ b/arch/powerpc/mm/hash_utils_64.c @@ -506,10 +506,10 @@ void __init htab_initialize(void) } else { /* Find storage for the HPT. Must be contiguous in * the absolute address space. On cell we want it to be - * in the first 1 Gig. + * in the first 2 Gig so we can use it for IOMMU hacks. */ if (machine_is(cell)) - limit = 0x40000000; + limit = 0x80000000; else limit = 0; diff --git a/arch/powerpc/oprofile/op_model_cell.c b/arch/powerpc/oprofile/op_model_cell.c index 13929771bee7c10e3fe70effebcfd3f670868ec8..9eed1f68fcab3495981b72f40375e26ed9be4d7d 100644 --- a/arch/powerpc/oprofile/op_model_cell.c +++ b/arch/powerpc/oprofile/op_model_cell.c @@ -1151,7 +1151,7 @@ static void cell_handle_interrupt(struct pt_regs *regs, for (i = 0; i < num_counters; ++i) { if ((interrupt_mask & CBE_PM_CTR_OVERFLOW_INTR(i)) && ctr[i].enabled) { - oprofile_add_pc(pc, is_kernel, i); + oprofile_add_ext_sample(pc, regs, i, is_kernel); cbe_write_ctr(cpu, i, reset_value[i]); } } diff --git a/arch/powerpc/platforms/52xx/mpc52xx_common.c b/arch/powerpc/platforms/52xx/mpc52xx_common.c index 9aa4425d80b20a4d1fe77eb36ca2eded77095bb0..4d5fd1dbd4007a5235b5b170367e451cc4f40b67 100644 --- a/arch/powerpc/platforms/52xx/mpc52xx_common.c +++ b/arch/powerpc/platforms/52xx/mpc52xx_common.c @@ -199,6 +199,7 @@ int mpc52xx_set_psc_clkdiv(int psc_id, int clkdiv) return 0; } +EXPORT_SYMBOL(mpc52xx_set_psc_clkdiv); /** * mpc52xx_restart: ppc_md->restart hook for mpc5200 using the watchdog timer diff --git a/arch/powerpc/platforms/83xx/mpc837x_mds.c b/arch/powerpc/platforms/83xx/mpc837x_mds.c index 8a9c26973605d918259acd874e7d5c627eb631fe..64d17b0d64555cbd4a29271b7f7122abed2caba0 100644 --- a/arch/powerpc/platforms/83xx/mpc837x_mds.c +++ b/arch/powerpc/platforms/83xx/mpc837x_mds.c @@ -39,12 +39,9 @@ static int mpc837xmds_usb_cfg(void) if (ret) return ret; /* Map BCSR area */ - np = of_find_node_by_name(NULL, "bcsr"); + np = of_find_compatible_node(NULL, NULL, "fsl,mpc837xmds-bcsr"); if (np) { - struct resource res; - - of_address_to_resource(np, 0, &res); - bcsr_regs = ioremap(res.start, res.end - res.start + 1); + bcsr_regs = of_iomap(np, 0); of_node_put(np); } if (!bcsr_regs) @@ -96,6 +93,7 @@ static void __init mpc837x_mds_setup_arch(void) static struct of_device_id mpc837x_ids[] = { { .type = "soc", }, { .compatible = "soc", }, + { .compatible = "simple-bus", }, {}, }; diff --git a/arch/powerpc/platforms/Kconfig b/arch/powerpc/platforms/Kconfig index 0afd22595546fc68d981972e15e0815eda7da09d..a578b966ecbc1da6452ff0160f07e5e0349d80eb 100644 --- a/arch/powerpc/platforms/Kconfig +++ b/arch/powerpc/platforms/Kconfig @@ -22,7 +22,6 @@ config PPC_83xx select FSL_SOC select MPC83xx select IPIC - select FSL_EMB_PERFMON config PPC_86xx bool "Freescale 86xx" diff --git a/arch/powerpc/platforms/Kconfig.cputype b/arch/powerpc/platforms/Kconfig.cputype index 73d81ce14b6763c185397d998c1208c4a073d0ab..0c3face0ddbb4d78010e1efcbd12569e8343e25c 100644 --- a/arch/powerpc/platforms/Kconfig.cputype +++ b/arch/powerpc/platforms/Kconfig.cputype @@ -113,7 +113,12 @@ config FSL_BOOKE default y config FSL_EMB_PERFMON - bool + bool "Freescale Embedded Perfmon" + depends on E500 || PPC_83xx + help + This is the Performance Monitor support found on the e500 core + and some e300 cores (c3 and c4). Select this only if your + core supports the Embedded Performance Monitor APU config PTE_64BIT bool diff --git a/arch/powerpc/platforms/cell/iommu.c b/arch/powerpc/platforms/cell/iommu.c index edab631a8dcb1bd92ef035a2fa620820112afbee..20ea0e118f246b21819b907d49c25e8c4d70e510 100644 --- a/arch/powerpc/platforms/cell/iommu.c +++ b/arch/powerpc/platforms/cell/iommu.c @@ -113,7 +113,7 @@ /* IOMMU sizing */ #define IO_SEGMENT_SHIFT 28 -#define IO_PAGENO_BITS (IO_SEGMENT_SHIFT - IOMMU_PAGE_SHIFT) +#define IO_PAGENO_BITS(shift) (IO_SEGMENT_SHIFT - (shift)) /* The high bit needs to be set on every DMA address */ #define SPIDER_DMA_OFFSET 0x80000000ul @@ -123,7 +123,6 @@ struct iommu_window { struct cbe_iommu *iommu; unsigned long offset; unsigned long size; - unsigned long pte_offset; unsigned int ioid; struct iommu_table table; }; @@ -200,7 +199,7 @@ static void tce_build_cell(struct iommu_table *tbl, long index, long npages, (window->ioid & IOPTE_IOID_Mask); #endif - io_pte = (unsigned long *)tbl->it_base + (index - window->pte_offset); + io_pte = (unsigned long *)tbl->it_base + (index - tbl->it_offset); for (i = 0; i < npages; i++, uaddr += IOMMU_PAGE_SIZE) io_pte[i] = base_pte | (__pa(uaddr) & IOPTE_RPN_Mask); @@ -232,7 +231,7 @@ static void tce_free_cell(struct iommu_table *tbl, long index, long npages) | (window->ioid & IOPTE_IOID_Mask); #endif - io_pte = (unsigned long *)tbl->it_base + (index - window->pte_offset); + io_pte = (unsigned long *)tbl->it_base + (index - tbl->it_offset); for (i = 0; i < npages; i++) io_pte[i] = pte; @@ -307,76 +306,84 @@ static int cell_iommu_find_ioc(int nid, unsigned long *base) return -ENODEV; } -static void cell_iommu_setup_page_tables(struct cbe_iommu *iommu, +static void cell_iommu_setup_stab(struct cbe_iommu *iommu, unsigned long dbase, unsigned long dsize, unsigned long fbase, unsigned long fsize) { struct page *page; - int i; - unsigned long reg, segments, pages_per_segment, ptab_size, stab_size, - n_pte_pages, base; - - base = dbase; - if (fsize != 0) - base = min(fbase, dbase); + unsigned long segments, stab_size; segments = max(dbase + dsize, fbase + fsize) >> IO_SEGMENT_SHIFT; - pages_per_segment = 1ull << IO_PAGENO_BITS; - pr_debug("%s: iommu[%d]: segments: %lu, pages per segment: %lu\n", - __FUNCTION__, iommu->nid, segments, pages_per_segment); + pr_debug("%s: iommu[%d]: segments: %lu\n", + __FUNCTION__, iommu->nid, segments); /* set up the segment table */ stab_size = segments * sizeof(unsigned long); page = alloc_pages_node(iommu->nid, GFP_KERNEL, get_order(stab_size)); BUG_ON(!page); iommu->stab = page_address(page); - clear_page(iommu->stab); + memset(iommu->stab, 0, stab_size); +} + +static unsigned long *cell_iommu_alloc_ptab(struct cbe_iommu *iommu, + unsigned long base, unsigned long size, unsigned long gap_base, + unsigned long gap_size, unsigned long page_shift) +{ + struct page *page; + int i; + unsigned long reg, segments, pages_per_segment, ptab_size, + n_pte_pages, start_seg, *ptab; + + start_seg = base >> IO_SEGMENT_SHIFT; + segments = size >> IO_SEGMENT_SHIFT; + pages_per_segment = 1ull << IO_PAGENO_BITS(page_shift); + /* PTEs for each segment must start on a 4K bounday */ + pages_per_segment = max(pages_per_segment, + (1 << 12) / sizeof(unsigned long)); - /* ... and the page tables. Since these are contiguous, we can treat - * the page tables as one array of ptes, like pSeries does. - */ ptab_size = segments * pages_per_segment * sizeof(unsigned long); pr_debug("%s: iommu[%d]: ptab_size: %lu, order: %d\n", __FUNCTION__, iommu->nid, ptab_size, get_order(ptab_size)); page = alloc_pages_node(iommu->nid, GFP_KERNEL, get_order(ptab_size)); BUG_ON(!page); - iommu->ptab = page_address(page); - memset(iommu->ptab, 0, ptab_size); + ptab = page_address(page); + memset(ptab, 0, ptab_size); - /* allocate a bogus page for the end of each mapping */ - page = alloc_pages_node(iommu->nid, GFP_KERNEL, 0); - BUG_ON(!page); - iommu->pad_page = page_address(page); - clear_page(iommu->pad_page); - - /* number of pages needed for a page table */ - n_pte_pages = (pages_per_segment * - sizeof(unsigned long)) >> IOMMU_PAGE_SHIFT; + /* number of 4K pages needed for a page table */ + n_pte_pages = (pages_per_segment * sizeof(unsigned long)) >> 12; pr_debug("%s: iommu[%d]: stab at %p, ptab at %p, n_pte_pages: %lu\n", - __FUNCTION__, iommu->nid, iommu->stab, iommu->ptab, + __FUNCTION__, iommu->nid, iommu->stab, ptab, n_pte_pages); /* initialise the STEs */ reg = IOSTE_V | ((n_pte_pages - 1) << 5); - if (IOMMU_PAGE_SIZE == 0x1000) - reg |= IOSTE_PS_4K; - else if (IOMMU_PAGE_SIZE == 0x10000) - reg |= IOSTE_PS_64K; - else { - extern void __unknown_page_size_error(void); - __unknown_page_size_error(); + switch (page_shift) { + case 12: reg |= IOSTE_PS_4K; break; + case 16: reg |= IOSTE_PS_64K; break; + case 20: reg |= IOSTE_PS_1M; break; + case 24: reg |= IOSTE_PS_16M; break; + default: BUG(); } + gap_base = gap_base >> IO_SEGMENT_SHIFT; + gap_size = gap_size >> IO_SEGMENT_SHIFT; + pr_debug("Setting up IOMMU stab:\n"); - for (i = base >> IO_SEGMENT_SHIFT; i < segments; i++) { - iommu->stab[i] = reg | - (__pa(iommu->ptab) + n_pte_pages * IOMMU_PAGE_SIZE * i); + for (i = start_seg; i < (start_seg + segments); i++) { + if (i >= gap_base && i < (gap_base + gap_size)) { + pr_debug("\toverlap at %d, skipping\n", i); + continue; + } + iommu->stab[i] = reg | (__pa(ptab) + (n_pte_pages << 12) * + (i - start_seg)); pr_debug("\t[%d] 0x%016lx\n", i, iommu->stab[i]); } + + return ptab; } static void cell_iommu_enable_hardware(struct cbe_iommu *iommu) @@ -423,7 +430,9 @@ static void cell_iommu_enable_hardware(struct cbe_iommu *iommu) static void cell_iommu_setup_hardware(struct cbe_iommu *iommu, unsigned long base, unsigned long size) { - cell_iommu_setup_page_tables(iommu, base, size, 0, 0); + cell_iommu_setup_stab(iommu, base, size, 0, 0); + iommu->ptab = cell_iommu_alloc_ptab(iommu, base, size, 0, 0, + IOMMU_PAGE_SHIFT); cell_iommu_enable_hardware(iommu); } @@ -464,6 +473,7 @@ cell_iommu_setup_window(struct cbe_iommu *iommu, struct device_node *np, unsigned long pte_offset) { struct iommu_window *window; + struct page *page; u32 ioid; ioid = cell_iommu_get_ioid(np); @@ -475,13 +485,11 @@ cell_iommu_setup_window(struct cbe_iommu *iommu, struct device_node *np, window->size = size; window->ioid = ioid; window->iommu = iommu; - window->pte_offset = pte_offset; window->table.it_blocksize = 16; window->table.it_base = (unsigned long)iommu->ptab; window->table.it_index = iommu->nid; - window->table.it_offset = (offset >> IOMMU_PAGE_SHIFT) + - window->pte_offset; + window->table.it_offset = (offset >> IOMMU_PAGE_SHIFT) + pte_offset; window->table.it_size = size >> IOMMU_PAGE_SHIFT; iommu_init_table(&window->table, iommu->nid); @@ -504,6 +512,11 @@ cell_iommu_setup_window(struct cbe_iommu *iommu, struct device_node *np, * This code also assumes that we have a window that starts at 0, * which is the case on all spider based blades. */ + page = alloc_pages_node(iommu->nid, GFP_KERNEL, 0); + BUG_ON(!page); + iommu->pad_page = page_address(page); + clear_page(iommu->pad_page); + __set_bit(0, window->table.it_map); tce_build_cell(&window->table, window->table.it_offset, 1, (unsigned long)iommu->pad_page, DMA_TO_DEVICE); @@ -549,7 +562,7 @@ static void cell_dma_dev_setup_iommu(struct device *dev) archdata->dma_data = &window->table; } -static void cell_dma_dev_setup_static(struct device *dev); +static void cell_dma_dev_setup_fixed(struct device *dev); static void cell_dma_dev_setup(struct device *dev) { @@ -557,7 +570,7 @@ static void cell_dma_dev_setup(struct device *dev) /* Order is important here, these are not mutually exclusive */ if (get_dma_ops(dev) == &dma_iommu_fixed_ops) - cell_dma_dev_setup_static(dev); + cell_dma_dev_setup_fixed(dev); else if (get_pci_dma_ops() == &dma_iommu_ops) cell_dma_dev_setup_iommu(dev); else if (get_pci_dma_ops() == &dma_direct_ops) @@ -858,7 +871,7 @@ static int dma_set_mask_and_switch(struct device *dev, u64 dma_mask) return 0; } -static void cell_dma_dev_setup_static(struct device *dev) +static void cell_dma_dev_setup_fixed(struct device *dev) { struct dev_archdata *archdata = &dev->archdata; u64 addr; @@ -869,35 +882,45 @@ static void cell_dma_dev_setup_static(struct device *dev) dev_dbg(dev, "iommu: fixed addr = %lx\n", addr); } +static void insert_16M_pte(unsigned long addr, unsigned long *ptab, + unsigned long base_pte) +{ + unsigned long segment, offset; + + segment = addr >> IO_SEGMENT_SHIFT; + offset = (addr >> 24) - (segment << IO_PAGENO_BITS(24)); + ptab = ptab + (segment * (1 << 12) / sizeof(unsigned long)); + + pr_debug("iommu: addr %lx ptab %p segment %lx offset %lx\n", + addr, ptab, segment, offset); + + ptab[offset] = base_pte | (__pa(addr) & IOPTE_RPN_Mask); +} + static void cell_iommu_setup_fixed_ptab(struct cbe_iommu *iommu, struct device_node *np, unsigned long dbase, unsigned long dsize, unsigned long fbase, unsigned long fsize) { - unsigned long base_pte, uaddr, *io_pte; - int i; + unsigned long base_pte, uaddr, ioaddr, *ptab; - dma_iommu_fixed_base = fbase; + ptab = cell_iommu_alloc_ptab(iommu, fbase, fsize, dbase, dsize, 24); - /* convert from bytes into page table indices */ - dbase = dbase >> IOMMU_PAGE_SHIFT; - dsize = dsize >> IOMMU_PAGE_SHIFT; - fbase = fbase >> IOMMU_PAGE_SHIFT; - fsize = fsize >> IOMMU_PAGE_SHIFT; + dma_iommu_fixed_base = fbase; pr_debug("iommu: mapping 0x%lx pages from 0x%lx\n", fsize, fbase); - io_pte = iommu->ptab; base_pte = IOPTE_PP_W | IOPTE_PP_R | IOPTE_M | IOPTE_SO_RW | (cell_iommu_get_ioid(np) & IOPTE_IOID_Mask); - uaddr = 0; - for (i = fbase; i < fbase + fsize; i++, uaddr += IOMMU_PAGE_SIZE) { + for (uaddr = 0; uaddr < fsize; uaddr += (1 << 24)) { /* Don't touch the dynamic region */ - if (i >= dbase && i < (dbase + dsize)) { - pr_debug("iommu: static/dynamic overlap, skipping\n"); + ioaddr = uaddr + fbase; + if (ioaddr >= dbase && ioaddr < (dbase + dsize)) { + pr_debug("iommu: fixed/dynamic overlap, skipping\n"); continue; } - io_pte[i] = base_pte | (__pa(uaddr) & IOPTE_RPN_Mask); + + insert_16M_pte(uaddr, ptab, base_pte); } mb(); @@ -995,7 +1018,9 @@ static int __init cell_iommu_fixed_mapping_init(void) "fixed window 0x%lx-0x%lx\n", iommu->nid, dbase, dbase + dsize, fbase, fbase + fsize); - cell_iommu_setup_page_tables(iommu, dbase, dsize, fbase, fsize); + cell_iommu_setup_stab(iommu, dbase, dsize, fbase, fsize); + iommu->ptab = cell_iommu_alloc_ptab(iommu, dbase, dsize, 0, 0, + IOMMU_PAGE_SHIFT); cell_iommu_setup_fixed_ptab(iommu, np, dbase, dsize, fbase, fsize); cell_iommu_enable_hardware(iommu); diff --git a/arch/powerpc/platforms/cell/setup.c b/arch/powerpc/platforms/cell/setup.c index a7f609b3b876d61b1f128bf3902f8262761d0927..dda34650cb07d32afff1c86dadd856e0eb48c394 100644 --- a/arch/powerpc/platforms/cell/setup.c +++ b/arch/powerpc/platforms/cell/setup.c @@ -149,6 +149,11 @@ static void __init cell_init_irq(void) mpic_init_IRQ(); } +static void __init cell_set_dabrx(void) +{ + mtspr(SPRN_DABRX, DABRX_KERNEL | DABRX_USER); +} + static void __init cell_setup_arch(void) { #ifdef CONFIG_SPU_BASE @@ -158,6 +163,8 @@ static void __init cell_setup_arch(void) cbe_regs_init(); + cell_set_dabrx(); + #ifdef CONFIG_CBE_RAS cbe_ras_init(); #endif diff --git a/arch/powerpc/platforms/cell/spu_base.c b/arch/powerpc/platforms/cell/spu_base.c index 87eb07f94c5f111e345cdebe47640bb1d4a6a1ea..712001f6b7dad366cd1b2ab78107811cf6f485fb 100644 --- a/arch/powerpc/platforms/cell/spu_base.c +++ b/arch/powerpc/platforms/cell/spu_base.c @@ -81,9 +81,12 @@ struct spu_slb { void spu_invalidate_slbs(struct spu *spu) { struct spu_priv2 __iomem *priv2 = spu->priv2; + unsigned long flags; + spin_lock_irqsave(&spu->register_lock, flags); if (spu_mfc_sr1_get(spu) & MFC_STATE1_RELOCATE_MASK) out_be64(&priv2->slb_invalidate_all_W, 0UL); + spin_unlock_irqrestore(&spu->register_lock, flags); } EXPORT_SYMBOL_GPL(spu_invalidate_slbs); @@ -148,7 +151,11 @@ static inline void spu_load_slb(struct spu *spu, int slbe, struct spu_slb *slb) __func__, slbe, slb->vsid, slb->esid); out_be64(&priv2->slb_index_W, slbe); + /* set invalid before writing vsid */ + out_be64(&priv2->slb_esid_RW, 0); + /* now it's safe to write the vsid */ out_be64(&priv2->slb_vsid_RW, slb->vsid); + /* setting the new esid makes the entry valid again */ out_be64(&priv2->slb_esid_RW, slb->esid); } @@ -290,9 +297,11 @@ void spu_setup_kernel_slbs(struct spu *spu, struct spu_lscsa *lscsa, nr_slbs++; } + spin_lock_irq(&spu->register_lock); /* Add the set of SLBs */ for (i = 0; i < nr_slbs; i++) spu_load_slb(spu, i, &slbs[i]); + spin_unlock_irq(&spu->register_lock); } EXPORT_SYMBOL_GPL(spu_setup_kernel_slbs); @@ -337,13 +346,14 @@ spu_irq_class_1(int irq, void *data) if (stat & CLASS1_STORAGE_FAULT_INTR) spu_mfc_dsisr_set(spu, 0ul); spu_int_stat_clear(spu, 1, stat); - spin_unlock(&spu->register_lock); - pr_debug("%s: %lx %lx %lx %lx\n", __FUNCTION__, mask, stat, - dar, dsisr); if (stat & CLASS1_SEGMENT_FAULT_INTR) __spu_trap_data_seg(spu, dar); + spin_unlock(&spu->register_lock); + pr_debug("%s: %lx %lx %lx %lx\n", __FUNCTION__, mask, stat, + dar, dsisr); + if (stat & CLASS1_STORAGE_FAULT_INTR) __spu_trap_data_map(spu, dar, dsisr); diff --git a/arch/powerpc/platforms/cell/spufs/context.c b/arch/powerpc/platforms/cell/spufs/context.c index 133995ed5cc78c104745534915ec3331f6601ed6..0ad83aeb70b114758c68de984aa45161954c1eae 100644 --- a/arch/powerpc/platforms/cell/spufs/context.c +++ b/arch/powerpc/platforms/cell/spufs/context.c @@ -109,13 +109,12 @@ void spu_forget(struct spu_context *ctx) /* * This is basically an open-coded spu_acquire_saved, except that - * we don't acquire the state mutex interruptible. + * we don't acquire the state mutex interruptible, and we don't + * want this context to be rescheduled on release. */ mutex_lock(&ctx->state_mutex); - if (ctx->state != SPU_STATE_SAVED) { - set_bit(SPU_SCHED_WAS_ACTIVE, &ctx->sched_flags); + if (ctx->state != SPU_STATE_SAVED) spu_deactivate(ctx); - } mm = ctx->owner; ctx->owner = NULL; @@ -171,7 +170,8 @@ void spu_release_saved(struct spu_context *ctx) { BUG_ON(ctx->state != SPU_STATE_SAVED); - if (test_and_clear_bit(SPU_SCHED_WAS_ACTIVE, &ctx->sched_flags)) + if (test_and_clear_bit(SPU_SCHED_WAS_ACTIVE, &ctx->sched_flags) && + test_bit(SPU_SCHED_SPU_RUN, &ctx->sched_flags)) spu_activate(ctx, 0); spu_release(ctx); diff --git a/arch/powerpc/platforms/cell/spufs/file.c b/arch/powerpc/platforms/cell/spufs/file.c index c66c3756970d53d52ae56df931e38219a9e79ade..f7a7e8635fb6f98d11ab8aa5bf5cf3d2d6f49bf8 100644 --- a/arch/powerpc/platforms/cell/spufs/file.c +++ b/arch/powerpc/platforms/cell/spufs/file.c @@ -366,6 +366,13 @@ static unsigned long spufs_ps_nopfn(struct vm_area_struct *vma, if (offset >= ps_size) return NOPFN_SIGBUS; + /* + * Because we release the mmap_sem, the context may be destroyed while + * we're in spu_wait. Grab an extra reference so it isn't destroyed + * in the meantime. + */ + get_spu_context(ctx); + /* * We have to wait for context to be loaded before we have * pages to hand out to the user, but we don't want to wait @@ -375,7 +382,7 @@ static unsigned long spufs_ps_nopfn(struct vm_area_struct *vma, * hanged. */ if (spu_acquire(ctx)) - return NOPFN_REFAULT; + goto refault; if (ctx->state == SPU_STATE_SAVED) { up_read(¤t->mm->mmap_sem); @@ -391,6 +398,9 @@ static unsigned long spufs_ps_nopfn(struct vm_area_struct *vma, if (!ret) spu_release(ctx); + +refault: + put_spu_context(ctx); return NOPFN_REFAULT; } diff --git a/arch/powerpc/platforms/cell/spufs/run.c b/arch/powerpc/platforms/cell/spufs/run.c index 6221968c2a3ce24d6bc11f3a5807db3ccaff440e..cac69e116776bd6bc5e91553057b3f2e4526ac79 100644 --- a/arch/powerpc/platforms/cell/spufs/run.c +++ b/arch/powerpc/platforms/cell/spufs/run.c @@ -220,6 +220,7 @@ static int spu_run_init(struct spu_context *ctx, u32 *npc) } } + set_bit(SPU_SCHED_SPU_RUN, &ctx->sched_flags); return 0; } @@ -234,7 +235,7 @@ static int spu_run_fini(struct spu_context *ctx, u32 *npc, *npc = ctx->ops->npc_read(ctx); spuctx_switch_state(ctx, SPU_UTIL_IDLE_LOADED); - ctx->policy = SCHED_IDLE; + clear_bit(SPU_SCHED_SPU_RUN, &ctx->sched_flags); spu_release(ctx); if (signal_pending(current)) diff --git a/arch/powerpc/platforms/cell/spufs/sched.c b/arch/powerpc/platforms/cell/spufs/sched.c index 3a5972117de7cdcd04504ae46d97e8b79376e0bc..00528ef84ad2085613703a8feab52a25b1ee9f93 100644 --- a/arch/powerpc/platforms/cell/spufs/sched.c +++ b/arch/powerpc/platforms/cell/spufs/sched.c @@ -246,7 +246,7 @@ static void spu_bind_context(struct spu *spu, struct spu_context *ctx) spu_switch_notify(spu, ctx); ctx->state = SPU_STATE_RUNNABLE; - spuctx_switch_state(ctx, SPU_UTIL_IDLE_LOADED); + spuctx_switch_state(ctx, SPU_UTIL_USER); } /* @@ -867,7 +867,7 @@ static noinline void spusched_tick(struct spu_context *ctx) if (ctx->policy == SCHED_FIFO) goto out; - if (--ctx->time_slice && ctx->policy != SCHED_IDLE) + if (--ctx->time_slice && test_bit(SPU_SCHED_SPU_RUN, &ctx->sched_flags)) goto out; spu = ctx->spu; @@ -877,7 +877,7 @@ static noinline void spusched_tick(struct spu_context *ctx) new = grab_runnable_context(ctx->prio + 1, spu->node); if (new) { spu_unschedule(spu, ctx); - if (ctx->policy != SCHED_IDLE) + if (test_bit(SPU_SCHED_SPU_RUN, &ctx->sched_flags)) spu_add_to_rq(ctx); } else { spu_context_nospu_trace(spusched_tick__newslice, ctx); diff --git a/arch/powerpc/platforms/cell/spufs/spufs.h b/arch/powerpc/platforms/cell/spufs/spufs.h index 2c2fe3c07d72da414038e8a81d327eaa4457baf4..cdc515182f823fc71357886c7dc5205f1d97f11d 100644 --- a/arch/powerpc/platforms/cell/spufs/spufs.h +++ b/arch/powerpc/platforms/cell/spufs/spufs.h @@ -44,6 +44,7 @@ struct spu_gang; enum { SPU_SCHED_NOTIFY_ACTIVE, SPU_SCHED_WAS_ACTIVE, /* was active upon spu_acquire_saved() */ + SPU_SCHED_SPU_RUN, /* context is within spu_run */ }; struct spu_context { diff --git a/arch/powerpc/platforms/cell/spufs/sputrace.c b/arch/powerpc/platforms/cell/spufs/sputrace.c index 01974f7776e184d798d33cb2728dc5c610cad368..79aa773f3c992abff92f38f51608bdcc5497c0a1 100644 --- a/arch/powerpc/platforms/cell/spufs/sputrace.c +++ b/arch/powerpc/platforms/cell/spufs/sputrace.c @@ -58,12 +58,12 @@ static int sputrace_sprint(char *tbuf, int n) ktime_to_timespec(ktime_sub(t->tstamp, sputrace_start)); return snprintf(tbuf, n, - "[%lu.%09lu] %d: %s (thread = %d, spu = %d)\n", + "[%lu.%09lu] %d: %s (ctxthread = %d, spu = %d)\n", (unsigned long) tv.tv_sec, (unsigned long) tv.tv_nsec, - t->owner_tid, - t->name, t->curr_tid, + t->name, + t->owner_tid, t->number); } @@ -188,6 +188,7 @@ struct spu_probe spu_probes[] = { { "spufs_ps_nopfn__insert", "%p %p", spu_context_event }, { "spu_acquire_saved__enter", "%p", spu_context_nospu_event }, { "destroy_spu_context__enter", "%p", spu_context_nospu_event }, + { "spufs_stop_callback__enter", "%p %p", spu_context_event }, }; static int __init sputrace_init(void) diff --git a/arch/powerpc/platforms/cell/spufs/switch.c b/arch/powerpc/platforms/cell/spufs/switch.c index 6f5886c7b1f9a8e5f16c1220df0a53c9c60cf241..e9dc7a55d1b9466d5f5e5597371a79789b46ed30 100644 --- a/arch/powerpc/platforms/cell/spufs/switch.c +++ b/arch/powerpc/platforms/cell/spufs/switch.c @@ -34,6 +34,7 @@ #include #include +#include #include #include #include @@ -117,6 +118,8 @@ static inline void disable_interrupts(struct spu_state *csa, struct spu *spu) * Write INT_MASK_class1 with value of 0. * Save INT_Mask_class2 in CSA. * Write INT_MASK_class2 with value of 0. + * Synchronize all three interrupts to be sure + * we no longer execute a handler on another CPU. */ spin_lock_irq(&spu->register_lock); if (csa) { @@ -129,6 +132,9 @@ static inline void disable_interrupts(struct spu_state *csa, struct spu *spu) spu_int_mask_set(spu, 2, 0ul); eieio(); spin_unlock_irq(&spu->register_lock); + synchronize_irq(spu->irqs[0]); + synchronize_irq(spu->irqs[1]); + synchronize_irq(spu->irqs[2]); } static inline void set_watchdog_timer(struct spu_state *csa, struct spu *spu) diff --git a/arch/powerpc/platforms/celleb/beat.h b/arch/powerpc/platforms/celleb/beat.h index b2e292df13ca25792b283bc7655bce2c9486e72f..ac82ac35b9918a98bff6ec5d4fcc8918e5796689 100644 --- a/arch/powerpc/platforms/celleb/beat.h +++ b/arch/powerpc/platforms/celleb/beat.h @@ -21,9 +21,6 @@ #ifndef _CELLEB_BEAT_H #define _CELLEB_BEAT_H -#define DABRX_KERNEL (1UL<<1) -#define DABRX_USER (1UL<<0) - int64_t beat_get_term_char(uint64_t,uint64_t*,uint64_t*,uint64_t*); int64_t beat_put_term_char(uint64_t,uint64_t,uint64_t,uint64_t); int64_t beat_repository_encode(int, const char *, uint64_t[4]); diff --git a/arch/powerpc/platforms/powermac/pic.c b/arch/powerpc/platforms/powermac/pic.c index 40736400ef80c2455e763d630175c93de73f22a9..829b8b02527bfb4f5d2a388256687ee10a2847a0 100644 --- a/arch/powerpc/platforms/powermac/pic.c +++ b/arch/powerpc/platforms/powermac/pic.c @@ -618,9 +618,9 @@ static int pmacpic_find_viaint(void) if (np == NULL) goto not_found; viaint = irq_of_parse_and_map(np, 0);; -#endif /* CONFIG_ADB_PMU */ not_found: +#endif /* CONFIG_ADB_PMU */ return viaint; } diff --git a/arch/powerpc/sysdev/qe_lib/qe.c b/arch/powerpc/sysdev/qe_lib/qe.c index 6efbd5e5bb1b6f1b8119ed8ccf7e8ed35591a015..cc81fd1141b031ffe476a12f033a7c925aff8f79 100644 --- a/arch/powerpc/sysdev/qe_lib/qe.c +++ b/arch/powerpc/sysdev/qe_lib/qe.c @@ -509,7 +509,7 @@ int qe_upload_firmware(const struct qe_firmware *firmware) } /* Validate some of the fields */ - if ((firmware->count < 1) || (firmware->count >= MAX_QE_RISC)) { + if ((firmware->count < 1) || (firmware->count > MAX_QE_RISC)) { printk(KERN_ERR "qe-firmware: invalid data\n"); return -EINVAL; } @@ -609,7 +609,10 @@ struct qe_firmware_info *qe_get_firmware_info(void) * If we haven't checked yet, and a driver hasn't uploaded a firmware * yet, then check the device tree for information. */ - if (initialized || qe_firmware_uploaded) + if (qe_firmware_uploaded) + return &qe_firmware_info; + + if (initialized) return NULL; initialized = 1; diff --git a/arch/ppc/kernel/head_8xx.S b/arch/ppc/kernel/head_8xx.S index eb8d26f8736239ace4aaac1163a81150e9003e78..321bda2de2cb8a40ab0600bb75da4676556edda3 100644 --- a/arch/ppc/kernel/head_8xx.S +++ b/arch/ppc/kernel/head_8xx.S @@ -329,8 +329,18 @@ InstructionTLBMiss: mfspr r11, SPRN_MD_TWC /* ....and get the pte address */ lwz r10, 0(r11) /* Get the pte */ +#ifdef CONFIG_SWAP + /* do not set the _PAGE_ACCESSED bit of a non-present page */ + andi. r11, r10, _PAGE_PRESENT + beq 4f + ori r10, r10, _PAGE_ACCESSED + mfspr r11, SPRN_MD_TWC /* get the pte address again */ + stw r10, 0(r11) +4: +#else ori r10, r10, _PAGE_ACCESSED stw r10, 0(r11) +#endif /* The Linux PTE won't go exactly into the MMU TLB. * Software indicator bits 21, 22 and 28 must be clear. @@ -395,8 +405,17 @@ DataStoreTLBMiss: DO_8xx_CPU6(0x3b80, r3) mtspr SPRN_MD_TWC, r11 - mfspr r11, SPRN_MD_TWC /* get the pte address again */ +#ifdef CONFIG_SWAP + /* do not set the _PAGE_ACCESSED bit of a non-present page */ + andi. r11, r10, _PAGE_PRESENT + beq 4f + ori r10, r10, _PAGE_ACCESSED +4: + /* and update pte in table */ +#else ori r10, r10, _PAGE_ACCESSED +#endif + mfspr r11, SPRN_MD_TWC /* get the pte address again */ stw r10, 0(r11) /* The Linux PTE won't go exactly into the MMU TLB. @@ -575,7 +594,16 @@ DataTLBError: /* Update 'changed', among others. */ +#ifdef CONFIG_SWAP + ori r10, r10, _PAGE_DIRTY|_PAGE_HWWRITE + /* do not set the _PAGE_ACCESSED bit of a non-present page */ + andi. r11, r10, _PAGE_PRESENT + beq 4f + ori r10, r10, _PAGE_ACCESSED +4: +#else ori r10, r10, _PAGE_DIRTY|_PAGE_ACCESSED|_PAGE_HWWRITE +#endif mfspr r11, SPRN_MD_TWC /* Get pte address again */ stw r10, 0(r11) /* and update pte in table */ diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig index b21444b681b667b526ddbebcca337e24d6b48581..1831833c430edc8d17015c739e9262b46bc88e77 100644 --- a/arch/s390/Kconfig +++ b/arch/s390/Kconfig @@ -61,6 +61,7 @@ config S390 def_bool y select HAVE_OPROFILE select HAVE_KPROBES + select HAVE_KRETPROBES source "init/Kconfig" @@ -350,6 +351,10 @@ endchoice source "fs/Kconfig.binfmt" +config FORCE_MAX_ZONEORDER + int + default "9" + config PROCESS_DEBUG bool "Show crashed user process info" help diff --git a/arch/s390/defconfig b/arch/s390/defconfig index 39921f3a9685a74247c9c2b8fbee8ad48bf1142c..62f6b5a606ddf3a8afbd63983822c0f14e45d483 100644 --- a/arch/s390/defconfig +++ b/arch/s390/defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.24 -# Sat Feb 9 12:13:01 2008 +# Linux kernel version: 2.6.25-rc4 +# Wed Mar 5 11:22:59 2008 # CONFIG_MMU=y CONFIG_ZONE_DMA=y @@ -43,12 +43,15 @@ CONFIG_CGROUPS=y # CONFIG_CGROUP_DEBUG is not set CONFIG_CGROUP_NS=y # CONFIG_CPUSETS is not set +CONFIG_GROUP_SCHED=y CONFIG_FAIR_GROUP_SCHED=y -CONFIG_FAIR_USER_SCHED=y -# CONFIG_FAIR_CGROUP_SCHED is not set +# CONFIG_RT_GROUP_SCHED is not set +CONFIG_USER_SCHED=y +# CONFIG_CGROUP_SCHED is not set # CONFIG_CGROUP_CPUACCT is not set # CONFIG_RESOURCE_COUNTERS is not set CONFIG_SYSFS_DEPRECATED=y +CONFIG_SYSFS_DEPRECATED_V2=y # CONFIG_RELAY is not set CONFIG_NAMESPACES=y CONFIG_UTS_NS=y @@ -85,7 +88,9 @@ CONFIG_SLAB=y # CONFIG_MARKERS is not set CONFIG_HAVE_OPROFILE=y CONFIG_KPROBES=y +CONFIG_KRETPROBES=y CONFIG_HAVE_KPROBES=y +CONFIG_HAVE_KRETPROBES=y CONFIG_PROC_PAGE_MONITOR=y CONFIG_SLABINFO=y CONFIG_RT_MUTEXES=y @@ -185,6 +190,7 @@ CONFIG_IPL=y CONFIG_IPL_VM=y CONFIG_BINFMT_ELF=y CONFIG_BINFMT_MISC=m +CONFIG_FORCE_MAX_ZONEORDER=9 # CONFIG_PROCESS_DEBUG is not set CONFIG_PFAULT=y # CONFIG_SHARED_KERNEL is not set @@ -435,6 +441,7 @@ CONFIG_DASD_EER=y CONFIG_MISC_DEVICES=y # CONFIG_EEPROM_93CX6 is not set # CONFIG_ENCLOSURE_SERVICES is not set +# CONFIG_HAVE_IDE is not set # # SCSI device support @@ -593,6 +600,7 @@ CONFIG_S390_VMUR=m # # Sonics Silicon Backplane # +# CONFIG_MEMSTICK is not set # # File systems @@ -750,7 +758,6 @@ CONFIG_DEBUG_BUGVERBOSE=y # CONFIG_DEBUG_LIST is not set # CONFIG_DEBUG_SG is not set # CONFIG_FRAME_POINTER is not set -CONFIG_FORCED_INLINING=y # CONFIG_RCU_TORTURE_TEST is not set # CONFIG_KPROBES_SANITY_TEST is not set # CONFIG_BACKTRACE_SELF_TEST is not set @@ -759,6 +766,7 @@ CONFIG_FORCED_INLINING=y # CONFIG_LATENCYTOP is not set CONFIG_SAMPLES=y # CONFIG_SAMPLE_KOBJECT is not set +# CONFIG_SAMPLE_KPROBES is not set # CONFIG_DEBUG_PAGEALLOC is not set # diff --git a/arch/s390/kernel/Makefile b/arch/s390/kernel/Makefile index b3b650a93c7c752f6d95c5b789beef5cfbd99589..4d3e38392cb1486dd11db7868098ec30c22808b4 100644 --- a/arch/s390/kernel/Makefile +++ b/arch/s390/kernel/Makefile @@ -4,6 +4,11 @@ EXTRA_AFLAGS := -traditional +# +# Passing null pointers is ok for smp code, since we access the lowcore here. +# +CFLAGS_smp.o := -Wno-nonnull + obj-y := bitmap.o traps.o time.o process.o base.o early.o \ setup.o sys_s390.o ptrace.o signal.o cpcmd.o ebcdic.o \ semaphore.o s390_ext.o debug.o irq.o ipl.o dis.o diag.o diff --git a/arch/s390/kernel/early.c b/arch/s390/kernel/early.c index 9f7b73b180f00a064ce36457b9ba88e0ecb38c79..01832c44063629ebf66afc77bb01fc2d838197bc 100644 --- a/arch/s390/kernel/early.c +++ b/arch/s390/kernel/early.c @@ -88,13 +88,17 @@ static noinline __init void create_kernel_nss(void) __cpcmd(defsys_cmd, NULL, 0, &response); - if (response != 0) + if (response != 0) { + kernel_nss_name[0] = '\0'; return; + } __cpcmd(savesys_cmd, NULL, 0, &response); - if (response != strlen(savesys_cmd)) + if (response != strlen(savesys_cmd)) { + kernel_nss_name[0] = '\0'; return; + } ipl_flags = IPL_NSS_VALID; } diff --git a/arch/s390/kernel/ipl.c b/arch/s390/kernel/ipl.c index 60acdc266db177fab528d5cedea72829a1cbe939..375232c46c7a51178f1e51c7a83043026c8c68d1 100644 --- a/arch/s390/kernel/ipl.c +++ b/arch/s390/kernel/ipl.c @@ -704,6 +704,7 @@ void reipl_run(struct shutdown_trigger *trigger) default: break; } + disabled_wait((unsigned long) __builtin_return_address(0)); } static void __init reipl_probe(void) diff --git a/arch/s390/kernel/process.c b/arch/s390/kernel/process.c index 1c59ec161cf8772e5ac260aa0cce812c4db84ba8..ce203154d8ce3a6c8f9bf4a07cd7ad072e3b3ec8 100644 --- a/arch/s390/kernel/process.c +++ b/arch/s390/kernel/process.c @@ -152,6 +152,10 @@ static void default_idle(void) local_mcck_disable(); if (test_thread_flag(TIF_MCCK_PENDING)) { local_mcck_enable(); + /* disable monitor call class 0 */ + __ctl_clear_bit(8, 15); + atomic_notifier_call_chain(&idle_chain, S390_CPU_NOT_IDLE, + hcpu); local_irq_enable(); s390_handle_mcck(); return; diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c index 818bd09c0260e05fb3a58eb2764f88e8f055a585..8f894d380a626316c68aeb073043f027abdcfee6 100644 --- a/arch/s390/kernel/smp.c +++ b/arch/s390/kernel/smp.c @@ -629,14 +629,8 @@ static int __cpuinit smp_alloc_lowcore(int cpu) panic_stack = __get_free_page(GFP_KERNEL); if (!panic_stack || !async_stack) goto out; - /* - * Only need to copy the first 512 bytes from address 0. But since - * the compiler emits a warning if src == NULL for memcpy use copy_page - * instead. Copies more than needed but this code is not performance - * critical. - */ - copy_page(lowcore, &S390_lowcore); - memset((void *)lowcore + 512, 0, sizeof(*lowcore) - 512); + memcpy(lowcore, &S390_lowcore, 512); + memset((char *)lowcore + 512, 0, sizeof(*lowcore) - 512); lowcore->async_stack = async_stack + ASYNC_SIZE; lowcore->panic_stack = panic_stack + PAGE_SIZE; diff --git a/arch/s390/kernel/time.c b/arch/s390/kernel/time.c index 76a5dd1b4ce9a1376f85c7d1e8711aa423a6f85a..cb232c155360627866c4e9f7decda622f4048b50 100644 --- a/arch/s390/kernel/time.c +++ b/arch/s390/kernel/time.c @@ -209,8 +209,6 @@ static void stop_hz_timer(void) */ static void start_hz_timer(void) { - BUG_ON(!in_interrupt()); - if (!cpu_isset(smp_processor_id(), nohz_cpu_mask)) return; account_ticks(get_clock()); diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig index b3400b5ad5c605cface4aedcd88cd565a25b8909..95b7534e9e3ccb53a6ea55addf0e2d60a5cbe45f 100644 --- a/arch/sh/Kconfig +++ b/arch/sh/Kconfig @@ -330,6 +330,7 @@ config CPU_SUBTYPE_SH5_101 config CPU_SUBTYPE_SH5_103 bool "Support SH5-103 processor" + select CPU_SH5 endchoice @@ -455,13 +456,6 @@ config SH_SECUREEDGE5410 This includes both the OEM SecureEdge products as well as the SME product line. -config SH_7710VOIPGW - bool "SH7710-VOIP-GW" - depends on CPU_SUBTYPE_SH7710 - help - Select this option to build a kernel for the SH7710 based - VOIP GW. - config SH_RTS7751R2D bool "RTS7751R2D" depends on CPU_SUBTYPE_SH7751R diff --git a/arch/sh/Makefile b/arch/sh/Makefile index 81381e5773c85b841e42a8fb0e7dd41d37579484..c510c225144fc57a9222af156f98fe8384073cb3 100644 --- a/arch/sh/Makefile +++ b/arch/sh/Makefile @@ -118,7 +118,6 @@ machdir-$(CONFIG_SH_EDOSK7705) += renesas/edosk7705 machdir-$(CONFIG_SH_HIGHLANDER) += renesas/r7780rp machdir-$(CONFIG_SH_MIGOR) += renesas/migor machdir-$(CONFIG_SH_SDK7780) += renesas/sdk7780 -machdir-$(CONFIG_SH_7710VOIPGW) += renesas/sh7710voipgw machdir-$(CONFIG_SH_X3PROTO) += renesas/x3proto machdir-$(CONFIG_SH_SH4202_MICRODEV) += superh/microdev machdir-$(CONFIG_SH_LANDISK) += landisk diff --git a/arch/sh/boards/hp6xx/hp6xx_apm.c b/arch/sh/boards/hp6xx/hp6xx_apm.c index 640ca2a74f163c07ef42ac570e11cb254da76e0f..177f4f028e0dd5769d6d530290b6b6fec9097318 100644 --- a/arch/sh/boards/hp6xx/hp6xx_apm.c +++ b/arch/sh/boards/hp6xx/hp6xx_apm.c @@ -2,6 +2,7 @@ * bios-less APM driver for hp680 * * Copyright 2005 (c) Andriy Skulysh + * Copyright 2008 (c) Kristoffer Ericson * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License. @@ -15,17 +16,19 @@ #include #include -#define SH7709_PGDR 0xa400012c - +/* percentage values */ #define APM_CRITICAL 10 #define APM_LOW 30 +/* resonably sane values */ #define HP680_BATTERY_MAX 898 #define HP680_BATTERY_MIN 486 #define HP680_BATTERY_AC_ON 1023 #define MODNAME "hp6x0_apm" +#define PGDR 0xa400012c + static void hp6x0_apm_get_power_status(struct apm_power_info *info) { int battery, backup, charging, percentage; @@ -38,17 +41,26 @@ static void hp6x0_apm_get_power_status(struct apm_power_info *info) percentage = 100 * (battery - HP680_BATTERY_MIN) / (HP680_BATTERY_MAX - HP680_BATTERY_MIN); + /* % of full battery */ + info->battery_life = percentage; + + /* We want our estimates in minutes */ + info->units = 0; + + /* Extremely(!!) rough estimate, we will replace this with a datalist later on */ + info->time = (2 * battery); + info->ac_line_status = (battery > HP680_BATTERY_AC_ON) ? APM_AC_ONLINE : APM_AC_OFFLINE; - pgdr = ctrl_inb(SH7709_PGDR); + pgdr = ctrl_inb(PGDR); if (pgdr & PGDR_MAIN_BATTERY_OUT) { info->battery_status = APM_BATTERY_STATUS_NOT_PRESENT; info->battery_flag = 0x80; } else if (charging < 8) { info->battery_status = APM_BATTERY_STATUS_CHARGING; info->battery_flag = 0x08; - info->ac_line_status = 0xff; + info->ac_line_status = 0x01; } else if (percentage <= APM_CRITICAL) { info->battery_status = APM_BATTERY_STATUS_CRITICAL; info->battery_flag = 0x04; @@ -59,8 +71,6 @@ static void hp6x0_apm_get_power_status(struct apm_power_info *info) info->battery_status = APM_BATTERY_STATUS_HIGH; info->battery_flag = 0x01; } - - info->units = 0; } static irqreturn_t hp6x0_apm_interrupt(int irq, void *dev) diff --git a/arch/sh/boards/renesas/sh7710voipgw/Makefile b/arch/sh/boards/renesas/sh7710voipgw/Makefile deleted file mode 100644 index 77037567633b674f1a312fd190db2d6eb9013ec3..0000000000000000000000000000000000000000 --- a/arch/sh/boards/renesas/sh7710voipgw/Makefile +++ /dev/null @@ -1 +0,0 @@ -obj-y := setup.o diff --git a/arch/sh/boards/renesas/sh7710voipgw/setup.c b/arch/sh/boards/renesas/sh7710voipgw/setup.c deleted file mode 100644 index 0d56fd83bcba750c07c3267e30fed4565a92064f..0000000000000000000000000000000000000000 --- a/arch/sh/boards/renesas/sh7710voipgw/setup.c +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Renesas Technology SH7710 VoIP Gateway - * - * Copyright (C) 2006 Ranjit Deshpande - * Kenati Technologies Inc. - * - * May be copied or modified under the terms of the GNU General Public - * License. See linux/COPYING for more information. - */ -#include -#include -#include -#include - -static struct ipr_data sh7710voipgw_ipr_map[] = { - { TIMER2_IRQ, TIMER2_IPR_ADDR, TIMER2_IPR_POS, TIMER2_PRIORITY }, - { WDT_IRQ, WDT_IPR_ADDR, WDT_IPR_POS, WDT_PRIORITY }, - - /* SCIF0 */ - { SCIF0_ERI_IRQ, SCIF0_IPR_ADDR, SCIF0_IPR_POS, SCIF0_PRIORITY }, - { SCIF0_RXI_IRQ, SCIF0_IPR_ADDR, SCIF0_IPR_POS, SCIF0_PRIORITY }, - { SCIF0_BRI_IRQ, SCIF0_IPR_ADDR, SCIF0_IPR_POS, SCIF0_PRIORITY }, - { SCIF0_TXI_IRQ, SCIF0_IPR_ADDR, SCIF0_IPR_POS, SCIF0_PRIORITY }, - - /* DMAC-1 */ - { DMTE0_IRQ, DMA_IPR_ADDR, DMA_IPR_POS, DMA_PRIORITY }, - { DMTE1_IRQ, DMA_IPR_ADDR, DMA_IPR_POS, DMA_PRIORITY }, - { DMTE2_IRQ, DMA_IPR_ADDR, DMA_IPR_POS, DMA_PRIORITY }, - { DMTE3_IRQ, DMA_IPR_ADDR, DMA_IPR_POS, DMA_PRIORITY }, - - /* DMAC-2 */ - { DMTE4_IRQ, DMA2_IPR_ADDR, DMA2_IPR_POS, DMA2_PRIORITY }, - { DMTE4_IRQ, DMA2_IPR_ADDR, DMA2_IPR_POS, DMA2_PRIORITY }, - - /* IPSEC */ - { IPSEC_IRQ, IPSEC_IPR_ADDR, IPSEC_IPR_POS, IPSEC_PRIORITY }, - - /* EDMAC */ - { EDMAC0_IRQ, EDMAC0_IPR_ADDR, EDMAC0_IPR_POS, EDMAC0_PRIORITY }, - { EDMAC1_IRQ, EDMAC1_IPR_ADDR, EDMAC1_IPR_POS, EDMAC1_PRIORITY }, - { EDMAC2_IRQ, EDMAC2_IPR_ADDR, EDMAC2_IPR_POS, EDMAC2_PRIORITY }, - - /* SIOF0 */ - { SIOF0_ERI_IRQ, SIOF0_IPR_ADDR, SIOF0_IPR_POS, SIOF0_PRIORITY }, - { SIOF0_TXI_IRQ, SIOF0_IPR_ADDR, SIOF0_IPR_POS, SIOF0_PRIORITY }, - { SIOF0_RXI_IRQ, SIOF0_IPR_ADDR, SIOF0_IPR_POS, SIOF0_PRIORITY }, - { SIOF0_CCI_IRQ, SIOF0_IPR_ADDR, SIOF0_IPR_POS, SIOF0_PRIORITY }, - - /* SIOF1 */ - { SIOF1_ERI_IRQ, SIOF1_IPR_ADDR, SIOF1_IPR_POS, SIOF1_PRIORITY }, - { SIOF1_TXI_IRQ, SIOF1_IPR_ADDR, SIOF1_IPR_POS, SIOF1_PRIORITY }, - { SIOF1_RXI_IRQ, SIOF1_IPR_ADDR, SIOF1_IPR_POS, SIOF1_PRIORITY }, - { SIOF1_CCI_IRQ, SIOF1_IPR_ADDR, SIOF1_IPR_POS, SIOF1_PRIORITY }, - - /* SLIC IRQ's */ - { IRQ1_IRQ, IRQ1_IPR_ADDR, IRQ1_IPR_POS, IRQ1_PRIORITY }, - { IRQ2_IRQ, IRQ2_IPR_ADDR, IRQ2_IPR_POS, IRQ2_PRIORITY }, -}; - -/* - * Initialize IRQ setting - */ -static void __init sh7710voipgw_init_irq(void) -{ - /* Disable all interrupts in IPR registers */ - ctrl_outw(0x0, INTC_IPRA); - ctrl_outw(0x0, INTC_IPRB); - ctrl_outw(0x0, INTC_IPRC); - ctrl_outw(0x0, INTC_IPRD); - ctrl_outw(0x0, INTC_IPRE); - ctrl_outw(0x0, INTC_IPRF); - ctrl_outw(0x0, INTC_IPRG); - ctrl_outw(0x0, INTC_IPRH); - ctrl_outw(0x0, INTC_IPRI); - - /* Ack all interrupt sources in the IRR0 register */ - ctrl_outb(0x3f, INTC_IRR0); - - /* Use IRQ0 - IRQ3 as active low interrupt lines i.e. disable - * IRL mode. - */ - ctrl_outw(0x2aa, INTC_ICR1); - - make_ipr_irq(sh7710voipgw_ipr_map, ARRAY_SIZE(sh7710voipgw_ipr_map)); -} - -/* - * The Machine Vector - */ -static struct sh_machine_vector mv_sh7710voipgw __initmv = { - .mv_name = "SH7710 VoIP Gateway", - .mv_nr_irqs = 104, - .mv_init_irq = sh7710voipgw_init_irq, -}; diff --git a/arch/sh/boards/renesas/x3proto/ilsel.c b/arch/sh/boards/renesas/x3proto/ilsel.c index 6d4454fef97c948e3ba9640ced74c636e326adcc..b5c673c39337ef14fb6b7b7ab99de0b6d838c0c6 100644 --- a/arch/sh/boards/renesas/x3proto/ilsel.c +++ b/arch/sh/boards/renesas/x3proto/ilsel.c @@ -68,7 +68,7 @@ static void __ilsel_enable(ilsel_source_t set, unsigned int bit) shift = mk_ilsel_shift(bit); pr_debug("%s: bit#%d: addr - 0x%08lx (shift %d, set %d)\n", - __FUNCTION__, bit, addr, shift, set); + __func__, bit, addr, shift, set); tmp = ctrl_inw(addr); tmp &= ~(0xf << shift); diff --git a/arch/sh/boards/superh/microdev/io.c b/arch/sh/boards/superh/microdev/io.c index b704e20d7e4dccf35ac9c5b3c614577840f5ec80..9f8a540f7e141d0ee61f9094c7d9436fc1135b1c 100644 --- a/arch/sh/boards/superh/microdev/io.c +++ b/arch/sh/boards/superh/microdev/io.c @@ -127,7 +127,7 @@ static unsigned long microdev_isa_port2addr(unsigned long offset) * safe default. */ printk("Warning: unexpected port in %s( offset = 0x%lx )\n", - __FUNCTION__, offset); + __func__, offset); result = PVR; } diff --git a/arch/sh/configs/r7780mp_defconfig b/arch/sh/configs/r7780mp_defconfig index 2ad804ec920a62d6f3373f74955f595f2dc138f0..1a072615ffd41a1c62c1dbc547d43cbfa61657b3 100644 --- a/arch/sh/configs/r7780mp_defconfig +++ b/arch/sh/configs/r7780mp_defconfig @@ -1,9 +1,10 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.24-rc2 -# Tue Nov 13 20:32:39 2007 +# Linux kernel version: 2.6.25-rc4 +# Thu Mar 6 15:39:59 2008 # CONFIG_SUPERH=y +CONFIG_SUPERH32=y CONFIG_RWSEM_GENERIC_SPINLOCK=y CONFIG_GENERIC_BUG=y CONFIG_GENERIC_FIND_NEXT_BIT=y @@ -19,6 +20,8 @@ CONFIG_LOCKDEP_SUPPORT=y # CONFIG_ARCH_HAS_ILOG2_U32 is not set # CONFIG_ARCH_HAS_ILOG2_U64 is not set CONFIG_ARCH_NO_VIRT_TO_BUS=y +CONFIG_ARCH_SUPPORTS_AOUT=y +CONFIG_IO_TRAPPED=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # @@ -37,17 +40,20 @@ CONFIG_SYSVIPC_SYSCTL=y CONFIG_BSD_PROCESS_ACCT=y # CONFIG_BSD_PROCESS_ACCT_V3 is not set # CONFIG_TASKSTATS is not set -# CONFIG_USER_NS is not set # CONFIG_AUDIT is not set CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y CONFIG_LOG_BUF_SHIFT=14 # CONFIG_CGROUPS is not set +CONFIG_GROUP_SCHED=y CONFIG_FAIR_GROUP_SCHED=y -CONFIG_FAIR_USER_SCHED=y -# CONFIG_FAIR_CGROUP_SCHED is not set -# CONFIG_SYSFS_DEPRECATED is not set +# CONFIG_RT_GROUP_SCHED is not set +CONFIG_USER_SCHED=y +# CONFIG_CGROUP_SCHED is not set +CONFIG_SYSFS_DEPRECATED=y +CONFIG_SYSFS_DEPRECATED_V2=y # CONFIG_RELAY is not set +# CONFIG_NAMESPACES is not set # CONFIG_BLK_DEV_INITRD is not set CONFIG_CC_OPTIMIZE_FOR_SIZE=y CONFIG_SYSCTL=y @@ -61,17 +67,27 @@ CONFIG_HOTPLUG=y CONFIG_PRINTK=y CONFIG_BUG=y CONFIG_ELF_CORE=y +CONFIG_COMPAT_BRK=y CONFIG_BASE_FULL=y # CONFIG_FUTEX is not set CONFIG_ANON_INODES=y # CONFIG_EPOLL is not set CONFIG_SIGNALFD=y +CONFIG_TIMERFD=y CONFIG_EVENTFD=y CONFIG_SHMEM=y CONFIG_VM_EVENT_COUNTERS=y CONFIG_SLAB=y # CONFIG_SLUB is not set # CONFIG_SLOB is not set +CONFIG_PROFILING=y +# CONFIG_MARKERS is not set +CONFIG_OPROFILE=m +CONFIG_HAVE_OPROFILE=y +# CONFIG_HAVE_KPROBES is not set +# CONFIG_HAVE_KRETPROBES is not set +CONFIG_PROC_PAGE_MONITOR=y +CONFIG_SLABINFO=y # CONFIG_TINY_SHMEM is not set CONFIG_BASE_SMALL=0 CONFIG_MODULES=y @@ -98,6 +114,8 @@ CONFIG_IOSCHED_NOOP=y # CONFIG_DEFAULT_CFQ is not set CONFIG_DEFAULT_NOOP=y CONFIG_DEFAULT_IOSCHED="noop" +CONFIG_CLASSIC_RCU=y +# CONFIG_PREEMPT_RCU is not set # # System type @@ -105,7 +123,9 @@ CONFIG_DEFAULT_IOSCHED="noop" CONFIG_CPU_SH4=y CONFIG_CPU_SH4A=y # CONFIG_CPU_SUBTYPE_SH7619 is not set +# CONFIG_CPU_SUBTYPE_SH7203 is not set # CONFIG_CPU_SUBTYPE_SH7206 is not set +# CONFIG_CPU_SUBTYPE_SH7263 is not set # CONFIG_CPU_SUBTYPE_SH7705 is not set # CONFIG_CPU_SUBTYPE_SH7706 is not set # CONFIG_CPU_SUBTYPE_SH7707 is not set @@ -114,6 +134,7 @@ CONFIG_CPU_SH4A=y # CONFIG_CPU_SUBTYPE_SH7710 is not set # CONFIG_CPU_SUBTYPE_SH7712 is not set # CONFIG_CPU_SUBTYPE_SH7720 is not set +# CONFIG_CPU_SUBTYPE_SH7721 is not set # CONFIG_CPU_SUBTYPE_SH7750 is not set # CONFIG_CPU_SUBTYPE_SH7091 is not set # CONFIG_CPU_SUBTYPE_SH7750R is not set @@ -122,12 +143,16 @@ CONFIG_CPU_SH4A=y # CONFIG_CPU_SUBTYPE_SH7751R is not set # CONFIG_CPU_SUBTYPE_SH7760 is not set # CONFIG_CPU_SUBTYPE_SH4_202 is not set +# CONFIG_CPU_SUBTYPE_SH7763 is not set # CONFIG_CPU_SUBTYPE_SH7770 is not set CONFIG_CPU_SUBTYPE_SH7780=y # CONFIG_CPU_SUBTYPE_SH7785 is not set # CONFIG_CPU_SUBTYPE_SHX3 is not set # CONFIG_CPU_SUBTYPE_SH7343 is not set # CONFIG_CPU_SUBTYPE_SH7722 is not set +# CONFIG_CPU_SUBTYPE_SH7366 is not set +# CONFIG_CPU_SUBTYPE_SH5_101 is not set +# CONFIG_CPU_SUBTYPE_SH5_103 is not set # # Memory management options @@ -137,7 +162,8 @@ CONFIG_MMU=y CONFIG_PAGE_OFFSET=0x80000000 CONFIG_MEMORY_START=0x08000000 CONFIG_MEMORY_SIZE=0x08000000 -# CONFIG_32BIT is not set +CONFIG_29BIT=y +# CONFIG_PMB is not set CONFIG_VSYSCALL=y CONFIG_ARCH_FLATMEM_ENABLE=y CONFIG_ARCH_SPARSEMEM_ENABLE=y @@ -153,6 +179,7 @@ CONFIG_HUGETLB_PAGE_SIZE_64K=y # CONFIG_HUGETLB_PAGE_SIZE_1MB is not set # CONFIG_HUGETLB_PAGE_SIZE_4MB is not set # CONFIG_HUGETLB_PAGE_SIZE_64MB is not set +# CONFIG_HUGETLB_PAGE_SIZE_512MB is not set CONFIG_SELECT_MEMORY_MODEL=y CONFIG_FLATMEM_MANUAL=y # CONFIG_DISCONTIGMEM_MANUAL is not set @@ -190,6 +217,7 @@ CONFIG_CPU_HAS_FPU=y # Board support # # CONFIG_SH_7780_SOLUTION_ENGINE is not set +# CONFIG_SH_SDK7780 is not set CONFIG_SH_HIGHLANDER=y # CONFIG_SH_R7780RP is not set CONFIG_SH_R7780MP=y @@ -234,12 +262,13 @@ CONFIG_HZ_250=y # CONFIG_HZ_300 is not set # CONFIG_HZ_1000 is not set CONFIG_HZ=250 +# CONFIG_SCHED_HRTICK is not set CONFIG_KEXEC=y # CONFIG_CRASH_DUMP is not set # CONFIG_PREEMPT_NONE is not set # CONFIG_PREEMPT_VOLUNTARY is not set CONFIG_PREEMPT=y -CONFIG_PREEMPT_BKL=y +CONFIG_RCU_TRACE=y CONFIG_GUSA=y # @@ -284,6 +313,7 @@ CONFIG_XFRM=y # CONFIG_XFRM_USER is not set # CONFIG_XFRM_SUB_POLICY is not set # CONFIG_XFRM_MIGRATE is not set +# CONFIG_XFRM_STATISTICS is not set # CONFIG_NET_KEY is not set CONFIG_INET=y # CONFIG_IP_MULTICAST is not set @@ -344,6 +374,7 @@ CONFIG_LLC=m # # CONFIG_NET_PKTGEN is not set # CONFIG_HAMRADIO is not set +# CONFIG_CAN is not set # CONFIG_IRDA is not set # CONFIG_BT is not set # CONFIG_AF_RXRPC is not set @@ -386,7 +417,7 @@ CONFIG_BLK_DEV=y CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_COUNT=16 CONFIG_BLK_DEV_RAM_SIZE=4096 -CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 +# CONFIG_BLK_DEV_XIP is not set # CONFIG_CDROM_PKTCDVD is not set # CONFIG_ATA_OVER_ETH is not set CONFIG_MISC_DEVICES=y @@ -394,6 +425,8 @@ CONFIG_MISC_DEVICES=y CONFIG_EEPROM_93CX6=y # CONFIG_SGI_IOC4 is not set # CONFIG_TIFM_CORE is not set +# CONFIG_ENCLOSURE_SERVICES is not set +CONFIG_HAVE_IDE=y # CONFIG_IDE is not set # @@ -453,6 +486,7 @@ CONFIG_SCSI_LOWLEVEL=y # CONFIG_SCSI_IPS is not set # CONFIG_SCSI_INITIO is not set # CONFIG_SCSI_INIA100 is not set +# CONFIG_SCSI_MVSAS is not set # CONFIG_SCSI_STEX is not set # CONFIG_SCSI_SYM53C8XX_2 is not set # CONFIG_SCSI_IPR is not set @@ -506,6 +540,7 @@ CONFIG_SATA_SIL=y # CONFIG_PATA_MPIIX is not set # CONFIG_PATA_OLDPIIX is not set # CONFIG_PATA_NETCELL is not set +# CONFIG_PATA_NINJA32 is not set # CONFIG_PATA_NS87410 is not set # CONFIG_PATA_NS87415 is not set # CONFIG_PATA_OPTI is not set @@ -538,7 +573,6 @@ CONFIG_NETDEVICES=y # CONFIG_EQUALIZER is not set # CONFIG_TUN is not set # CONFIG_VETH is not set -# CONFIG_IP1000 is not set # CONFIG_ARCNET is not set # CONFIG_PHYLIB is not set CONFIG_NET_ETHERNET=y @@ -551,7 +585,6 @@ CONFIG_AX88796_93CX6=y # CONFIG_CASSINI is not set # CONFIG_NET_VENDOR_3COM is not set # CONFIG_SMC91X is not set -# CONFIG_SMC911X is not set # CONFIG_NET_TULIP is not set # CONFIG_HP100 is not set # CONFIG_IBM_NEW_EMAC_ZMII is not set @@ -576,6 +609,7 @@ CONFIG_8139TOO=m # CONFIG_8139TOO_TUNE_TWISTER is not set CONFIG_8139TOO_8129=y # CONFIG_8139_OLD_RX_RESET is not set +# CONFIG_R6040 is not set # CONFIG_SIS900 is not set # CONFIG_EPIC100 is not set # CONFIG_SUNDANCE is not set @@ -591,6 +625,9 @@ CONFIG_E1000=m # CONFIG_E1000_NAPI is not set # CONFIG_E1000_DISABLE_PACKET_SPLIT is not set # CONFIG_E1000E is not set +# CONFIG_E1000E_ENABLED is not set +# CONFIG_IP1000 is not set +# CONFIG_IGB is not set # CONFIG_NS83820 is not set # CONFIG_HAMACHI is not set # CONFIG_YELLOWFIN is not set @@ -616,6 +653,7 @@ CONFIG_NETDEV_10000=y # CONFIG_NIU is not set # CONFIG_MLX4_CORE is not set # CONFIG_TEHUTI is not set +# CONFIG_BNX2X is not set # CONFIG_TR is not set # @@ -629,7 +667,6 @@ CONFIG_NETDEV_10000=y # CONFIG_PPP is not set # CONFIG_SLIP is not set # CONFIG_NET_FC is not set -# CONFIG_SHAPER is not set # CONFIG_NETCONSOLE is not set # CONFIG_NETPOLL is not set # CONFIG_NET_POLL_CONTROLLER is not set @@ -686,6 +723,7 @@ CONFIG_SERIO_LIBPS2=y # # CONFIG_VT is not set # CONFIG_SERIAL_NONSTANDARD is not set +# CONFIG_NOZOMI is not set # # Serial drivers @@ -722,6 +760,7 @@ CONFIG_DEVPORT=y # CONFIG_POWER_SUPPLY is not set CONFIG_HWMON=y # CONFIG_HWMON_VID is not set +# CONFIG_SENSORS_I5K_AMB is not set # CONFIG_SENSORS_F71805F is not set # CONFIG_SENSORS_F71882FG is not set # CONFIG_SENSORS_IT87 is not set @@ -736,6 +775,7 @@ CONFIG_HWMON=y # CONFIG_SENSORS_W83627HF is not set # CONFIG_SENSORS_W83627EHF is not set # CONFIG_HWMON_DEBUG_CHIP is not set +CONFIG_THERMAL=y # CONFIG_WATCHDOG is not set # @@ -800,12 +840,9 @@ CONFIG_USB_ARCH_HAS_EHCI=y # # NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' # - -# -# USB Gadget Support -# # CONFIG_USB_GADGET is not set # CONFIG_MMC is not set +# CONFIG_MEMSTICK is not set # CONFIG_NEW_LEDS is not set # CONFIG_INFINIBAND is not set CONFIG_RTC_LIB=y @@ -830,9 +867,10 @@ CONFIG_RTC_INTF_DEV=y # # Platform RTC drivers # +# CONFIG_RTC_DRV_DS1511 is not set # CONFIG_RTC_DRV_DS1553 is not set -# CONFIG_RTC_DRV_STK17TA8 is not set # CONFIG_RTC_DRV_DS1742 is not set +# CONFIG_RTC_DRV_STK17TA8 is not set # CONFIG_RTC_DRV_M48T86 is not set # CONFIG_RTC_DRV_M48T59 is not set # CONFIG_RTC_DRV_V3020 is not set @@ -867,12 +905,10 @@ CONFIG_FS_POSIX_ACL=y # CONFIG_XFS_FS is not set # CONFIG_GFS2_FS is not set # CONFIG_OCFS2_FS is not set -CONFIG_MINIX_FS=y -# CONFIG_ROMFS_FS is not set +CONFIG_DNOTIFY=y CONFIG_INOTIFY=y CONFIG_INOTIFY_USER=y # CONFIG_QUOTA is not set -CONFIG_DNOTIFY=y # CONFIG_AUTOFS_FS is not set # CONFIG_AUTOFS4_FS is not set CONFIG_FUSE_FS=m @@ -920,8 +956,10 @@ CONFIG_CONFIGFS_FS=m # CONFIG_EFS_FS is not set # CONFIG_CRAMFS is not set # CONFIG_VXFS_FS is not set +CONFIG_MINIX_FS=y # CONFIG_HPFS_FS is not set # CONFIG_QNX4FS_FS is not set +# CONFIG_ROMFS_FS is not set # CONFIG_SYSV_FS is not set # CONFIG_UFS_FS is not set CONFIG_NETWORK_FILESYSTEMS=y @@ -997,10 +1035,6 @@ CONFIG_NLS_ISO8859_1=y # CONFIG_NLS_KOI8_U is not set # CONFIG_NLS_UTF8 is not set # CONFIG_DLM is not set -CONFIG_INSTRUMENTATION=y -CONFIG_PROFILING=y -CONFIG_OPROFILE=m -# CONFIG_MARKERS is not set # # Kernel hacking @@ -1035,9 +1069,9 @@ CONFIG_DEBUG_INFO=y # CONFIG_DEBUG_LIST is not set # CONFIG_DEBUG_SG is not set # CONFIG_FRAME_POINTER is not set -CONFIG_FORCED_INLINING=y # CONFIG_BOOT_PRINTK_DELAY is not set # CONFIG_RCU_TORTURE_TEST is not set +# CONFIG_BACKTRACE_SELF_TEST is not set # CONFIG_FAULT_INJECTION is not set # CONFIG_SAMPLES is not set CONFIG_SH_STANDARD_BIOS=y @@ -1059,6 +1093,7 @@ CONFIG_DEBUG_STACKOVERFLOW=y CONFIG_CRYPTO=y CONFIG_CRYPTO_ALGAPI=y CONFIG_CRYPTO_BLKCIPHER=y +# CONFIG_CRYPTO_SEQIV is not set CONFIG_CRYPTO_HASH=y CONFIG_CRYPTO_MANAGER=y CONFIG_CRYPTO_HMAC=y @@ -1077,6 +1112,9 @@ CONFIG_CRYPTO_CBC=y CONFIG_CRYPTO_PCBC=m # CONFIG_CRYPTO_LRW is not set # CONFIG_CRYPTO_XTS is not set +# CONFIG_CRYPTO_CTR is not set +# CONFIG_CRYPTO_GCM is not set +# CONFIG_CRYPTO_CCM is not set # CONFIG_CRYPTO_CRYPTD is not set CONFIG_CRYPTO_DES=y # CONFIG_CRYPTO_FCRYPT is not set @@ -1091,13 +1129,16 @@ CONFIG_CRYPTO_DES=y # CONFIG_CRYPTO_KHAZAD is not set # CONFIG_CRYPTO_ANUBIS is not set # CONFIG_CRYPTO_SEED is not set +# CONFIG_CRYPTO_SALSA20 is not set # CONFIG_CRYPTO_DEFLATE is not set # CONFIG_CRYPTO_MICHAEL_MIC is not set # CONFIG_CRYPTO_CRC32C is not set # CONFIG_CRYPTO_CAMELLIA is not set # CONFIG_CRYPTO_TEST is not set # CONFIG_CRYPTO_AUTHENC is not set +# CONFIG_CRYPTO_LZO is not set CONFIG_CRYPTO_HW=y +# CONFIG_CRYPTO_DEV_HIFN_795X is not set # # Library routines diff --git a/arch/sh/configs/se7780_defconfig b/arch/sh/configs/se7780_defconfig index f68743dc3931e876838f03d5a4dfdddbdf69e96b..30f5ee40c312fc43105d4660d9eb4e23c6796d05 100644 --- a/arch/sh/configs/se7780_defconfig +++ b/arch/sh/configs/se7780_defconfig @@ -1,9 +1,10 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.21-rc3 -# Thu Mar 15 14:06:20 2007 +# Linux kernel version: 2.6.25-rc3 +# Thu Feb 28 10:18:04 2008 # CONFIG_SUPERH=y +CONFIG_SUPERH32=y CONFIG_RWSEM_GENERIC_SPINLOCK=y CONFIG_GENERIC_BUG=y CONFIG_GENERIC_FIND_NEXT_BIT=y @@ -11,38 +12,44 @@ CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_HARDIRQS=y CONFIG_GENERIC_IRQ_PROBE=y CONFIG_GENERIC_CALIBRATE_DELAY=y -# CONFIG_GENERIC_TIME is not set +CONFIG_GENERIC_TIME=y +CONFIG_GENERIC_CLOCKEVENTS=y +CONFIG_SYS_SUPPORTS_PCI=y CONFIG_STACKTRACE_SUPPORT=y CONFIG_LOCKDEP_SUPPORT=y # CONFIG_ARCH_HAS_ILOG2_U32 is not set # CONFIG_ARCH_HAS_ILOG2_U64 is not set +CONFIG_ARCH_NO_VIRT_TO_BUS=y +CONFIG_ARCH_SUPPORTS_AOUT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # -# Code maturity level options +# General setup # # CONFIG_EXPERIMENTAL is not set CONFIG_BROKEN_ON_SMP=y CONFIG_INIT_ENV_ARG_LIMIT=32 - -# -# General setup -# CONFIG_LOCALVERSION="" CONFIG_LOCALVERSION_AUTO=y # CONFIG_SWAP is not set CONFIG_SYSVIPC=y -# CONFIG_IPC_NS is not set CONFIG_SYSVIPC_SYSCTL=y # CONFIG_BSD_PROCESS_ACCT is not set # CONFIG_TASKSTATS is not set -# CONFIG_UTS_NS is not set # CONFIG_AUDIT is not set CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y +CONFIG_LOG_BUF_SHIFT=14 +# CONFIG_CGROUPS is not set +CONFIG_GROUP_SCHED=y +CONFIG_FAIR_GROUP_SCHED=y +CONFIG_USER_SCHED=y +# CONFIG_CGROUP_SCHED is not set CONFIG_SYSFS_DEPRECATED=y # CONFIG_RELAY is not set +# CONFIG_NAMESPACES is not set # CONFIG_BLK_DEV_INITRD is not set +CONFIG_CC_OPTIMIZE_FOR_SIZE=y CONFIG_SYSCTL=y CONFIG_EMBEDDED=y CONFIG_UID16=y @@ -52,31 +59,36 @@ CONFIG_SYSCTL_SYSCALL=y CONFIG_PRINTK=y CONFIG_BUG=y CONFIG_ELF_CORE=y +CONFIG_COMPAT_BRK=y CONFIG_BASE_FULL=y CONFIG_FUTEX=y +CONFIG_ANON_INODES=y # CONFIG_EPOLL is not set +CONFIG_SIGNALFD=y +CONFIG_TIMERFD=y +CONFIG_EVENTFD=y CONFIG_SHMEM=y -CONFIG_SLAB=y CONFIG_VM_EVENT_COUNTERS=y +CONFIG_SLAB=y +# CONFIG_SLUB is not set +# CONFIG_SLOB is not set +# CONFIG_PROFILING is not set +# CONFIG_MARKERS is not set +CONFIG_HAVE_OPROFILE=y +# CONFIG_HAVE_KPROBES is not set +CONFIG_PROC_PAGE_MONITOR=y +CONFIG_SLABINFO=y CONFIG_RT_MUTEXES=y # CONFIG_TINY_SHMEM is not set CONFIG_BASE_SMALL=0 -# CONFIG_SLOB is not set - -# -# Loadable module support -# CONFIG_MODULES=y CONFIG_MODULE_UNLOAD=y # CONFIG_MODVERSIONS is not set # CONFIG_MODULE_SRCVERSION_ALL is not set CONFIG_KMOD=y - -# -# Block layer -# CONFIG_BLOCK=y # CONFIG_LBD is not set +# CONFIG_BLK_DEV_IO_TRACE is not set # CONFIG_LSF is not set # @@ -91,68 +103,27 @@ CONFIG_DEFAULT_DEADLINE=y # CONFIG_DEFAULT_CFQ is not set # CONFIG_DEFAULT_NOOP is not set CONFIG_DEFAULT_IOSCHED="deadline" +CONFIG_CLASSIC_RCU=y +# CONFIG_PREEMPT_RCU is not set # # System type # -CONFIG_SOLUTION_ENGINE=y -# CONFIG_SH_SOLUTION_ENGINE is not set -# CONFIG_SH_7751_SOLUTION_ENGINE is not set -CONFIG_SH_7780_SOLUTION_ENGINE=y -# CONFIG_SH_7300_SOLUTION_ENGINE is not set -# CONFIG_SH_7343_SOLUTION_ENGINE is not set -# CONFIG_SH_73180_SOLUTION_ENGINE is not set -# CONFIG_SH_7751_SYSTEMH is not set -# CONFIG_SH_HP6XX is not set -# CONFIG_SH_SATURN is not set -# CONFIG_SH_DREAMCAST is not set -# CONFIG_SH_MPC1211 is not set -# CONFIG_SH_SH03 is not set -# CONFIG_SH_SECUREEDGE5410 is not set -# CONFIG_SH_HS7751RVOIP is not set -# CONFIG_SH_7710VOIPGW is not set -# CONFIG_SH_RTS7751R2D is not set -# CONFIG_SH_HIGHLANDER is not set -# CONFIG_SH_EDOSK7705 is not set -# CONFIG_SH_SH4202_MICRODEV is not set -# CONFIG_SH_LANDISK is not set -# CONFIG_SH_TITAN is not set -# CONFIG_SH_SHMIN is not set -# CONFIG_SH_7206_SOLUTION_ENGINE is not set -# CONFIG_SH_7619_SOLUTION_ENGINE is not set -# CONFIG_SH_UNKNOWN is not set - -# -# Processor selection -# CONFIG_CPU_SH4=y CONFIG_CPU_SH4A=y - -# -# SH-2 Processor Support -# -# CONFIG_CPU_SUBTYPE_SH7604 is not set # CONFIG_CPU_SUBTYPE_SH7619 is not set - -# -# SH-2A Processor Support -# +# CONFIG_CPU_SUBTYPE_SH7203 is not set # CONFIG_CPU_SUBTYPE_SH7206 is not set - -# -# SH-3 Processor Support -# -# CONFIG_CPU_SUBTYPE_SH7300 is not set +# CONFIG_CPU_SUBTYPE_SH7263 is not set # CONFIG_CPU_SUBTYPE_SH7705 is not set # CONFIG_CPU_SUBTYPE_SH7706 is not set # CONFIG_CPU_SUBTYPE_SH7707 is not set # CONFIG_CPU_SUBTYPE_SH7708 is not set # CONFIG_CPU_SUBTYPE_SH7709 is not set # CONFIG_CPU_SUBTYPE_SH7710 is not set - -# -# SH-4 Processor Support -# +# CONFIG_CPU_SUBTYPE_SH7712 is not set +# CONFIG_CPU_SUBTYPE_SH7720 is not set +# CONFIG_CPU_SUBTYPE_SH7721 is not set # CONFIG_CPU_SUBTYPE_SH7750 is not set # CONFIG_CPU_SUBTYPE_SH7091 is not set # CONFIG_CPU_SUBTYPE_SH7750R is not set @@ -161,52 +132,58 @@ CONFIG_CPU_SH4A=y # CONFIG_CPU_SUBTYPE_SH7751R is not set # CONFIG_CPU_SUBTYPE_SH7760 is not set # CONFIG_CPU_SUBTYPE_SH4_202 is not set - -# -# ST40 Processor Support -# -# CONFIG_CPU_SUBTYPE_ST40STB1 is not set -# CONFIG_CPU_SUBTYPE_ST40GX1 is not set - -# -# SH-4A Processor Support -# +# CONFIG_CPU_SUBTYPE_SH7763 is not set # CONFIG_CPU_SUBTYPE_SH7770 is not set CONFIG_CPU_SUBTYPE_SH7780=y # CONFIG_CPU_SUBTYPE_SH7785 is not set - -# -# SH4AL-DSP Processor Support -# -# CONFIG_CPU_SUBTYPE_SH73180 is not set +# CONFIG_CPU_SUBTYPE_SHX3 is not set # CONFIG_CPU_SUBTYPE_SH7343 is not set # CONFIG_CPU_SUBTYPE_SH7722 is not set +# CONFIG_CPU_SUBTYPE_SH7366 is not set +# CONFIG_CPU_SUBTYPE_SH5_101 is not set +# CONFIG_CPU_SUBTYPE_SH5_103 is not set # # Memory management options # +CONFIG_QUICKLIST=y CONFIG_MMU=y CONFIG_PAGE_OFFSET=0x80000000 CONFIG_MEMORY_START=0x08000000 CONFIG_MEMORY_SIZE=0x08000000 -CONFIG_32BIT=y +CONFIG_29BIT=y +# CONFIG_PMB is not set CONFIG_VSYSCALL=y +CONFIG_ARCH_FLATMEM_ENABLE=y +CONFIG_ARCH_SPARSEMEM_ENABLE=y +CONFIG_ARCH_SPARSEMEM_DEFAULT=y +CONFIG_MAX_ACTIVE_REGIONS=1 +CONFIG_ARCH_POPULATES_NODE_MAP=y +CONFIG_ARCH_SELECT_MEMORY_MODEL=y +CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y CONFIG_PAGE_SIZE_4KB=y # CONFIG_PAGE_SIZE_8KB is not set # CONFIG_PAGE_SIZE_64KB is not set -CONFIG_FLATMEM=y -CONFIG_FLAT_NODE_MEM_MAP=y -# CONFIG_SPARSEMEM_STATIC is not set +CONFIG_SELECT_MEMORY_MODEL=y +# CONFIG_FLATMEM_MANUAL is not set +# CONFIG_DISCONTIGMEM_MANUAL is not set +CONFIG_SPARSEMEM_MANUAL=y +CONFIG_SPARSEMEM=y +CONFIG_HAVE_MEMORY_PRESENT=y +CONFIG_SPARSEMEM_STATIC=y +# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set CONFIG_SPLIT_PTLOCK_CPUS=4 # CONFIG_RESOURCES_64BIT is not set CONFIG_ZONE_DMA_FLAG=0 +CONFIG_NR_QUICK=2 # # Cache configuration # # CONFIG_SH_DIRECT_MAPPED is not set -# CONFIG_SH_WRITETHROUGH is not set -# CONFIG_SH_OCRAM is not set +CONFIG_CACHE_WRITEBACK=y +# CONFIG_CACHE_WRITETHROUGH is not set +# CONFIG_CACHE_OFF is not set # # Processor features @@ -214,20 +191,29 @@ CONFIG_ZONE_DMA_FLAG=0 CONFIG_CPU_LITTLE_ENDIAN=y # CONFIG_CPU_BIG_ENDIAN is not set CONFIG_SH_FPU=y -# CONFIG_SH_DSP is not set # CONFIG_SH_STORE_QUEUES is not set CONFIG_CPU_HAS_INTEVT=y -CONFIG_CPU_HAS_INTC2_IRQ=y -CONFIG_CPU_HAS_INTC_IRQ=y CONFIG_CPU_HAS_SR_RB=y +CONFIG_CPU_HAS_FPU=y + +# +# Board support +# +CONFIG_SOLUTION_ENGINE=y +CONFIG_SH_7780_SOLUTION_ENGINE=y +# CONFIG_SH_SDK7780 is not set +# CONFIG_SH_HIGHLANDER is not set # # Timer and clock configuration # CONFIG_SH_TMU=y CONFIG_SH_TIMER_IRQ=28 -# CONFIG_NO_IDLE_HZ is not set CONFIG_SH_PCLK_FREQ=33333333 +# CONFIG_TICK_ONESHOT is not set +# CONFIG_NO_HZ is not set +# CONFIG_HIGH_RES_TIMERS is not set +CONFIG_GENERIC_CLOCKEVENTS_BUILD=y # # CPU Frequency scaling @@ -242,7 +228,6 @@ CONFIG_SH_PCLK_FREQ=33333333 # # Companion Chips # -# CONFIG_HD6446X_SERIES is not set # # Additional SuperH Device Drivers @@ -258,40 +243,36 @@ CONFIG_HZ_250=y # CONFIG_HZ_300 is not set # CONFIG_HZ_1000 is not set CONFIG_HZ=250 -# CONFIG_SMP is not set +# CONFIG_SCHED_HRTICK is not set CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT_VOLUNTARY is not set # CONFIG_PREEMPT is not set +CONFIG_RCU_TRACE=y +CONFIG_GUSA=y # # Boot options # CONFIG_ZERO_PAGE_OFFSET=0x00001000 CONFIG_BOOT_LINK_OFFSET=0x00810000 -# CONFIG_UBC_WAKEUP is not set -# CONFIG_CMDLINE_BOOL is not set +CONFIG_CMDLINE_BOOL=y +CONFIG_CMDLINE="console=ttySC0.115200 root=/dev/sda1" # # Bus options # +# CONFIG_CF_ENABLER is not set CONFIG_PCI=y CONFIG_SH_PCIDMA_NONCOHERENT=y CONFIG_PCI_AUTO=y CONFIG_PCI_AUTO_UPDATE_RESOURCES=y - -# -# PCCARD (PCMCIA/CardBus) support -# - -# -# PCI Hotplug Support -# +# CONFIG_ARCH_SUPPORTS_MSI is not set +CONFIG_PCI_LEGACY=y # # Executable file formats # CONFIG_BINFMT_ELF=y -# CONFIG_BINFMT_FLAT is not set # CONFIG_BINFMT_MISC is not set # @@ -302,7 +283,6 @@ CONFIG_NET=y # # Networking options # -# CONFIG_NETDEBUG is not set CONFIG_PACKET=y # CONFIG_PACKET_MMAP is not set CONFIG_UNIX=y @@ -329,6 +309,7 @@ CONFIG_IP_PNP=y CONFIG_INET_XFRM_MODE_TRANSPORT=y CONFIG_INET_XFRM_MODE_TUNNEL=y CONFIG_INET_XFRM_MODE_BEET=y +# CONFIG_INET_LRO is not set CONFIG_INET_DIAG=y CONFIG_INET_TCP_DIAG=y # CONFIG_TCP_CONG_ADVANCED is not set @@ -349,16 +330,13 @@ CONFIG_IPV6=y # CONFIG_IPV6_TUNNEL is not set # CONFIG_NETWORK_SECMARK is not set # CONFIG_NETFILTER 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 - -# -# QoS and/or fair queueing -# # CONFIG_NET_SCHED is not set # @@ -366,9 +344,18 @@ CONFIG_IPV6=y # # CONFIG_NET_PKTGEN is not set # CONFIG_HAMRADIO is not set +# CONFIG_CAN is not set # CONFIG_IRDA is not set # CONFIG_BT is not set + +# +# Wireless +# +# CONFIG_CFG80211 is not set +# CONFIG_WIRELESS_EXT is not set +# CONFIG_MAC80211 is not set # CONFIG_IEEE80211 is not set +# CONFIG_RFKILL is not set # # Device Drivers @@ -380,15 +367,7 @@ CONFIG_IPV6=y CONFIG_STANDALONE=y # CONFIG_PREVENT_FIRMWARE_BUILD is not set # CONFIG_SYS_HYPERVISOR is not set - -# -# Connector - unified userspace <-> kernelspace linker -# # CONFIG_CONNECTOR is not set - -# -# Memory Technology Devices (MTD) -# CONFIG_MTD=y # CONFIG_MTD_DEBUG is not set # CONFIG_MTD_CONCAT is not set @@ -407,6 +386,7 @@ CONFIG_MTD_BLOCK=y # CONFIG_INFTL is not set # CONFIG_RFD_FTL is not set # CONFIG_SSFDC is not set +# CONFIG_MTD_OOPS is not set # # RAM/ROM/Flash chip drivers @@ -437,13 +417,13 @@ CONFIG_MTD_CFI_UTIL=y # CONFIG_MTD_RAM is not set CONFIG_MTD_ROM=y # CONFIG_MTD_ABSENT is not set -# CONFIG_MTD_OBSOLETE_CHIPS is not set # # Mapping drivers for chip access # # CONFIG_MTD_COMPLEX_MAPPINGS is not set # CONFIG_MTD_PHYSMAP is not set +# CONFIG_MTD_INTEL_VR_NOR is not set # CONFIG_MTD_PLATRAM is not set # @@ -461,31 +441,15 @@ CONFIG_MTD_ROM=y # CONFIG_MTD_DOC2000 is not set # CONFIG_MTD_DOC2001 is not set # CONFIG_MTD_DOC2001PLUS is not set - -# -# NAND Flash Device Drivers -# # CONFIG_MTD_NAND is not set - -# -# OneNAND Flash Device Drivers -# # CONFIG_MTD_ONENAND is not set # -# Parallel port support +# UBI - Unsorted block images # +# CONFIG_MTD_UBI is not set # CONFIG_PARPORT is not set - -# -# Plug and Play support -# -# CONFIG_PNPACPI is not set - -# -# Block devices -# -# CONFIG_BLK_CPQ_DA is not set +CONFIG_BLK_DEV=y # CONFIG_BLK_CPQ_CISS_DA is not set # CONFIG_BLK_DEV_DAC960 is not set # CONFIG_BLK_DEV_COW_COMMON is not set @@ -497,15 +461,12 @@ CONFIG_BLK_DEV_LOOP=y # CONFIG_BLK_DEV_RAM is not set # CONFIG_CDROM_PKTCDVD is not set # CONFIG_ATA_OVER_ETH is not set - -# -# Misc devices -# +CONFIG_MISC_DEVICES=y +# CONFIG_PHANTOM is not set +# CONFIG_EEPROM_93CX6 is not set # CONFIG_SGI_IOC4 is not set - -# -# ATA/ATAPI/MFM/RLL support -# +# CONFIG_ENCLOSURE_SERVICES is not set +CONFIG_HAVE_IDE=y # CONFIG_IDE is not set # @@ -513,6 +474,7 @@ CONFIG_BLK_DEV_LOOP=y # # CONFIG_RAID_ATTRS is not set CONFIG_SCSI=y +CONFIG_SCSI_DMA=y # CONFIG_SCSI_NETLINK is not set CONFIG_SCSI_PROC_FS=y @@ -533,6 +495,7 @@ CONFIG_CHR_DEV_SG=y # CONFIG_SCSI_CONSTANTS is not set # CONFIG_SCSI_LOGGING is not set # CONFIG_SCSI_SCAN_ASYNC is not set +CONFIG_SCSI_WAIT_SCAN=m # # SCSI Transports @@ -540,12 +503,9 @@ CONFIG_CHR_DEV_SG=y # CONFIG_SCSI_SPI_ATTRS is not set # CONFIG_SCSI_FC_ATTRS is not set # CONFIG_SCSI_ISCSI_ATTRS is not set -# CONFIG_SCSI_SAS_ATTRS is not set # CONFIG_SCSI_SAS_LIBSAS is not set - -# -# SCSI low-level drivers -# +# CONFIG_SCSI_SRP_ATTRS is not set +CONFIG_SCSI_LOWLEVEL=y # CONFIG_ISCSI_TCP is not set # CONFIG_BLK_DEV_3W_XXXX_RAID is not set # CONFIG_SCSI_3W_9XXX is not set @@ -555,7 +515,6 @@ CONFIG_CHR_DEV_SG=y # CONFIG_SCSI_AIC7XXX_OLD is not set # CONFIG_SCSI_AIC79XX is not set # CONFIG_SCSI_AIC94XX is not set -# CONFIG_SCSI_DPT_I2O is not set # CONFIG_SCSI_ARCMSR is not set # CONFIG_MEGARAID_NEWGEN is not set # CONFIG_MEGARAID_LEGACY is not set @@ -566,6 +525,7 @@ CONFIG_CHR_DEV_SG=y # CONFIG_SCSI_IPS is not set # CONFIG_SCSI_INITIO is not set # CONFIG_SCSI_INIA100 is not set +# CONFIG_SCSI_MVSAS is not set # CONFIG_SCSI_STEX is not set # CONFIG_SCSI_SYM53C8XX_2 is not set # CONFIG_SCSI_IPR is not set @@ -577,10 +537,6 @@ CONFIG_CHR_DEV_SG=y # CONFIG_SCSI_NSP32 is not set # CONFIG_SCSI_DEBUG is not set # CONFIG_SCSI_SRP is not set - -# -# Serial ATA (prod) and Parallel ATA (experimental) drivers -# CONFIG_ATA=y # CONFIG_ATA_NONSTANDARD is not set # CONFIG_SATA_AHCI is not set @@ -597,62 +553,48 @@ CONFIG_SATA_SIL=y # CONFIG_SATA_VIA is not set # CONFIG_SATA_VITESSE is not set # CONFIG_PATA_AMD is not set +# CONFIG_PATA_ARTOP is not set +# CONFIG_PATA_ATIIXP is not set +# CONFIG_PATA_CMD64X is not set # CONFIG_PATA_CS5520 is not set # CONFIG_PATA_EFAR is not set # CONFIG_ATA_GENERIC is not set +# CONFIG_PATA_HPT366 is not set # CONFIG_PATA_HPT3X3 is not set +# CONFIG_PATA_IT821X is not set # CONFIG_PATA_JMICRON is not set # CONFIG_PATA_TRIFLEX is not set # CONFIG_PATA_MARVELL is not set # CONFIG_PATA_MPIIX is not set +# CONFIG_PATA_OLDPIIX is not set # CONFIG_PATA_NETCELL is not set # CONFIG_PATA_RZ1000 is not set +# CONFIG_PATA_SERVERWORKS is not set # CONFIG_PATA_PDC2027X is not set # CONFIG_PATA_SIL680 is not set # CONFIG_PATA_VIA is not set # CONFIG_PATA_WINBOND is not set # CONFIG_PATA_PLATFORM is not set - -# -# Multi-device support (RAID and LVM) -# # CONFIG_MD is not set - -# -# Fusion MPT device support -# # CONFIG_FUSION is not set -# CONFIG_FUSION_SPI is not set -# CONFIG_FUSION_FC is not set -# CONFIG_FUSION_SAS is not set # # IEEE 1394 (FireWire) support # -# CONFIG_IEEE1394 is not set # -# I2O device support +# An alternative FireWire stack is available with EXPERIMENTAL=y # +# CONFIG_IEEE1394 is not set # CONFIG_I2O is not set - -# -# Network device support -# CONFIG_NETDEVICES=y +# CONFIG_NETDEVICES_MULTIQUEUE is not set # CONFIG_DUMMY is not set # CONFIG_BONDING is not set # CONFIG_EQUALIZER is not set # CONFIG_TUN is not set - -# -# ARCnet devices -# +# CONFIG_VETH is not set # CONFIG_ARCNET is not set - -# -# PHY device support -# CONFIG_PHYLIB=y # @@ -666,85 +608,59 @@ CONFIG_PHYLIB=y # CONFIG_VITESSE_PHY is not set CONFIG_SMSC_PHY=y # CONFIG_BROADCOM_PHY is not set +# CONFIG_ICPLUS_PHY is not set +# CONFIG_REALTEK_PHY is not set # CONFIG_FIXED_PHY is not set - -# -# Ethernet (10 or 100Mbit) -# +# CONFIG_MDIO_BITBANG is not set CONFIG_NET_ETHERNET=y CONFIG_MII=y +# CONFIG_AX88796 is not set # CONFIG_STNIC is not set # CONFIG_HAPPYMEAL is not set # CONFIG_SUNGEM is not set # CONFIG_CASSINI is not set # CONFIG_NET_VENDOR_3COM is not set CONFIG_SMC91X=y - -# -# Tulip family network device support -# # CONFIG_NET_TULIP is not set # CONFIG_HP100 is not set +# CONFIG_IBM_NEW_EMAC_ZMII is not set +# CONFIG_IBM_NEW_EMAC_RGMII is not set +# CONFIG_IBM_NEW_EMAC_TAH is not set +# CONFIG_IBM_NEW_EMAC_EMAC4 is not set CONFIG_NET_PCI=y # CONFIG_PCNET32 is not set # CONFIG_AMD8111_ETH is not set # CONFIG_ADAPTEC_STARFIRE is not set # CONFIG_B44 is not set # CONFIG_FORCEDETH is not set -# CONFIG_DGRS is not set # CONFIG_EEPRO100 is not set # CONFIG_E100 is not set # CONFIG_FEALNX is not set # CONFIG_NATSEMI is not set # CONFIG_NE2K_PCI is not set # CONFIG_8139TOO is not set +# CONFIG_R6040 is not set # CONFIG_SIS900 is not set # CONFIG_EPIC100 is not set # CONFIG_SUNDANCE is not set # CONFIG_TLAN is not set # CONFIG_VIA_RHINE is not set - -# -# Ethernet (1000 Mbit) -# -# CONFIG_ACENIC is not set -# CONFIG_DL2K is not set -# CONFIG_E1000 is not set -# CONFIG_NS83820 is not set -# CONFIG_HAMACHI is not set -# CONFIG_R8169 is not set -# CONFIG_SIS190 is not set -# CONFIG_SKGE is not set -# CONFIG_SKY2 is not set -# CONFIG_SK98LIN is not set -# CONFIG_VIA_VELOCITY is not set -# CONFIG_TIGON3 is not set -# CONFIG_BNX2 is not set -# CONFIG_QLA3XXX is not set - -# -# Ethernet (10000 Mbit) -# -# CONFIG_CHELSIO_T1 is not set -# CONFIG_CHELSIO_T3 is not set -# CONFIG_IXGB is not set -# CONFIG_S2IO is not set -# CONFIG_MYRI10GE is not set -# CONFIG_NETXEN_NIC is not set - -# -# Token Ring devices -# +# CONFIG_NETDEV_1000 is not set +# CONFIG_NETDEV_10000 is not set # CONFIG_TR is not set # -# Wireless LAN (non-hamradio) +# Wireless LAN # -# CONFIG_NET_RADIO is not set +# CONFIG_WLAN_PRE80211 is not set +# CONFIG_WLAN_80211 is not set # -# Wan interfaces +# USB Network Adapters # +# CONFIG_USB_KAWETH is not set +# CONFIG_USB_PEGASUS is not set +# CONFIG_USB_USBNET is not set # CONFIG_WAN is not set # CONFIG_FDDI is not set # CONFIG_PPP is not set @@ -752,15 +668,7 @@ CONFIG_NET_PCI=y # CONFIG_NET_FC is not set # CONFIG_NETPOLL is not set # CONFIG_NET_POLL_CONTROLLER is not set - -# -# ISDN subsystem -# # CONFIG_ISDN is not set - -# -# Telephony Support -# # CONFIG_PHONE is not set # @@ -768,6 +676,7 @@ CONFIG_NET_PCI=y # CONFIG_INPUT=y # CONFIG_INPUT_FF_MEMLESS is not set +# CONFIG_INPUT_POLLDEV is not set # # Userland interfaces @@ -777,7 +686,6 @@ CONFIG_INPUT_MOUSEDEV=y CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 # CONFIG_INPUT_JOYDEV is not set -# CONFIG_INPUT_TSDEV is not set # CONFIG_INPUT_EVDEV is not set # CONFIG_INPUT_EVBUG is not set @@ -787,6 +695,7 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 # CONFIG_INPUT_KEYBOARD is not set # CONFIG_INPUT_MOUSE is not set # CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TABLET is not set # CONFIG_INPUT_TOUCHSCREEN is not set # CONFIG_INPUT_MISC is not set @@ -821,31 +730,12 @@ CONFIG_SERIAL_CORE_CONSOLE=y # CONFIG_SERIAL_JSM is not set CONFIG_UNIX98_PTYS=y # CONFIG_LEGACY_PTYS is not set - -# -# IPMI -# # CONFIG_IPMI_HANDLER is not set - -# -# Watchdog Cards -# -# CONFIG_WATCHDOG is not set # CONFIG_HW_RANDOM is not set -# CONFIG_GEN_RTC is not set -# CONFIG_DTLK is not set # CONFIG_R3964 is not set # CONFIG_APPLICOM is not set -# CONFIG_DRM is not set # CONFIG_RAW_DRIVER is not set - -# -# TPM devices -# - -# -# I2C support -# +CONFIG_DEVPORT=y # CONFIG_I2C is not set # @@ -853,18 +743,27 @@ CONFIG_UNIX98_PTYS=y # # 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_POWER_SUPPLY is not set CONFIG_HWMON=y # CONFIG_HWMON_VID is not set +# CONFIG_SENSORS_IT87 is not set +# CONFIG_SENSORS_PC87360 is not set +# CONFIG_SENSORS_SIS5595 is not set +# CONFIG_SENSORS_SMSC47M1 is not set +# CONFIG_SENSORS_VIA686A is not set +# CONFIG_SENSORS_VT8231 is not set +# CONFIG_SENSORS_W83627HF is not set +# CONFIG_SENSORS_W83627EHF is not set # CONFIG_HWMON_DEBUG_CHIP is not set +CONFIG_THERMAL=y +# CONFIG_WATCHDOG is not set + +# +# Sonics Silicon Backplane +# +CONFIG_SSB_POSSIBLE=y +# CONFIG_SSB is not set # # Multifunction device drivers @@ -875,23 +774,27 @@ CONFIG_HWMON=y # Multimedia devices # # CONFIG_VIDEO_DEV is not set - -# -# Digital Video Broadcasting Devices -# -# CONFIG_DVB is not set -# CONFIG_USB_DABUSB is not set +# CONFIG_DVB_CORE is not set +# CONFIG_DAB is not set # # Graphics support # -# CONFIG_BACKLIGHT_LCD_SUPPORT is not set +# CONFIG_DRM is not set +# CONFIG_VGASTATE is not set +# CONFIG_VIDEO_OUTPUT_CONTROL is not set CONFIG_FB=y CONFIG_FIRMWARE_EDID=y # CONFIG_FB_DDC is not set # CONFIG_FB_CFB_FILLRECT is not set # CONFIG_FB_CFB_COPYAREA is not set # CONFIG_FB_CFB_IMAGEBLIT is not set +# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set +# CONFIG_FB_SYS_FILLRECT is not set +# CONFIG_FB_SYS_COPYAREA is not set +# CONFIG_FB_SYS_IMAGEBLIT is not set +# CONFIG_FB_SYS_FOPS is not set +CONFIG_FB_DEFERRED_IO=y # CONFIG_FB_SVGALIB is not set # CONFIG_FB_MACMODES is not set # CONFIG_FB_BACKLIGHT is not set @@ -899,14 +802,13 @@ CONFIG_FIRMWARE_EDID=y # CONFIG_FB_TILEBLITTING is not set # -# Frambuffer hardware drivers +# Frame buffer hardware drivers # # CONFIG_FB_CIRRUS is not set # CONFIG_FB_PM2 is not set # CONFIG_FB_CYBER2000 is not set # CONFIG_FB_ASILIANT is not set # CONFIG_FB_IMSTT is not set -# CONFIG_FB_EPSON1355 is not set # CONFIG_FB_S1D13XXX is not set # CONFIG_FB_NVIDIA is not set # CONFIG_FB_RIVA is not set @@ -920,22 +822,27 @@ CONFIG_FIRMWARE_EDID=y # CONFIG_FB_KYRO is not set # CONFIG_FB_3DFX is not set # CONFIG_FB_VOODOO1 is not set +# CONFIG_FB_VT8623 is not set # CONFIG_FB_TRIDENT is not set +# CONFIG_FB_ARK is not set # CONFIG_FB_VIRTUAL is not set +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set + +# +# Display device support +# +# CONFIG_DISPLAY_SUPPORT is not set # # Console display driver support # CONFIG_DUMMY_CONSOLE=y CONFIG_FRAMEBUFFER_CONSOLE=y +# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set # CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set # CONFIG_FONTS is not set CONFIG_FONT_8x8=y CONFIG_FONT_8x16=y - -# -# Logo configuration -# CONFIG_LOGO=y # CONFIG_LOGO_LINUX_MONO is not set # CONFIG_LOGO_LINUX_VGA16 is not set @@ -958,39 +865,38 @@ CONFIG_SOUND=y # Open Sound System # CONFIG_SOUND_PRIME=y -# CONFIG_OBSOLETE_OSS is not set -# CONFIG_SOUND_BT878 is not set -# CONFIG_SOUND_ICH is not set # CONFIG_SOUND_TRIDENT is not set # CONFIG_SOUND_MSNDCLAS is not set # CONFIG_SOUND_MSNDPIN is not set -# CONFIG_SOUND_VIA82CXXX is not set - -# -# HID Devices -# +CONFIG_HID_SUPPORT=y CONFIG_HID=y # CONFIG_HID_DEBUG is not set +# CONFIG_HIDRAW is not set # -# USB support +# USB Input Devices # +CONFIG_USB_HID=y +# CONFIG_USB_HIDINPUT_POWERBOOK is not set +# CONFIG_USB_HIDDEV is not set +CONFIG_USB_SUPPORT=y CONFIG_USB_ARCH_HAS_HCD=y CONFIG_USB_ARCH_HAS_OHCI=y CONFIG_USB_ARCH_HAS_EHCI=y CONFIG_USB=y -CONFIG_USB_DEBUG=y +# CONFIG_USB_DEBUG is not set +# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set # # Miscellaneous USB options # CONFIG_USB_DEVICEFS=y +# CONFIG_USB_DEVICE_CLASS is not set # # USB Host Controller Drivers # CONFIG_USB_EHCI_HCD=y -# CONFIG_USB_EHCI_BIG_ENDIAN_MMIO is not set # CONFIG_USB_ISP116X_HCD is not set CONFIG_USB_OHCI_HCD=y # CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set @@ -998,6 +904,7 @@ CONFIG_USB_OHCI_HCD=y CONFIG_USB_OHCI_LITTLE_ENDIAN=y # CONFIG_USB_UHCI_HCD is not set # CONFIG_USB_SL811_HCD is not set +# CONFIG_USB_R8A66597_HCD is not set # # USB Device Class drivers @@ -1015,49 +922,20 @@ CONFIG_USB_OHCI_LITTLE_ENDIAN=y CONFIG_USB_STORAGE=y # CONFIG_USB_STORAGE_DEBUG is not set # CONFIG_USB_STORAGE_FREECOM is not set +# CONFIG_USB_STORAGE_ISD200 is not set # CONFIG_USB_STORAGE_DPCM is not set # CONFIG_USB_STORAGE_KARMA is not set # CONFIG_USB_LIBUSUAL is not set -# -# USB Input Devices -# -CONFIG_USB_HID=y -# CONFIG_USB_HIDINPUT_POWERBOOK is not set -# CONFIG_USB_HIDDEV is not set -# CONFIG_USB_AIPTEK is not set -# CONFIG_USB_WACOM is not set -# CONFIG_USB_ACECAD is not set -# CONFIG_USB_KBTAB is not set -# CONFIG_USB_POWERMATE is not set -# CONFIG_USB_TOUCHSCREEN is not set -# CONFIG_USB_XPAD is not set -# CONFIG_USB_ATI_REMOTE is not set -# CONFIG_USB_ATI_REMOTE2 is not set -# CONFIG_USB_APPLETOUCH is not set -# CONFIG_USB_GTCO is not set - # # USB Imaging devices # # CONFIG_USB_MICROTEK is not set - -# -# USB Network Adapters -# -# CONFIG_USB_KAWETH is not set -# CONFIG_USB_PEGASUS is not set -# CONFIG_USB_USBNET_MII is not set -# CONFIG_USB_USBNET is not set CONFIG_USB_MON=y # # USB port drivers # - -# -# USB Serial Converter support -# # CONFIG_USB_SERIAL is not set # @@ -1078,67 +956,17 @@ CONFIG_USB_MON=y # CONFIG_USB_LD is not set # CONFIG_USB_TRANCEVIBRATOR is not set # CONFIG_USB_IOWARRIOR is not set - -# -# USB DSL modem support -# - -# -# USB Gadget Support -# # CONFIG_USB_GADGET is not set - -# -# MMC/SD Card support -# # CONFIG_MMC is not set - -# -# LED devices -# +# CONFIG_MEMSTICK is not set # CONFIG_NEW_LEDS is not set - -# -# LED drivers -# - -# -# LED Triggers -# - -# -# InfiniBand support -# # CONFIG_INFINIBAND is not set +# CONFIG_RTC_CLASS is not set # -# EDAC - error detection and reporting (RAS) (EXPERIMENTAL) -# - -# -# Real Time Clock -# - -# -# DMA Engine support -# -# CONFIG_DMA_ENGINE is not set - -# -# DMA Clients -# - -# -# DMA Devices -# - -# -# Auxiliary Display support -# - -# -# Virtualization +# Userspace I/O # +# CONFIG_UIO is not set # # File systems @@ -1151,12 +979,11 @@ CONFIG_EXT2_FS=y # CONFIG_JFS_FS is not set # CONFIG_FS_POSIX_ACL is not set # CONFIG_XFS_FS is not set -# CONFIG_MINIX_FS is not set -# CONFIG_ROMFS_FS is not set +# CONFIG_OCFS2_FS is not set +# CONFIG_DNOTIFY is not set CONFIG_INOTIFY=y CONFIG_INOTIFY_USER=y # CONFIG_QUOTA is not set -# CONFIG_DNOTIFY is not set # CONFIG_AUTOFS_FS is not set # CONFIG_AUTOFS4_FS is not set # CONFIG_FUSE_FS is not set @@ -1181,14 +1008,14 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" # Pseudo filesystems # CONFIG_PROC_FS=y -# CONFIG_PROC_KCORE is not set +CONFIG_PROC_KCORE=y CONFIG_PROC_SYSCTL=y -# CONFIG_SYSFS is not set +CONFIG_SYSFS=y CONFIG_TMPFS=y # CONFIG_TMPFS_POSIX_ACL is not set # CONFIG_HUGETLBFS is not set # CONFIG_HUGETLB_PAGE is not set -CONFIG_RAMFS=y +# CONFIG_CONFIGFS_FS is not set # # Miscellaneous filesystems @@ -1197,14 +1024,13 @@ CONFIG_RAMFS=y # CONFIG_JFFS2_FS is not set CONFIG_CRAMFS=y # CONFIG_VXFS_FS is not set +# CONFIG_MINIX_FS is not set # CONFIG_HPFS_FS is not set # CONFIG_QNX4FS_FS is not set +# CONFIG_ROMFS_FS is not set # CONFIG_SYSV_FS is not set # CONFIG_UFS_FS is not set - -# -# Network File Systems -# +CONFIG_NETWORK_FILESYSTEMS=y CONFIG_NFS_FS=y CONFIG_NFS_V3=y # CONFIG_NFS_V3_ACL is not set @@ -1225,10 +1051,6 @@ CONFIG_SUNRPC=y # # CONFIG_PARTITION_ADVANCED is not set CONFIG_MSDOS_PARTITION=y - -# -# Native Language Support -# CONFIG_NLS=y CONFIG_NLS_DEFAULT="iso8859-1" # CONFIG_NLS_CODEPAGE_437 is not set @@ -1275,13 +1097,15 @@ CONFIG_NLS_DEFAULT="iso8859-1" # CONFIG_TRACE_IRQFLAGS_SUPPORT=y # CONFIG_PRINTK_TIME is not set +CONFIG_ENABLE_WARN_DEPRECATED=y CONFIG_ENABLE_MUST_CHECK=y # CONFIG_MAGIC_SYSRQ is not set # CONFIG_UNUSED_SYMBOLS is not set +CONFIG_DEBUG_FS=y # CONFIG_HEADERS_CHECK is not set # CONFIG_DEBUG_KERNEL is not set -CONFIG_LOG_BUF_SHIFT=14 # CONFIG_DEBUG_BUGVERBOSE is not set +# CONFIG_SAMPLES is not set # CONFIG_SH_STANDARD_BIOS is not set # CONFIG_EARLY_SCIF_CONSOLE is not set # CONFIG_SH_KGDB is not set @@ -1290,11 +1114,48 @@ CONFIG_LOG_BUF_SHIFT=14 # Security options # # CONFIG_KEYS is not set - -# -# Cryptographic options -# -# CONFIG_CRYPTO is not set +# CONFIG_SECURITY is not set +CONFIG_CRYPTO=y +# CONFIG_CRYPTO_SEQIV is not set +# CONFIG_CRYPTO_MANAGER is not set +# CONFIG_CRYPTO_HMAC is not set +# CONFIG_CRYPTO_NULL is not set +# CONFIG_CRYPTO_MD4 is not set +# CONFIG_CRYPTO_MD5 is not set +# CONFIG_CRYPTO_SHA1 is not set +# CONFIG_CRYPTO_SHA256 is not set +# CONFIG_CRYPTO_SHA512 is not set +# CONFIG_CRYPTO_WP512 is not set +# CONFIG_CRYPTO_TGR192 is not set +# CONFIG_CRYPTO_ECB is not set +# CONFIG_CRYPTO_CBC is not set +# CONFIG_CRYPTO_PCBC is not set +# CONFIG_CRYPTO_CTR is not set +# CONFIG_CRYPTO_GCM is not set +# CONFIG_CRYPTO_CCM is not set +# CONFIG_CRYPTO_CRYPTD is not set +# CONFIG_CRYPTO_DES is not set +# CONFIG_CRYPTO_FCRYPT is not set +# CONFIG_CRYPTO_BLOWFISH is not set +# CONFIG_CRYPTO_TWOFISH is not set +# CONFIG_CRYPTO_SERPENT is not set +# CONFIG_CRYPTO_AES is not set +# CONFIG_CRYPTO_CAST5 is not set +# CONFIG_CRYPTO_CAST6 is not set +# CONFIG_CRYPTO_TEA is not set +# CONFIG_CRYPTO_ARC4 is not set +# CONFIG_CRYPTO_KHAZAD is not set +# CONFIG_CRYPTO_ANUBIS is not set +# CONFIG_CRYPTO_SEED is not set +# CONFIG_CRYPTO_DEFLATE is not set +# CONFIG_CRYPTO_MICHAEL_MIC is not set +# CONFIG_CRYPTO_CRC32C is not set +# CONFIG_CRYPTO_CAMELLIA is not set +# CONFIG_CRYPTO_TEST is not set +# CONFIG_CRYPTO_AUTHENC is not set +# CONFIG_CRYPTO_LZO is not set +CONFIG_CRYPTO_HW=y +# CONFIG_CRYPTO_DEV_HIFN_795X is not set # # Library routines @@ -1302,9 +1163,12 @@ CONFIG_LOG_BUF_SHIFT=14 CONFIG_BITREVERSE=y # CONFIG_CRC_CCITT is not set # CONFIG_CRC16 is not set +# CONFIG_CRC_ITU_T is not set CONFIG_CRC32=y +# CONFIG_CRC7 is not set # CONFIG_LIBCRC32C is not set CONFIG_ZLIB_INFLATE=y CONFIG_PLIST=y CONFIG_HAS_IOMEM=y CONFIG_HAS_IOPORT=y +CONFIG_HAS_DMA=y diff --git a/arch/sh/configs/sh7710voipgw_defconfig b/arch/sh/configs/sh7710voipgw_defconfig index 9380c321169a747d19a993bc52a51776591a1f84..37e49a58920792af09be018214e24011074e9bde 100644 --- a/arch/sh/configs/sh7710voipgw_defconfig +++ b/arch/sh/configs/sh7710voipgw_defconfig @@ -1,40 +1,55 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.18 -# Tue Oct 3 12:48:56 2006 +# Linux kernel version: 2.6.25-rc4 +# Thu Mar 6 16:02:29 2008 # CONFIG_SUPERH=y +CONFIG_SUPERH32=y CONFIG_RWSEM_GENERIC_SPINLOCK=y +CONFIG_GENERIC_BUG=y CONFIG_GENERIC_FIND_NEXT_BIT=y CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_HARDIRQS=y CONFIG_GENERIC_IRQ_PROBE=y CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_GENERIC_TIME=y +CONFIG_GENERIC_CLOCKEVENTS=y +CONFIG_STACKTRACE_SUPPORT=y +CONFIG_LOCKDEP_SUPPORT=y +# CONFIG_ARCH_HAS_ILOG2_U32 is not set +# CONFIG_ARCH_HAS_ILOG2_U64 is not set +CONFIG_ARCH_NO_VIRT_TO_BUS=y +CONFIG_ARCH_SUPPORTS_AOUT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # -# Code maturity level options +# General setup # CONFIG_EXPERIMENTAL=y CONFIG_BROKEN_ON_SMP=y CONFIG_INIT_ENV_ARG_LIMIT=32 - -# -# General setup -# CONFIG_LOCALVERSION="" CONFIG_LOCALVERSION_AUTO=y # CONFIG_SWAP is not set CONFIG_SYSVIPC=y -# CONFIG_IPC_NS is not set +CONFIG_SYSVIPC_SYSCTL=y CONFIG_POSIX_MQUEUE=y # CONFIG_BSD_PROCESS_ACCT is not set # CONFIG_TASKSTATS is not set -# CONFIG_UTS_NS is not set # CONFIG_AUDIT is not set # CONFIG_IKCONFIG is not set +CONFIG_LOG_BUF_SHIFT=14 +# CONFIG_CGROUPS is not set +CONFIG_GROUP_SCHED=y +CONFIG_FAIR_GROUP_SCHED=y +# CONFIG_RT_GROUP_SCHED is not set +CONFIG_USER_SCHED=y +# CONFIG_CGROUP_SCHED is not set +CONFIG_SYSFS_DEPRECATED=y +CONFIG_SYSFS_DEPRECATED_V2=y # CONFIG_RELAY is not set -CONFIG_INITRAMFS_SOURCE="" +# CONFIG_NAMESPACES is not set +# CONFIG_BLK_DEV_INITRD is not set CONFIG_CC_OPTIMIZE_FOR_SIZE=y CONFIG_SYSCTL=y CONFIG_EMBEDDED=y @@ -46,33 +61,39 @@ CONFIG_HOTPLUG=y CONFIG_PRINTK=y CONFIG_BUG=y CONFIG_ELF_CORE=y +CONFIG_COMPAT_BRK=y CONFIG_BASE_FULL=y # CONFIG_FUTEX is not set +CONFIG_ANON_INODES=y # CONFIG_EPOLL is not set +CONFIG_SIGNALFD=y +CONFIG_TIMERFD=y +CONFIG_EVENTFD=y # CONFIG_SHMEM is not set -CONFIG_SLAB=y CONFIG_VM_EVENT_COUNTERS=y +CONFIG_SLAB=y +# CONFIG_SLUB is not set +# CONFIG_SLOB is not set +# CONFIG_PROFILING is not set +# CONFIG_MARKERS is not set +CONFIG_HAVE_OPROFILE=y +# CONFIG_HAVE_KPROBES is not set +# CONFIG_HAVE_KRETPROBES is not set +CONFIG_PROC_PAGE_MONITOR=y +CONFIG_SLABINFO=y CONFIG_TINY_SHMEM=y CONFIG_BASE_SMALL=0 -# CONFIG_SLOB is not set - -# -# Loadable module support -# CONFIG_MODULES=y CONFIG_MODULE_UNLOAD=y CONFIG_MODULE_FORCE_UNLOAD=y # CONFIG_MODVERSIONS is not set # CONFIG_MODULE_SRCVERSION_ALL is not set # CONFIG_KMOD is not set - -# -# Block layer -# CONFIG_BLOCK=y # CONFIG_LBD is not set # CONFIG_BLK_DEV_IO_TRACE is not set # CONFIG_LSF is not set +# CONFIG_BLK_DEV_BSG is not set # # IO Schedulers @@ -86,59 +107,26 @@ CONFIG_DEFAULT_DEADLINE=y # CONFIG_DEFAULT_CFQ is not set # CONFIG_DEFAULT_NOOP is not set CONFIG_DEFAULT_IOSCHED="deadline" +CONFIG_CLASSIC_RCU=y +# CONFIG_PREEMPT_RCU is not set # # System type # -# CONFIG_SH_SOLUTION_ENGINE is not set -# CONFIG_SH_7751_SOLUTION_ENGINE is not set -# CONFIG_SH_7300_SOLUTION_ENGINE is not set -# CONFIG_SH_7343_SOLUTION_ENGINE is not set -# CONFIG_SH_73180_SOLUTION_ENGINE is not set -# CONFIG_SH_7751_SYSTEMH is not set -# CONFIG_SH_HP6XX is not set -# CONFIG_SH_EC3104 is not set -# CONFIG_SH_SATURN is not set -# CONFIG_SH_DREAMCAST is not set -# CONFIG_SH_BIGSUR is not set -# CONFIG_SH_MPC1211 is not set -# CONFIG_SH_SH03 is not set -# CONFIG_SH_SECUREEDGE5410 is not set -# CONFIG_SH_HS7751RVOIP is not set -CONFIG_SH_7710VOIPGW=y -# CONFIG_SH_RTS7751R2D is not set -# CONFIG_SH_R7780RP is not set -# CONFIG_SH_EDOSK7705 is not set -# CONFIG_SH_SH4202_MICRODEV is not set -# CONFIG_SH_LANDISK is not set -# CONFIG_SH_TITAN is not set -# CONFIG_SH_SHMIN is not set -# CONFIG_SH_UNKNOWN is not set - -# -# Processor selection -# CONFIG_CPU_SH3=y - -# -# SH-2 Processor Support -# -# CONFIG_CPU_SUBTYPE_SH7604 is not set - -# -# SH-3 Processor Support -# -# CONFIG_CPU_SUBTYPE_SH7300 is not set +# CONFIG_CPU_SUBTYPE_SH7619 is not set +# CONFIG_CPU_SUBTYPE_SH7203 is not set +# CONFIG_CPU_SUBTYPE_SH7206 is not set +# CONFIG_CPU_SUBTYPE_SH7263 is not set # CONFIG_CPU_SUBTYPE_SH7705 is not set # CONFIG_CPU_SUBTYPE_SH7706 is not set # CONFIG_CPU_SUBTYPE_SH7707 is not set # CONFIG_CPU_SUBTYPE_SH7708 is not set # CONFIG_CPU_SUBTYPE_SH7709 is not set CONFIG_CPU_SUBTYPE_SH7710=y - -# -# SH-4 Processor Support -# +# CONFIG_CPU_SUBTYPE_SH7712 is not set +# CONFIG_CPU_SUBTYPE_SH7720 is not set +# CONFIG_CPU_SUBTYPE_SH7721 is not set # CONFIG_CPU_SUBTYPE_SH7750 is not set # CONFIG_CPU_SUBTYPE_SH7091 is not set # CONFIG_CPU_SUBTYPE_SH7750R is not set @@ -147,65 +135,84 @@ CONFIG_CPU_SUBTYPE_SH7710=y # CONFIG_CPU_SUBTYPE_SH7751R is not set # CONFIG_CPU_SUBTYPE_SH7760 is not set # CONFIG_CPU_SUBTYPE_SH4_202 is not set - -# -# ST40 Processor Support -# -# CONFIG_CPU_SUBTYPE_ST40STB1 is not set -# CONFIG_CPU_SUBTYPE_ST40GX1 is not set - -# -# SH-4A Processor Support -# +# CONFIG_CPU_SUBTYPE_SH7763 is not set # CONFIG_CPU_SUBTYPE_SH7770 is not set # CONFIG_CPU_SUBTYPE_SH7780 is not set - -# -# SH4AL-DSP Processor Support -# -# CONFIG_CPU_SUBTYPE_SH73180 is not set +# CONFIG_CPU_SUBTYPE_SH7785 is not set +# CONFIG_CPU_SUBTYPE_SHX3 is not set # CONFIG_CPU_SUBTYPE_SH7343 is not set +# CONFIG_CPU_SUBTYPE_SH7722 is not set +# CONFIG_CPU_SUBTYPE_SH7366 is not set +# CONFIG_CPU_SUBTYPE_SH5_101 is not set +# CONFIG_CPU_SUBTYPE_SH5_103 is not set # # Memory management options # +CONFIG_QUICKLIST=y CONFIG_MMU=y CONFIG_PAGE_OFFSET=0x80000000 CONFIG_MEMORY_START=0x0c000000 CONFIG_MEMORY_SIZE=0x00800000 +CONFIG_29BIT=y CONFIG_VSYSCALL=y +CONFIG_ARCH_FLATMEM_ENABLE=y +CONFIG_ARCH_SPARSEMEM_ENABLE=y +CONFIG_ARCH_SPARSEMEM_DEFAULT=y +CONFIG_MAX_ACTIVE_REGIONS=1 +CONFIG_ARCH_POPULATES_NODE_MAP=y +CONFIG_ARCH_SELECT_MEMORY_MODEL=y +CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_8KB is not set +# CONFIG_PAGE_SIZE_64KB is not set CONFIG_SELECT_MEMORY_MODEL=y CONFIG_FLATMEM_MANUAL=y # CONFIG_DISCONTIGMEM_MANUAL is not set # CONFIG_SPARSEMEM_MANUAL is not set CONFIG_FLATMEM=y CONFIG_FLAT_NODE_MEM_MAP=y -# CONFIG_SPARSEMEM_STATIC is not set +CONFIG_SPARSEMEM_STATIC=y +# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set CONFIG_SPLIT_PTLOCK_CPUS=4 # CONFIG_RESOURCES_64BIT is not set +CONFIG_ZONE_DMA_FLAG=0 +CONFIG_NR_QUICK=2 # # Cache configuration # # CONFIG_SH_DIRECT_MAPPED is not set -# CONFIG_SH_WRITETHROUGH is not set -# CONFIG_SH_OCRAM is not set +CONFIG_CACHE_WRITEBACK=y +# CONFIG_CACHE_WRITETHROUGH is not set +# CONFIG_CACHE_OFF is not set # # Processor features # CONFIG_CPU_LITTLE_ENDIAN=y +# CONFIG_CPU_BIG_ENDIAN is not set # CONFIG_SH_FPU_EMU is not set CONFIG_SH_DSP=y # CONFIG_SH_ADC is not set CONFIG_CPU_HAS_INTEVT=y CONFIG_CPU_HAS_SR_RB=y +CONFIG_CPU_HAS_DSP=y # -# Timer support +# Board support +# +# CONFIG_SH_SOLUTION_ENGINE is not set + +# +# Timer and clock configuration # CONFIG_SH_TMU=y +CONFIG_SH_TIMER_IRQ=16 CONFIG_SH_PCLK_FREQ=32768000 +# CONFIG_TICK_ONESHOT is not set +# CONFIG_NO_HZ is not set +# CONFIG_HIGH_RES_TIMERS is not set +CONFIG_GENERIC_CLOCKEVENTS_BUILD=y # # CPU Frequency scaling @@ -220,55 +227,50 @@ CONFIG_SH_PCLK_FREQ=32768000 # # Companion Chips # -# CONFIG_HD6446X_SERIES is not set + +# +# Additional SuperH Device Drivers +# +# CONFIG_HEARTBEAT is not set +# CONFIG_PUSH_SWITCH is not set # # Kernel features # # CONFIG_HZ_100 is not set CONFIG_HZ_250=y +# CONFIG_HZ_300 is not set # CONFIG_HZ_1000 is not set CONFIG_HZ=250 +# CONFIG_SCHED_HRTICK is not set # CONFIG_KEXEC is not set -# CONFIG_SMP is not set +# CONFIG_CRASH_DUMP is not set CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT_VOLUNTARY is not set # CONFIG_PREEMPT is not set +CONFIG_RCU_TRACE=y +CONFIG_GUSA=y +# CONFIG_GUSA_RB is not set # # Boot options # CONFIG_ZERO_PAGE_OFFSET=0x00001000 CONFIG_BOOT_LINK_OFFSET=0x00800000 -# CONFIG_UBC_WAKEUP is not set # CONFIG_CMDLINE_BOOL is not set # # Bus options # -# CONFIG_PCI is not set - -# -# PCCARD (PCMCIA/CardBus) support -# +# CONFIG_ARCH_SUPPORTS_MSI is not set # CONFIG_PCCARD is not set -# -# PCI Hotplug Support -# - # # Executable file formats # CONFIG_BINFMT_ELF=y -# CONFIG_BINFMT_FLAT is not set # CONFIG_BINFMT_MISC is not set -# -# Power management options (EXPERIMENTAL) -# -# CONFIG_PM is not set - # # Networking # @@ -277,13 +279,14 @@ CONFIG_NET=y # # Networking options # -# CONFIG_NETDEBUG is not set CONFIG_PACKET=y # CONFIG_PACKET_MMAP is not set CONFIG_UNIX=y CONFIG_XFRM=y # CONFIG_XFRM_USER is not set # CONFIG_XFRM_SUB_POLICY is not set +# CONFIG_XFRM_MIGRATE is not set +# CONFIG_XFRM_STATISTICS is not set # CONFIG_NET_KEY is not set CONFIG_INET=y # CONFIG_IP_MULTICAST is not set @@ -301,14 +304,13 @@ CONFIG_SYN_COOKIES=y # CONFIG_INET_TUNNEL is not set CONFIG_INET_XFRM_MODE_TRANSPORT=y CONFIG_INET_XFRM_MODE_TUNNEL=y +CONFIG_INET_XFRM_MODE_BEET=y +# CONFIG_INET_LRO is not set # CONFIG_INET_DIAG is not set # CONFIG_TCP_CONG_ADVANCED is not set CONFIG_TCP_CONG_CUBIC=y CONFIG_DEFAULT_TCP_CONG="cubic" - -# -# IP: Virtual Server Configuration -# +# CONFIG_TCP_MD5SIG is not set # CONFIG_IP_VS is not set # CONFIG_IPV6 is not set # CONFIG_INET6_XFRM_TUNNEL is not set @@ -316,44 +318,24 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # CONFIG_NETWORK_SECMARK is not set CONFIG_NETFILTER=y # CONFIG_NETFILTER_DEBUG is not set +CONFIG_NETFILTER_ADVANCED=y # # Core Netfilter Configuration # -# CONFIG_NETFILTER_NETLINK is not set +# CONFIG_NETFILTER_NETLINK_QUEUE is not set +# CONFIG_NETFILTER_NETLINK_LOG is not set +# CONFIG_NF_CONNTRACK is not set # CONFIG_NETFILTER_XTABLES is not set # # IP: Netfilter Configuration # -CONFIG_IP_NF_CONNTRACK=y -# CONFIG_IP_NF_CT_ACCT is not set -# CONFIG_IP_NF_CONNTRACK_MARK is not set -# CONFIG_IP_NF_CONNTRACK_EVENTS is not set -# CONFIG_IP_NF_CT_PROTO_SCTP is not set -CONFIG_IP_NF_FTP=m -# CONFIG_IP_NF_IRC is not set -# CONFIG_IP_NF_NETBIOS_NS is not set -# CONFIG_IP_NF_TFTP is not set -# CONFIG_IP_NF_AMANDA is not set -CONFIG_IP_NF_PPTP=m -# CONFIG_IP_NF_H323 is not set -# CONFIG_IP_NF_SIP is not set # CONFIG_IP_NF_QUEUE is not set - -# -# DCCP Configuration (EXPERIMENTAL) -# +# CONFIG_IP_NF_IPTABLES is not set +# CONFIG_IP_NF_ARPTABLES is not set # 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 @@ -366,14 +348,7 @@ CONFIG_IP_NF_PPTP=m # CONFIG_LAPB is not set # CONFIG_ECONET is not set # CONFIG_WAN_ROUTER is not set - -# -# QoS and/or fair queueing -# CONFIG_NET_SCHED=y -CONFIG_NET_SCH_CLK_JIFFIES=y -# CONFIG_NET_SCH_CLK_GETTIMEOFDAY is not set -# CONFIG_NET_SCH_CLK_CPU is not set # # Queueing/Scheduling @@ -382,6 +357,7 @@ CONFIG_NET_SCH_CBQ=y # CONFIG_NET_SCH_HTB is not set # CONFIG_NET_SCH_HFSC is not set # CONFIG_NET_SCH_PRIO is not set +# CONFIG_NET_SCH_RR is not set # CONFIG_NET_SCH_RED is not set # CONFIG_NET_SCH_SFQ is not set # CONFIG_NET_SCH_TEQL is not set @@ -389,7 +365,6 @@ CONFIG_NET_SCH_CBQ=y # CONFIG_NET_SCH_GRED is not set # CONFIG_NET_SCH_DSMARK is not set # CONFIG_NET_SCH_NETEM is not set -CONFIG_NET_SCH_INGRESS=y # # Classification @@ -405,20 +380,31 @@ CONFIG_NET_CLS_U32=y # CONFIG_CLS_U32_MARK is not set # CONFIG_NET_CLS_RSVP is not set # CONFIG_NET_CLS_RSVP6 is not set +# CONFIG_NET_CLS_FLOW is not set # CONFIG_NET_EMATCH is not set # CONFIG_NET_CLS_ACT is not set -CONFIG_NET_CLS_POLICE=y # CONFIG_NET_CLS_IND is not set -CONFIG_NET_ESTIMATOR=y +CONFIG_NET_SCH_FIFO=y # # Network testing # # CONFIG_NET_PKTGEN is not set # CONFIG_HAMRADIO is not set +# CONFIG_CAN is not set # CONFIG_IRDA is not set # CONFIG_BT is not set +# CONFIG_AF_RXRPC is not set + +# +# Wireless +# +# CONFIG_CFG80211 is not set +# CONFIG_WIRELESS_EXT is not set +# CONFIG_MAC80211 is not set # CONFIG_IEEE80211 is not set +# CONFIG_RFKILL is not set +# CONFIG_NET_9P is not set # # Device Drivers @@ -427,19 +413,12 @@ CONFIG_NET_ESTIMATOR=y # # Generic Driver Options # +CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" CONFIG_STANDALONE=y CONFIG_PREVENT_FIRMWARE_BUILD=y CONFIG_FW_LOADER=y # CONFIG_SYS_HYPERVISOR is not set - -# -# Connector - unified userspace <-> kernelspace linker -# # CONFIG_CONNECTOR is not set - -# -# Memory Technology Devices (MTD) -# CONFIG_MTD=y # CONFIG_MTD_DEBUG is not set # CONFIG_MTD_CONCAT is not set @@ -451,12 +430,14 @@ CONFIG_MTD_PARTITIONS=y # User Modules And Translation Layers # CONFIG_MTD_CHAR=y +CONFIG_MTD_BLKDEVS=y 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 # CONFIG_SSFDC is not set +# CONFIG_MTD_OOPS is not set # # RAM/ROM/Flash chip drivers @@ -482,7 +463,6 @@ CONFIG_MTD_CFI_UTIL=y CONFIG_MTD_RAM=y # CONFIG_MTD_ROM is not set # CONFIG_MTD_ABSENT is not set -# CONFIG_MTD_OBSOLETE_CHIPS is not set # # Mapping drivers for chip access @@ -505,40 +485,25 @@ CONFIG_MTD_RAM=y # CONFIG_MTD_DOC2000 is not set # CONFIG_MTD_DOC2001 is not set # CONFIG_MTD_DOC2001PLUS is not set - -# -# NAND Flash Device Drivers -# # CONFIG_MTD_NAND is not set - -# -# OneNAND Flash Device Drivers -# # CONFIG_MTD_ONENAND is not set # -# Parallel port support +# UBI - Unsorted block images # +# CONFIG_MTD_UBI is not set # CONFIG_PARPORT is not set - -# -# Plug and Play support -# - -# -# Block devices -# +CONFIG_BLK_DEV=y # CONFIG_BLK_DEV_COW_COMMON is not set # CONFIG_BLK_DEV_LOOP is not set # CONFIG_BLK_DEV_NBD is not set # CONFIG_BLK_DEV_RAM is not set -# CONFIG_BLK_DEV_INITRD is not set # CONFIG_CDROM_PKTCDVD is not set # CONFIG_ATA_OVER_ETH is not set - -# -# ATA/ATAPI/MFM/RLL support -# +CONFIG_MISC_DEVICES=y +# CONFIG_EEPROM_93CX6 is not set +# CONFIG_ENCLOSURE_SERVICES is not set +CONFIG_HAVE_IDE=y # CONFIG_IDE is not set # @@ -546,104 +511,59 @@ CONFIG_MTD_RAM=y # # CONFIG_RAID_ATTRS is not set # CONFIG_SCSI is not set +# CONFIG_SCSI_DMA is not set # CONFIG_SCSI_NETLINK is not set - -# -# Serial ATA (prod) and Parallel ATA (experimental) drivers -# # CONFIG_ATA is not set - -# -# Multi-device support (RAID and LVM) -# # CONFIG_MD is not set - -# -# Fusion MPT device support -# -# CONFIG_FUSION is not set - -# -# IEEE 1394 (FireWire) support -# - -# -# I2O device support -# - -# -# Network device support -# CONFIG_NETDEVICES=y +# CONFIG_NETDEVICES_MULTIQUEUE is not set # CONFIG_DUMMY is not set # CONFIG_BONDING is not set +# CONFIG_MACVLAN is not set # CONFIG_EQUALIZER is not set # CONFIG_TUN is not set - -# -# PHY device support -# +# CONFIG_VETH is not set # CONFIG_PHYLIB is not set - -# -# Ethernet (10 or 100Mbit) -# CONFIG_NET_ETHERNET=y # CONFIG_MII is not set +# CONFIG_AX88796 is not set # CONFIG_STNIC is not set # CONFIG_SMC91X is not set +# CONFIG_IBM_NEW_EMAC_ZMII is not set +# CONFIG_IBM_NEW_EMAC_RGMII is not set +# CONFIG_IBM_NEW_EMAC_TAH is not set +# CONFIG_IBM_NEW_EMAC_EMAC4 is not set +# CONFIG_B44 is not set +CONFIG_NETDEV_1000=y +# CONFIG_E1000E_ENABLED is not set +CONFIG_NETDEV_10000=y # -# Ethernet (1000 Mbit) -# - -# -# Ethernet (10000 Mbit) -# - -# -# Token Ring devices -# - -# -# Wireless LAN (non-hamradio) -# -# CONFIG_NET_RADIO is not set - -# -# Wan interfaces +# Wireless LAN # +# CONFIG_WLAN_PRE80211 is not set +# CONFIG_WLAN_80211 is not set # CONFIG_WAN is not set # CONFIG_PPP 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 - -# -# ISDN subsystem -# # CONFIG_ISDN is not set - -# -# Telephony Support -# CONFIG_PHONE=y -# CONFIG_PHONE_IXJ is not set # # Input device support # CONFIG_INPUT=y # CONFIG_INPUT_FF_MEMLESS is not set +# CONFIG_INPUT_POLLDEV is not set # # Userland interfaces # # CONFIG_INPUT_MOUSEDEV is not set # CONFIG_INPUT_JOYDEV is not set -# CONFIG_INPUT_TSDEV is not set # CONFIG_INPUT_EVDEV is not set # CONFIG_INPUT_EVBUG is not set @@ -653,6 +573,7 @@ CONFIG_INPUT=y # CONFIG_INPUT_KEYBOARD is not set # CONFIG_INPUT_MOUSE is not set # CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TABLET is not set # CONFIG_INPUT_TOUCHSCREEN is not set # CONFIG_INPUT_MISC is not set @@ -684,35 +605,11 @@ CONFIG_SERIAL_CORE_CONSOLE=y # CONFIG_UNIX98_PTYS is not set CONFIG_LEGACY_PTYS=y CONFIG_LEGACY_PTY_COUNT=256 - -# -# IPMI -# # CONFIG_IPMI_HANDLER is not set - -# -# Watchdog Cards -# -# CONFIG_WATCHDOG is not set CONFIG_HW_RANDOM=y -# CONFIG_GEN_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 -# # CONFIG_TCG_TPM is not set -# CONFIG_TELCLOCK is not set - -# -# I2C support -# # CONFIG_I2C is not set # @@ -720,119 +617,86 @@ CONFIG_HW_RANDOM=y # # CONFIG_SPI is not set # CONFIG_SPI_MASTER is not set +# CONFIG_W1 is not set +# CONFIG_POWER_SUPPLY is not set +# CONFIG_HWMON is not set +CONFIG_THERMAL=y +# CONFIG_WATCHDOG is not set # -# Dallas's 1-wire bus -# - -# -# Hardware Monitoring support +# Sonics Silicon Backplane # -# CONFIG_HWMON is not set -# CONFIG_HWMON_VID is not set +CONFIG_SSB_POSSIBLE=y +# CONFIG_SSB is not set # -# Misc devices +# Multifunction device drivers # +# CONFIG_MFD_SM501 is not set # # Multimedia devices # # CONFIG_VIDEO_DEV is not set -CONFIG_VIDEO_V4L2=y - -# -# Digital Video Broadcasting Devices -# -# CONFIG_DVB is not set +# CONFIG_DVB_CORE is not set +# CONFIG_DAB is not set # # Graphics support # -CONFIG_FIRMWARE_EDID=y +# CONFIG_VGASTATE is not set +# CONFIG_VIDEO_OUTPUT_CONTROL is not set # CONFIG_FB is not set # CONFIG_BACKLIGHT_LCD_SUPPORT is not set # -# Sound +# Display device support # -# CONFIG_SOUND is not set +# CONFIG_DISPLAY_SUPPORT is not set # -# USB support +# Sound # -# CONFIG_USB_ARCH_HAS_HCD is not set +# CONFIG_SOUND is not set +CONFIG_HID_SUPPORT=y +CONFIG_HID=y +# CONFIG_HID_DEBUG is not set +# CONFIG_HIDRAW is not set +CONFIG_USB_SUPPORT=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 is not set - -# -# MMC/SD Card support -# # CONFIG_MMC is not set - -# -# LED devices -# +# CONFIG_MEMSTICK is not set # CONFIG_NEW_LEDS is not set - -# -# LED drivers -# - -# -# LED Triggers -# - -# -# InfiniBand support -# - -# -# EDAC - error detection and reporting (RAS) (EXPERIMENTAL) -# - -# -# Real Time Clock -# # CONFIG_RTC_CLASS is not set # -# DMA Engine support -# -# CONFIG_DMA_ENGINE is not set - -# -# DMA Clients -# - -# -# DMA Devices +# Userspace I/O # +# CONFIG_UIO is not set # # File systems # # CONFIG_EXT2_FS is not set # CONFIG_EXT3_FS is not set +# CONFIG_EXT4DEV_FS is not set # CONFIG_REISERFS_FS is not set # CONFIG_JFS_FS is not set # CONFIG_FS_POSIX_ACL is not set # CONFIG_XFS_FS is not set +# CONFIG_GFS2_FS is not set # CONFIG_OCFS2_FS is not set -# CONFIG_MINIX_FS is not set -# CONFIG_ROMFS_FS is not set +# CONFIG_DNOTIFY is not set # CONFIG_INOTIFY is not set # CONFIG_QUOTA is not set -# CONFIG_DNOTIFY is not set # CONFIG_AUTOFS_FS is not set # CONFIG_AUTOFS4_FS is not set # CONFIG_FUSE_FS is not set @@ -861,7 +725,6 @@ CONFIG_TMPFS=y # CONFIG_TMPFS_POSIX_ACL is not set # CONFIG_HUGETLBFS is not set # CONFIG_HUGETLB_PAGE is not set -CONFIG_RAMFS=y # CONFIG_CONFIGFS_FS is not set # @@ -874,26 +737,26 @@ CONFIG_RAMFS=y # CONFIG_BEFS_FS is not set # CONFIG_BFS_FS is not set # CONFIG_EFS_FS is not set -# CONFIG_JFFS_FS is not set CONFIG_JFFS2_FS=y CONFIG_JFFS2_FS_DEBUG=0 CONFIG_JFFS2_FS_WRITEBUFFER=y +# CONFIG_JFFS2_FS_WBUF_VERIFY is not set # CONFIG_JFFS2_SUMMARY is not set # CONFIG_JFFS2_FS_XATTR is not set # CONFIG_JFFS2_COMPRESSION_OPTIONS is not set CONFIG_JFFS2_ZLIB=y +# CONFIG_JFFS2_LZO is not set CONFIG_JFFS2_RTIME=y # CONFIG_JFFS2_RUBIN is not set # CONFIG_CRAMFS is not set # CONFIG_VXFS_FS is not set +# CONFIG_MINIX_FS is not set # CONFIG_HPFS_FS is not set # CONFIG_QNX4FS_FS is not set +# CONFIG_ROMFS_FS is not set # CONFIG_SYSV_FS is not set # CONFIG_UFS_FS is not set - -# -# Network File Systems -# +CONFIG_NETWORK_FILESYSTEMS=y # CONFIG_NFS_FS is not set # CONFIG_NFSD is not set # CONFIG_SMB_FS is not set @@ -901,55 +764,97 @@ CONFIG_JFFS2_RTIME=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 # # CONFIG_PARTITION_ADVANCED is not set CONFIG_MSDOS_PARTITION=y - -# -# Native Language Support -# # CONFIG_NLS is not set - -# -# Profiling support -# -# CONFIG_PROFILING is not set +# CONFIG_DLM is not set # # Kernel hacking # +CONFIG_TRACE_IRQFLAGS_SUPPORT=y # CONFIG_PRINTK_TIME is not set +CONFIG_ENABLE_WARN_DEPRECATED=y CONFIG_ENABLE_MUST_CHECK=y # CONFIG_MAGIC_SYSRQ is not set # CONFIG_UNUSED_SYMBOLS is not set +CONFIG_DEBUG_FS=y +# CONFIG_HEADERS_CHECK is not set # CONFIG_DEBUG_KERNEL is not set -CONFIG_LOG_BUF_SHIFT=14 # CONFIG_DEBUG_BUGVERBOSE is not set -# CONFIG_DEBUG_FS is not set +# CONFIG_SAMPLES is not set # CONFIG_SH_STANDARD_BIOS is not set -# CONFIG_KGDB is not set +# CONFIG_EARLY_SCIF_CONSOLE is not set +# CONFIG_SH_KGDB is not set # # Security options # # CONFIG_KEYS is not set # CONFIG_SECURITY is not set - -# -# Cryptographic options -# -# CONFIG_CRYPTO is not set +# CONFIG_SECURITY_FILE_CAPABILITIES is not set +CONFIG_CRYPTO=y +# CONFIG_CRYPTO_SEQIV is not set +# CONFIG_CRYPTO_MANAGER is not set +# CONFIG_CRYPTO_HMAC is not set +# CONFIG_CRYPTO_XCBC is not set +# CONFIG_CRYPTO_NULL is not set +# CONFIG_CRYPTO_MD4 is not set +# CONFIG_CRYPTO_MD5 is not set +# CONFIG_CRYPTO_SHA1 is not set +# CONFIG_CRYPTO_SHA256 is not set +# CONFIG_CRYPTO_SHA512 is not set +# CONFIG_CRYPTO_WP512 is not set +# CONFIG_CRYPTO_TGR192 is not set +# CONFIG_CRYPTO_GF128MUL is not set +# CONFIG_CRYPTO_ECB is not set +# CONFIG_CRYPTO_CBC is not set +# CONFIG_CRYPTO_PCBC is not set +# CONFIG_CRYPTO_LRW is not set +# CONFIG_CRYPTO_XTS is not set +# CONFIG_CRYPTO_CTR is not set +# CONFIG_CRYPTO_GCM is not set +# CONFIG_CRYPTO_CCM is not set +# CONFIG_CRYPTO_CRYPTD is not set +# CONFIG_CRYPTO_DES is not set +# CONFIG_CRYPTO_FCRYPT is not set +# CONFIG_CRYPTO_BLOWFISH is not set +# CONFIG_CRYPTO_TWOFISH is not set +# CONFIG_CRYPTO_SERPENT is not set +# CONFIG_CRYPTO_AES is not set +# CONFIG_CRYPTO_CAST5 is not set +# CONFIG_CRYPTO_CAST6 is not set +# CONFIG_CRYPTO_TEA is not set +# CONFIG_CRYPTO_ARC4 is not set +# CONFIG_CRYPTO_KHAZAD is not set +# CONFIG_CRYPTO_ANUBIS is not set +# CONFIG_CRYPTO_SEED is not set +# CONFIG_CRYPTO_SALSA20 is not set +# CONFIG_CRYPTO_DEFLATE is not set +# CONFIG_CRYPTO_MICHAEL_MIC is not set +# CONFIG_CRYPTO_CRC32C is not set +# CONFIG_CRYPTO_CAMELLIA is not set +# CONFIG_CRYPTO_TEST is not set +# CONFIG_CRYPTO_AUTHENC is not set +# CONFIG_CRYPTO_LZO is not set +CONFIG_CRYPTO_HW=y # # Library routines # +CONFIG_BITREVERSE=y # CONFIG_CRC_CCITT is not set # CONFIG_CRC16 is not set +# CONFIG_CRC_ITU_T is not set CONFIG_CRC32=y +# CONFIG_CRC7 is not set # CONFIG_LIBCRC32C is not set CONFIG_ZLIB_INFLATE=y CONFIG_ZLIB_DEFLATE=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT=y +CONFIG_HAS_DMA=y diff --git a/arch/sh/drivers/dma/dma-sh.c b/arch/sh/drivers/dma/dma-sh.c index 5c3359756a926fe01e1107a1af4bfc53239b25e4..71ff3d6f26e2924462de6132ca9242685c9ddacf 100644 --- a/arch/sh/drivers/dma/dma-sh.c +++ b/arch/sh/drivers/dma/dma-sh.c @@ -90,7 +90,7 @@ static irqreturn_t dma_tei(int irq, void *dev_id) static int sh_dmac_request_dma(struct dma_channel *chan) { - if (unlikely(!chan->flags & DMA_TEI_CAPABLE)) + if (unlikely(!(chan->flags & DMA_TEI_CAPABLE))) return 0; return request_irq(get_dmte_irq(chan->chan), dma_tei, diff --git a/arch/sh/drivers/heartbeat.c b/arch/sh/drivers/heartbeat.c index b76a14f12ce24dfba85431fc551cb292bee7f5ed..ab77b0e0fa0ebea7b0cef65f4fbda8f549b2483c 100644 --- a/arch/sh/drivers/heartbeat.c +++ b/arch/sh/drivers/heartbeat.c @@ -93,7 +93,7 @@ static int heartbeat_drv_probe(struct platform_device *pdev) } hd->base = ioremap_nocache(res->start, res->end - res->start + 1); - if (!unlikely(hd->base)) { + if (unlikely(!hd->base)) { dev_err(&pdev->dev, "ioremap failed\n"); if (!pdev->dev.platform_data) diff --git a/arch/sh/drivers/pci/ops-dreamcast.c b/arch/sh/drivers/pci/ops-dreamcast.c index 0dac87b19624f5ac7dbfd15362dbe884c865b1bc..e1284fc693611a266c5b4307f569bf81fa1ff0d7 100644 --- a/arch/sh/drivers/pci/ops-dreamcast.c +++ b/arch/sh/drivers/pci/ops-dreamcast.c @@ -83,9 +83,9 @@ static int gapspci_read(struct pci_bus *bus, unsigned int devfn, int where, int return PCIBIOS_DEVICE_NOT_FOUND; switch (size) { - case 1: *val = ctrl_inb(GAPSPCI_BBA_CONFIG+where); break; - case 2: *val = ctrl_inw(GAPSPCI_BBA_CONFIG+where); break; - case 4: *val = ctrl_inl(GAPSPCI_BBA_CONFIG+where); break; + case 1: *val = inb(GAPSPCI_BBA_CONFIG+where); break; + case 2: *val = inw(GAPSPCI_BBA_CONFIG+where); break; + case 4: *val = inl(GAPSPCI_BBA_CONFIG+where); break; } return PCIBIOS_SUCCESSFUL; @@ -97,9 +97,9 @@ static int gapspci_write(struct pci_bus *bus, unsigned int devfn, int where, int return PCIBIOS_DEVICE_NOT_FOUND; switch (size) { - case 1: ctrl_outb(( u8)val, GAPSPCI_BBA_CONFIG+where); break; - case 2: ctrl_outw((u16)val, GAPSPCI_BBA_CONFIG+where); break; - case 4: ctrl_outl((u32)val, GAPSPCI_BBA_CONFIG+where); break; + case 1: outb(( u8)val, GAPSPCI_BBA_CONFIG+where); break; + case 2: outw((u16)val, GAPSPCI_BBA_CONFIG+where); break; + case 4: outl((u32)val, GAPSPCI_BBA_CONFIG+where); break; } return PCIBIOS_SUCCESSFUL; @@ -127,36 +127,36 @@ int __init gapspci_init(void) */ for (i=0; i<16; i++) - idbuf[i] = ctrl_inb(GAPSPCI_REGS+i); + idbuf[i] = inb(GAPSPCI_REGS+i); if (strncmp(idbuf, "GAPSPCI_BRIDGE_2", 16)) return -ENODEV; - ctrl_outl(0x5a14a501, GAPSPCI_REGS+0x18); + outl(0x5a14a501, GAPSPCI_REGS+0x18); for (i=0; i<1000000; i++) ; - if (ctrl_inl(GAPSPCI_REGS+0x18) != 1) + if (inl(GAPSPCI_REGS+0x18) != 1) return -EINVAL; - ctrl_outl(0x01000000, GAPSPCI_REGS+0x20); - ctrl_outl(0x01000000, GAPSPCI_REGS+0x24); + outl(0x01000000, GAPSPCI_REGS+0x20); + outl(0x01000000, GAPSPCI_REGS+0x24); - ctrl_outl(GAPSPCI_DMA_BASE, GAPSPCI_REGS+0x28); - ctrl_outl(GAPSPCI_DMA_BASE+GAPSPCI_DMA_SIZE, GAPSPCI_REGS+0x2c); + outl(GAPSPCI_DMA_BASE, GAPSPCI_REGS+0x28); + outl(GAPSPCI_DMA_BASE+GAPSPCI_DMA_SIZE, GAPSPCI_REGS+0x2c); - ctrl_outl(1, GAPSPCI_REGS+0x14); - ctrl_outl(1, GAPSPCI_REGS+0x34); + outl(1, GAPSPCI_REGS+0x14); + outl(1, GAPSPCI_REGS+0x34); /* Setting Broadband Adapter */ - ctrl_outw(0xf900, GAPSPCI_BBA_CONFIG+0x06); - ctrl_outl(0x00000000, GAPSPCI_BBA_CONFIG+0x30); - ctrl_outb(0x00, GAPSPCI_BBA_CONFIG+0x3c); - ctrl_outb(0xf0, GAPSPCI_BBA_CONFIG+0x0d); - ctrl_outw(0x0006, GAPSPCI_BBA_CONFIG+0x04); - ctrl_outl(0x00002001, GAPSPCI_BBA_CONFIG+0x10); - ctrl_outl(0x01000000, GAPSPCI_BBA_CONFIG+0x14); + outw(0xf900, GAPSPCI_BBA_CONFIG+0x06); + outl(0x00000000, GAPSPCI_BBA_CONFIG+0x30); + outb(0x00, GAPSPCI_BBA_CONFIG+0x3c); + outb(0xf0, GAPSPCI_BBA_CONFIG+0x0d); + outw(0x0006, GAPSPCI_BBA_CONFIG+0x04); + outl(0x00002001, GAPSPCI_BBA_CONFIG+0x10); + outl(0x01000000, GAPSPCI_BBA_CONFIG+0x14); return 0; } diff --git a/arch/sh/kernel/cpu/init.c b/arch/sh/kernel/cpu/init.c index 80a31329ead9cfb05ff428a00755faefd1889568..75fb03d3567008e733748d2748366ab4fb3d1654 100644 --- a/arch/sh/kernel/cpu/init.c +++ b/arch/sh/kernel/cpu/init.c @@ -233,7 +233,7 @@ static void __init dsp_init(void) * and cache configuration in detect_cpu_and_cache_system(). */ -asmlinkage void __cpuinit sh_cpu_init(void) +asmlinkage void __init sh_cpu_init(void) { current_thread_info()->cpu = hard_smp_processor_id(); diff --git a/arch/sh/kernel/cpu/sh2/setup-sh7619.c b/arch/sh/kernel/cpu/sh2/setup-sh7619.c index b230eb278cef73b7f36ce48efb849b3b0f7ca90d..cc530f4d84d679a1418571319cf3b98be02d18fd 100644 --- a/arch/sh/kernel/cpu/sh2/setup-sh7619.c +++ b/arch/sh/kernel/cpu/sh2/setup-sh7619.c @@ -10,7 +10,7 @@ #include #include #include -#include +#include enum { UNUSED = 0, diff --git a/arch/sh/kernel/cpu/sh2a/clock-sh7203.c b/arch/sh/kernel/cpu/sh2a/clock-sh7203.c index 3feb95a4fcbccae462c1fda63548a33709f7bdb5..fb781329848af930b22290d452fe99a8fdc7a169 100644 --- a/arch/sh/kernel/cpu/sh2a/clock-sh7203.c +++ b/arch/sh/kernel/cpu/sh2a/clock-sh7203.c @@ -21,8 +21,8 @@ #include #include -const static int pll1rate[]={8,12,16,0}; -const static int pfc_divisors[]={1,2,3,4,6,8,12}; +static const int pll1rate[]={8,12,16,0}; +static const int pfc_divisors[]={1,2,3,4,6,8,12}; #define ifc_divisors pfc_divisors #if (CONFIG_SH_CLK_MD == 0) diff --git a/arch/sh/kernel/cpu/sh2a/setup-sh7203.c b/arch/sh/kernel/cpu/sh2a/setup-sh7203.c index db6ef5cecde14b12993f5bbce9b657ba58fa86e1..e98dc4450352c6d1a474d2edfce07c03a723c53b 100644 --- a/arch/sh/kernel/cpu/sh2a/setup-sh7203.c +++ b/arch/sh/kernel/cpu/sh2a/setup-sh7203.c @@ -10,7 +10,7 @@ #include #include #include -#include +#include enum { UNUSED = 0, diff --git a/arch/sh/kernel/cpu/sh2a/setup-sh7206.c b/arch/sh/kernel/cpu/sh2a/setup-sh7206.c index a564425b905f6572ee710624504dc9283fd9b56b..e6d4ec445dd885d693a39e9b3c4d273ace48db6c 100644 --- a/arch/sh/kernel/cpu/sh2a/setup-sh7206.c +++ b/arch/sh/kernel/cpu/sh2a/setup-sh7206.c @@ -10,7 +10,7 @@ #include #include #include -#include +#include enum { UNUSED = 0, diff --git a/arch/sh/kernel/cpu/sh3/probe.c b/arch/sh/kernel/cpu/sh3/probe.c index fcc80bb7bee7f9de3192d6309554e1b9642848e5..10f2a760c5ee07ae6c2d71503070bea664733602 100644 --- a/arch/sh/kernel/cpu/sh3/probe.c +++ b/arch/sh/kernel/cpu/sh3/probe.c @@ -94,9 +94,9 @@ int __uses_jump_to_uncached detect_cpu_and_cache_system(void) boot_cpu_data.dcache.way_incr = (1 << 13); boot_cpu_data.dcache.entry_mask = 0x1ff0; boot_cpu_data.dcache.sets = 512; - ctrl_outl(CCR_CACHE_32KB, CCR3); + ctrl_outl(CCR_CACHE_32KB, CCR3_REG); #else - ctrl_outl(CCR_CACHE_16KB, CCR3); + ctrl_outl(CCR_CACHE_16KB, CCR3_REG); #endif #endif } diff --git a/arch/sh/kernel/cpu/sh3/setup-sh7705.c b/arch/sh/kernel/cpu/sh3/setup-sh7705.c index dd0a20a685f716309803fcf652d47ebe4a62b7ba..f581534cb732c08163b274dc452745e957d924d5 100644 --- a/arch/sh/kernel/cpu/sh3/setup-sh7705.c +++ b/arch/sh/kernel/cpu/sh3/setup-sh7705.c @@ -12,7 +12,7 @@ #include #include #include -#include +#include #include enum { diff --git a/arch/sh/kernel/cpu/sh3/setup-sh770x.c b/arch/sh/kernel/cpu/sh3/setup-sh770x.c index 969804bb523bab00964e6303de157e26f06b0096..d3733b13ea5298194020ee43114ce3bafe8420c4 100644 --- a/arch/sh/kernel/cpu/sh3/setup-sh770x.c +++ b/arch/sh/kernel/cpu/sh3/setup-sh770x.c @@ -16,7 +16,7 @@ #include #include #include -#include +#include enum { UNUSED = 0, @@ -123,15 +123,15 @@ static struct resource rtc_resources[] = { .flags = IORESOURCE_IO, }, [1] = { - .start = 20, + .start = 21, .flags = IORESOURCE_IRQ, }, [2] = { - .start = 21, + .start = 22, .flags = IORESOURCE_IRQ, }, [3] = { - .start = 22, + .start = 20, .flags = IORESOURCE_IRQ, }, }; diff --git a/arch/sh/kernel/cpu/sh3/setup-sh7710.c b/arch/sh/kernel/cpu/sh3/setup-sh7710.c index 0cc0e2bf135dd744676f3b58cf20a900c94644f1..7406c9ad92597c758cab7cecdf3102e48e72f078 100644 --- a/arch/sh/kernel/cpu/sh3/setup-sh7710.c +++ b/arch/sh/kernel/cpu/sh3/setup-sh7710.c @@ -12,7 +12,7 @@ #include #include #include -#include +#include #include enum { diff --git a/arch/sh/kernel/cpu/sh3/setup-sh7720.c b/arch/sh/kernel/cpu/sh3/setup-sh7720.c index 3855ea4c21c8acd30ed3f3c0bbf3a4ad598f9d67..8028082527c55a82d835fc32f800a4262dc1bf06 100644 --- a/arch/sh/kernel/cpu/sh3/setup-sh7720.c +++ b/arch/sh/kernel/cpu/sh3/setup-sh7720.c @@ -16,7 +16,7 @@ #include #include #include -#include +#include #include #define INTC_ICR1 0xA4140010UL diff --git a/arch/sh/kernel/cpu/sh4/setup-sh4-202.c b/arch/sh/kernel/cpu/sh4/setup-sh4-202.c index dab193293f2034c37f36090c1672540da299db0e..7371abf64f8082a902fefc675aec6579ec73b1ac 100644 --- a/arch/sh/kernel/cpu/sh4/setup-sh4-202.c +++ b/arch/sh/kernel/cpu/sh4/setup-sh4-202.c @@ -10,7 +10,7 @@ #include #include #include -#include +#include static struct plat_sci_port sci_platform_data[] = { { diff --git a/arch/sh/kernel/cpu/sh4/setup-sh7750.c b/arch/sh/kernel/cpu/sh4/setup-sh7750.c index ae3603aca615017e2296cf094a0a822ec291006a..ec884039b914cb5d424a544da7c41bd67e8a655b 100644 --- a/arch/sh/kernel/cpu/sh4/setup-sh7750.c +++ b/arch/sh/kernel/cpu/sh4/setup-sh7750.c @@ -12,7 +12,7 @@ #include #include #include -#include +#include static struct resource rtc_resources[] = { [0] = { diff --git a/arch/sh/kernel/cpu/sh4/setup-sh7760.c b/arch/sh/kernel/cpu/sh4/setup-sh7760.c index 85f81579b97e54e7494e556c65c86443f3d57e8a..254c5c55ab9170b846d9a9f5b0ac52db0f31e5fa 100644 --- a/arch/sh/kernel/cpu/sh4/setup-sh7760.c +++ b/arch/sh/kernel/cpu/sh4/setup-sh7760.c @@ -10,7 +10,7 @@ #include #include #include -#include +#include enum { UNUSED = 0, diff --git a/arch/sh/kernel/cpu/sh4/sq.c b/arch/sh/kernel/cpu/sh4/sq.c index 8250e017bd4eaac43989cfa037be64b4c59688fe..9561b02ade0ef84e0b1a904c0a89891517ef77b2 100644 --- a/arch/sh/kernel/cpu/sh4/sq.c +++ b/arch/sh/kernel/cpu/sh4/sq.c @@ -216,7 +216,7 @@ void sq_unmap(unsigned long vaddr) if (unlikely(!map)) { printk("%s: bad store queue address 0x%08lx\n", - __FUNCTION__, vaddr); + __func__, vaddr); return; } @@ -233,7 +233,7 @@ void sq_unmap(unsigned long vaddr) vma = remove_vm_area((void *)(map->sq_addr & PAGE_MASK)); if (!vma) { printk(KERN_ERR "%s: bad address 0x%08lx\n", - __FUNCTION__, map->sq_addr); + __func__, map->sq_addr); return; } } diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7343.c b/arch/sh/kernel/cpu/sh4a/setup-sh7343.c index c0a3f079dfdcda8565c1d3e83394d9b7930c70ac..6d4f50cd4aaf62ece55cce91bdab88c134f6e165 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7343.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7343.c @@ -10,7 +10,7 @@ #include #include #include -#include +#include static struct plat_sci_port sci_platform_data[] = { { diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7366.c b/arch/sh/kernel/cpu/sh4a/setup-sh7366.c index 967e8b69a2f814a1506d23ce72612d1091c295e3..f26b5cdad0d1fd0349665b30ea2c93ecef918ca1 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7366.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7366.c @@ -12,7 +12,7 @@ #include #include #include -#include +#include static struct plat_sci_port sci_platform_data[] = { { diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7722.c b/arch/sh/kernel/cpu/sh4a/setup-sh7722.c index 73c778d40d13f289f33b96f92945b9be49d1af6e..b98b4bc93ec9df41bfd5b61ada70a65b3bd8ba99 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7722.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7722.c @@ -10,9 +10,9 @@ #include #include #include +#include #include #include -#include static struct resource usbf_resources[] = { [0] = { diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7763.c b/arch/sh/kernel/cpu/sh4a/setup-sh7763.c index eabd5386812d089efa4084903f9244a21cdc688a..07c988dc9de6fa7bf07e7f315f294cc5e90453c0 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7763.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7763.c @@ -12,7 +12,7 @@ #include #include #include -#include +#include static struct resource rtc_resources[] = { [0] = { diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7770.c b/arch/sh/kernel/cpu/sh4a/setup-sh7770.c index 32f4f59a837b41ca36329488597177f6aa1573ef..b9cec48b18088dc0b0239f23b120626d10c5abe3 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7770.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7770.c @@ -10,7 +10,7 @@ #include #include #include -#include +#include static struct plat_sci_port sci_platform_data[] = { { diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7780.c b/arch/sh/kernel/cpu/sh4a/setup-sh7780.c index 293004b526ff98eefa9c0a1f61936e3d551a3396..18dbbe23fea1b172a22532b9cd93005d2eb52562 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7780.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7780.c @@ -11,7 +11,7 @@ #include #include #include -#include +#include static struct resource rtc_resources[] = { [0] = { diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7785.c b/arch/sh/kernel/cpu/sh4a/setup-sh7785.c index 74b60e96cdf43bf30d7b7624226116459a0bbbe8..621e7329ec63747b766301e72859a324dee8290e 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7785.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7785.c @@ -10,10 +10,10 @@ #include #include #include +#include #include #include #include -#include static struct plat_sci_port sci_platform_data[] = { { diff --git a/arch/sh/kernel/cpu/sh4a/setup-shx3.c b/arch/sh/kernel/cpu/sh4a/setup-shx3.c index 4dc958b6b31468a35b11d10536bb005e0d846c2f..bd35f32534b98e11a3e231a16940931915995b43 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-shx3.c +++ b/arch/sh/kernel/cpu/sh4a/setup-shx3.c @@ -10,9 +10,9 @@ #include #include #include +#include #include #include -#include static struct plat_sci_port sci_platform_data[] = { { diff --git a/arch/sh/kernel/cpu/sh5/unwind.c b/arch/sh/kernel/cpu/sh5/unwind.c index 119c20afd4e5afb0d9d8803c2d94f2b5747e7d15..b205b25eaf45d6d6b0b791703ee83fe3f9e45f8b 100644 --- a/arch/sh/kernel/cpu/sh5/unwind.c +++ b/arch/sh/kernel/cpu/sh5/unwind.c @@ -149,7 +149,7 @@ static int lookup_prev_stack_frame(unsigned long fp, unsigned long pc, if (dest >= 63) { printk(KERN_NOTICE "%s: Invalid dest reg %d " "specified in movi handler. Failed " - "opcode was 0x%lx: ", __FUNCTION__, + "opcode was 0x%lx: ", __func__, dest, op); continue; diff --git a/arch/sh/kernel/io_trapped.c b/arch/sh/kernel/io_trapped.c index 86a665d92201ef67ca91349da2bf46d4717edf45..39cd7f3aec7bc34b2139a272c497b2bbf8141276 100644 --- a/arch/sh/kernel/io_trapped.c +++ b/arch/sh/kernel/io_trapped.c @@ -32,7 +32,7 @@ EXPORT_SYMBOL_GPL(trapped_mem); #endif static DEFINE_SPINLOCK(trapped_lock); -int __init register_trapped_io(struct trapped_io *tiop) +int register_trapped_io(struct trapped_io *tiop) { struct resource *res; unsigned long len = 0, flags = 0; diff --git a/arch/sh/kernel/sh_ksyms_32.c b/arch/sh/kernel/sh_ksyms_32.c index e1a6de9088b5bde648fcae3f8ab0e9fcf89cb158..d80de39032710d094fdb73147eff86466a558ef2 100644 --- a/arch/sh/kernel/sh_ksyms_32.c +++ b/arch/sh/kernel/sh_ksyms_32.c @@ -111,9 +111,9 @@ DECLARE_EXPORT(__movmem_i4_even); DECLARE_EXPORT(__movmem_i4_odd); DECLARE_EXPORT(__movmemSI12_i4); -#if (__GNUC_MINOR__ == 2 || defined(__GNUC_STM_RELEASE__)) +#if (__GNUC_MINOR__ >= 2 || defined(__GNUC_STM_RELEASE__)) /* - * GCC 4.2 emits these for division, as do GCC 4.1.x versions of the ST + * GCC >= 4.2 emits these for division, as do GCC 4.1.x versions of the ST * compiler which include backported patches. */ DECLARE_EXPORT(__sdivsi3_i4i); @@ -146,5 +146,6 @@ EXPORT_SYMBOL(csum_partial_copy_generic); EXPORT_SYMBOL(csum_ipv6_magic); #endif EXPORT_SYMBOL(clear_page); +EXPORT_SYMBOL(copy_page); EXPORT_SYMBOL(__clear_user); EXPORT_SYMBOL(_ebss); diff --git a/arch/sh/kernel/sh_ksyms_64.c b/arch/sh/kernel/sh_ksyms_64.c index 8004c38d3d37f6ba73b1725f366dc892d7901060..dd38a683de65633d38176de60384dcb3432b5b77 100644 --- a/arch/sh/kernel/sh_ksyms_64.c +++ b/arch/sh/kernel/sh_ksyms_64.c @@ -42,6 +42,7 @@ EXPORT_SYMBOL(__down_trylock); EXPORT_SYMBOL(__up); EXPORT_SYMBOL(__put_user_asm_l); EXPORT_SYMBOL(__get_user_asm_l); +EXPORT_SYMBOL(copy_page); EXPORT_SYMBOL(__copy_user); EXPORT_SYMBOL(memcpy); EXPORT_SYMBOL(__udelay); diff --git a/arch/sh/kernel/timers/timer-cmt.c b/arch/sh/kernel/timers/timer-cmt.c index 71312324b5defb4383d4760ecfd12f196fd52b7e..d20c8c3758817981549ac4fce5e47d7dafc2ffa7 100644 --- a/arch/sh/kernel/timers/timer-cmt.c +++ b/arch/sh/kernel/timers/timer-cmt.c @@ -77,7 +77,7 @@ static unsigned long cmt_timer_get_offset(void) count -= LATCH; } else { printk("%s (): hardware timer problem?\n", - __FUNCTION__); + __func__); } } } else diff --git a/arch/sh/kernel/timers/timer-mtu2.c b/arch/sh/kernel/timers/timer-mtu2.c index ade9d6eb29f9e92ce40ab774db506e6e9817d817..fe453c01f9c9d533ab4d3fd5e4e1356c4bba6aa8 100644 --- a/arch/sh/kernel/timers/timer-mtu2.c +++ b/arch/sh/kernel/timers/timer-mtu2.c @@ -76,7 +76,7 @@ static unsigned long mtu2_timer_get_offset(void) count -= LATCH; } else { printk("%s (): hardware timer problem?\n", - __FUNCTION__); + __func__); } } } else diff --git a/arch/sh/kernel/topology.c b/arch/sh/kernel/topology.c index 9b5844a1bdaaa814d951b07da66fb848a9a94e5c..0838942b70837f715634e80d099e9f31b0f99001 100644 --- a/arch/sh/kernel/topology.c +++ b/arch/sh/kernel/topology.c @@ -29,7 +29,7 @@ static int __init topology_init(void) ret = register_cpu(&per_cpu(cpu_devices, i), i); if (unlikely(ret)) printk(KERN_WARNING "%s: register_cpu %d failed (%d)\n", - __FUNCTION__, i, ret); + __func__, i, ret); } #if defined(CONFIG_NUMA) && !defined(CONFIG_SMP) diff --git a/arch/sh/kernel/traps_64.c b/arch/sh/kernel/traps_64.c index a55ac81d795bd393a10caf8b394592815b0a8a01..1b58a749908739d4a3224ee5eb7eef33bc51c565 100644 --- a/arch/sh/kernel/traps_64.c +++ b/arch/sh/kernel/traps_64.c @@ -238,7 +238,7 @@ DO_ERROR(12, SIGILL, "reserved instruction", reserved_inst, current) /* Called with interrupts disabled */ asmlinkage void do_exception_error(unsigned long ex, struct pt_regs *regs) { - show_excp_regs(__FUNCTION__, -1, -1, regs); + show_excp_regs(__func__, -1, -1, regs); die_if_kernel("exception", regs, ex); } diff --git a/arch/sh/lib64/c-checksum.c b/arch/sh/lib64/c-checksum.c index 5dfbd8b5e5586b9e1c344ff3497e0b3a5cb8e182..5c284e0cff9c66c0fd298de301e173da94d99c97 100644 --- a/arch/sh/lib64/c-checksum.c +++ b/arch/sh/lib64/c-checksum.c @@ -207,7 +207,7 @@ __wsum csum_tcpudp_nofold(__be32 saddr, __be32 daddr, result = (result & 0xffffffff) + (result >> 32); pr_debug("%s saddr %x daddr %x len %x proto %x sum %x result %08Lx\n", - __FUNCTION__, saddr, daddr, len, proto, sum, result); + __func__, saddr, daddr, len, proto, sum, result); return (__wsum)result; } diff --git a/arch/sh/lib64/udelay.c b/arch/sh/lib64/udelay.c index 23c7d17fb9f7398b842c0c9a0b2a19faa2430930..d76bd801194f538972219b3682e90ed77ffa3cb3 100644 --- a/arch/sh/lib64/udelay.c +++ b/arch/sh/lib64/udelay.c @@ -21,7 +21,7 @@ * a 1GHz box, that's about 2 seconds. */ -void __delay(int loops) +void __delay(unsigned long loops) { long long dummy; __asm__ __volatile__("gettr tr0, %1\n\t" @@ -33,24 +33,17 @@ void __delay(int loops) :"0"(loops)); } -void __udelay(unsigned long long usecs, unsigned long lpj) +inline void __const_udelay(unsigned long xloops) { - usecs *= (((unsigned long long) HZ << 32) / 1000000) * lpj; - __delay((long long) usecs >> 32); + __delay(xloops * (HZ * cpu_data[raw_smp_processor_id()].loops_per_jiffy)); } -void __ndelay(unsigned long long nsecs, unsigned long lpj) +void __udelay(unsigned long usecs) { - nsecs *= (((unsigned long long) HZ << 32) / 1000000000) * lpj; - __delay((long long) nsecs >> 32); + __const_udelay(usecs * 0x000010c6); /* 2**32 / 1000000 */ } -void udelay(unsigned long usecs) +void __ndelay(unsigned long nsecs) { - __udelay(usecs, cpu_data[raw_smp_processor_id()].loops_per_jiffy); -} - -void ndelay(unsigned long nsecs) -{ - __ndelay(nsecs, cpu_data[raw_smp_processor_id()].loops_per_jiffy); + __const_udelay(nsecs * 0x00000005); } diff --git a/arch/sh/mm/Kconfig b/arch/sh/mm/Kconfig index f549b8cd25010c74fd3dbdfe054ec81e410ab1cc..5fd218430b19a9e1b91fc17c6f75d4650cf40142 100644 --- a/arch/sh/mm/Kconfig +++ b/arch/sh/mm/Kconfig @@ -59,7 +59,7 @@ config 32BIT config PMB bool "Support 32-bit physical addressing through PMB" - depends on MMU && (CPU_SUBTYPE_SH7780 || CPU_SUBTYPE_SH7785) + depends on MMU && EXPERIMENTAL && (CPU_SUBTYPE_SH7780 || CPU_SUBTYPE_SH7785) select 32BIT default y help diff --git a/arch/sh/mm/init.c b/arch/sh/mm/init.c index e2ed6dd252b9f1ca71c9c566ec2978897d3ba6d0..53dde06073627d693d431fd308e6c647d87da30e 100644 --- a/arch/sh/mm/init.c +++ b/arch/sh/mm/init.c @@ -328,7 +328,7 @@ int arch_add_memory(int nid, u64 start, u64 size) /* We only have ZONE_NORMAL, so this is easy.. */ ret = __add_pages(pgdat->node_zones + ZONE_NORMAL, start_pfn, nr_pages); if (unlikely(ret)) - printk("%s: Failed, __add_pages() == %d\n", __FUNCTION__, ret); + printk("%s: Failed, __add_pages() == %d\n", __func__, ret); return ret; } diff --git a/arch/sh/mm/ioremap_32.c b/arch/sh/mm/ioremap_32.c index 0c7b7e33abdcfd6e2ddf242623683d3ee89d7b6c..882a32ebc6b7c593c303a4d711cce5ae03001222 100644 --- a/arch/sh/mm/ioremap_32.c +++ b/arch/sh/mm/ioremap_32.c @@ -141,7 +141,7 @@ void __iounmap(void __iomem *addr) p = remove_vm_area((void *)(vaddr & PAGE_MASK)); if (!p) { - printk(KERN_ERR "%s: bad address %p\n", __FUNCTION__, addr); + printk(KERN_ERR "%s: bad address %p\n", __func__, addr); return; } diff --git a/arch/sh/mm/ioremap_64.c b/arch/sh/mm/ioremap_64.c index e27d165192354cda7d827b5a11ecac3207c9d802..cea224c3e49b6049b54edd6d5a6e782a02728dc2 100644 --- a/arch/sh/mm/ioremap_64.c +++ b/arch/sh/mm/ioremap_64.c @@ -178,7 +178,7 @@ static unsigned long shmedia_alloc_io(unsigned long phys, unsigned long size, } else { if (!printed_full) { printk("%s: done with statics, switching to kmalloc\n", - __FUNCTION__); + __func__); printed_full = 1; } tlen = strlen(name); @@ -352,7 +352,7 @@ void onchip_unmap(unsigned long vaddr) res = shmedia_find_resource(&shmedia_iomap, vaddr); if (!res) { printk(KERN_ERR "%s: Failed to free 0x%08lx\n", - __FUNCTION__, vaddr); + __func__, vaddr); return; } diff --git a/arch/sh/mm/pg-sh7705.c b/arch/sh/mm/pg-sh7705.c index a4b015f95a3ad379b69e9f2bffe13bcce3aa1450..7f885b7f8afffa36a4bac0d73e4180aeecf04ded 100644 --- a/arch/sh/mm/pg-sh7705.c +++ b/arch/sh/mm/pg-sh7705.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include diff --git a/arch/sh/mm/tlbflush_64.c b/arch/sh/mm/tlbflush_64.c index 2a98c9ec88ff49c48d919aa696f8700b72901dcf..7876997ba19a829f50941757ba6807bd93d3b3d4 100644 --- a/arch/sh/mm/tlbflush_64.c +++ b/arch/sh/mm/tlbflush_64.c @@ -131,7 +131,7 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long writeaccess, #ifdef DEBUG_FAULT print_task(tsk); printk("%s:%d fault, address is 0x%08x PC %016Lx textaccess %d writeaccess %d\n", - __FUNCTION__,__LINE__, + __func__, __LINE__, address,regs->pc,textaccess,writeaccess); show_regs(regs); #endif @@ -145,7 +145,7 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long writeaccess, #ifdef DEBUG_FAULT print_task(tsk); printk("%s:%d fault, address is 0x%08x PC %016Lx textaccess %d writeaccess %d\n", - __FUNCTION__,__LINE__, + __func__, __LINE__, address,regs->pc,textaccess,writeaccess); show_regs(regs); @@ -157,7 +157,7 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long writeaccess, #ifdef DEBUG_FAULT print_task(tsk); printk("%s:%d fault, address is 0x%08x PC %016Lx textaccess %d writeaccess %d\n", - __FUNCTION__,__LINE__, + __func__, __LINE__, address,regs->pc,textaccess,writeaccess); show_regs(regs); #endif diff --git a/arch/sh/tools/mach-types b/arch/sh/tools/mach-types index 67997af25c0c3fa0b7a68d919aee59d956618dcf..d63b93da952d4e0eafa9e6df984bccdb6517881b 100644 --- a/arch/sh/tools/mach-types +++ b/arch/sh/tools/mach-types @@ -38,7 +38,6 @@ R7780MP SH_R7780MP R7785RP SH_R7785RP TITAN SH_TITAN SHMIN SH_SHMIN -7710VOIPGW SH_7710VOIPGW LBOXRE2 SH_LBOX_RE2 X3PROTO SH_X3PROTO MAGICPANELR2 SH_MAGIC_PANEL_R2 diff --git a/arch/sparc/kernel/Makefile b/arch/sparc/kernel/Makefile index e795f282dece9f29d6914bc639ffb0c73da5d9f9..bf1b15d3f6f58be2265f1d6e13a0bbf22c9c0862 100644 --- a/arch/sparc/kernel/Makefile +++ b/arch/sparc/kernel/Makefile @@ -1,4 +1,4 @@ -# $Id: Makefile,v 1.62 2000/12/15 00:41:17 davem Exp $ +# # Makefile for the linux kernel. # @@ -12,7 +12,8 @@ obj-y := entry.o wof.o wuf.o etrap.o rtrap.o traps.o $(IRQ_OBJS) \ sys_sparc.o sunos_asm.o systbls.o \ time.o windows.o cpu.o devices.o sclow.o \ tadpole.o tick14.o ptrace.o sys_solaris.o \ - unaligned.o muldiv.o semaphore.o prom.o of_device.o devres.o + unaligned.o una_asm.o muldiv.o semaphore.o \ + prom.o of_device.o devres.o devres-y = ../../../kernel/irq/devres.o diff --git a/arch/sparc/kernel/cpu.c b/arch/sparc/kernel/cpu.c index 259a559d4cea120fb2beb13ad808ef1f152056f8..e7a0edfc1a32532823d315a78deb6f1585a35502 100644 --- a/arch/sparc/kernel/cpu.c +++ b/arch/sparc/kernel/cpu.c @@ -32,7 +32,7 @@ struct cpu_fp_info { /* In order to get the fpu type correct, you need to take the IDPROM's * machine type value into consideration too. I will fix this. */ -struct cpu_fp_info linux_sparc_fpu[] = { +static struct cpu_fp_info linux_sparc_fpu[] = { { 0, 0, "Fujitsu MB86910 or Weitek WTL1164/5"}, { 0, 1, "Fujitsu MB86911 or Weitek WTL1164/5 or LSI L64831"}, { 0, 2, "LSI Logic L64802 or Texas Instruments ACT8847"}, @@ -76,7 +76,7 @@ struct cpu_fp_info linux_sparc_fpu[] = { #define NSPARCFPU ARRAY_SIZE(linux_sparc_fpu) -struct cpu_iu_info linux_sparc_chips[] = { +static struct cpu_iu_info linux_sparc_chips[] = { /* Sun4/100, 4/200, SLC */ { 0, 0, "Fujitsu MB86900/1A or LSI L64831 SparcKIT-40"}, /* borned STP1012PGA */ diff --git a/arch/sparc/kernel/ebus.c b/arch/sparc/kernel/ebus.c index d850785b20808716b5d843af7877712db1b9dc7d..96344ff2bbe165aff131a8d9f982286f8804e136 100644 --- a/arch/sparc/kernel/ebus.c +++ b/arch/sparc/kernel/ebus.c @@ -101,7 +101,7 @@ void __init fill_ebus_child(struct device_node *dp, prom_printf("UGH: property for %s was %d, need < %d\n", dev->prom_node->name, len, dev->parent->num_addrs); - panic(__FUNCTION__); + panic(__func__); } /* XXX resource */ @@ -162,7 +162,7 @@ void __init fill_ebus_device(struct device_node *dp, struct linux_ebus_device *d prom_printf("UGH: proplen for %s was %d, need multiple of %d\n", dev->prom_node->name, len, (int)sizeof(struct linux_prom_registers)); - panic(__FUNCTION__); + panic(__func__); } dev->num_addrs = len / sizeof(struct linux_prom_registers); @@ -324,7 +324,7 @@ void __init ebus_init(void) regs = of_get_property(dp, "reg", &len); if (!regs) { prom_printf("%s: can't find reg property\n", - __FUNCTION__); + __func__); prom_halt(); } nreg = len / sizeof(struct linux_prom_pci_registers); diff --git a/arch/sparc/kernel/led.c b/arch/sparc/kernel/led.c index 313d1620ae8ec65b3ce43c1ee8b180ec7abdeb68..59e9344e7a0da2f5f0ccc8f4586e3ef89a85debe 100644 --- a/arch/sparc/kernel/led.c +++ b/arch/sparc/kernel/led.c @@ -3,6 +3,9 @@ #include #include #include +#include +#include +#include #include diff --git a/arch/sparc/kernel/process.c b/arch/sparc/kernel/process.c index 0bd69d0b5cd7f75ee293d06ff4ab3c81a0ec48dd..70c0dd22491d2a5e4d3e4aaf1ebdc72ec7ca855f 100644 --- a/arch/sparc/kernel/process.c +++ b/arch/sparc/kernel/process.c @@ -139,8 +139,6 @@ void cpu_idle(void) #endif -extern char reboot_command []; - /* XXX cli/sti -> local_irq_xxx here, check this works once SMP is fixed. */ void machine_halt(void) { diff --git a/arch/sparc/kernel/sys_sunos.c b/arch/sparc/kernel/sys_sunos.c index 28c187c5d9fd68dc4eea2008fa253d63d8e0b9d8..f5b608bbe8aff79bacd298b07e0b6831d3dd969d 100644 --- a/arch/sparc/kernel/sys_sunos.c +++ b/arch/sparc/kernel/sys_sunos.c @@ -659,7 +659,7 @@ sunos_nfs_get_server_fd (int fd, struct sockaddr_in *addr) socket = SOCKET_I(inode); local.sin_family = AF_INET; - local.sin_addr.s_addr = INADDR_ANY; + local.sin_addr.s_addr = htonl(INADDR_ANY); /* IPPORT_RESERVED = 1024, can't find the definition in the kernel */ try_port = 1024; diff --git a/arch/sparc/kernel/una_asm.S b/arch/sparc/kernel/una_asm.S new file mode 100644 index 0000000000000000000000000000000000000000..8cc03458eb7ee6cbf8314ff36bea92d80aafa6b0 --- /dev/null +++ b/arch/sparc/kernel/una_asm.S @@ -0,0 +1,153 @@ +/* una_asm.S: Kernel unaligned trap assembler helpers. + * + * Copyright (C) 1996,2005,2008 David S. Miller (davem@davemloft.net) + * Copyright (C) 1996,1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz) + */ + +#include + + .text + +retl_efault: + retl + mov -EFAULT, %o0 + + /* int __do_int_store(unsigned long *dst_addr, int size, + * unsigned long *src_val) + * + * %o0 = dest_addr + * %o1 = size + * %o2 = src_val + * + * Return '0' on success, -EFAULT on failure. + */ + .globl __do_int_store +__do_int_store: + ld [%o2], %g1 + cmp %1, 2 + be 2f + cmp %1, 4 + be 1f + srl %g1, 24, %g2 + srl %g1, 16, %g7 +4: stb %g2, [%o0] + srl %g1, 8, %g2 +5: stb %g7, [%o0 + 1] + ld [%o2 + 4], %g7 +6: stb %g2, [%o0 + 2] + srl %g7, 24, %g2 +7: stb %g1, [%o0 + 3] + srl %g7, 16, %g1 +8: stb %g2, [%o0 + 4] + srl %g7, 8, %g2 +9: stb %g1, [%o0 + 5] +10: stb %g2, [%o0 + 6] + b 0f +11: stb %g7, [%o0 + 7] +1: srl %g1, 16, %g7 +12: stb %g2, [%o0] + srl %g1, 8, %g2 +13: stb %g7, [%o0 + 1] +14: stb %g2, [%o0 + 2] + b 0f +15: stb %g1, [%o0 + 3] +2: srl %g1, 8, %g2 +16: stb %g2, [%o0] +17: stb %g1, [%o0 + 1] +0: retl + mov 0, %o0 + + .section __ex_table,#alloc + .word 4b, retl_efault + .word 5b, retl_efault + .word 6b, retl_efault + .word 7b, retl_efault + .word 8b, retl_efault + .word 9b, retl_efault + .word 10b, retl_efault + .word 11b, retl_efault + .word 12b, retl_efault + .word 13b, retl_efault + .word 14b, retl_efault + .word 15b, retl_efault + .word 16b, retl_efault + .word 17b, retl_efault + .previous + + /* int do_int_load(unsigned long *dest_reg, int size, + * unsigned long *saddr, int is_signed) + * + * %o0 = dest_reg + * %o1 = size + * %o2 = saddr + * %o3 = is_signed + * + * Return '0' on success, -EFAULT on failure. + */ + .globl do_int_load +do_int_load: + cmp %o1, 8 + be 9f + cmp %o1, 4 + be 6f +4: ldub [%o2], %g1 +5: ldub [%o2 + 1], %g2 + sll %g1, 8, %g1 + tst %o3 + be 3f + or %g1, %g2, %g1 + sll %g1, 16, %g1 + sra %g1, 16, %g1 +3: b 0f + st %g1, [%o0] +6: ldub [%o2 + 1], %g2 + sll %g1, 24, %g1 +7: ldub [%o2 + 2], %g7 + sll %g2, 16, %g2 +8: ldub [%o2 + 3], %g3 + sll %g7, 8, %g7 + or %g3, %g2, %g3 + or %g7, %g3, %g7 + or %g1, %g7, %g1 + b 0f + st %g1, [%o0] +9: ldub [%o2], %g1 +10: ldub [%o2 + 1], %g2 + sll %g1, 24, %g1 +11: ldub [%o2 + 2], %g7 + sll %g2, 16, %g2 +12: ldub [%o2 + 3], %g3 + sll %g7, 8, %g7 + or %g1, %g2, %g1 + or %g7, %g3, %g7 + or %g1, %g7, %g7 +13: ldub [%o2 + 4], %g1 + st %g7, [%o0] +14: ldub [%o2 + 5], %g2 + sll %g1, 24, %g1 +15: ldub [%o2 + 6], %g7 + sll %g2, 16, %g2 +16: ldub [%o2 + 7], %g3 + sll %g7, 8, %g7 + or %g1, %g2, %g1 + or %g7, %g3, %g7 + or %g1, %g7, %g7 + st %g7, [%o0 + 4] +0: retl + mov 0, %o0 + + .section __ex_table,#alloc + .word 4b, retl_efault + .word 5b, retl_efault + .word 6b, retl_efault + .word 7b, retl_efault + .word 8b, retl_efault + .word 9b, retl_efault + .word 10b, retl_efault + .word 11b, retl_efault + .word 12b, retl_efault + .word 13b, retl_efault + .word 14b, retl_efault + .word 15b, retl_efault + .word 16b, retl_efault + .previous diff --git a/arch/sparc/kernel/unaligned.c b/arch/sparc/kernel/unaligned.c index a6330fbc9dd935a805aa7b9f05f12dbfe605579a..33857be16661a53e7b2c1741eb51ab02a5fee020 100644 --- a/arch/sparc/kernel/unaligned.c +++ b/arch/sparc/kernel/unaligned.c @@ -175,157 +175,31 @@ static void unaligned_panic(char *str) panic(str); } -#define do_integer_load(dest_reg, size, saddr, is_signed, errh) ({ \ -__asm__ __volatile__ ( \ - "cmp %1, 8\n\t" \ - "be 9f\n\t" \ - " cmp %1, 4\n\t" \ - "be 6f\n" \ -"4:\t" " ldub [%2], %%l1\n" \ -"5:\t" "ldub [%2 + 1], %%l2\n\t" \ - "sll %%l1, 8, %%l1\n\t" \ - "tst %3\n\t" \ - "be 3f\n\t" \ - " add %%l1, %%l2, %%l1\n\t" \ - "sll %%l1, 16, %%l1\n\t" \ - "sra %%l1, 16, %%l1\n" \ -"3:\t" "b 0f\n\t" \ - " st %%l1, [%0]\n" \ -"6:\t" "ldub [%2 + 1], %%l2\n\t" \ - "sll %%l1, 24, %%l1\n" \ -"7:\t" "ldub [%2 + 2], %%g7\n\t" \ - "sll %%l2, 16, %%l2\n" \ -"8:\t" "ldub [%2 + 3], %%g1\n\t" \ - "sll %%g7, 8, %%g7\n\t" \ - "or %%l1, %%l2, %%l1\n\t" \ - "or %%g7, %%g1, %%g7\n\t" \ - "or %%l1, %%g7, %%l1\n\t" \ - "b 0f\n\t" \ - " st %%l1, [%0]\n" \ -"9:\t" "ldub [%2], %%l1\n" \ -"10:\t" "ldub [%2 + 1], %%l2\n\t" \ - "sll %%l1, 24, %%l1\n" \ -"11:\t" "ldub [%2 + 2], %%g7\n\t" \ - "sll %%l2, 16, %%l2\n" \ -"12:\t" "ldub [%2 + 3], %%g1\n\t" \ - "sll %%g7, 8, %%g7\n\t" \ - "or %%l1, %%l2, %%l1\n\t" \ - "or %%g7, %%g1, %%g7\n\t" \ - "or %%l1, %%g7, %%g7\n" \ -"13:\t" "ldub [%2 + 4], %%l1\n\t" \ - "st %%g7, [%0]\n" \ -"14:\t" "ldub [%2 + 5], %%l2\n\t" \ - "sll %%l1, 24, %%l1\n" \ -"15:\t" "ldub [%2 + 6], %%g7\n\t" \ - "sll %%l2, 16, %%l2\n" \ -"16:\t" "ldub [%2 + 7], %%g1\n\t" \ - "sll %%g7, 8, %%g7\n\t" \ - "or %%l1, %%l2, %%l1\n\t" \ - "or %%g7, %%g1, %%g7\n\t" \ - "or %%l1, %%g7, %%g7\n\t" \ - "st %%g7, [%0 + 4]\n" \ -"0:\n\n\t" \ - ".section __ex_table,#alloc\n\t" \ - ".word 4b, " #errh "\n\t" \ - ".word 5b, " #errh "\n\t" \ - ".word 6b, " #errh "\n\t" \ - ".word 7b, " #errh "\n\t" \ - ".word 8b, " #errh "\n\t" \ - ".word 9b, " #errh "\n\t" \ - ".word 10b, " #errh "\n\t" \ - ".word 11b, " #errh "\n\t" \ - ".word 12b, " #errh "\n\t" \ - ".word 13b, " #errh "\n\t" \ - ".word 14b, " #errh "\n\t" \ - ".word 15b, " #errh "\n\t" \ - ".word 16b, " #errh "\n\n\t" \ - ".previous\n\t" \ - : : "r" (dest_reg), "r" (size), "r" (saddr), "r" (is_signed) \ - : "l1", "l2", "g7", "g1", "cc"); \ -}) - -#define store_common(dst_addr, size, src_val, errh) ({ \ -__asm__ __volatile__ ( \ - "ld [%2], %%l1\n" \ - "cmp %1, 2\n\t" \ - "be 2f\n\t" \ - " cmp %1, 4\n\t" \ - "be 1f\n\t" \ - " srl %%l1, 24, %%l2\n\t" \ - "srl %%l1, 16, %%g7\n" \ -"4:\t" "stb %%l2, [%0]\n\t" \ - "srl %%l1, 8, %%l2\n" \ -"5:\t" "stb %%g7, [%0 + 1]\n\t" \ - "ld [%2 + 4], %%g7\n" \ -"6:\t" "stb %%l2, [%0 + 2]\n\t" \ - "srl %%g7, 24, %%l2\n" \ -"7:\t" "stb %%l1, [%0 + 3]\n\t" \ - "srl %%g7, 16, %%l1\n" \ -"8:\t" "stb %%l2, [%0 + 4]\n\t" \ - "srl %%g7, 8, %%l2\n" \ -"9:\t" "stb %%l1, [%0 + 5]\n" \ -"10:\t" "stb %%l2, [%0 + 6]\n\t" \ - "b 0f\n" \ -"11:\t" " stb %%g7, [%0 + 7]\n" \ -"1:\t" "srl %%l1, 16, %%g7\n" \ -"12:\t" "stb %%l2, [%0]\n\t" \ - "srl %%l1, 8, %%l2\n" \ -"13:\t" "stb %%g7, [%0 + 1]\n" \ -"14:\t" "stb %%l2, [%0 + 2]\n\t" \ - "b 0f\n" \ -"15:\t" " stb %%l1, [%0 + 3]\n" \ -"2:\t" "srl %%l1, 8, %%l2\n" \ -"16:\t" "stb %%l2, [%0]\n" \ -"17:\t" "stb %%l1, [%0 + 1]\n" \ -"0:\n\n\t" \ - ".section __ex_table,#alloc\n\t" \ - ".word 4b, " #errh "\n\t" \ - ".word 5b, " #errh "\n\t" \ - ".word 6b, " #errh "\n\t" \ - ".word 7b, " #errh "\n\t" \ - ".word 8b, " #errh "\n\t" \ - ".word 9b, " #errh "\n\t" \ - ".word 10b, " #errh "\n\t" \ - ".word 11b, " #errh "\n\t" \ - ".word 12b, " #errh "\n\t" \ - ".word 13b, " #errh "\n\t" \ - ".word 14b, " #errh "\n\t" \ - ".word 15b, " #errh "\n\t" \ - ".word 16b, " #errh "\n\t" \ - ".word 17b, " #errh "\n\n\t" \ - ".previous\n\t" \ - : : "r" (dst_addr), "r" (size), "r" (src_val) \ - : "l1", "l2", "g7", "g1", "cc"); \ -}) - -#define do_integer_store(reg_num, size, dst_addr, regs, errh) ({ \ - unsigned long *src_val; \ - static unsigned long zero[2] = { 0, }; \ - \ - if (reg_num) src_val = fetch_reg_addr(reg_num, regs); \ - else { \ - src_val = &zero[0]; \ - if (size == 8) \ - zero[1] = fetch_reg(1, regs); \ - } \ - store_common(dst_addr, size, src_val, errh); \ -}) +/* una_asm.S */ +extern int do_int_load(unsigned long *dest_reg, int size, + unsigned long *saddr, int is_signed); +extern int __do_int_store(unsigned long *dst_addr, int size, + unsigned long *src_val); + +static int do_int_store(int reg_num, int size, unsigned long *dst_addr, + struct pt_regs *regs) +{ + unsigned long zero[2] = { 0, 0 }; + unsigned long *src_val; + + if (reg_num) + src_val = fetch_reg_addr(reg_num, regs); + else { + src_val = &zero[0]; + if (size == 8) + zero[1] = fetch_reg(1, regs); + } + return __do_int_store(dst_addr, size, src_val); +} extern void smp_capture(void); extern void smp_release(void); -#define do_atomic(srcdest_reg, mem, errh) ({ \ - unsigned long flags, tmp; \ - \ - smp_capture(); \ - local_irq_save(flags); \ - tmp = *srcdest_reg; \ - do_integer_load(srcdest_reg, 4, mem, 0, errh); \ - store_common(mem, 4, &tmp, errh); \ - local_irq_restore(flags); \ - smp_release(); \ -}) - static inline void advance(struct pt_regs *regs) { regs->pc = regs->npc; @@ -342,9 +216,7 @@ static inline int ok_for_kernel(unsigned int insn) return !floating_point_load_or_store_p(insn); } -void kernel_mna_trap_fault(struct pt_regs *regs, unsigned int insn) __asm__ ("kernel_mna_trap_fault"); - -void kernel_mna_trap_fault(struct pt_regs *regs, unsigned int insn) +static void kernel_mna_trap_fault(struct pt_regs *regs, unsigned int insn) { unsigned long g2 = regs->u_regs [UREG_G2]; unsigned long fixup = search_extables_range(regs->pc, &g2); @@ -379,48 +251,34 @@ asmlinkage void kernel_unaligned_trap(struct pt_regs *regs, unsigned int insn) printk("Unsupported unaligned load/store trap for kernel at <%08lx>.\n", regs->pc); unaligned_panic("Wheee. Kernel does fpu/atomic unaligned load/store."); - - __asm__ __volatile__ ("\n" -"kernel_unaligned_trap_fault:\n\t" - "mov %0, %%o0\n\t" - "call kernel_mna_trap_fault\n\t" - " mov %1, %%o1\n\t" - : - : "r" (regs), "r" (insn) - : "o0", "o1", "o2", "o3", "o4", "o5", "o7", - "g1", "g2", "g3", "g4", "g5", "g7", "cc"); } else { unsigned long addr = compute_effective_address(regs, insn); + int err; #ifdef DEBUG_MNA printk("KMNA: pc=%08lx [dir=%s addr=%08lx size=%d] retpc[%08lx]\n", regs->pc, dirstrings[dir], addr, size, regs->u_regs[UREG_RETPC]); #endif - switch(dir) { + switch (dir) { case load: - do_integer_load(fetch_reg_addr(((insn>>25)&0x1f), regs), - size, (unsigned long *) addr, - decode_signedness(insn), - kernel_unaligned_trap_fault); + err = do_int_load(fetch_reg_addr(((insn>>25)&0x1f), + regs), + size, (unsigned long *) addr, + decode_signedness(insn)); break; case store: - do_integer_store(((insn>>25)&0x1f), size, - (unsigned long *) addr, regs, - kernel_unaligned_trap_fault); + err = do_int_store(((insn>>25)&0x1f), size, + (unsigned long *) addr, regs); break; -#if 0 /* unsupported */ - case both: - do_atomic(fetch_reg_addr(((insn>>25)&0x1f), regs), - (unsigned long *) addr, - kernel_unaligned_trap_fault); - break; -#endif default: panic("Impossible kernel unaligned trap."); /* Not reached... */ } - advance(regs); + if (err) + kernel_mna_trap_fault(regs, insn); + else + advance(regs); } } @@ -459,9 +317,7 @@ static inline int ok_for_user(struct pt_regs *regs, unsigned int insn, return 0; } -void user_mna_trap_fault(struct pt_regs *regs, unsigned int insn) __asm__ ("user_mna_trap_fault"); - -void user_mna_trap_fault(struct pt_regs *regs, unsigned int insn) +static void user_mna_trap_fault(struct pt_regs *regs, unsigned int insn) { siginfo_t info; @@ -485,7 +341,7 @@ asmlinkage void user_unaligned_trap(struct pt_regs *regs, unsigned int insn) if(!ok_for_user(regs, insn, dir)) { goto kill_user; } else { - int size = decode_access_size(insn); + int err, size = decode_access_size(insn); unsigned long addr; if(floating_point_load_or_store_p(insn)) { @@ -496,48 +352,34 @@ asmlinkage void user_unaligned_trap(struct pt_regs *regs, unsigned int insn) addr = compute_effective_address(regs, insn); switch(dir) { case load: - do_integer_load(fetch_reg_addr(((insn>>25)&0x1f), regs), - size, (unsigned long *) addr, - decode_signedness(insn), - user_unaligned_trap_fault); + err = do_int_load(fetch_reg_addr(((insn>>25)&0x1f), + regs), + size, (unsigned long *) addr, + decode_signedness(insn)); break; case store: - do_integer_store(((insn>>25)&0x1f), size, - (unsigned long *) addr, regs, - user_unaligned_trap_fault); + err = do_int_store(((insn>>25)&0x1f), size, + (unsigned long *) addr, regs); break; case both: -#if 0 /* unsupported */ - do_atomic(fetch_reg_addr(((insn>>25)&0x1f), regs), - (unsigned long *) addr, - user_unaligned_trap_fault); -#else /* * This was supported in 2.4. However, we question * the value of SWAP instruction across word boundaries. */ printk("Unaligned SWAP unsupported.\n"); - goto kill_user; -#endif + err = -EFAULT; break; default: unaligned_panic("Impossible user unaligned trap."); - - __asm__ __volatile__ ("\n" -"user_unaligned_trap_fault:\n\t" - "mov %0, %%o0\n\t" - "call user_mna_trap_fault\n\t" - " mov %1, %%o1\n\t" - : - : "r" (regs), "r" (insn) - : "o0", "o1", "o2", "o3", "o4", "o5", "o7", - "g1", "g2", "g3", "g4", "g5", "g7", "cc"); goto out; } - advance(regs); + if (err) + goto kill_user; + else + advance(regs); goto out; } diff --git a/arch/sparc64/Kconfig b/arch/sparc64/Kconfig index 3af378ddb6ae8008db5619074414b489165370a6..463d1be32c98614cea3fc98cb31154895a5858eb 100644 --- a/arch/sparc64/Kconfig +++ b/arch/sparc64/Kconfig @@ -10,6 +10,7 @@ config SPARC default y select HAVE_OPROFILE select HAVE_KPROBES + select HAVE_KRETPROBES config SPARC64 bool diff --git a/arch/sparc64/kernel/cpu.c b/arch/sparc64/kernel/cpu.c index e43db73f2b911151b1e0194b5a7595c8945474b9..dd5d28e3d79899df97342266e79c1372a9c79707 100644 --- a/arch/sparc64/kernel/cpu.c +++ b/arch/sparc64/kernel/cpu.c @@ -30,7 +30,7 @@ struct cpu_fp_info { char* fp_name; }; -struct cpu_fp_info linux_sparc_fpu[] = { +static struct cpu_fp_info linux_sparc_fpu[] = { { 0x17, 0x10, 0, "UltraSparc I integrated FPU"}, { 0x22, 0x10, 0, "UltraSparc I integrated FPU"}, { 0x17, 0x11, 0, "UltraSparc II integrated FPU"}, @@ -46,7 +46,7 @@ struct cpu_fp_info linux_sparc_fpu[] = { #define NSPARCFPU ARRAY_SIZE(linux_sparc_fpu) -struct cpu_iu_info linux_sparc_chips[] = { +static struct cpu_iu_info linux_sparc_chips[] = { { 0x17, 0x10, "TI UltraSparc I (SpitFire)"}, { 0x22, 0x10, "TI UltraSparc I (SpitFire)"}, { 0x17, 0x11, "TI UltraSparc II (BlackBird)"}, diff --git a/arch/sparc64/kernel/ds.c b/arch/sparc64/kernel/ds.c index eeb5a2fc788d2615e47660ae7c6962ca1777126a..bd76482077be66aa3e9e1d6e22d3523a34e4597a 100644 --- a/arch/sparc64/kernel/ds.c +++ b/arch/sparc64/kernel/ds.c @@ -525,10 +525,10 @@ static void dr_cpu_mark(struct ds_data *resp, int cpu, int ncpus, } } -static int dr_cpu_configure(struct ds_info *dp, - struct ds_cap_state *cp, - u64 req_num, - cpumask_t *mask) +static int __cpuinit dr_cpu_configure(struct ds_info *dp, + struct ds_cap_state *cp, + u64 req_num, + cpumask_t *mask) { struct ds_data *resp; int resp_len, ncpus, cpu; @@ -623,9 +623,9 @@ static int dr_cpu_unconfigure(struct ds_info *dp, return 0; } -static void dr_cpu_data(struct ds_info *dp, - struct ds_cap_state *cp, - void *buf, int len) +static void __cpuinit dr_cpu_data(struct ds_info *dp, + struct ds_cap_state *cp, + void *buf, int len) { struct ds_data *data = buf; struct dr_cpu_tag *tag = (struct dr_cpu_tag *) (data + 1); diff --git a/arch/sparc64/kernel/mdesc.c b/arch/sparc64/kernel/mdesc.c index 856659bb13116ed7444c263ec1a9f8087c660ec7..9100835895691e1c8f93f6ac38b8bfcf42db7132 100644 --- a/arch/sparc64/kernel/mdesc.c +++ b/arch/sparc64/kernel/mdesc.c @@ -758,7 +758,7 @@ static void __devinit get_mondo_data(struct mdesc_handle *hp, u64 mp, get_one_mondo_bits(val, &tb->nonresum_qmask, 2); } -void __devinit mdesc_fill_in_cpu_data(cpumask_t mask) +void __cpuinit mdesc_fill_in_cpu_data(cpumask_t mask) { struct mdesc_handle *hp = mdesc_grab(); u64 mp; diff --git a/arch/sparc64/kernel/process.c b/arch/sparc64/kernel/process.c index 2aafce7dfc0ecf31b42ba94f422032208553220e..e116e38b160ec3cd9a9b8a5aaecfef2ff2d659db 100644 --- a/arch/sparc64/kernel/process.c +++ b/arch/sparc64/kernel/process.c @@ -114,8 +114,6 @@ void cpu_idle(void) } } -extern char reboot_command []; - void machine_halt(void) { sstate_halt(); diff --git a/arch/sparc64/kernel/sys_sunos32.c b/arch/sparc64/kernel/sys_sunos32.c index cfc22d3fe54c1cdd631ff3ffe1160d73e78aec18..e91194fe39d7fb3c9a2eea05cba13f21b8dae684 100644 --- a/arch/sparc64/kernel/sys_sunos32.c +++ b/arch/sparc64/kernel/sys_sunos32.c @@ -618,7 +618,7 @@ sunos_nfs_get_server_fd (int fd, struct sockaddr_in *addr) socket = SOCKET_I(inode); local.sin_family = AF_INET; - local.sin_addr.s_addr = INADDR_ANY; + local.sin_addr.s_addr = htonl(INADDR_ANY); /* IPPORT_RESERVED = 1024, can't find the definition in the kernel */ try_port = 1024; diff --git a/arch/sparc64/mm/fault.c b/arch/sparc64/mm/fault.c index e2027f27c0fe73f2f43546aa838577e86fc6e3ba..2650d0d33ac25cbc656baa97adec4c29e1a65a93 100644 --- a/arch/sparc64/mm/fault.c +++ b/arch/sparc64/mm/fault.c @@ -244,16 +244,8 @@ static void do_kernel_fault(struct pt_regs *regs, int si_code, int fault_code, if (regs->tstate & TSTATE_PRIV) { const struct exception_table_entry *entry; - if (asi == ASI_P && (insn & 0xc0800000) == 0xc0800000) { - if (insn & 0x2000) - asi = (regs->tstate >> 24); - else - asi = (insn >> 5); - } - - /* Look in asi.h: All _S asis have LS bit set */ - if ((asi & 0x1) && - (entry = search_exception_tables(regs->tpc))) { + entry = search_exception_tables(regs->tpc); + if (entry) { regs->tpc = entry->fixup; regs->tnpc = regs->tpc + 4; return; @@ -294,7 +286,7 @@ asmlinkage void __kprobes do_sparc64_fault(struct pt_regs *regs) unsigned long tpc = regs->tpc; /* Sanity check the PC. */ - if ((tpc >= KERNBASE && tpc < (unsigned long) _etext) || + if ((tpc >= KERNBASE && tpc < (unsigned long) __init_end) || (tpc >= MODULES_VADDR && tpc < MODULES_END)) { /* Valid, no problems... */ } else { diff --git a/arch/sparc64/mm/init.c b/arch/sparc64/mm/init.c index 9e6bca266d88338df73baf4dd1079a5c17672b69..b5c30416fdac221e9bc31c4d720865769c988e85 100644 --- a/arch/sparc64/mm/init.c +++ b/arch/sparc64/mm/init.c @@ -1010,7 +1010,8 @@ static struct linux_prom64_registers pall[MAX_BANKS] __initdata; static int pall_ents __initdata; #ifdef CONFIG_DEBUG_PAGEALLOC -static unsigned long kernel_map_range(unsigned long pstart, unsigned long pend, pgprot_t prot) +static unsigned long __ref kernel_map_range(unsigned long pstart, + unsigned long pend, pgprot_t prot) { unsigned long vstart = PAGE_OFFSET + pstart; unsigned long vend = PAGE_OFFSET + pend; diff --git a/arch/sparc64/solaris/conv.h b/arch/sparc64/solaris/conv.h index 5faf59a9de399e33eb6a07592b768b5904658bca..50e58232cf2b014c128ee9148761c121f947e11b 100644 --- a/arch/sparc64/solaris/conv.h +++ b/arch/sparc64/solaris/conv.h @@ -28,7 +28,7 @@ extern unsigned sunos_sys_table[]; #define SUNOS(x) ((long)sunos_sys_table[x]) #ifdef DEBUG_SOLARIS -#define SOLD(s) printk("%s,%d,%s(): %s\n",__FILE__,__LINE__,__FUNCTION__,(s)) +#define SOLD(s) printk("%s,%d,%s(): %s\n",__FILE__,__LINE__,__func__,(s)) #define SOLDD(s) printk("solaris: "); printk s #else #define SOLD(s) diff --git a/arch/sparc64/solaris/timod.c b/arch/sparc64/solaris/timod.c index f53123c02c2b6b76f9b687bd1f675753d1342633..15234fcd191a209041a6dd6712cdfae9c7fd3000 100644 --- a/arch/sparc64/solaris/timod.c +++ b/arch/sparc64/solaris/timod.c @@ -81,7 +81,7 @@ void mykfree(void *p) #define MKCTL_MAGIC 0xDEADBABEBADC0DEDL #define PUT_MAGIC(a,m) do{(*(u64*)(a))=(m);}while(0) #define SCHECK_MAGIC(a,m) do{if((*(u64*)(a))!=(m))printk("%s,%u,%s(): magic %08x at %p corrupted!\n",\ - __FILE__,__LINE__,__FUNCTION__,(m),(a));}while(0) + __FILE__,__LINE__,__func__,(m),(a));}while(0) #define BUF_OFFSET sizeof(u64) #define MKCTL_TRAILER sizeof(u64) diff --git a/arch/um/kernel/process.c b/arch/um/kernel/process.c index fc50d2f959d12f44bc6c41171f3cc030d6ad38fa..e8cb9ff183e9fe1da41020bc39ffe22b43ef56c7 100644 --- a/arch/um/kernel/process.c +++ b/arch/um/kernel/process.c @@ -128,8 +128,6 @@ void *get_current(void) return current; } -extern void schedule_tail(struct task_struct *prev); - /* * This is called magically, by its address being stuffed in a jmp_buf * and being longjmp-d to. diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index 4a88cf7695b418927c61ce760259db85bbd68cfe..6c70fed0f9a0f9e35cd027072a464b8c42b85434 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -21,7 +21,8 @@ config X86 select HAVE_IDE select HAVE_OPROFILE select HAVE_KPROBES - select HAVE_KVM + select HAVE_KRETPROBES + select HAVE_KVM if ((X86_32 && !X86_VOYAGER && !X86_VISWS && !X86_NUMAQ) || X86_64) config GENERIC_LOCKBREAK @@ -65,9 +66,6 @@ config MMU config ZONE_DMA def_bool y -config QUICKLIST - def_bool X86_32 - config SBUS bool @@ -1261,7 +1259,7 @@ menuconfig APM machines with more than one CPU. In order to use APM, you will need supporting software. For location - and more information, read and the + and more information, read and the Battery Powered Linux mini-HOWTO, available from . diff --git a/arch/x86/Kconfig.cpu b/arch/x86/Kconfig.cpu index e09a6b73a1aab5c3fc6a353e22af4936b047416f..9304bfba7d450fae5dc61ffa627a49fe1fdfeae6 100644 --- a/arch/x86/Kconfig.cpu +++ b/arch/x86/Kconfig.cpu @@ -377,6 +377,19 @@ config X86_OOSTORE def_bool y depends on (MWINCHIP3D || MWINCHIP2 || MWINCHIPC6) && MTRR +# +# P6_NOPs are a relatively minor optimization that require a family >= +# 6 processor, except that it is broken on certain VIA chips. +# Furthermore, AMD chips prefer a totally different sequence of NOPs +# (which work on all CPUs). As a result, disallow these if we're +# compiling X86_GENERIC but not X86_64 (these NOPs do work on all +# x86-64 capable chips); the list of processors in the right-hand clause +# are the cores that benefit from this optimization. +# +config X86_P6_NOP + def_bool y + depends on (X86_64 || !X86_GENERIC) && (M686 || MPENTIUMII || MPENTIUMIII || MPENTIUMM || MCORE2 || MPENTIUM4) + config X86_TSC def_bool y depends on ((MWINCHIP3D || MWINCHIP2 || MCRUSOE || MEFFICEON || MCYRIXIII || MK7 || MK6 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || MK8 || MVIAC3_2 || MVIAC7 || MGEODEGX1 || MGEODE_LX || MCORE2) && !X86_NUMAQ) || X86_64 @@ -390,6 +403,7 @@ config X86_CMOV config X86_MINIMUM_CPU_FAMILY int default "64" if X86_64 + default "6" if X86_32 && X86_P6_NOP default "4" if X86_32 && (X86_XADD || X86_CMPXCHG || X86_BSWAP || X86_WP_WORKS_OK) default "3" diff --git a/arch/x86/boot/memory.c b/arch/x86/boot/memory.c index 378353956b5dfc86469b66419b9680e1770a7410..e77d89f9e8aa23c13751bee268718e8ed7ee54a7 100644 --- a/arch/x86/boot/memory.c +++ b/arch/x86/boot/memory.c @@ -37,6 +37,12 @@ static int detect_memory_e820(void) "=m" (*desc) : "D" (desc), "d" (SMAP), "a" (0xe820)); + /* BIOSes which terminate the chain with CF = 1 as opposed + to %ebx = 0 don't always report the SMAP signature on + the final, failing, probe. */ + if (err) + break; + /* Some BIOSes stop returning SMAP in the middle of the search loop. We don't know exactly how the BIOS screwed up the map at that point, we might have a @@ -47,9 +53,6 @@ static int detect_memory_e820(void) break; } - if (err) - break; - count++; desc++; } while (next && count < E820MAX); diff --git a/arch/x86/boot/vesa.h b/arch/x86/boot/vesa.h index ff5b73cd406f1b0e4130ae3ae8eb8e38e21a07cb..468e444622c507bd4d48c1e4d3277760e501789f 100644 --- a/arch/x86/boot/vesa.h +++ b/arch/x86/boot/vesa.h @@ -26,17 +26,10 @@ struct vesa_general_info { far_ptr video_mode_ptr; /* 14 */ u16 total_memory; /* 18 */ - u16 oem_software_rev; /* 20 */ - far_ptr oem_vendor_name_ptr; /* 22 */ - far_ptr oem_product_name_ptr; /* 26 */ - far_ptr oem_product_rev_ptr; /* 30 */ - - u8 reserved[222]; /* 34 */ - u8 oem_data[256]; /* 256 */ + u8 reserved[236]; /* 20 */ } __attribute__ ((packed)); #define VESA_MAGIC ('V' + ('E' << 8) + ('S' << 16) + ('A' << 24)) -#define VBE2_MAGIC ('V' + ('B' << 8) + ('E' << 16) + ('2' << 24)) struct vesa_mode_info { u16 mode_attr; /* 0 */ diff --git a/arch/x86/boot/video-vesa.c b/arch/x86/boot/video-vesa.c index 662dd2f130684c050d46f6950263ef9b4e7cfc08..419b5c27337463b59ffc6bf5ae545c25c8aaafbc 100644 --- a/arch/x86/boot/video-vesa.c +++ b/arch/x86/boot/video-vesa.c @@ -37,8 +37,6 @@ static int vesa_probe(void) video_vesa.modes = GET_HEAP(struct mode_info, 0); - vginfo.signature = VBE2_MAGIC; - ax = 0x4f00; di = (size_t)&vginfo; asm(INT10 diff --git a/arch/x86/ia32/ia32_signal.c b/arch/x86/ia32/ia32_signal.c index 1c0503bdfb1a1dbd33080620ec67715644fcf054..5e7771a3ba2f136451a64fc4caccf4ac76519428 100644 --- a/arch/x86/ia32/ia32_signal.c +++ b/arch/x86/ia32/ia32_signal.c @@ -500,7 +500,7 @@ int ia32_setup_frame(int sig, struct k_sigaction *ka, regs->ss = __USER32_DS; set_fs(USER_DS); - regs->flags &= ~X86_EFLAGS_TF; + regs->flags &= ~(X86_EFLAGS_TF | X86_EFLAGS_DF); if (test_thread_flag(TIF_SINGLESTEP)) ptrace_notify(SIGTRAP); @@ -600,7 +600,7 @@ int ia32_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, regs->ss = __USER32_DS; set_fs(USER_DS); - regs->flags &= ~X86_EFLAGS_TF; + regs->flags &= ~(X86_EFLAGS_TF | X86_EFLAGS_DF); if (test_thread_flag(TIF_SINGLESTEP)) ptrace_notify(SIGTRAP); diff --git a/arch/x86/kernel/asm-offsets_32.c b/arch/x86/kernel/asm-offsets_32.c index a33d53017997df4849660cccbab4f45a223a2bd3..8ea040124f7dc930de83225dbe45d9c642e7f196 100644 --- a/arch/x86/kernel/asm-offsets_32.c +++ b/arch/x86/kernel/asm-offsets_32.c @@ -128,13 +128,11 @@ void foo(void) OFFSET(XEN_vcpu_info_pending, vcpu_info, evtchn_upcall_pending); #endif -#ifdef CONFIG_LGUEST_GUEST +#if defined(CONFIG_LGUEST) || defined(CONFIG_LGUEST_GUEST) || defined(CONFIG_LGUEST_MODULE) BLANK(); OFFSET(LGUEST_DATA_irq_enabled, lguest_data, irq_enabled); OFFSET(LGUEST_DATA_pgdir, lguest_data, pgdir); -#endif -#ifdef CONFIG_LGUEST BLANK(); OFFSET(LGUEST_PAGES_host_gdt_desc, lguest_pages, state.host_gdt_desc); OFFSET(LGUEST_PAGES_host_idt_desc, lguest_pages, state.host_idt_desc); diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c index f86a3c4a2669909be340d195a6ee93201c53cdf9..a38aafaefc230b4bfc49c34c98fc2c443fff8318 100644 --- a/arch/x86/kernel/cpu/common.c +++ b/arch/x86/kernel/cpu/common.c @@ -504,7 +504,7 @@ void __cpuinit identify_cpu(struct cpuinfo_x86 *c) /* Clear all flags overriden by options */ for (i = 0; i < NCAPINTS; i++) - c->x86_capability[i] ^= cleared_cpu_caps[i]; + c->x86_capability[i] &= ~cleared_cpu_caps[i]; /* Init Machine Check Exception if available. */ mcheck_init(c); diff --git a/arch/x86/kernel/cpu/cpufreq/e_powersaver.c b/arch/x86/kernel/cpu/cpufreq/e_powersaver.c index 39f8cb18296c68fc74fa999a195f0d1fa20a9787..c2f930d8664091932c1a7b614d860f8f365b7f10 100644 --- a/arch/x86/kernel/cpu/cpufreq/e_powersaver.c +++ b/arch/x86/kernel/cpu/cpufreq/e_powersaver.c @@ -55,7 +55,6 @@ static int eps_set_state(struct eps_cpu_data *centaur, { struct cpufreq_freqs freqs; u32 lo, hi; - u8 current_multiplier, current_voltage; int err = 0; int i; @@ -95,6 +94,10 @@ postchange: rdmsr(MSR_IA32_PERF_STATUS, lo, hi); freqs.new = centaur->fsb * ((lo >> 8) & 0xff); +#ifdef DEBUG + { + u8 current_multiplier, current_voltage; + /* Print voltage and multiplier */ rdmsr(MSR_IA32_PERF_STATUS, lo, hi); current_voltage = lo & 0xff; @@ -103,7 +106,8 @@ postchange: current_multiplier = (lo >> 8) & 0xff; printk(KERN_INFO "eps: Current multiplier = %d\n", current_multiplier); - + } +#endif cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); return err; } diff --git a/arch/x86/kernel/cpu/mtrr/main.c b/arch/x86/kernel/cpu/mtrr/main.c index b6e136f23d3d3219094bc9fdadaeaba048f01b96..be83336fddba9c6c3629bbe1748aa42480a6e707 100644 --- a/arch/x86/kernel/cpu/mtrr/main.c +++ b/arch/x86/kernel/cpu/mtrr/main.c @@ -43,6 +43,7 @@ #include #include #include +#include #include "mtrr.h" u32 num_var_ranges = 0; @@ -649,6 +650,7 @@ static __init int amd_special_default_mtrr(void) /** * mtrr_trim_uncached_memory - trim RAM not covered by MTRRs + * @end_pfn: ending page frame number * * Some buggy BIOSes don't setup the MTRRs properly for systems with certain * memory configurations. This routine checks that the highest MTRR matches @@ -688,8 +690,11 @@ int __init mtrr_trim_uncached_memory(unsigned long end_pfn) /* kvm/qemu doesn't have mtrr set right, don't trim them all */ if (!highest_pfn) { - printk(KERN_WARNING "WARNING: strange, CPU MTRRs all blank?\n"); - WARN_ON(1); + if (!kvm_para_available()) { + printk(KERN_WARNING + "WARNING: strange, CPU MTRRs all blank?\n"); + WARN_ON(1); + } return 0; } diff --git a/arch/x86/kernel/cpu/transmeta.c b/arch/x86/kernel/cpu/transmeta.c index 200fb3f9ebfbda2ec232deec234ded94128f4cfb..e8b422c1c51267419275e5db474fbd2b5e237ea3 100644 --- a/arch/x86/kernel/cpu/transmeta.c +++ b/arch/x86/kernel/cpu/transmeta.c @@ -76,13 +76,6 @@ static void __cpuinit init_transmeta(struct cpuinfo_x86 *c) /* All Transmeta CPUs have a constant TSC */ set_bit(X86_FEATURE_CONSTANT_TSC, c->x86_capability); - /* If we can run i686 user-space code, call us an i686 */ -#define USER686 ((1 << X86_FEATURE_TSC)|\ - (1 << X86_FEATURE_CX8)|\ - (1 << X86_FEATURE_CMOV)) - if (c->x86 == 5 && (c->x86_capability[0] & USER686) == USER686) - c->x86 = 6; - #ifdef CONFIG_SYSCTL /* randomize_va_space slows us down enormously; it probably triggers retranslation of x86->native bytecode */ diff --git a/arch/x86/kernel/entry_64.S b/arch/x86/kernel/entry_64.S index 2ad9a1bc6a73fafd6ea8e34b9117877eb2e736dd..c20c9e7e08dd2a644860dabc206ae1fb843ea173 100644 --- a/arch/x86/kernel/entry_64.S +++ b/arch/x86/kernel/entry_64.S @@ -453,6 +453,7 @@ ENTRY(stub_execve) CFI_REGISTER rip, r11 SAVE_REST FIXUP_TOP_OF_STACK %r11 + movq %rsp, %rcx call sys_execve RESTORE_TOP_OF_STACK %r11 movq %rax,RAX(%rsp) @@ -1036,15 +1037,16 @@ ENDPROC(child_rip) * rdi: name, rsi: argv, rdx: envp * * We want to fallback into: - * extern long sys_execve(char *name, char **argv,char **envp, struct pt_regs regs) + * extern long sys_execve(char *name, char **argv,char **envp, struct pt_regs *regs) * * do_sys_execve asm fallback arguments: - * rdi: name, rsi: argv, rdx: envp, fake frame on the stack + * rdi: name, rsi: argv, rdx: envp, rcx: fake frame on the stack */ ENTRY(kernel_execve) CFI_STARTPROC FAKE_STACK_FRAME $0 SAVE_ALL + movq %rsp,%rcx call sys_execve movq %rax, RAX(%rsp) RESTORE_REST diff --git a/arch/x86/kernel/head_32.S b/arch/x86/kernel/head_32.S index 25eb98540a41e067f7593753a51b8430fd8930df..fd8ca53943a8e0f01b86bb0157d5027de0bcf5bd 100644 --- a/arch/x86/kernel/head_32.S +++ b/arch/x86/kernel/head_32.S @@ -606,7 +606,7 @@ ENTRY(_stext) .section ".bss.page_aligned","wa" .align PAGE_SIZE_asm #ifdef CONFIG_X86_PAE -ENTRY(swapper_pg_pmd) +swapper_pg_pmd: .fill 1024*KPMDS,4,0 #else ENTRY(swapper_pg_dir) diff --git a/arch/x86/kernel/head_64.S b/arch/x86/kernel/head_64.S index eb415043a9297d742f3df5d9a1de10fa35d0b69b..a007454133a33743b60fce4ebd3c90e8c32ee85e 100644 --- a/arch/x86/kernel/head_64.S +++ b/arch/x86/kernel/head_64.S @@ -379,18 +379,24 @@ NEXT_PAGE(level2_ident_pgt) /* Since I easily can, map the first 1G. * Don't set NX because code runs from these pages. */ - PMDS(0x0000000000000000, __PAGE_KERNEL_LARGE_EXEC, PTRS_PER_PMD) + PMDS(0, __PAGE_KERNEL_LARGE_EXEC, PTRS_PER_PMD) NEXT_PAGE(level2_kernel_pgt) - /* 40MB kernel mapping. The kernel code cannot be bigger than that. - When you change this change KERNEL_TEXT_SIZE in page.h too. */ - /* (2^48-(2*1024*1024*1024)-((2^39)*511)-((2^30)*510)) = 0 */ - PMDS(0x0000000000000000, __PAGE_KERNEL_LARGE_EXEC|_PAGE_GLOBAL, KERNEL_TEXT_SIZE/PMD_SIZE) - /* Module mapping starts here */ - .fill (PTRS_PER_PMD - (KERNEL_TEXT_SIZE/PMD_SIZE)),8,0 + /* + * 128 MB kernel mapping. We spend a full page on this pagetable + * anyway. + * + * The kernel code+data+bss must not be bigger than that. + * + * (NOTE: at +128MB starts the module area, see MODULES_VADDR. + * If you want to increase this then increase MODULES_VADDR + * too.) + */ + PMDS(0, __PAGE_KERNEL_LARGE_EXEC|_PAGE_GLOBAL, + KERNEL_IMAGE_SIZE/PMD_SIZE) NEXT_PAGE(level2_spare_pgt) - .fill 512,8,0 + .fill 512, 8, 0 #undef PMDS #undef NEXT_PAGE diff --git a/arch/x86/kernel/hpet.c b/arch/x86/kernel/hpet.c index 429d084e014d4b11a829bbf01f53fdc860e276e2..235fd6c77504c9baedcfddd1610b143910e97e21 100644 --- a/arch/x86/kernel/hpet.c +++ b/arch/x86/kernel/hpet.c @@ -368,8 +368,8 @@ static int hpet_clocksource_register(void) return 0; } -/* - * Try to setup the HPET timer +/** + * hpet_enable - Try to setup the HPET timer. Returns 1 on success. */ int __init hpet_enable(void) { diff --git a/arch/x86/kernel/i387.c b/arch/x86/kernel/i387.c index 763dfc407232b0133750f3f61898a120f0685ebc..d2e39e69aaf860e39e391e899ea349c5e8632ee2 100644 --- a/arch/x86/kernel/i387.c +++ b/arch/x86/kernel/i387.c @@ -132,7 +132,7 @@ int xfpregs_get(struct task_struct *target, const struct user_regset *regset, if (!cpu_has_fxsr) return -ENODEV; - unlazy_fpu(target); + init_fpu(target); return user_regset_copyout(&pos, &count, &kbuf, &ubuf, &target->thread.i387.fxsave, 0, -1); @@ -147,7 +147,7 @@ int xfpregs_set(struct task_struct *target, const struct user_regset *regset, if (!cpu_has_fxsr) return -ENODEV; - unlazy_fpu(target); + init_fpu(target); set_stopped_child_used_math(target); ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, @@ -261,7 +261,7 @@ static void convert_from_fxsr(struct user_i387_ia32_struct *env, } #else env->fip = fxsave->fip; - env->fcs = fxsave->fcs; + env->fcs = (u16) fxsave->fcs | ((u32) fxsave->fop << 16); env->foo = fxsave->foo; env->fos = fxsave->fos; #endif @@ -307,7 +307,7 @@ int fpregs_get(struct task_struct *target, const struct user_regset *regset, if (!HAVE_HWFP) return fpregs_soft_get(target, regset, pos, count, kbuf, ubuf); - unlazy_fpu(target); + init_fpu(target); if (!cpu_has_fxsr) return user_regset_copyout(&pos, &count, &kbuf, &ubuf, @@ -332,7 +332,7 @@ int fpregs_set(struct task_struct *target, const struct user_regset *regset, if (!HAVE_HWFP) return fpregs_soft_set(target, regset, pos, count, kbuf, ubuf); - unlazy_fpu(target); + init_fpu(target); set_stopped_child_used_math(target); if (!cpu_has_fxsr) diff --git a/arch/x86/kernel/init_task.c b/arch/x86/kernel/init_task.c index 5b3ce7934363af3a5a3db53c471b889bcd4b834e..3d01e47777db6106a2387016f39a6c70bd744ece 100644 --- a/arch/x86/kernel/init_task.c +++ b/arch/x86/kernel/init_task.c @@ -15,6 +15,7 @@ static struct files_struct init_files = INIT_FILES; static struct signal_struct init_signals = INIT_SIGNALS(init_signals); static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand); struct mm_struct init_mm = INIT_MM(init_mm); +EXPORT_UNUSED_SYMBOL(init_mm); /* will be removed in 2.6.26 */ /* * Initial thread structure. diff --git a/arch/x86/kernel/process_32.c b/arch/x86/kernel/process_32.c index a7d50a547dc2a8a1be9f2af87a52226d95c6438c..be3c7a299f02541cb8f1e03797f737230dcca0ce 100644 --- a/arch/x86/kernel/process_32.c +++ b/arch/x86/kernel/process_32.c @@ -603,11 +603,13 @@ __switch_to_xtra(struct task_struct *prev_p, struct task_struct *next_p, } #endif +#ifdef X86_BTS if (test_tsk_thread_flag(prev_p, TIF_BTS_TRACE_TS)) ptrace_bts_take_timestamp(prev_p, BTS_TASK_DEPARTS); if (test_tsk_thread_flag(next_p, TIF_BTS_TRACE_TS)) ptrace_bts_take_timestamp(next_p, BTS_TASK_ARRIVES); +#endif if (!test_tsk_thread_flag(next_p, TIF_IO_BITMAP)) { diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c index b0cc8f0136d8096e9e4cdad316787f89d4f55a8c..3baf9b9f4c87e9f941223b7ca0e862f52f3a818c 100644 --- a/arch/x86/kernel/process_64.c +++ b/arch/x86/kernel/process_64.c @@ -604,11 +604,13 @@ static inline void __switch_to_xtra(struct task_struct *prev_p, memset(tss->io_bitmap, 0xff, prev->io_bitmap_max); } +#ifdef X86_BTS if (test_tsk_thread_flag(prev_p, TIF_BTS_TRACE_TS)) ptrace_bts_take_timestamp(prev_p, BTS_TASK_DEPARTS); if (test_tsk_thread_flag(next_p, TIF_BTS_TRACE_TS)) ptrace_bts_take_timestamp(next_p, BTS_TASK_ARRIVES); +#endif } /* @@ -730,16 +732,16 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p) */ asmlinkage long sys_execve(char __user *name, char __user * __user *argv, - char __user * __user *envp, struct pt_regs regs) + char __user * __user *envp, struct pt_regs *regs) { long error; char * filename; filename = getname(name); error = PTR_ERR(filename); - if (IS_ERR(filename)) + if (IS_ERR(filename)) return error; - error = do_execve(filename, argv, envp, ®s); + error = do_execve(filename, argv, envp, regs); putname(filename); return error; } diff --git a/arch/x86/kernel/ptrace.c b/arch/x86/kernel/ptrace.c index d862e396b0994e0878a481efd6c9d81edfc90cbd..d5904eef1d319a00eaf71d7efb842d0f87b2fab5 100644 --- a/arch/x86/kernel/ptrace.c +++ b/arch/x86/kernel/ptrace.c @@ -323,6 +323,16 @@ static int putreg(struct task_struct *child, return set_flags(child, value); #ifdef CONFIG_X86_64 + /* + * Orig_ax is really just a flag with small positive and + * negative values, so make sure to always sign-extend it + * from 32 bits so that it works correctly regardless of + * whether we come from a 32-bit environment or not. + */ + case offsetof(struct user_regs_struct, orig_ax): + value = (long) (s32) value; + break; + case offsetof(struct user_regs_struct,fs_base): if (value >= TASK_SIZE_OF(child)) return -EIO; @@ -544,6 +554,8 @@ static int ptrace_set_debugreg(struct task_struct *child, return 0; } +#ifdef X86_BTS + static int ptrace_bts_get_size(struct task_struct *child) { if (!child->thread.ds_area_msr) @@ -826,6 +838,7 @@ void ptrace_bts_take_timestamp(struct task_struct *tsk, ptrace_bts_write_record(tsk, &rec); } +#endif /* X86_BTS */ /* * Called by kernel/ptrace.c when detaching.. @@ -839,7 +852,9 @@ void ptrace_disable(struct task_struct *child) clear_tsk_thread_flag(child, TIF_SYSCALL_EMU); #endif if (child->thread.ds_area_msr) { +#ifdef X86_BTS ptrace_bts_realloc(child, 0, 0); +#endif child->thread.debugctlmsr &= ~ds_debugctl_mask(); if (!child->thread.debugctlmsr) clear_tsk_thread_flag(child, TIF_DEBUGCTLMSR); @@ -961,6 +976,10 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) break; #endif + /* + * These bits need more cooking - not enabled yet: + */ +#ifdef X86_BTS case PTRACE_BTS_CONFIG: ret = ptrace_bts_config (child, data, (struct ptrace_bts_config __user *)addr); @@ -988,6 +1007,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) ret = ptrace_bts_drain (child, data, (struct bts_struct __user *) addr); break; +#endif default: ret = ptrace_request(child, request, addr, data); @@ -1035,10 +1055,17 @@ static int putreg32(struct task_struct *child, unsigned regno, u32 value) R32(esi, si); R32(ebp, bp); R32(eax, ax); - R32(orig_eax, orig_ax); R32(eip, ip); R32(esp, sp); + case offsetof(struct user32, regs.orig_eax): + /* + * Sign-extend the value so that orig_eax = -1 + * causes (long)orig_ax < 0 tests to fire correctly. + */ + regs->orig_ax = (long) (s32) value; + break; + case offsetof(struct user32, regs.eflags): return set_flags(child, value); @@ -1226,12 +1253,14 @@ asmlinkage long sys32_ptrace(long request, u32 pid, u32 addr, u32 data) case PTRACE_SETOPTIONS: case PTRACE_SET_THREAD_AREA: case PTRACE_GET_THREAD_AREA: +#ifdef X86_BTS case PTRACE_BTS_CONFIG: case PTRACE_BTS_STATUS: case PTRACE_BTS_SIZE: case PTRACE_BTS_GET: case PTRACE_BTS_CLEAR: case PTRACE_BTS_DRAIN: +#endif return sys_ptrace(request, pid, addr, data); default: diff --git a/arch/x86/kernel/reboot.c b/arch/x86/kernel/reboot.c index 7fd6ac43e4a114a6de9826fe71c7a0cede037c69..55ceb8cdef75c760f1552649e2cd102326760aec 100644 --- a/arch/x86/kernel/reboot.c +++ b/arch/x86/kernel/reboot.c @@ -326,6 +326,10 @@ static inline void kb_wait(void) } } +void __attribute__((weak)) mach_reboot_fixups(void) +{ +} + static void native_machine_emergency_restart(void) { int i; @@ -337,6 +341,8 @@ static void native_machine_emergency_restart(void) /* Could also try the reset bit in the Hammer NB */ switch (reboot_type) { case BOOT_KBD: + mach_reboot_fixups(); /* for board specific fixups */ + for (i = 0; i < 10; i++) { kb_wait(); udelay(50); diff --git a/arch/x86/kernel/setup_64.c b/arch/x86/kernel/setup_64.c index 6fd804f0782145be3b45c223590c5c287a9bdb57..7637dc91c79bebac16365bbcff3b480c408584ef 100644 --- a/arch/x86/kernel/setup_64.c +++ b/arch/x86/kernel/setup_64.c @@ -1021,7 +1021,7 @@ void __cpuinit identify_cpu(struct cpuinfo_x86 *c) /* Clear all flags overriden by options */ for (i = 0; i < NCAPINTS; i++) - c->x86_capability[i] ^= cleared_cpu_caps[i]; + c->x86_capability[i] &= ~cleared_cpu_caps[i]; #ifdef CONFIG_X86_MCE mcheck_init(c); diff --git a/arch/x86/kernel/signal_32.c b/arch/x86/kernel/signal_32.c index caee1f002fed39476d54e61b3aa6762b28e92c31..0157a6f0f41f501ee19c607aa3a5c593c7824d7f 100644 --- a/arch/x86/kernel/signal_32.c +++ b/arch/x86/kernel/signal_32.c @@ -407,7 +407,7 @@ static int setup_frame(int sig, struct k_sigaction *ka, * The tracer may want to single-step inside the * handler too. */ - regs->flags &= ~TF_MASK; + regs->flags &= ~(TF_MASK | X86_EFLAGS_DF); if (test_thread_flag(TIF_SINGLESTEP)) ptrace_notify(SIGTRAP); @@ -500,7 +500,7 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, * The tracer may want to single-step inside the * handler too. */ - regs->flags &= ~TF_MASK; + regs->flags &= ~(TF_MASK | X86_EFLAGS_DF); if (test_thread_flag(TIF_SINGLESTEP)) ptrace_notify(SIGTRAP); diff --git a/arch/x86/kernel/signal_64.c b/arch/x86/kernel/signal_64.c index 7347bb14e306bb3ff66385beee9cc1e5c6a15113..1c83e5124c65813f7c966a9ed0e882627b2a84a9 100644 --- a/arch/x86/kernel/signal_64.c +++ b/arch/x86/kernel/signal_64.c @@ -295,7 +295,7 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, see include/asm-x86_64/uaccess.h for details. */ set_fs(USER_DS); - regs->flags &= ~X86_EFLAGS_TF; + regs->flags &= ~(X86_EFLAGS_TF | X86_EFLAGS_DF); if (test_thread_flag(TIF_SINGLESTEP)) ptrace_notify(SIGTRAP); #ifdef DEBUG_SIG @@ -310,6 +310,35 @@ give_sigsegv: return -EFAULT; } +/* + * Return -1L or the syscall number that @regs is executing. + */ +static long current_syscall(struct pt_regs *regs) +{ + /* + * We always sign-extend a -1 value being set here, + * so this is always either -1L or a syscall number. + */ + return regs->orig_ax; +} + +/* + * Return a value that is -EFOO if the system call in @regs->orig_ax + * returned an error. This only works for @regs from @current. + */ +static long current_syscall_ret(struct pt_regs *regs) +{ +#ifdef CONFIG_IA32_EMULATION + if (test_thread_flag(TIF_IA32)) + /* + * Sign-extend the value so (int)-EFOO becomes (long)-EFOO + * and will match correctly in comparisons. + */ + return (int) regs->ax; +#endif + return regs->ax; +} + /* * OK, we're invoking a handler */ @@ -327,9 +356,9 @@ handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka, #endif /* Are we from a system call? */ - if ((long)regs->orig_ax >= 0) { + if (current_syscall(regs) >= 0) { /* If so, check system call restarting.. */ - switch (regs->ax) { + switch (current_syscall_ret(regs)) { case -ERESTART_RESTARTBLOCK: case -ERESTARTNOHAND: regs->ax = -EINTR; @@ -426,10 +455,9 @@ static void do_signal(struct pt_regs *regs) } /* Did we come from a system call? */ - if ((long)regs->orig_ax >= 0) { + if (current_syscall(regs) >= 0) { /* Restart the system call - no handlers present */ - long res = regs->ax; - switch (res) { + switch (current_syscall_ret(regs)) { case -ERESTARTNOHAND: case -ERESTARTSYS: case -ERESTARTNOINTR: diff --git a/arch/x86/kernel/smpboot_64.c b/arch/x86/kernel/smpboot_64.c index d53bd6fcb42877106dea1c2e8500c31f2614f15a..0880f2c388a901fd318ac39856e4105b98e4d09d 100644 --- a/arch/x86/kernel/smpboot_64.c +++ b/arch/x86/kernel/smpboot_64.c @@ -554,10 +554,10 @@ static int __cpuinit do_boot_cpu(int cpu, int apicid) int timeout; unsigned long start_rip; struct create_idle c_idle = { - .work = __WORK_INITIALIZER(c_idle.work, do_fork_idle), .cpu = cpu, .done = COMPLETION_INITIALIZER_ONSTACK(c_idle.done), }; + INIT_WORK(&c_idle.work, do_fork_idle); /* allocate memory for gdts of secondary cpus. Hotplug is considered */ if (!cpu_gdt_descr[cpu].address && diff --git a/arch/x86/kernel/stacktrace.c b/arch/x86/kernel/stacktrace.c index 02f0f61f5b1131a511851546393ef06665787507..c28c342c162f0a90d3ad6e50ba0fb1d5ecd132a7 100644 --- a/arch/x86/kernel/stacktrace.c +++ b/arch/x86/kernel/stacktrace.c @@ -25,6 +25,8 @@ static int save_stack_stack(void *data, char *name) static void save_stack_address(void *data, unsigned long addr, int reliable) { struct stack_trace *trace = data; + if (!reliable) + return; if (trace->skip > 0) { trace->skip--; return; @@ -37,6 +39,8 @@ static void save_stack_address_nosched(void *data, unsigned long addr, int reliable) { struct stack_trace *trace = (struct stack_trace *)data; + if (!reliable) + return; if (in_sched_functions(addr)) return; if (trace->skip > 0) { diff --git a/arch/x86/kernel/step.c b/arch/x86/kernel/step.c index 2ef1a5f8d6758043b6ce2204da47cb71e5cc1614..9d406cdc847f4da493611d3f48a634e8f868792b 100644 --- a/arch/x86/kernel/step.c +++ b/arch/x86/kernel/step.c @@ -166,7 +166,7 @@ static void enable_step(struct task_struct *child, bool block) child->thread.debugctlmsr | DEBUGCTLMSR_BTF); } else { write_debugctlmsr(child, - child->thread.debugctlmsr & ~TIF_DEBUGCTLMSR); + child->thread.debugctlmsr & ~DEBUGCTLMSR_BTF); if (!child->thread.debugctlmsr) clear_tsk_thread_flag(child, TIF_DEBUGCTLMSR); @@ -189,7 +189,7 @@ void user_disable_single_step(struct task_struct *child) * Make sure block stepping (BTF) is disabled. */ write_debugctlmsr(child, - child->thread.debugctlmsr & ~TIF_DEBUGCTLMSR); + child->thread.debugctlmsr & ~DEBUGCTLMSR_BTF); if (!child->thread.debugctlmsr) clear_tsk_thread_flag(child, TIF_DEBUGCTLMSR); diff --git a/arch/x86/kernel/tls.c b/arch/x86/kernel/tls.c index 6dfd4e76661a18d11643eef1d8bafe64783749da..022bcaa3b42ed0c9e270a9734ad36c77bd3092f0 100644 --- a/arch/x86/kernel/tls.c +++ b/arch/x86/kernel/tls.c @@ -91,7 +91,9 @@ int do_set_thread_area(struct task_struct *p, int idx, asmlinkage int sys_set_thread_area(struct user_desc __user *u_info) { - return do_set_thread_area(current, -1, u_info, 1); + int ret = do_set_thread_area(current, -1, u_info, 1); + prevent_tail_call(ret); + return ret; } @@ -139,7 +141,9 @@ int do_get_thread_area(struct task_struct *p, int idx, asmlinkage int sys_get_thread_area(struct user_desc __user *u_info) { - return do_get_thread_area(current, -1, u_info); + int ret = do_get_thread_area(current, -1, u_info); + prevent_tail_call(ret); + return ret; } int regset_tls_active(struct task_struct *target, diff --git a/arch/x86/kernel/tsc_32.c b/arch/x86/kernel/tsc_32.c index 43517e324be83e73096fe28a39ec5275c9a378e0..f14cfd9d1f94c1a634833da25e86eea9cb43b864 100644 --- a/arch/x86/kernel/tsc_32.c +++ b/arch/x86/kernel/tsc_32.c @@ -28,7 +28,8 @@ EXPORT_SYMBOL_GPL(tsc_khz); static int __init tsc_setup(char *str) { printk(KERN_WARNING "notsc: Kernel compiled with CONFIG_X86_TSC, " - "cannot disable TSC.\n"); + "cannot disable TSC completely.\n"); + mark_tsc_unstable("user disabled TSC"); return 1; } #else diff --git a/arch/x86/kernel/vsyscall_64.c b/arch/x86/kernel/vsyscall_64.c index 3f82427745802f0e30ff19ff5ed5aee7e50d7fa2..edff4c9854854429fda22ce2d35f7f08fa64c593 100644 --- a/arch/x86/kernel/vsyscall_64.c +++ b/arch/x86/kernel/vsyscall_64.c @@ -44,11 +44,6 @@ #define __vsyscall(nr) __attribute__ ((unused,__section__(".vsyscall_" #nr))) #define __syscall_clobber "r11","cx","memory" -#define __pa_vsymbol(x) \ - ({unsigned long v; \ - extern char __vsyscall_0; \ - asm("" : "=r" (v) : "0" (x)); \ - ((v - VSYSCALL_START) + __pa_symbol(&__vsyscall_0)); }) /* * vsyscall_gtod_data contains data that is : @@ -102,7 +97,7 @@ static __always_inline void do_get_tz(struct timezone * tz) static __always_inline int gettimeofday(struct timeval *tv, struct timezone *tz) { int ret; - asm volatile("vsysc2: syscall" + asm volatile("syscall" : "=a" (ret) : "0" (__NR_gettimeofday),"D" (tv),"S" (tz) : __syscall_clobber ); @@ -112,7 +107,7 @@ static __always_inline int gettimeofday(struct timeval *tv, struct timezone *tz) static __always_inline long time_syscall(long *t) { long secs; - asm volatile("vsysc1: syscall" + asm volatile("syscall" : "=a" (secs) : "0" (__NR_time),"D" (t) : __syscall_clobber); return secs; @@ -228,42 +223,11 @@ long __vsyscall(3) venosys_1(void) #ifdef CONFIG_SYSCTL -#define SYSCALL 0x050f -#define NOP2 0x9090 - -/* - * NOP out syscall in vsyscall page when not needed. - */ -static int vsyscall_sysctl_change(ctl_table *ctl, int write, struct file * filp, - void __user *buffer, size_t *lenp, loff_t *ppos) +static int +vsyscall_sysctl_change(ctl_table *ctl, int write, struct file * filp, + void __user *buffer, size_t *lenp, loff_t *ppos) { - extern u16 vsysc1, vsysc2; - u16 __iomem *map1; - u16 __iomem *map2; - int ret = proc_dointvec(ctl, write, filp, buffer, lenp, ppos); - if (!write) - return ret; - /* gcc has some trouble with __va(__pa()), so just do it this - way. */ - map1 = ioremap(__pa_vsymbol(&vsysc1), 2); - if (!map1) - return -ENOMEM; - map2 = ioremap(__pa_vsymbol(&vsysc2), 2); - if (!map2) { - ret = -ENOMEM; - goto out; - } - if (!vsyscall_gtod_data.sysctl_enabled) { - writew(SYSCALL, map1); - writew(SYSCALL, map2); - } else { - writew(NOP2, map1); - writew(NOP2, map2); - } - iounmap(map2); -out: - iounmap(map1); - return ret; + return proc_dointvec(ctl, write, filp, buffer, lenp, ppos); } static ctl_table kernel_table2[] = { @@ -279,7 +243,6 @@ static ctl_table kernel_root_table2[] = { .child = kernel_table2 }, {} }; - #endif /* Assume __initcall executes before all user space. Hopefully kmod diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c index 2cbee9479ce423850a99df39290e3efbbe51ae48..68a6b1511934760e97117080166f78b9a7d5ab72 100644 --- a/arch/x86/kvm/lapic.c +++ b/arch/x86/kvm/lapic.c @@ -647,6 +647,10 @@ static void start_apic_timer(struct kvm_lapic *apic) apic->timer.period = apic_get_reg(apic, APIC_TMICT) * APIC_BUS_CYCLE_NS * apic->timer.divide_count; atomic_set(&apic->timer.pending, 0); + + if (!apic->timer.period) + return; + hrtimer_start(&apic->timer.dev, ktime_add_ns(now, apic->timer.period), HRTIMER_MODE_ABS); diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c index 8efdcdbebb0356483816de769856fd57c20944ea..d8172aabc660de7503c43b697fea470d81f7eb9a 100644 --- a/arch/x86/kvm/mmu.c +++ b/arch/x86/kvm/mmu.c @@ -681,8 +681,7 @@ static struct kvm_mmu_page *kvm_mmu_get_page(struct kvm_vcpu *vcpu, unsigned level, int metaphysical, unsigned access, - u64 *parent_pte, - bool *new_page) + u64 *parent_pte) { union kvm_mmu_page_role role; unsigned index; @@ -722,8 +721,6 @@ static struct kvm_mmu_page *kvm_mmu_get_page(struct kvm_vcpu *vcpu, vcpu->arch.mmu.prefetch_page(vcpu, sp); if (!metaphysical) rmap_write_protect(vcpu->kvm, gfn); - if (new_page) - *new_page = 1; return sp; } @@ -876,11 +873,18 @@ static void page_header_update_slot(struct kvm *kvm, void *pte, gfn_t gfn) struct page *gva_to_page(struct kvm_vcpu *vcpu, gva_t gva) { + struct page *page; + gpa_t gpa = vcpu->arch.mmu.gva_to_gpa(vcpu, gva); if (gpa == UNMAPPED_GVA) return NULL; - return gfn_to_page(vcpu->kvm, gpa >> PAGE_SHIFT); + + down_read(¤t->mm->mmap_sem); + page = gfn_to_page(vcpu->kvm, gpa >> PAGE_SHIFT); + up_read(¤t->mm->mmap_sem); + + return page; } static void mmu_set_spte(struct kvm_vcpu *vcpu, u64 *shadow_pte, @@ -999,8 +1003,7 @@ static int __nonpaging_map(struct kvm_vcpu *vcpu, gva_t v, int write, >> PAGE_SHIFT; new_table = kvm_mmu_get_page(vcpu, pseudo_gfn, v, level - 1, - 1, ACC_ALL, &table[index], - NULL); + 1, ACC_ALL, &table[index]); if (!new_table) { pgprintk("nonpaging_map: ENOMEM\n"); kvm_release_page_clean(page); @@ -1020,15 +1023,18 @@ static int nonpaging_map(struct kvm_vcpu *vcpu, gva_t v, int write, gfn_t gfn) struct page *page; + down_read(&vcpu->kvm->slots_lock); + down_read(¤t->mm->mmap_sem); page = gfn_to_page(vcpu->kvm, gfn); + up_read(¤t->mm->mmap_sem); spin_lock(&vcpu->kvm->mmu_lock); kvm_mmu_free_some_pages(vcpu); r = __nonpaging_map(vcpu, v, write, gfn, page); spin_unlock(&vcpu->kvm->mmu_lock); - up_read(¤t->mm->mmap_sem); + up_read(&vcpu->kvm->slots_lock); return r; } @@ -1090,7 +1096,7 @@ static void mmu_alloc_roots(struct kvm_vcpu *vcpu) ASSERT(!VALID_PAGE(root)); sp = kvm_mmu_get_page(vcpu, root_gfn, 0, - PT64_ROOT_LEVEL, 0, ACC_ALL, NULL, NULL); + PT64_ROOT_LEVEL, 0, ACC_ALL, NULL); root = __pa(sp->spt); ++sp->root_count; vcpu->arch.mmu.root_hpa = root; @@ -1111,7 +1117,7 @@ static void mmu_alloc_roots(struct kvm_vcpu *vcpu) root_gfn = 0; sp = kvm_mmu_get_page(vcpu, root_gfn, i << 30, PT32_ROOT_LEVEL, !is_paging(vcpu), - ACC_ALL, NULL, NULL); + ACC_ALL, NULL); root = __pa(sp->spt); ++sp->root_count; vcpu->arch.mmu.pae_root[i] = root | PT_PRESENT_MASK; @@ -1172,7 +1178,7 @@ void kvm_mmu_flush_tlb(struct kvm_vcpu *vcpu) static void paging_new_cr3(struct kvm_vcpu *vcpu) { - pgprintk("%s: cr3 %lx\n", __FUNCTION__, vcpu->cr3); + pgprintk("%s: cr3 %lx\n", __FUNCTION__, vcpu->arch.cr3); mmu_free_roots(vcpu); } @@ -1362,6 +1368,7 @@ static void mmu_guess_page_from_pte_write(struct kvm_vcpu *vcpu, gpa_t gpa, gfn_t gfn; int r; u64 gpte = 0; + struct page *page; if (bytes != 4 && bytes != 8) return; @@ -1389,6 +1396,11 @@ static void mmu_guess_page_from_pte_write(struct kvm_vcpu *vcpu, gpa_t gpa, if (!is_present_pte(gpte)) return; gfn = (gpte & PT64_BASE_ADDR_MASK) >> PAGE_SHIFT; + + down_read(¤t->mm->mmap_sem); + page = gfn_to_page(vcpu->kvm, gfn); + up_read(¤t->mm->mmap_sem); + vcpu->arch.update_pte.gfn = gfn; vcpu->arch.update_pte.page = gfn_to_page(vcpu->kvm, gfn); } @@ -1496,9 +1508,9 @@ int kvm_mmu_unprotect_page_virt(struct kvm_vcpu *vcpu, gva_t gva) gpa_t gpa; int r; - down_read(¤t->mm->mmap_sem); + down_read(&vcpu->kvm->slots_lock); gpa = vcpu->arch.mmu.gva_to_gpa(vcpu, gva); - up_read(¤t->mm->mmap_sem); + up_read(&vcpu->kvm->slots_lock); spin_lock(&vcpu->kvm->mmu_lock); r = kvm_mmu_unprotect_page(vcpu->kvm, gpa >> PAGE_SHIFT); diff --git a/arch/x86/kvm/paging_tmpl.h b/arch/x86/kvm/paging_tmpl.h index 03ba8608fe0f43816c91fc2bdc77b1c22725d7bb..ecc0856268c47c8c7a5c5773ac0d239d37dbc58e 100644 --- a/arch/x86/kvm/paging_tmpl.h +++ b/arch/x86/kvm/paging_tmpl.h @@ -91,7 +91,10 @@ static bool FNAME(cmpxchg_gpte)(struct kvm *kvm, pt_element_t *table; struct page *page; + down_read(¤t->mm->mmap_sem); page = gfn_to_page(kvm, table_gfn); + up_read(¤t->mm->mmap_sem); + table = kmap_atomic(page, KM_USER0); ret = CMPXCHG(&table[index], orig_pte, new_pte); @@ -140,7 +143,7 @@ walk: } #endif ASSERT((!is_long_mode(vcpu) && is_pae(vcpu)) || - (vcpu->cr3 & CR3_NONPAE_RESERVED_BITS) == 0); + (vcpu->arch.cr3 & CR3_NONPAE_RESERVED_BITS) == 0); pt_access = ACC_ALL; @@ -297,7 +300,6 @@ static u64 *FNAME(fetch)(struct kvm_vcpu *vcpu, gva_t addr, u64 shadow_pte; int metaphysical; gfn_t table_gfn; - bool new_page = 0; shadow_ent = ((u64 *)__va(shadow_addr)) + index; if (level == PT_PAGE_TABLE_LEVEL) @@ -319,8 +321,8 @@ static u64 *FNAME(fetch)(struct kvm_vcpu *vcpu, gva_t addr, } shadow_page = kvm_mmu_get_page(vcpu, table_gfn, addr, level-1, metaphysical, access, - shadow_ent, &new_page); - if (new_page && !metaphysical) { + shadow_ent); + if (!metaphysical) { int r; pt_element_t curr_pte; r = kvm_read_guest_atomic(vcpu->kvm, @@ -378,7 +380,7 @@ static int FNAME(page_fault)(struct kvm_vcpu *vcpu, gva_t addr, if (r) return r; - down_read(¤t->mm->mmap_sem); + down_read(&vcpu->kvm->slots_lock); /* * Look up the shadow pte for the faulting address. */ @@ -392,11 +394,13 @@ static int FNAME(page_fault)(struct kvm_vcpu *vcpu, gva_t addr, pgprintk("%s: guest page fault\n", __FUNCTION__); inject_page_fault(vcpu, addr, walker.error_code); vcpu->arch.last_pt_write_count = 0; /* reset fork detector */ - up_read(¤t->mm->mmap_sem); + up_read(&vcpu->kvm->slots_lock); return 0; } + down_read(¤t->mm->mmap_sem); page = gfn_to_page(vcpu->kvm, walker.gfn); + up_read(¤t->mm->mmap_sem); spin_lock(&vcpu->kvm->mmu_lock); kvm_mmu_free_some_pages(vcpu); @@ -413,14 +417,14 @@ static int FNAME(page_fault)(struct kvm_vcpu *vcpu, gva_t addr, */ if (shadow_pte && is_io_pte(*shadow_pte)) { spin_unlock(&vcpu->kvm->mmu_lock); - up_read(¤t->mm->mmap_sem); + up_read(&vcpu->kvm->slots_lock); return 1; } ++vcpu->stat.pf_fixed; kvm_mmu_audit(vcpu, "post page fault (fixed)"); spin_unlock(&vcpu->kvm->mmu_lock); - up_read(¤t->mm->mmap_sem); + up_read(&vcpu->kvm->slots_lock); return write_pt; } diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c index de755cb1431dcef84617b04e29eacb5a06fc59d0..1a582f1090e895aaa19634aa21d02ccf6c1584f0 100644 --- a/arch/x86/kvm/svm.c +++ b/arch/x86/kvm/svm.c @@ -792,6 +792,10 @@ static void svm_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0) vcpu->arch.cr0 = cr0; cr0 |= X86_CR0_PG | X86_CR0_WP; cr0 &= ~(X86_CR0_CD | X86_CR0_NW); + if (!vcpu->fpu_active) { + svm->vmcb->control.intercept_exceptions |= (1 << NM_VECTOR); + cr0 |= X86_CR0_TS; + } svm->vmcb->save.cr0 = cr0; } @@ -1096,6 +1100,24 @@ static int svm_get_msr(struct kvm_vcpu *vcpu, unsigned ecx, u64 *data) case MSR_IA32_SYSENTER_ESP: *data = svm->vmcb->save.sysenter_esp; break; + /* Nobody will change the following 5 values in the VMCB so + we can safely return them on rdmsr. They will always be 0 + until LBRV is implemented. */ + case MSR_IA32_DEBUGCTLMSR: + *data = svm->vmcb->save.dbgctl; + break; + case MSR_IA32_LASTBRANCHFROMIP: + *data = svm->vmcb->save.br_from; + break; + case MSR_IA32_LASTBRANCHTOIP: + *data = svm->vmcb->save.br_to; + break; + case MSR_IA32_LASTINTFROMIP: + *data = svm->vmcb->save.last_excp_from; + break; + case MSR_IA32_LASTINTTOIP: + *data = svm->vmcb->save.last_excp_to; + break; default: return kvm_get_msr_common(vcpu, ecx, data); } @@ -1156,6 +1178,10 @@ static int svm_set_msr(struct kvm_vcpu *vcpu, unsigned ecx, u64 data) case MSR_IA32_SYSENTER_ESP: svm->vmcb->save.sysenter_esp = data; break; + case MSR_IA32_DEBUGCTLMSR: + pr_unimpl(vcpu, "%s: MSR_IA32_DEBUGCTLMSR 0x%llx, nop\n", + __FUNCTION__, data); + break; case MSR_K7_EVNTSEL0: case MSR_K7_EVNTSEL1: case MSR_K7_EVNTSEL2: diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index ad36447e696e6c80bbf70ce53e0b88a7e2c2bbe8..94ea724638fda63b87ec248c2c3b40783ad93e08 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c @@ -638,6 +638,7 @@ static void setup_msrs(struct vcpu_vmx *vmx) { int save_nmsrs; + vmx_load_host_state(vmx); save_nmsrs = 0; #ifdef CONFIG_X86_64 if (is_long_mode(&vmx->vcpu)) { @@ -1477,7 +1478,7 @@ static int alloc_apic_access_page(struct kvm *kvm) struct kvm_userspace_memory_region kvm_userspace_mem; int r = 0; - down_write(¤t->mm->mmap_sem); + down_write(&kvm->slots_lock); if (kvm->arch.apic_access_page) goto out; kvm_userspace_mem.slot = APIC_ACCESS_PAGE_PRIVATE_MEMSLOT; @@ -1487,9 +1488,12 @@ static int alloc_apic_access_page(struct kvm *kvm) r = __kvm_set_memory_region(kvm, &kvm_userspace_mem, 0); if (r) goto out; + + down_read(¤t->mm->mmap_sem); kvm->arch.apic_access_page = gfn_to_page(kvm, 0xfee00); + up_read(¤t->mm->mmap_sem); out: - up_write(¤t->mm->mmap_sem); + up_write(&kvm->slots_lock); return r; } @@ -1602,9 +1606,6 @@ static int vmx_vcpu_setup(struct vcpu_vmx *vmx) vmcs_writel(CR0_GUEST_HOST_MASK, ~0UL); vmcs_writel(CR4_GUEST_HOST_MASK, KVM_GUEST_CR4_MASK); - if (vm_need_virtualize_apic_accesses(vmx->vcpu.kvm)) - if (alloc_apic_access_page(vmx->vcpu.kvm) != 0) - return -ENOMEM; return 0; } @@ -2534,6 +2535,9 @@ static struct kvm_vcpu *vmx_create_vcpu(struct kvm *kvm, unsigned int id) put_cpu(); if (err) goto free_vmcs; + if (vm_need_virtualize_apic_accesses(kvm)) + if (alloc_apic_access_page(kvm) != 0) + goto free_vmcs; return &vmx->vcpu; diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index cf530814868957a9de8058849538405ca493dcc5..6b01552bd1f1cb91c64af4fdf9f3124e734d4d19 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -46,6 +46,9 @@ #define VM_STAT(x) offsetof(struct kvm, stat.x), KVM_STAT_VM #define VCPU_STAT(x) offsetof(struct kvm_vcpu, stat.x), KVM_STAT_VCPU +static int kvm_dev_ioctl_get_supported_cpuid(struct kvm_cpuid2 *cpuid, + struct kvm_cpuid_entry2 __user *entries); + struct kvm_x86_ops *kvm_x86_ops; struct kvm_stats_debugfs_item debugfs_entries[] = { @@ -181,7 +184,7 @@ int load_pdptrs(struct kvm_vcpu *vcpu, unsigned long cr3) int ret; u64 pdpte[ARRAY_SIZE(vcpu->arch.pdptrs)]; - down_read(¤t->mm->mmap_sem); + down_read(&vcpu->kvm->slots_lock); ret = kvm_read_guest_page(vcpu->kvm, pdpt_gfn, pdpte, offset * sizeof(u64), sizeof(pdpte)); if (ret < 0) { @@ -198,7 +201,7 @@ int load_pdptrs(struct kvm_vcpu *vcpu, unsigned long cr3) memcpy(vcpu->arch.pdptrs, pdpte, sizeof(vcpu->arch.pdptrs)); out: - up_read(¤t->mm->mmap_sem); + up_read(&vcpu->kvm->slots_lock); return ret; } @@ -212,13 +215,13 @@ static bool pdptrs_changed(struct kvm_vcpu *vcpu) if (is_long_mode(vcpu) || !is_pae(vcpu)) return false; - down_read(¤t->mm->mmap_sem); + down_read(&vcpu->kvm->slots_lock); r = kvm_read_guest(vcpu->kvm, vcpu->arch.cr3 & ~31u, pdpte, sizeof(pdpte)); if (r < 0) goto out; changed = memcmp(pdpte, vcpu->arch.pdptrs, sizeof(pdpte)) != 0; out: - up_read(¤t->mm->mmap_sem); + up_read(&vcpu->kvm->slots_lock); return changed; } @@ -356,7 +359,7 @@ void set_cr3(struct kvm_vcpu *vcpu, unsigned long cr3) */ } - down_read(¤t->mm->mmap_sem); + down_read(&vcpu->kvm->slots_lock); /* * Does the new cr3 value map to physical memory? (Note, we * catch an invalid cr3 even in real-mode, because it would @@ -372,7 +375,7 @@ void set_cr3(struct kvm_vcpu *vcpu, unsigned long cr3) vcpu->arch.cr3 = cr3; vcpu->arch.mmu.new_cr3(vcpu); } - up_read(¤t->mm->mmap_sem); + up_read(&vcpu->kvm->slots_lock); } EXPORT_SYMBOL_GPL(set_cr3); @@ -484,6 +487,10 @@ int kvm_set_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 data) pr_unimpl(vcpu, "%s: MSR_IA32_MCG_STATUS 0x%llx, nop\n", __FUNCTION__, data); break; + case MSR_IA32_MCG_CTL: + pr_unimpl(vcpu, "%s: MSR_IA32_MCG_CTL 0x%llx, nop\n", + __FUNCTION__, data); + break; case MSR_IA32_UCODE_REV: case MSR_IA32_UCODE_WRITE: case 0x200 ... 0x2ff: /* MTRRs */ @@ -526,6 +533,7 @@ int kvm_get_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata) case MSR_IA32_MC0_CTL: case MSR_IA32_MCG_STATUS: case MSR_IA32_MCG_CAP: + case MSR_IA32_MCG_CTL: case MSR_IA32_MC0_MISC: case MSR_IA32_MC0_MISC+4: case MSR_IA32_MC0_MISC+8: @@ -727,6 +735,24 @@ long kvm_arch_dev_ioctl(struct file *filp, r = 0; break; } + case KVM_GET_SUPPORTED_CPUID: { + struct kvm_cpuid2 __user *cpuid_arg = argp; + struct kvm_cpuid2 cpuid; + + r = -EFAULT; + if (copy_from_user(&cpuid, cpuid_arg, sizeof cpuid)) + goto out; + r = kvm_dev_ioctl_get_supported_cpuid(&cpuid, + cpuid_arg->entries); + if (r) + goto out; + + r = -EFAULT; + if (copy_to_user(cpuid_arg, &cpuid, sizeof cpuid)) + goto out; + r = 0; + break; + } default: r = -EINVAL; } @@ -974,8 +1000,7 @@ static void do_cpuid_ent(struct kvm_cpuid_entry2 *entry, u32 function, put_cpu(); } -static int kvm_vm_ioctl_get_supported_cpuid(struct kvm *kvm, - struct kvm_cpuid2 *cpuid, +static int kvm_dev_ioctl_get_supported_cpuid(struct kvm_cpuid2 *cpuid, struct kvm_cpuid_entry2 __user *entries) { struct kvm_cpuid_entry2 *cpuid_entries; @@ -1207,12 +1232,12 @@ static int kvm_vm_ioctl_set_nr_mmu_pages(struct kvm *kvm, if (kvm_nr_mmu_pages < KVM_MIN_ALLOC_MMU_PAGES) return -EINVAL; - down_write(¤t->mm->mmap_sem); + down_write(&kvm->slots_lock); kvm_mmu_change_mmu_pages(kvm, kvm_nr_mmu_pages); kvm->arch.n_requested_mmu_pages = kvm_nr_mmu_pages; - up_write(¤t->mm->mmap_sem); + up_write(&kvm->slots_lock); return 0; } @@ -1261,7 +1286,7 @@ static int kvm_vm_ioctl_set_memory_alias(struct kvm *kvm, < alias->target_phys_addr) goto out; - down_write(¤t->mm->mmap_sem); + down_write(&kvm->slots_lock); p = &kvm->arch.aliases[alias->slot]; p->base_gfn = alias->guest_phys_addr >> PAGE_SHIFT; @@ -1275,7 +1300,7 @@ static int kvm_vm_ioctl_set_memory_alias(struct kvm *kvm, kvm_mmu_zap_all(kvm); - up_write(¤t->mm->mmap_sem); + up_write(&kvm->slots_lock); return 0; @@ -1351,7 +1376,7 @@ int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm, struct kvm_memory_slot *memslot; int is_dirty = 0; - down_write(¤t->mm->mmap_sem); + down_write(&kvm->slots_lock); r = kvm_get_dirty_log(kvm, log, &is_dirty); if (r) @@ -1367,7 +1392,7 @@ int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm, } r = 0; out: - up_write(¤t->mm->mmap_sem); + up_write(&kvm->slots_lock); return r; } @@ -1487,24 +1512,6 @@ long kvm_arch_vm_ioctl(struct file *filp, r = 0; break; } - case KVM_GET_SUPPORTED_CPUID: { - struct kvm_cpuid2 __user *cpuid_arg = argp; - struct kvm_cpuid2 cpuid; - - r = -EFAULT; - if (copy_from_user(&cpuid, cpuid_arg, sizeof cpuid)) - goto out; - r = kvm_vm_ioctl_get_supported_cpuid(kvm, &cpuid, - cpuid_arg->entries); - if (r) - goto out; - - r = -EFAULT; - if (copy_to_user(cpuid_arg, &cpuid, sizeof cpuid)) - goto out; - r = 0; - break; - } default: ; } @@ -1563,7 +1570,7 @@ int emulator_read_std(unsigned long addr, void *data = val; int r = X86EMUL_CONTINUE; - down_read(¤t->mm->mmap_sem); + down_read(&vcpu->kvm->slots_lock); while (bytes) { gpa_t gpa = vcpu->arch.mmu.gva_to_gpa(vcpu, addr); unsigned offset = addr & (PAGE_SIZE-1); @@ -1585,7 +1592,7 @@ int emulator_read_std(unsigned long addr, addr += tocopy; } out: - up_read(¤t->mm->mmap_sem); + up_read(&vcpu->kvm->slots_lock); return r; } EXPORT_SYMBOL_GPL(emulator_read_std); @@ -1604,9 +1611,9 @@ static int emulator_read_emulated(unsigned long addr, return X86EMUL_CONTINUE; } - down_read(¤t->mm->mmap_sem); + down_read(&vcpu->kvm->slots_lock); gpa = vcpu->arch.mmu.gva_to_gpa(vcpu, addr); - up_read(¤t->mm->mmap_sem); + up_read(&vcpu->kvm->slots_lock); /* For APIC access vmexit */ if ((gpa & PAGE_MASK) == APIC_DEFAULT_PHYS_BASE) @@ -1644,14 +1651,14 @@ static int emulator_write_phys(struct kvm_vcpu *vcpu, gpa_t gpa, { int ret; - down_read(¤t->mm->mmap_sem); + down_read(&vcpu->kvm->slots_lock); ret = kvm_write_guest(vcpu->kvm, gpa, val, bytes); if (ret < 0) { - up_read(¤t->mm->mmap_sem); + up_read(&vcpu->kvm->slots_lock); return 0; } kvm_mmu_pte_write(vcpu, gpa, val, bytes); - up_read(¤t->mm->mmap_sem); + up_read(&vcpu->kvm->slots_lock); return 1; } @@ -1663,9 +1670,9 @@ static int emulator_write_emulated_onepage(unsigned long addr, struct kvm_io_device *mmio_dev; gpa_t gpa; - down_read(¤t->mm->mmap_sem); + down_read(&vcpu->kvm->slots_lock); gpa = vcpu->arch.mmu.gva_to_gpa(vcpu, addr); - up_read(¤t->mm->mmap_sem); + up_read(&vcpu->kvm->slots_lock); if (gpa == UNMAPPED_GVA) { kvm_inject_page_fault(vcpu, addr, 2); @@ -1742,7 +1749,7 @@ static int emulator_cmpxchg_emulated(unsigned long addr, char *kaddr; u64 val; - down_read(¤t->mm->mmap_sem); + down_read(&vcpu->kvm->slots_lock); gpa = vcpu->arch.mmu.gva_to_gpa(vcpu, addr); if (gpa == UNMAPPED_GVA || @@ -1753,13 +1760,17 @@ static int emulator_cmpxchg_emulated(unsigned long addr, goto emul_write; val = *(u64 *)new; + + down_read(¤t->mm->mmap_sem); page = gfn_to_page(vcpu->kvm, gpa >> PAGE_SHIFT); + up_read(¤t->mm->mmap_sem); + kaddr = kmap_atomic(page, KM_USER0); set_64bit((u64 *)(kaddr + offset_in_page(gpa)), val); kunmap_atomic(kaddr, KM_USER0); kvm_release_page_dirty(page); emul_write: - up_read(¤t->mm->mmap_sem); + up_read(&vcpu->kvm->slots_lock); } #endif @@ -2152,10 +2163,10 @@ int kvm_emulate_pio_string(struct kvm_vcpu *vcpu, struct kvm_run *run, int in, kvm_x86_ops->skip_emulated_instruction(vcpu); for (i = 0; i < nr_pages; ++i) { - down_read(¤t->mm->mmap_sem); + down_read(&vcpu->kvm->slots_lock); page = gva_to_page(vcpu, address + i * PAGE_SIZE); vcpu->arch.pio.guest_pages[i] = page; - up_read(¤t->mm->mmap_sem); + up_read(&vcpu->kvm->slots_lock); if (!page) { kvm_inject_gp(vcpu, 0); free_pio_guest_pages(vcpu); @@ -2478,8 +2489,9 @@ static void vapic_enter(struct kvm_vcpu *vcpu) down_read(¤t->mm->mmap_sem); page = gfn_to_page(vcpu->kvm, apic->vapic_addr >> PAGE_SHIFT); - vcpu->arch.apic->vapic_page = page; up_read(¤t->mm->mmap_sem); + + vcpu->arch.apic->vapic_page = page; } static void vapic_exit(struct kvm_vcpu *vcpu) @@ -2861,8 +2873,8 @@ int kvm_arch_vcpu_ioctl_set_sregs(struct kvm_vcpu *vcpu, kvm_x86_ops->decache_cr4_guest_bits(vcpu); mmu_reset_needed |= vcpu->arch.cr0 != sregs->cr0; - vcpu->arch.cr0 = sregs->cr0; kvm_x86_ops->set_cr0(vcpu, sregs->cr0); + vcpu->arch.cr0 = sregs->cr0; mmu_reset_needed |= vcpu->arch.cr4 != sregs->cr4; kvm_x86_ops->set_cr4(vcpu, sregs->cr4); @@ -2952,9 +2964,9 @@ int kvm_arch_vcpu_ioctl_translate(struct kvm_vcpu *vcpu, gpa_t gpa; vcpu_load(vcpu); - down_read(¤t->mm->mmap_sem); + down_read(&vcpu->kvm->slots_lock); gpa = vcpu->arch.mmu.gva_to_gpa(vcpu, vaddr); - up_read(¤t->mm->mmap_sem); + up_read(&vcpu->kvm->slots_lock); tr->physical_address = gpa; tr->valid = gpa != UNMAPPED_GVA; tr->writeable = 1; @@ -3227,11 +3239,13 @@ int kvm_arch_set_memory_region(struct kvm *kvm, */ if (!user_alloc) { if (npages && !old.rmap) { + down_write(¤t->mm->mmap_sem); memslot->userspace_addr = do_mmap(NULL, 0, npages * PAGE_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, 0); + up_write(¤t->mm->mmap_sem); if (IS_ERR((void *)memslot->userspace_addr)) return PTR_ERR((void *)memslot->userspace_addr); @@ -3239,8 +3253,10 @@ int kvm_arch_set_memory_region(struct kvm *kvm, if (!old.user_alloc && old.rmap) { int ret; + down_write(¤t->mm->mmap_sem); ret = do_munmap(current->mm, old.userspace_addr, old.npages * PAGE_SIZE); + up_write(¤t->mm->mmap_sem); if (ret < 0) printk(KERN_WARNING "kvm_vm_ioctl_set_memory_region: " diff --git a/arch/x86/lguest/boot.c b/arch/x86/lguest/boot.c index 5afdde4895dcefe823e0e500df57d977a7ffa350..a104c532ff706cb9845140421371fc208a90605b 100644 --- a/arch/x86/lguest/boot.c +++ b/arch/x86/lguest/boot.c @@ -57,6 +57,7 @@ #include #include #include +#include #include #include #include @@ -75,15 +76,6 @@ * behaving in simplified but equivalent ways. In particular, the Guest is the * same kernel as the Host (or at least, built from the same source code). :*/ -/* Declarations for definitions in lguest_guest.S */ -extern char lguest_noirq_start[], lguest_noirq_end[]; -extern const char lgstart_cli[], lgend_cli[]; -extern const char lgstart_sti[], lgend_sti[]; -extern const char lgstart_popf[], lgend_popf[]; -extern const char lgstart_pushf[], lgend_pushf[]; -extern const char lgstart_iret[], lgend_iret[]; -extern void lguest_iret(void); - struct lguest_data lguest_data = { .hcall_status = { [0 ... LHCALL_RING_SIZE-1] = 0xFF }, .noirq_start = (u32)lguest_noirq_start, @@ -92,7 +84,6 @@ struct lguest_data lguest_data = { .blocked_interrupts = { 1 }, /* Block timer interrupts */ .syscall_vec = SYSCALL_VECTOR, }; -static cycle_t clock_base; /*G:037 async_hcall() is pretty simple: I'm quite proud of it really. We have a * ring buffer of stored hypercalls which the Host will run though next time we @@ -335,8 +326,8 @@ static void lguest_cpuid(unsigned int *ax, unsigned int *bx, case 1: /* Basic feature request. */ /* We only allow kernel to see SSE3, CMPXCHG16B and SSSE3 */ *cx &= 0x00002201; - /* SSE, SSE2, FXSR, MMX, CMOV, CMPXCHG8B, FPU. */ - *dx &= 0x07808101; + /* SSE, SSE2, FXSR, MMX, CMOV, CMPXCHG8B, TSC, FPU. */ + *dx &= 0x07808111; /* The Host can do a nice optimization if it knows that the * kernel mappings (addresses above 0xC0000000 or whatever * PAGE_OFFSET is set to) haven't changed. But Linux calls @@ -603,19 +594,25 @@ static unsigned long lguest_get_wallclock(void) return lguest_data.time.tv_sec; } +/* The TSC is a Time Stamp Counter. The Host tells us what speed it runs at, + * or 0 if it's unusable as a reliable clock source. This matches what we want + * here: if we return 0 from this function, the x86 TSC clock will not register + * itself. */ +static unsigned long lguest_cpu_khz(void) +{ + return lguest_data.tsc_khz; +} + +/* If we can't use the TSC, the kernel falls back to our "lguest_clock", where + * we read the time value given to us by the Host. */ static cycle_t lguest_clock_read(void) { unsigned long sec, nsec; - /* If the Host tells the TSC speed, we can trust that. */ - if (lguest_data.tsc_khz) - return native_read_tsc(); - - /* If we can't use the TSC, we read the time value written by the Host. - * Since it's in two parts (seconds and nanoseconds), we risk reading - * it just as it's changing from 99 & 0.999999999 to 100 and 0, and - * getting 99 and 0. As Linux tends to come apart under the stress of - * time travel, we must be careful: */ + /* Since the time is in two parts (seconds and nanoseconds), we risk + * reading it just as it's changing from 99 & 0.999999999 to 100 and 0, + * and getting 99 and 0. As Linux tends to come apart under the stress + * of time travel, we must be careful: */ do { /* First we read the seconds part. */ sec = lguest_data.time.tv_sec; @@ -630,14 +627,14 @@ static cycle_t lguest_clock_read(void) /* Now if the seconds part has changed, try again. */ } while (unlikely(lguest_data.time.tv_sec != sec)); - /* Our non-TSC clock is in real nanoseconds. */ + /* Our lguest clock is in real nanoseconds. */ return sec*1000000000ULL + nsec; } -/* This is what we tell the kernel is our clocksource. */ +/* This is the fallback clocksource: lower priority than the TSC clocksource. */ static struct clocksource lguest_clock = { .name = "lguest", - .rating = 400, + .rating = 200, .read = lguest_clock_read, .mask = CLOCKSOURCE_MASK(64), .mult = 1 << 22, @@ -645,12 +642,6 @@ static struct clocksource lguest_clock = { .flags = CLOCK_SOURCE_IS_CONTINUOUS, }; -/* The "scheduler clock" is just our real clock, adjusted to start at zero */ -static unsigned long long lguest_sched_clock(void) -{ - return cyc2ns(&lguest_clock, lguest_clock_read() - clock_base); -} - /* We also need a "struct clock_event_device": Linux asks us to set it to go * off some time in the future. Actually, James Morris figured all this out, I * just applied the patch. */ @@ -720,19 +711,8 @@ static void lguest_time_init(void) /* Set up the timer interrupt (0) to go to our simple timer routine */ set_irq_handler(0, lguest_time_irq); - /* Our clock structure looks like arch/x86/kernel/tsc_32.c if we can - * use the TSC, otherwise it's a dumb nanosecond-resolution clock. - * Either way, the "rating" is set so high that it's always chosen over - * any other clocksource. */ - if (lguest_data.tsc_khz) - lguest_clock.mult = clocksource_khz2mult(lguest_data.tsc_khz, - lguest_clock.shift); - clock_base = lguest_clock_read(); clocksource_register(&lguest_clock); - /* Now we've set up our clock, we can use it as the scheduler clock */ - pv_time_ops.sched_clock = lguest_sched_clock; - /* We can't set cpumask in the initializer: damn C limitations! Set it * here and register our timer device. */ lguest_clockevent.cpumask = cpumask_of_cpu(0); @@ -1003,6 +983,7 @@ __init void lguest_init(void) /* time operations */ pv_time_ops.get_wallclock = lguest_get_wallclock; pv_time_ops.time_init = lguest_time_init; + pv_time_ops.get_cpu_khz = lguest_cpu_khz; /* Now is a good time to look at the implementations of these functions * before returning to the rest of lguest_init(). */ diff --git a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c index bb652f5a93fb9c6e73e1fa09dd97617d9c41c574..a02a14f0f324f9a3392810a46d587dfcda23a157 100644 --- a/arch/x86/mm/init_64.c +++ b/arch/x86/mm/init_64.c @@ -172,8 +172,9 @@ set_pte_phys(unsigned long vaddr, unsigned long phys, pgprot_t prot) } /* - * The head.S code sets up the kernel high mapping from: - * __START_KERNEL_map to __START_KERNEL_map + KERNEL_TEXT_SIZE + * The head.S code sets up the kernel high mapping: + * + * from __START_KERNEL_map to __START_KERNEL_map + size (== _end-_text) * * phys_addr holds the negative offset to the kernel, which is added * to the compile time generated pmds. This results in invalid pmds up @@ -515,14 +516,6 @@ void __init mem_init(void) /* clear_bss() already clear the empty_zero_page */ - /* temporary debugging - double check it's true: */ - { - int i; - - for (i = 0; i < 1024; i++) - WARN_ON_ONCE(empty_zero_page[i]); - } - reservedpages = 0; /* this will put all low memory onto the freelists */ diff --git a/arch/x86/mm/ioremap.c b/arch/x86/mm/ioremap.c index 882328efc3dbab30920cfa041892f1e877be9a50..8fe576baa14870c225f00606c84967d2941defe8 100644 --- a/arch/x86/mm/ioremap.c +++ b/arch/x86/mm/ioremap.c @@ -134,8 +134,6 @@ static void __iomem *__ioremap(unsigned long phys_addr, unsigned long size, return NULL; } - WARN_ON_ONCE(page_is_ram(pfn)); - switch (mode) { case IOR_MODE_UNCACHED: default: @@ -162,7 +160,7 @@ static void __iomem *__ioremap(unsigned long phys_addr, unsigned long size, area->phys_addr = phys_addr; vaddr = (unsigned long) area->addr; if (ioremap_page_range(vaddr, vaddr + size, phys_addr, prot)) { - remove_vm_area((void *)(vaddr & PAGE_MASK)); + free_vm_area(area); return NULL; } diff --git a/arch/x86/mm/numa_64.c b/arch/x86/mm/numa_64.c index 59898fb0a4aa1edc115858e10de10fc9004c820e..8ccfee10f5b52258526a2942a238b135f3d75743 100644 --- a/arch/x86/mm/numa_64.c +++ b/arch/x86/mm/numa_64.c @@ -622,13 +622,17 @@ void __init init_cpu_to_node(void) int i; for (i = 0; i < NR_CPUS; i++) { + int node; u16 apicid = x86_cpu_to_apicid_init[i]; if (apicid == BAD_APICID) continue; - if (apicid_to_node[apicid] == NUMA_NO_NODE) + node = apicid_to_node[apicid]; + if (node == NUMA_NO_NODE) continue; - numa_set_node(i, apicid_to_node[apicid]); + if (!node_online(node)) + continue; + numa_set_node(i, node); } } diff --git a/arch/x86/mm/pageattr.c b/arch/x86/mm/pageattr.c index 464d8fc21ce69b67d8d8bf057f5a57ef6a84c677..14e48b5a94ba193c1cb4acc667482e05905d373e 100644 --- a/arch/x86/mm/pageattr.c +++ b/arch/x86/mm/pageattr.c @@ -44,6 +44,12 @@ static inline unsigned long highmap_end_pfn(void) #endif +#ifdef CONFIG_DEBUG_PAGEALLOC +# define debug_pagealloc 1 +#else +# define debug_pagealloc 0 +#endif + static inline int within(unsigned long addr, unsigned long start, unsigned long end) { @@ -355,45 +361,48 @@ out_unlock: static LIST_HEAD(page_pool); static unsigned long pool_size, pool_pages, pool_low; -static unsigned long pool_used, pool_failed, pool_refill; +static unsigned long pool_used, pool_failed; -static void cpa_fill_pool(void) +static void cpa_fill_pool(struct page **ret) { - struct page *p; gfp_t gfp = GFP_KERNEL; + unsigned long flags; + struct page *p; - /* Do not allocate from interrupt context */ - if (in_irq() || irqs_disabled()) - return; /* - * Check unlocked. I does not matter when we have one more - * page in the pool. The bit lock avoids recursive pool - * allocations: + * Avoid recursion (on debug-pagealloc) and also signal + * our priority to get to these pagetables: */ - if (pool_pages >= pool_size || test_and_set_bit_lock(0, &pool_refill)) + if (current->flags & PF_MEMALLOC) return; + current->flags |= PF_MEMALLOC; -#ifdef CONFIG_DEBUG_PAGEALLOC /* - * We could do: - * gfp = in_atomic() ? GFP_ATOMIC : GFP_KERNEL; - * but this fails on !PREEMPT kernels + * Allocate atomically from atomic contexts: */ - gfp = GFP_ATOMIC | __GFP_NORETRY | __GFP_NOWARN; -#endif + if (in_atomic() || irqs_disabled() || debug_pagealloc) + gfp = GFP_ATOMIC | __GFP_NORETRY | __GFP_NOWARN; - while (pool_pages < pool_size) { + while (pool_pages < pool_size || (ret && !*ret)) { p = alloc_pages(gfp, 0); if (!p) { pool_failed++; break; } - spin_lock_irq(&pgd_lock); + /* + * If the call site needs a page right now, provide it: + */ + if (ret && !*ret) { + *ret = p; + continue; + } + spin_lock_irqsave(&pgd_lock, flags); list_add(&p->lru, &page_pool); pool_pages++; - spin_unlock_irq(&pgd_lock); + spin_unlock_irqrestore(&pgd_lock, flags); } - clear_bit_unlock(0, &pool_refill); + + current->flags &= ~PF_MEMALLOC; } #define SHIFT_MB (20 - PAGE_SHIFT) @@ -414,11 +423,15 @@ void __init cpa_init(void) * GiB. Shift MiB to Gib and multiply the result by * POOL_PAGES_PER_GB: */ - gb = ((si.totalram >> SHIFT_MB) + ROUND_MB_GB) >> SHIFT_MB_GB; - pool_size = POOL_PAGES_PER_GB * gb; + if (debug_pagealloc) { + gb = ((si.totalram >> SHIFT_MB) + ROUND_MB_GB) >> SHIFT_MB_GB; + pool_size = POOL_PAGES_PER_GB * gb; + } else { + pool_size = 1; + } pool_low = pool_size; - cpa_fill_pool(); + cpa_fill_pool(NULL); printk(KERN_DEBUG "CPA: page pool initialized %lu of %lu pages preallocated\n", pool_pages, pool_size); @@ -440,16 +453,20 @@ static int split_large_page(pte_t *kpte, unsigned long address) spin_lock_irqsave(&pgd_lock, flags); if (list_empty(&page_pool)) { spin_unlock_irqrestore(&pgd_lock, flags); - return -ENOMEM; + base = NULL; + cpa_fill_pool(&base); + if (!base) + return -ENOMEM; + spin_lock_irqsave(&pgd_lock, flags); + } else { + base = list_first_entry(&page_pool, struct page, lru); + list_del(&base->lru); + pool_pages--; + + if (pool_pages < pool_low) + pool_low = pool_pages; } - base = list_first_entry(&page_pool, struct page, lru); - list_del(&base->lru); - pool_pages--; - - if (pool_pages < pool_low) - pool_low = pool_pages; - /* * Check for races, another CPU might have split this page * up for us already: @@ -734,7 +751,8 @@ static int change_page_attr_set_clr(unsigned long addr, int numpages, cpa_flush_all(cache); out: - cpa_fill_pool(); + cpa_fill_pool(NULL); + return ret; } @@ -897,7 +915,7 @@ void kernel_map_pages(struct page *page, int numpages, int enable) * Try to refill the page pool here. We can do this only after * the tlb flush. */ - cpa_fill_pool(); + cpa_fill_pool(NULL); } #ifdef CONFIG_HIBERNATION diff --git a/arch/x86/mm/pgtable_32.c b/arch/x86/mm/pgtable_32.c index 73aba7125203764b41a3cb3af48ac6d5d5cee5a4..2f9e9afcb9f4270d6e5f5a496f33999d6ce8298b 100644 --- a/arch/x86/mm/pgtable_32.c +++ b/arch/x86/mm/pgtable_32.c @@ -342,12 +342,16 @@ static void pgd_mop_up_pmds(struct mm_struct *mm, pgd_t *pgdp) pgd_t *pgd_alloc(struct mm_struct *mm) { - pgd_t *pgd = quicklist_alloc(0, GFP_KERNEL, pgd_ctor); + pgd_t *pgd = (pgd_t *)__get_free_page(GFP_KERNEL | __GFP_ZERO); - mm->pgd = pgd; /* so that alloc_pd can use it */ + /* so that alloc_pd can use it */ + mm->pgd = pgd; + if (pgd) + pgd_ctor(pgd); if (pgd && !pgd_prepopulate_pmd(mm, pgd)) { - quicklist_free(0, pgd_dtor, pgd); + pgd_dtor(pgd); + free_page((unsigned long)pgd); pgd = NULL; } @@ -357,12 +361,8 @@ pgd_t *pgd_alloc(struct mm_struct *mm) void pgd_free(struct mm_struct *mm, pgd_t *pgd) { pgd_mop_up_pmds(mm, pgd); - quicklist_free(0, pgd_dtor, pgd); -} - -void check_pgt_cache(void) -{ - quicklist_trim(0, pgd_dtor, 25, 16); + pgd_dtor(pgd); + free_page((unsigned long)pgd); } void __pte_free_tlb(struct mmu_gather *tlb, struct page *pte) diff --git a/arch/x86/pci/pcbios.c b/arch/x86/pci/pcbios.c index 10ac8c316c468b1161d5b5e17f88b60ddceba2ff..2f7109ac4c151046a812faaeed2f276718bc1857 100644 --- a/arch/x86/pci/pcbios.c +++ b/arch/x86/pci/pcbios.c @@ -198,6 +198,11 @@ static int pci_bios_read(unsigned int seg, unsigned int bus, "b" (bx), "D" ((long)reg), "S" (&pci_indirect)); + /* + * Zero-extend the result beyond 8 bits, do not trust the + * BIOS having done it: + */ + *value &= 0xff; break; case 2: __asm__("lcall *(%%esi); cld\n\t" @@ -210,6 +215,11 @@ static int pci_bios_read(unsigned int seg, unsigned int bus, "b" (bx), "D" ((long)reg), "S" (&pci_indirect)); + /* + * Zero-extend the result beyond 16 bits, do not trust the + * BIOS having done it: + */ + *value &= 0xffff; break; case 4: __asm__("lcall *(%%esi); cld\n\t" diff --git a/arch/x86/vdso/Makefile b/arch/x86/vdso/Makefile index f385a4b4a484e36d3262ca154b96dcfd596b7510..0a8f4742ef519f2aa2b43d7318fed524eede671d 100644 --- a/arch/x86/vdso/Makefile +++ b/arch/x86/vdso/Makefile @@ -50,7 +50,9 @@ obj-$(VDSO64-y) += vdso-syms.lds sed-vdsosym := -e 's/^00*/0/' \ -e 's/^\([0-9a-fA-F]*\) . \(VDSO[a-zA-Z0-9_]*\)$$/\2 = 0x\1;/p' quiet_cmd_vdsosym = VDSOSYM $@ - cmd_vdsosym = $(NM) $< | sed -n $(sed-vdsosym) | LC_ALL=C sort > $@ +define cmd_vdsosym + $(NM) $< | LC_ALL=C sed -n $(sed-vdsosym) | LC_ALL=C sort > $@ +endef $(obj)/%-syms.lds: $(obj)/%.so.dbg FORCE $(call if_changed,vdsosym) diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c index 49e5358f481a2fdcb5e7eec2c2d4087ec256786a..8b9ee27805fdd10be4cb19b082131745d1c4a670 100644 --- a/arch/x86/xen/enlighten.c +++ b/arch/x86/xen/enlighten.c @@ -153,6 +153,7 @@ static void xen_cpuid(unsigned int *ax, unsigned int *bx, if (*ax == 1) maskedx = ~((1 << X86_FEATURE_APIC) | /* disable APIC */ (1 << X86_FEATURE_ACPI) | /* disable ACPI */ + (1 << X86_FEATURE_SEP) | /* disable SEP */ (1 << X86_FEATURE_ACC)); /* thermal monitoring */ asm(XEN_EMULATE_PREFIX "cpuid" diff --git a/arch/x86/xen/setup.c b/arch/x86/xen/setup.c index 3bad4773a2f3c36ff0eb8694014a010cfd903fb8..2341492bf7a056743097e06bfabd0b8c01f7436f 100644 --- a/arch/x86/xen/setup.c +++ b/arch/x86/xen/setup.c @@ -38,7 +38,8 @@ char * __init xen_memory_setup(void) unsigned long max_pfn = xen_start_info->nr_pages; e820.nr_map = 0; - add_memory_region(0, PFN_PHYS(max_pfn), E820_RAM); + add_memory_region(0, LOWMEMSIZE(), E820_RAM); + add_memory_region(HIGH_MEMORY, PFN_PHYS(max_pfn)-HIGH_MEMORY, E820_RAM); return "Xen"; } diff --git a/block/blk-barrier.c b/block/blk-barrier.c index 6901eedeffce83bd3db09b3d0b802da6486994b4..55c5f1fc4f1fcd90c1f119a9bc0f58b46f446e83 100644 --- a/block/blk-barrier.c +++ b/block/blk-barrier.c @@ -259,8 +259,11 @@ int blk_do_ordered(struct request_queue *q, struct request **rqp) static void bio_end_empty_barrier(struct bio *bio, int err) { - if (err) + if (err) { + if (err == -EOPNOTSUPP) + set_bit(BIO_EOPNOTSUPP, &bio->bi_flags); clear_bit(BIO_UPTODATE, &bio->bi_flags); + } complete(bio->bi_private); } @@ -309,7 +312,9 @@ int blkdev_issue_flush(struct block_device *bdev, sector_t *error_sector) *error_sector = bio->bi_sector; ret = 0; - if (!bio_flagged(bio, BIO_UPTODATE)) + if (bio_flagged(bio, BIO_EOPNOTSUPP)) + ret = -EOPNOTSUPP; + else if (!bio_flagged(bio, BIO_UPTODATE)) ret = -EIO; bio_put(bio); diff --git a/block/blk-core.c b/block/blk-core.c index 775c8516abf5fe5b083416e3be5f07e969ec6f93..2a438a93f7233d8bc2033956f23e3f436f0e1f44 100644 --- a/block/blk-core.c +++ b/block/blk-core.c @@ -127,7 +127,6 @@ void rq_init(struct request_queue *q, struct request *rq) rq->nr_hw_segments = 0; rq->ioprio = 0; rq->special = NULL; - rq->raw_data_len = 0; rq->buffer = NULL; rq->tag = -1; rq->errors = 0; @@ -135,6 +134,7 @@ void rq_init(struct request_queue *q, struct request *rq) rq->cmd_len = 0; memset(rq->cmd, 0, sizeof(rq->cmd)); rq->data_len = 0; + rq->extra_len = 0; rq->sense_len = 0; rq->data = NULL; rq->sense = NULL; @@ -424,7 +424,6 @@ void blk_put_queue(struct request_queue *q) { kobject_put(&q->kobj); } -EXPORT_SYMBOL(blk_put_queue); void blk_cleanup_queue(struct request_queue *q) { @@ -592,7 +591,6 @@ int blk_get_queue(struct request_queue *q) return 1; } -EXPORT_SYMBOL(blk_get_queue); static inline void blk_free_request(struct request_queue *q, struct request *rq) { @@ -1768,6 +1766,7 @@ static inline void __end_request(struct request *rq, int uptodate, /** * blk_rq_bytes - Returns bytes left to complete in the entire request + * @rq: the request being processed **/ unsigned int blk_rq_bytes(struct request *rq) { @@ -1780,6 +1779,7 @@ EXPORT_SYMBOL_GPL(blk_rq_bytes); /** * blk_rq_cur_bytes - Returns bytes left to complete in the current segment + * @rq: the request being processed **/ unsigned int blk_rq_cur_bytes(struct request *rq) { @@ -2016,7 +2016,6 @@ void blk_rq_bio_prep(struct request_queue *q, struct request *rq, rq->hard_cur_sectors = rq->current_nr_sectors; rq->hard_nr_sectors = rq->nr_sectors = bio_sectors(bio); rq->buffer = bio_data(bio); - rq->raw_data_len = bio->bi_size; rq->data_len = bio->bi_size; rq->bio = rq->biotail = bio; diff --git a/block/blk-map.c b/block/blk-map.c index 09f7fd0bcb73000d4899f2b96dc088d852d41aab..c07d9c8317f4c055d3821302c22df20cf2627195 100644 --- a/block/blk-map.c +++ b/block/blk-map.c @@ -19,7 +19,6 @@ int blk_rq_append_bio(struct request_queue *q, struct request *rq, rq->biotail->bi_next = bio; rq->biotail = bio; - rq->raw_data_len += bio->bi_size; rq->data_len += bio->bi_size; } return 0; @@ -44,6 +43,7 @@ static int __blk_rq_map_user(struct request_queue *q, struct request *rq, void __user *ubuf, unsigned int len) { unsigned long uaddr; + unsigned int alignment; struct bio *bio, *orig_bio; int reading, ret; @@ -54,8 +54,8 @@ static int __blk_rq_map_user(struct request_queue *q, struct request *rq, * direct dma. else, set up kernel bounce buffers */ uaddr = (unsigned long) ubuf; - if (!(uaddr & queue_dma_alignment(q)) && - !(len & queue_dma_alignment(q))) + alignment = queue_dma_alignment(q) | q->dma_pad_mask; + if (!(uaddr & alignment) && !(len & alignment)) bio = bio_map_user(q, NULL, uaddr, len, reading); else bio = bio_copy_user(q, uaddr, len, reading); @@ -142,20 +142,22 @@ int blk_rq_map_user(struct request_queue *q, struct request *rq, /* * __blk_rq_map_user() copies the buffers if starting address - * or length isn't aligned. As the copied buffer is always - * page aligned, we know that there's enough room for padding. - * Extend the last bio and update rq->data_len accordingly. + * or length isn't aligned to dma_pad_mask. As the copied + * buffer is always page aligned, we know that there's enough + * room for padding. Extend the last bio and update + * rq->data_len accordingly. * * On unmap, bio_uncopy_user() will use unmodified * bio_map_data pointed to by bio->bi_private. */ - if (len & queue_dma_alignment(q)) { - unsigned int pad_len = (queue_dma_alignment(q) & ~len) + 1; - struct bio *bio = rq->biotail; + if (len & q->dma_pad_mask) { + unsigned int pad_len = (q->dma_pad_mask & ~len) + 1; + struct bio *tail = rq->biotail; - bio->bi_io_vec[bio->bi_vcnt - 1].bv_len += pad_len; - bio->bi_size += pad_len; - rq->data_len += pad_len; + tail->bi_io_vec[tail->bi_vcnt - 1].bv_len += pad_len; + tail->bi_size += pad_len; + + rq->extra_len += pad_len; } rq->buffer = rq->data = NULL; @@ -215,7 +217,6 @@ int blk_rq_map_user_iov(struct request_queue *q, struct request *rq, rq->buffer = rq->data = NULL; return 0; } -EXPORT_SYMBOL(blk_rq_map_user_iov); /** * blk_rq_unmap_user - unmap a request with user data diff --git a/block/blk-merge.c b/block/blk-merge.c index 7506c4fe0264bd6038d24108f5438fea42478508..0f58616bcd7f183514c43eb913f0e0c23c855215 100644 --- a/block/blk-merge.c +++ b/block/blk-merge.c @@ -231,7 +231,7 @@ new_segment: ((unsigned long)q->dma_drain_buffer) & (PAGE_SIZE - 1)); nsegs++; - rq->data_len += q->dma_drain_size; + rq->extra_len += q->dma_drain_size; } if (sg) diff --git a/block/blk-settings.c b/block/blk-settings.c index 9a8ffdd0ce3d4a570deac27111b5559ccf6b1714..1344a0ea5cc6c00a89ef9536cbbfda7183d2b28b 100644 --- a/block/blk-settings.c +++ b/block/blk-settings.c @@ -140,7 +140,7 @@ void blk_queue_bounce_limit(struct request_queue *q, u64 dma_addr) /* Assume anything <= 4GB can be handled by IOMMU. Actually some IOMMUs can handle everything, but I don't know of a way to test this here. */ - if (b_pfn < (min_t(u64, 0xffffffff, BLK_BOUNCE_HIGH) >> PAGE_SHIFT)) + if (b_pfn <= (min_t(u64, 0xffffffff, BLK_BOUNCE_HIGH) >> PAGE_SHIFT)) dma = 1; q->bounce_pfn = max_low_pfn; #else @@ -293,8 +293,24 @@ void blk_queue_stack_limits(struct request_queue *t, struct request_queue *b) EXPORT_SYMBOL(blk_queue_stack_limits); /** - * blk_queue_dma_drain - Set up a drain buffer for excess dma. + * blk_queue_dma_pad - set pad mask + * @q: the request queue for the device + * @mask: pad mask + * + * Set pad mask. Direct IO requests are padded to the mask specified. * + * Appending pad buffer to a request modifies ->data_len such that it + * includes the pad buffer. The original requested data length can be + * obtained using blk_rq_raw_data_len(). + **/ +void blk_queue_dma_pad(struct request_queue *q, unsigned int mask) +{ + q->dma_pad_mask = mask; +} +EXPORT_SYMBOL(blk_queue_dma_pad); + +/** + * blk_queue_dma_drain - Set up a drain buffer for excess dma. * @q: the request queue for the device * @dma_drain_needed: fn which returns non-zero if drain is necessary * @buf: physically contiguous buffer @@ -316,7 +332,7 @@ EXPORT_SYMBOL(blk_queue_stack_limits); * device can support otherwise there won't be room for the drain * buffer. */ -extern int blk_queue_dma_drain(struct request_queue *q, +int blk_queue_dma_drain(struct request_queue *q, dma_drain_needed_fn *dma_drain_needed, void *buf, unsigned int size) { diff --git a/block/blk-tag.c b/block/blk-tag.c index a8c37d4bbb32064f8a7f4dcd39734ccb403c2fae..4780a46ce2346898953085a6f4079c7734dcbaf7 100644 --- a/block/blk-tag.c +++ b/block/blk-tag.c @@ -6,6 +6,8 @@ #include #include +#include "blk.h" + /** * blk_queue_find_tag - find a request by its tag and queue * @q: The request queue for the device diff --git a/block/blk.h b/block/blk.h index ec898dd0c65c466ca2854ee987d7f178a83458d5..ec9120fb789a67c560df9c12e38dc8e0cc46a008 100644 --- a/block/blk.h +++ b/block/blk.h @@ -32,6 +32,8 @@ void blk_recalc_rq_sectors(struct request *rq, int nsect); void blk_queue_congestion_threshold(struct request_queue *q); +int blk_dev_init(void); + /* * Return the threshold (number of used requests) at which the queue is * considered to be congested. It include a little hysteresis to keep the diff --git a/block/bsg.c b/block/bsg.c index 7f3c09549e4be7364be012d834450215bcd7096f..8917c5174dc2646c5ad8d4d67eb67529a98783f5 100644 --- a/block/bsg.c +++ b/block/bsg.c @@ -437,14 +437,14 @@ static int blk_complete_sgv4_hdr_rq(struct request *rq, struct sg_io_v4 *hdr, } if (rq->next_rq) { - hdr->dout_resid = rq->raw_data_len; - hdr->din_resid = rq->next_rq->raw_data_len; + hdr->dout_resid = rq->data_len; + hdr->din_resid = rq->next_rq->data_len; blk_rq_unmap_user(bidi_bio); blk_put_request(rq->next_rq); } else if (rq_data_dir(rq) == READ) - hdr->din_resid = rq->raw_data_len; + hdr->din_resid = rq->data_len; else - hdr->dout_resid = rq->raw_data_len; + hdr->dout_resid = rq->data_len; /* * If the request generated a negative error number, return it diff --git a/block/genhd.c b/block/genhd.c index 53f2238e69c8494997ad8660a9f9fbdb298ab33a..00da5219ee37c02a066d45e6ceefa65d9606d5e6 100644 --- a/block/genhd.c +++ b/block/genhd.c @@ -17,11 +17,15 @@ #include #include +#include "blk.h" + static DEFINE_MUTEX(block_class_lock); #ifndef CONFIG_SYSFS_DEPRECATED struct kobject *block_depr; #endif +static struct device_type disk_type; + /* * Can be deleted altogether. Later. * @@ -346,8 +350,6 @@ const struct seq_operations partitions_op = { #endif -extern int blk_dev_init(void); - static struct kobject *base_probe(dev_t devt, int *part, void *data) { if (request_module("block-major-%d-%d", MAJOR(devt), MINOR(devt)) > 0) @@ -358,7 +360,9 @@ static struct kobject *base_probe(dev_t devt, int *part, void *data) static int __init genhd_device_init(void) { - class_register(&block_class); + int error = class_register(&block_class); + if (unlikely(error)) + return error; bdev_map = kobj_map_init(base_probe, &block_class_lock); blk_dev_init(); @@ -502,7 +506,7 @@ struct class block_class = { .name = "block", }; -struct device_type disk_type = { +static struct device_type disk_type = { .name = "disk", .groups = disk_attr_groups, .release = disk_release, @@ -632,12 +636,14 @@ static void media_change_notify_thread(struct work_struct *work) put_device(gd->driverfs_dev); } +#if 0 void genhd_media_change_notify(struct gendisk *disk) { get_device(disk->driverfs_dev); schedule_work(&disk->async_notify); } EXPORT_SYMBOL_GPL(genhd_media_change_notify); +#endif /* 0 */ dev_t blk_lookup_devt(const char *name) { diff --git a/block/scsi_ioctl.c b/block/scsi_ioctl.c index e993cac4911dbc9f3d3c0249f3912285ea61e581..a2c3a936ebf98e1481346e76a7ef268b803c76ea 100644 --- a/block/scsi_ioctl.c +++ b/block/scsi_ioctl.c @@ -266,7 +266,7 @@ static int blk_complete_sghdr_rq(struct request *rq, struct sg_io_hdr *hdr, hdr->info = 0; if (hdr->masked_status || hdr->host_status || hdr->driver_status) hdr->info |= SG_INFO_CHECK; - hdr->resid = rq->raw_data_len; + hdr->resid = rq->data_len; hdr->sb_len_wr = 0; if (rq->sense_len && hdr->sbp) { @@ -528,8 +528,8 @@ static int __blk_send_generic(struct request_queue *q, struct gendisk *bd_disk, rq = blk_get_request(q, WRITE, __GFP_WAIT); rq->cmd_type = REQ_TYPE_BLOCK_PC; rq->data = NULL; - rq->raw_data_len = 0; rq->data_len = 0; + rq->extra_len = 0; rq->timeout = BLK_DEFAULT_SG_TIMEOUT; memset(rq->cmd, 0, sizeof(rq->cmd)); rq->cmd[0] = cmd; diff --git a/crypto/Kconfig b/crypto/Kconfig index 898acc5c1967b5d700901a8acf9a15b00f079049..69f1be6816f7cc6740ff206cf173e12feac7450e 100644 --- a/crypto/Kconfig +++ b/crypto/Kconfig @@ -575,6 +575,7 @@ config CRYPTO_TEST config CRYPTO_AUTHENC tristate "Authenc support" select CRYPTO_AEAD + select CRYPTO_BLKCIPHER select CRYPTO_MANAGER select CRYPTO_HASH help diff --git a/crypto/Makefile b/crypto/Makefile index 48c7583799541045751655aa6de6af80fed70ae9..7cf36253a75ee3b898e61c24a7a9c524cb524495 100644 --- a/crypto/Makefile +++ b/crypto/Makefile @@ -12,9 +12,9 @@ obj-$(CONFIG_CRYPTO_AEAD) += aead.o crypto_blkcipher-objs := ablkcipher.o crypto_blkcipher-objs += blkcipher.o +crypto_blkcipher-objs += chainiv.o +crypto_blkcipher-objs += eseqiv.o obj-$(CONFIG_CRYPTO_BLKCIPHER) += crypto_blkcipher.o -obj-$(CONFIG_CRYPTO_BLKCIPHER) += chainiv.o -obj-$(CONFIG_CRYPTO_BLKCIPHER) += eseqiv.o obj-$(CONFIG_CRYPTO_SEQIV) += seqiv.o crypto_hash-objs := hash.o diff --git a/crypto/ablkcipher.c b/crypto/ablkcipher.c index 3bcb099b4a85bd779d752f7d42868c48cb07d87a..94140b3756fcd598d49179deac34ed5a80a83ed5 100644 --- a/crypto/ablkcipher.c +++ b/crypto/ablkcipher.c @@ -341,6 +341,3 @@ err: return ERR_PTR(err); } EXPORT_SYMBOL_GPL(crypto_alloc_ablkcipher); - -MODULE_LICENSE("GPL"); -MODULE_DESCRIPTION("Asynchronous block chaining cipher type"); diff --git a/crypto/async_tx/async_memcpy.c b/crypto/async_tx/async_memcpy.c index 0f6282207b3223baf9910332681fd5b3eb98295c..84caa4efc0d447516ce269ed91e85b3ad4f4c85b 100644 --- a/crypto/async_tx/async_memcpy.c +++ b/crypto/async_tx/async_memcpy.c @@ -66,11 +66,11 @@ async_memcpy(struct page *dest, struct page *src, unsigned int dest_offset, } if (tx) { - pr_debug("%s: (async) len: %zu\n", __FUNCTION__, len); + pr_debug("%s: (async) len: %zu\n", __func__, len); async_tx_submit(chan, tx, flags, depend_tx, cb_fn, cb_param); } else { void *dest_buf, *src_buf; - pr_debug("%s: (sync) len: %zu\n", __FUNCTION__, len); + pr_debug("%s: (sync) len: %zu\n", __func__, len); /* wait for any prerequisite operations */ if (depend_tx) { @@ -80,7 +80,7 @@ async_memcpy(struct page *dest, struct page *src, unsigned int dest_offset, BUG_ON(depend_tx->ack); if (dma_wait_for_async_tx(depend_tx) == DMA_ERROR) panic("%s: DMA_ERROR waiting for depend_tx\n", - __FUNCTION__); + __func__); } dest_buf = kmap_atomic(dest, KM_USER0) + dest_offset; diff --git a/crypto/async_tx/async_memset.c b/crypto/async_tx/async_memset.c index 09c0e83664bc23f4465cad7b6c477ca76b1d46da..f5ff3906b035d52d5c6b28949ca6470b46d60f88 100644 --- a/crypto/async_tx/async_memset.c +++ b/crypto/async_tx/async_memset.c @@ -63,11 +63,11 @@ async_memset(struct page *dest, int val, unsigned int offset, } if (tx) { - pr_debug("%s: (async) len: %zu\n", __FUNCTION__, len); + pr_debug("%s: (async) len: %zu\n", __func__, len); async_tx_submit(chan, tx, flags, depend_tx, cb_fn, cb_param); } else { /* run the memset synchronously */ void *dest_buf; - pr_debug("%s: (sync) len: %zu\n", __FUNCTION__, len); + pr_debug("%s: (sync) len: %zu\n", __func__, len); dest_buf = (void *) (((char *) page_address(dest)) + offset); @@ -79,7 +79,7 @@ async_memset(struct page *dest, int val, unsigned int offset, BUG_ON(depend_tx->ack); if (dma_wait_for_async_tx(depend_tx) == DMA_ERROR) panic("%s: DMA_ERROR waiting for depend_tx\n", - __FUNCTION__); + __func__); } memset(dest_buf, val, len); diff --git a/crypto/async_tx/async_tx.c b/crypto/async_tx/async_tx.c index 562882189de589587c475b25770ff46b90eac6ac..2be3bae899301efa2fde18d972c436260b39a864 100644 --- a/crypto/async_tx/async_tx.c +++ b/crypto/async_tx/async_tx.c @@ -472,11 +472,11 @@ async_trigger_callback(enum async_tx_flags flags, tx = NULL; if (tx) { - pr_debug("%s: (async)\n", __FUNCTION__); + pr_debug("%s: (async)\n", __func__); async_tx_submit(chan, tx, flags, depend_tx, cb_fn, cb_param); } else { - pr_debug("%s: (sync)\n", __FUNCTION__); + pr_debug("%s: (sync)\n", __func__); /* wait for any prerequisite operations */ if (depend_tx) { @@ -486,7 +486,7 @@ async_trigger_callback(enum async_tx_flags flags, BUG_ON(depend_tx->ack); if (dma_wait_for_async_tx(depend_tx) == DMA_ERROR) panic("%s: DMA_ERROR waiting for depend_tx\n", - __FUNCTION__); + __func__); } async_tx_sync_epilog(flags, depend_tx, cb_fn, cb_param); diff --git a/crypto/async_tx/async_xor.c b/crypto/async_tx/async_xor.c index 2259a4ff15cb9ce7253f4cc5d4f6132586fe762d..7a9db353f1986fca6a4d778dd1e05977ff0fb790 100644 --- a/crypto/async_tx/async_xor.c +++ b/crypto/async_tx/async_xor.c @@ -47,7 +47,7 @@ do_async_xor(struct dma_device *device, int i; unsigned long dma_prep_flags = cb_fn ? DMA_PREP_INTERRUPT : 0; - pr_debug("%s: len: %zu\n", __FUNCTION__, len); + pr_debug("%s: len: %zu\n", __func__, len); dma_dest = dma_map_page(device->dev, dest, offset, len, DMA_FROM_DEVICE); @@ -86,7 +86,7 @@ do_sync_xor(struct page *dest, struct page **src_list, unsigned int offset, void *_dest; int i; - pr_debug("%s: len: %zu\n", __FUNCTION__, len); + pr_debug("%s: len: %zu\n", __func__, len); /* reuse the 'src_list' array to convert to buffer pointers */ for (i = 0; i < src_cnt; i++) @@ -196,7 +196,7 @@ async_xor(struct page *dest, struct page **src_list, unsigned int offset, DMA_ERROR) panic("%s: DMA_ERROR waiting for " "depend_tx\n", - __FUNCTION__); + __func__); } do_sync_xor(dest, &src_list[src_off], offset, @@ -276,7 +276,7 @@ async_xor_zero_sum(struct page *dest, struct page **src_list, unsigned long dma_prep_flags = cb_fn ? DMA_PREP_INTERRUPT : 0; int i; - pr_debug("%s: (async) len: %zu\n", __FUNCTION__, len); + pr_debug("%s: (async) len: %zu\n", __func__, len); for (i = 0; i < src_cnt; i++) dma_src[i] = dma_map_page(device->dev, src_list[i], @@ -299,7 +299,7 @@ async_xor_zero_sum(struct page *dest, struct page **src_list, } else { unsigned long xor_flags = flags; - pr_debug("%s: (sync) len: %zu\n", __FUNCTION__, len); + pr_debug("%s: (sync) len: %zu\n", __func__, len); xor_flags |= ASYNC_TX_XOR_DROP_DST; xor_flags &= ~ASYNC_TX_ACK; @@ -310,7 +310,7 @@ async_xor_zero_sum(struct page *dest, struct page **src_list, if (tx) { if (dma_wait_for_async_tx(tx) == DMA_ERROR) panic("%s: DMA_ERROR waiting for tx\n", - __FUNCTION__); + __func__); async_tx_ack(tx); } diff --git a/crypto/blkcipher.c b/crypto/blkcipher.c index 4a7e65c4df4dc3ac6af007efa1d136e1232be053..185f955fb0d7f79770b7765660bd1a9cbbcfab2e 100644 --- a/crypto/blkcipher.c +++ b/crypto/blkcipher.c @@ -696,5 +696,34 @@ void skcipher_geniv_exit(struct crypto_tfm *tfm) } EXPORT_SYMBOL_GPL(skcipher_geniv_exit); +static int __init blkcipher_module_init(void) +{ + int err; + + err = chainiv_module_init(); + if (err) + goto out; + + err = eseqiv_module_init(); + if (err) + goto eseqiv_err; + +out: + return err; + +eseqiv_err: + chainiv_module_exit(); + goto out; +} + +static void __exit blkcipher_module_exit(void) +{ + eseqiv_module_exit(); + chainiv_module_exit(); +} + +module_init(blkcipher_module_init); +module_exit(blkcipher_module_exit); + MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("Generic block chaining cipher type"); diff --git a/crypto/chainiv.c b/crypto/chainiv.c index d17fa0454dc30259baa69a111ff60f929311894e..6da3f577e4db1d6c81c95b1fc9bb3eb7a5424df4 100644 --- a/crypto/chainiv.c +++ b/crypto/chainiv.c @@ -314,18 +314,12 @@ static struct crypto_template chainiv_tmpl = { .module = THIS_MODULE, }; -static int __init chainiv_module_init(void) +int __init chainiv_module_init(void) { return crypto_register_template(&chainiv_tmpl); } -static void __exit chainiv_module_exit(void) +void chainiv_module_exit(void) { crypto_unregister_template(&chainiv_tmpl); } - -module_init(chainiv_module_init); -module_exit(chainiv_module_exit); - -MODULE_LICENSE("GPL"); -MODULE_DESCRIPTION("Chain IV Generator"); diff --git a/crypto/digest.c b/crypto/digest.c index 6fd43bddd545e788546d868b097e3ad811867e76..b526cc348b79313e21bea12808976f392b5505a8 100644 --- a/crypto/digest.c +++ b/crypto/digest.c @@ -21,6 +21,8 @@ #include #include +#include "internal.h" + static int init(struct hash_desc *desc) { struct crypto_tfm *tfm = crypto_hash_tfm(desc->tfm); diff --git a/crypto/eseqiv.c b/crypto/eseqiv.c index eb90d27ae118e0b79bc2d24daf94b476a4f89075..b14f14e314b6cf3ada4bc0694aa9f5f364ab73e7 100644 --- a/crypto/eseqiv.c +++ b/crypto/eseqiv.c @@ -247,18 +247,12 @@ static struct crypto_template eseqiv_tmpl = { .module = THIS_MODULE, }; -static int __init eseqiv_module_init(void) +int __init eseqiv_module_init(void) { return crypto_register_template(&eseqiv_tmpl); } -static void __exit eseqiv_module_exit(void) +void __exit eseqiv_module_exit(void) { crypto_unregister_template(&eseqiv_tmpl); } - -module_init(eseqiv_module_init); -module_exit(eseqiv_module_exit); - -MODULE_LICENSE("GPL"); -MODULE_DESCRIPTION("Encrypted Sequence Number IV Generator"); diff --git a/crypto/xcbc.c b/crypto/xcbc.c index 86727403e5ab1f0e5e7bbd15f3703046f4390548..2feb0f239c38179c579cbead01e7fe168d4ea0dd 100644 --- a/crypto/xcbc.c +++ b/crypto/xcbc.c @@ -124,6 +124,11 @@ static int crypto_xcbc_digest_update2(struct hash_desc *pdesc, unsigned int offset = sg[i].offset; unsigned int slen = sg[i].length; + if (unlikely(slen > nbytes)) + slen = nbytes; + + nbytes -= slen; + while (slen > 0) { unsigned int len = min(slen, ((unsigned int)(PAGE_SIZE)) - offset); char *p = crypto_kmap(pg, 0) + offset; @@ -177,7 +182,6 @@ static int crypto_xcbc_digest_update2(struct hash_desc *pdesc, offset = 0; pg++; } - nbytes-=sg[i].length; i++; } while (nbytes>0); diff --git a/crypto/xts.c b/crypto/xts.c index 8eb08bfaf7c099cc5b4dd0e06cbd48eb4f381c26..d87b0f3102c322337e38a8c67b8d7b0f0a69e661 100644 --- a/crypto/xts.c +++ b/crypto/xts.c @@ -77,16 +77,16 @@ static int setkey(struct crypto_tfm *parent, const u8 *key, } struct sinfo { - be128 t; + be128 *t; struct crypto_tfm *tfm; void (*fn)(struct crypto_tfm *, u8 *, const u8 *); }; static inline void xts_round(struct sinfo *s, void *dst, const void *src) { - be128_xor(dst, &s->t, src); /* PP <- T xor P */ + be128_xor(dst, s->t, src); /* PP <- T xor P */ s->fn(s->tfm, dst, dst); /* CC <- E(Key1,PP) */ - be128_xor(dst, dst, &s->t); /* C <- T xor CC */ + be128_xor(dst, dst, s->t); /* C <- T xor CC */ } static int crypt(struct blkcipher_desc *d, @@ -101,7 +101,6 @@ static int crypt(struct blkcipher_desc *d, .tfm = crypto_cipher_tfm(ctx->child), .fn = fn }; - be128 *iv; u8 *wsrc; u8 *wdst; @@ -109,20 +108,20 @@ static int crypt(struct blkcipher_desc *d, if (!w->nbytes) return err; + s.t = (be128 *)w->iv; avail = w->nbytes; wsrc = w->src.virt.addr; wdst = w->dst.virt.addr; /* calculate first value of T */ - iv = (be128 *)w->iv; - tw(crypto_cipher_tfm(ctx->tweak), (void *)&s.t, w->iv); + tw(crypto_cipher_tfm(ctx->tweak), w->iv, w->iv); goto first; for (;;) { do { - gf128mul_x_ble(&s.t, &s.t); + gf128mul_x_ble(s.t, s.t); first: xts_round(&s, wdst, wsrc); diff --git a/drivers/acorn/char/defkeymap-l7200.c b/drivers/acorn/char/defkeymap-l7200.c index 28a5fbc6aa1a456d335852914aa24ea48880c74b..93d80a1c36f994d4a98fcdba821acd142fe6d07b 100644 --- a/drivers/acorn/char/defkeymap-l7200.c +++ b/drivers/acorn/char/defkeymap-l7200.c @@ -347,40 +347,40 @@ char *func_table[MAX_NR_FUNC] = { }; struct kbdiacruc accent_table[MAX_DIACR] = { - {'`', 'A', '\300'}, {'`', 'a', '\340'}, - {'\'', 'A', '\301'}, {'\'', 'a', '\341'}, - {'^', 'A', '\302'}, {'^', 'a', '\342'}, - {'~', 'A', '\303'}, {'~', 'a', '\343'}, - {'"', 'A', '\304'}, {'"', 'a', '\344'}, - {'O', 'A', '\305'}, {'o', 'a', '\345'}, - {'0', 'A', '\305'}, {'0', 'a', '\345'}, - {'A', 'A', '\305'}, {'a', 'a', '\345'}, - {'A', 'E', '\306'}, {'a', 'e', '\346'}, - {',', 'C', '\307'}, {',', 'c', '\347'}, - {'`', 'E', '\310'}, {'`', 'e', '\350'}, - {'\'', 'E', '\311'}, {'\'', 'e', '\351'}, - {'^', 'E', '\312'}, {'^', 'e', '\352'}, - {'"', 'E', '\313'}, {'"', 'e', '\353'}, - {'`', 'I', '\314'}, {'`', 'i', '\354'}, - {'\'', 'I', '\315'}, {'\'', 'i', '\355'}, - {'^', 'I', '\316'}, {'^', 'i', '\356'}, - {'"', 'I', '\317'}, {'"', 'i', '\357'}, - {'-', 'D', '\320'}, {'-', 'd', '\360'}, - {'~', 'N', '\321'}, {'~', 'n', '\361'}, - {'`', 'O', '\322'}, {'`', 'o', '\362'}, - {'\'', 'O', '\323'}, {'\'', 'o', '\363'}, - {'^', 'O', '\324'}, {'^', 'o', '\364'}, - {'~', 'O', '\325'}, {'~', 'o', '\365'}, - {'"', 'O', '\326'}, {'"', 'o', '\366'}, - {'/', 'O', '\330'}, {'/', 'o', '\370'}, - {'`', 'U', '\331'}, {'`', 'u', '\371'}, - {'\'', 'U', '\332'}, {'\'', 'u', '\372'}, - {'^', 'U', '\333'}, {'^', 'u', '\373'}, - {'"', 'U', '\334'}, {'"', 'u', '\374'}, - {'\'', 'Y', '\335'}, {'\'', 'y', '\375'}, - {'T', 'H', '\336'}, {'t', 'h', '\376'}, - {'s', 's', '\337'}, {'"', 'y', '\377'}, - {'s', 'z', '\337'}, {'i', 'j', '\377'}, + {'`', 'A', 0300}, {'`', 'a', 0340}, + {'\'', 'A', 0301}, {'\'', 'a', 0341}, + {'^', 'A', 0302}, {'^', 'a', 0342}, + {'~', 'A', 0303}, {'~', 'a', 0343}, + {'"', 'A', 0304}, {'"', 'a', 0344}, + {'O', 'A', 0305}, {'o', 'a', 0345}, + {'0', 'A', 0305}, {'0', 'a', 0345}, + {'A', 'A', 0305}, {'a', 'a', 0345}, + {'A', 'E', 0306}, {'a', 'e', 0346}, + {',', 'C', 0307}, {',', 'c', 0347}, + {'`', 'E', 0310}, {'`', 'e', 0350}, + {'\'', 'E', 0311}, {'\'', 'e', 0351}, + {'^', 'E', 0312}, {'^', 'e', 0352}, + {'"', 'E', 0313}, {'"', 'e', 0353}, + {'`', 'I', 0314}, {'`', 'i', 0354}, + {'\'', 'I', 0315}, {'\'', 'i', 0355}, + {'^', 'I', 0316}, {'^', 'i', 0356}, + {'"', 'I', 0317}, {'"', 'i', 0357}, + {'-', 'D', 0320}, {'-', 'd', 0360}, + {'~', 'N', 0321}, {'~', 'n', 0361}, + {'`', 'O', 0322}, {'`', 'o', 0362}, + {'\'', 'O', 0323}, {'\'', 'o', 0363}, + {'^', 'O', 0324}, {'^', 'o', 0364}, + {'~', 'O', 0325}, {'~', 'o', 0365}, + {'"', 'O', 0326}, {'"', 'o', 0366}, + {'/', 'O', 0330}, {'/', 'o', 0370}, + {'`', 'U', 0331}, {'`', 'u', 0371}, + {'\'', 'U', 0332}, {'\'', 'u', 0372}, + {'^', 'U', 0333}, {'^', 'u', 0373}, + {'"', 'U', 0334}, {'"', 'u', 0374}, + {'\'', 'Y', 0335}, {'\'', 'y', 0375}, + {'T', 'H', 0336}, {'t', 'h', 0376}, + {'s', 's', 0337}, {'"', 'y', 0377}, + {'s', 'z', 0337}, {'i', 'j', 0377}, }; unsigned int accent_table_size = 68; diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig index f688c214be0c67110df1d039be5566d3c7f59bfe..b4f5e85428294eed21bb8f342af5a7a7c3fac87b 100644 --- a/drivers/acpi/Kconfig +++ b/drivers/acpi/Kconfig @@ -283,34 +283,22 @@ config ACPI_TOSHIBA If you have a legacy free Toshiba laptop (such as the Libretto L1 series), say Y. -config ACPI_CUSTOM_DSDT - bool "Include Custom DSDT" +config ACPI_CUSTOM_DSDT_FILE + string "Custom DSDT Table file to include" + default "" depends on !STANDALONE - default n help This option supports a custom DSDT by linking it into the kernel. See Documentation/acpi/dsdt-override.txt - If unsure, say N. - -config ACPI_CUSTOM_DSDT_FILE - string "Custom DSDT Table file to include" - depends on ACPI_CUSTOM_DSDT - default "" - help Enter the full path name to the file which includes the AmlCode declaration. -config ACPI_CUSTOM_DSDT_INITRD - bool "Read Custom DSDT from initramfs" - depends on BLK_DEV_INITRD - default n - help - This option supports a custom DSDT by optionally loading it from initrd. - See Documentation/acpi/dsdt-override.txt + If unsure, don't enter a file name. - If you are not using this feature now, but may use it later, - it is safe to say Y here. +config ACPI_CUSTOM_DSDT + bool + default ACPI_CUSTOM_DSDT_FILE != "" config ACPI_BLACKLIST_YEAR int "Disable ACPI for systems before Jan 1st this year" if X86_32 diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c index ce3c0a2cbac4dc81e9c5ff2712b100ec8a942b46..5b6760e0f9571d20e34dcb47346c354ad6dff116 100644 --- a/drivers/acpi/bus.c +++ b/drivers/acpi/bus.c @@ -776,7 +776,7 @@ static int __init acpi_init(void) acpi_kobj = kobject_create_and_add("acpi", firmware_kobj); if (!acpi_kobj) { - printk(KERN_WARNING "%s: kset create error\n", __FUNCTION__); + printk(KERN_WARNING "%s: kset create error\n", __func__); acpi_kobj = NULL; } diff --git a/drivers/acpi/button.c b/drivers/acpi/button.c index 24a7865a57cb2515c740fbee5d9b038ca3927630..6c5da83cdb6807be36db10253bd42c2c332c0402 100644 --- a/drivers/acpi/button.c +++ b/drivers/acpi/button.c @@ -449,6 +449,7 @@ static int acpi_button_add(struct acpi_device *device) input->phys = button->phys; input->id.bustype = BUS_HOST; input->id.product = button->type; + input->dev.parent = &device->dev; switch (button->type) { case ACPI_BUTTON_TYPE_POWER: diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index caf873c14bfb244a89ba9c322ada05c3c2b3c04e..e7e197e3a4ffce2151d61f5e6b48f89c98087dfa 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c @@ -129,6 +129,7 @@ static struct acpi_ec { struct mutex lock; wait_queue_head_t wait; struct list_head list; + atomic_t irq_count; u8 handlers_installed; } *boot_ec, *first_ec; @@ -181,6 +182,8 @@ static int acpi_ec_wait(struct acpi_ec *ec, enum ec_event event, int force_poll) { int ret = 0; + atomic_set(&ec->irq_count, 0); + if (unlikely(event == ACPI_EC_EVENT_OBF_1 && test_bit(EC_FLAGS_NO_OBF1_GPE, &ec->flags))) force_poll = 1; @@ -227,6 +230,7 @@ static int acpi_ec_wait(struct acpi_ec *ec, enum ec_event event, int force_poll) while (time_before(jiffies, delay)) { if (acpi_ec_check_status(ec, event)) goto end; + msleep(5); } } pr_err(PREFIX "acpi_ec_wait timeout," @@ -529,6 +533,13 @@ static u32 acpi_ec_gpe_handler(void *data) struct acpi_ec *ec = data; pr_debug(PREFIX "~~~> interrupt\n"); + atomic_inc(&ec->irq_count); + if (atomic_read(&ec->irq_count) > 5) { + pr_err(PREFIX "GPE storm detected, disabling EC GPE\n"); + acpi_disable_gpe(NULL, ec->gpe, ACPI_ISR); + clear_bit(EC_FLAGS_GPE_MODE, &ec->flags); + return ACPI_INTERRUPT_HANDLED; + } clear_bit(EC_FLAGS_WAIT_GPE, &ec->flags); if (test_bit(EC_FLAGS_GPE_MODE, &ec->flags)) wake_up(&ec->wait); @@ -943,11 +954,7 @@ int __init acpi_ec_ecdt_probe(void) boot_ec->command_addr = ecdt_ptr->control.address; boot_ec->data_addr = ecdt_ptr->data.address; boot_ec->gpe = ecdt_ptr->gpe; - if (ACPI_FAILURE(acpi_get_handle(NULL, ecdt_ptr->id, - &boot_ec->handle))) { - pr_info("Failed to locate handle for boot EC\n"); - boot_ec->handle = ACPI_ROOT_OBJECT; - } + boot_ec->handle = ACPI_ROOT_OBJECT; } else { /* This workaround is needed only on some broken machines, * which require early EC, but fail to provide ECDT */ diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c index 8edba7b678eb9d33493f422472dc16fdb4c6f84e..a697fb6cf050e8096d8be177f8303c5ed4290995 100644 --- a/drivers/acpi/osl.c +++ b/drivers/acpi/osl.c @@ -91,10 +91,6 @@ static DEFINE_SPINLOCK(acpi_res_lock); #define OSI_STRING_LENGTH_MAX 64 /* arbitrary */ static char osi_additional_string[OSI_STRING_LENGTH_MAX]; -#ifdef CONFIG_ACPI_CUSTOM_DSDT_INITRD -static int acpi_no_initrd_override; -#endif - /* * "Ode to _OSI(Linux)" * @@ -324,67 +320,6 @@ acpi_os_predefined_override(const struct acpi_predefined_names *init_val, return AE_OK; } -#ifdef CONFIG_ACPI_CUSTOM_DSDT_INITRD -static struct acpi_table_header *acpi_find_dsdt_initrd(void) -{ - struct file *firmware_file; - mm_segment_t oldfs; - unsigned long len, len2; - struct acpi_table_header *dsdt_buffer, *ret = NULL; - struct kstat stat; - char *ramfs_dsdt_name = "/DSDT.aml"; - - printk(KERN_INFO PREFIX "Checking initramfs for custom DSDT\n"); - - /* - * Never do this at home, only the user-space is allowed to open a file. - * The clean way would be to use the firmware loader. - * But this code must be run before there is any userspace available. - * A static/init firmware infrastructure doesn't exist yet... - */ - if (vfs_stat(ramfs_dsdt_name, &stat) < 0) - return ret; - - len = stat.size; - /* check especially against empty files */ - if (len <= 4) { - printk(KERN_ERR PREFIX "Failed: DSDT only %lu bytes.\n", len); - return ret; - } - - firmware_file = filp_open(ramfs_dsdt_name, O_RDONLY, 0); - if (IS_ERR(firmware_file)) { - printk(KERN_ERR PREFIX "Failed to open %s.\n", ramfs_dsdt_name); - return ret; - } - - dsdt_buffer = kmalloc(len, GFP_ATOMIC); - if (!dsdt_buffer) { - printk(KERN_ERR PREFIX "Failed to allocate %lu bytes.\n", len); - goto err; - } - - oldfs = get_fs(); - set_fs(KERNEL_DS); - len2 = vfs_read(firmware_file, (char __user *)dsdt_buffer, len, - &firmware_file->f_pos); - set_fs(oldfs); - if (len2 < len) { - printk(KERN_ERR PREFIX "Failed to read %lu bytes from %s.\n", - len, ramfs_dsdt_name); - ACPI_FREE(dsdt_buffer); - goto err; - } - - printk(KERN_INFO PREFIX "Found %lu byte DSDT in %s.\n", - len, ramfs_dsdt_name); - ret = dsdt_buffer; -err: - filp_close(firmware_file, NULL); - return ret; -} -#endif - acpi_status acpi_os_table_override(struct acpi_table_header * existing_table, struct acpi_table_header ** new_table) @@ -397,16 +332,6 @@ acpi_os_table_override(struct acpi_table_header * existing_table, #ifdef CONFIG_ACPI_CUSTOM_DSDT if (strncmp(existing_table->signature, "DSDT", 4) == 0) *new_table = (struct acpi_table_header *)AmlCode; -#endif -#ifdef CONFIG_ACPI_CUSTOM_DSDT_INITRD - if ((strncmp(existing_table->signature, "DSDT", 4) == 0) && - !acpi_no_initrd_override) { - struct acpi_table_header *initrd_table; - - initrd_table = acpi_find_dsdt_initrd(); - if (initrd_table) - *new_table = initrd_table; - } #endif if (*new_table != NULL) { printk(KERN_WARNING PREFIX "Override [%4.4s-%8.8s], " @@ -418,15 +343,6 @@ acpi_os_table_override(struct acpi_table_header * existing_table, return AE_OK; } -#ifdef CONFIG_ACPI_CUSTOM_DSDT_INITRD -static int __init acpi_no_initrd_override_setup(char *s) -{ - acpi_no_initrd_override = 1; - return 1; -} -__setup("acpi_no_initrd_override", acpi_no_initrd_override_setup); -#endif - static irqreturn_t acpi_irq(int irq, void *dev_id) { u32 handled; @@ -1237,7 +1153,7 @@ int acpi_check_resource_conflict(struct resource *res) if (clash) { if (acpi_enforce_resources != ENFORCE_RESOURCES_NO) { - printk(KERN_INFO "%sACPI: %s resource %s [0x%llx-0x%llx]" + printk("%sACPI: %s resource %s [0x%llx-0x%llx]" " conflicts with ACPI region %s" " [0x%llx-0x%llx]\n", acpi_enforce_resources == ENFORCE_RESOURCES_LAX diff --git a/drivers/acpi/pci_irq.c b/drivers/acpi/pci_irq.c index 7f19859580c7efcbdf9675d6be44436573d0e8d6..7af414a3c63ee89f3ec0624d256437f9d74a2825 100644 --- a/drivers/acpi/pci_irq.c +++ b/drivers/acpi/pci_irq.c @@ -25,6 +25,7 @@ */ +#include #include #include #include @@ -76,6 +77,101 @@ static struct acpi_prt_entry *acpi_pci_irq_find_prt_entry(int segment, return NULL; } +/* http://bugzilla.kernel.org/show_bug.cgi?id=4773 */ +static struct dmi_system_id medion_md9580[] = { + { + .ident = "Medion MD9580-F laptop", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "MEDIONNB"), + DMI_MATCH(DMI_PRODUCT_NAME, "A555"), + }, + }, + { } +}; + +/* http://bugzilla.kernel.org/show_bug.cgi?id=5044 */ +static struct dmi_system_id dell_optiplex[] = { + { + .ident = "Dell Optiplex GX1", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell Computer Corporation"), + DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex GX1 600S+"), + }, + }, + { } +}; + +/* http://bugzilla.kernel.org/show_bug.cgi?id=10138 */ +static struct dmi_system_id hp_t5710[] = { + { + .ident = "HP t5710", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), + DMI_MATCH(DMI_PRODUCT_NAME, "hp t5000 series"), + DMI_MATCH(DMI_BOARD_NAME, "098Ch"), + }, + }, + { } +}; + +struct prt_quirk { + struct dmi_system_id *system; + unsigned int segment; + unsigned int bus; + unsigned int device; + unsigned char pin; + char *source; /* according to BIOS */ + char *actual_source; +}; + +/* + * These systems have incorrect _PRT entries. The BIOS claims the PCI + * interrupt at the listed segment/bus/device/pin is connected to the first + * link device, but it is actually connected to the second. + */ +static struct prt_quirk prt_quirks[] = { + { medion_md9580, 0, 0, 9, 'A', + "\\_SB_.PCI0.ISA.LNKA", + "\\_SB_.PCI0.ISA.LNKB"}, + { dell_optiplex, 0, 0, 0xd, 'A', + "\\_SB_.LNKB", + "\\_SB_.LNKA"}, + { hp_t5710, 0, 0, 1, 'A', + "\\_SB_.PCI0.LNK1", + "\\_SB_.PCI0.LNK3"}, +}; + +static void +do_prt_fixups(struct acpi_prt_entry *entry, struct acpi_pci_routing_table *prt) +{ + int i; + struct prt_quirk *quirk; + + for (i = 0; i < ARRAY_SIZE(prt_quirks); i++) { + quirk = &prt_quirks[i]; + + /* All current quirks involve link devices, not GSIs */ + if (!prt->source) + continue; + + if (dmi_check_system(quirk->system) && + entry->id.segment == quirk->segment && + entry->id.bus == quirk->bus && + entry->id.device == quirk->device && + entry->pin + 'A' == quirk->pin && + !strcmp(prt->source, quirk->source) && + strlen(prt->source) >= strlen(quirk->actual_source)) { + printk(KERN_WARNING PREFIX "firmware reports " + "%04x:%02x:%02x[%c] connected to %s; " + "changing to %s\n", + entry->id.segment, entry->id.bus, + entry->id.device, 'A' + entry->pin, + prt->source, quirk->actual_source); + strcpy(prt->source, quirk->actual_source); + } + } +} + static int acpi_pci_irq_add_entry(acpi_handle handle, int segment, int bus, struct acpi_pci_routing_table *prt) @@ -96,6 +192,8 @@ acpi_pci_irq_add_entry(acpi_handle handle, entry->id.function = prt->address & 0xFFFF; entry->pin = prt->pin; + do_prt_fixups(entry, prt); + /* * Type 1: Dynamic * --------------- diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c index f14ff1ffab29c24156d2cff92d75340460337745..c3fed31166b552761f2bb9c3b26ef2b7c3e47592 100644 --- a/drivers/acpi/pci_root.c +++ b/drivers/acpi/pci_root.c @@ -184,7 +184,7 @@ static void acpi_pci_bridge_scan(struct acpi_device *device) } } -static int acpi_pci_root_add(struct acpi_device *device) +static int __devinit acpi_pci_root_add(struct acpi_device *device) { int result = 0; struct acpi_pci_root *root = NULL; diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c index a3cc8a98255cf724248c7efbf749a912bc9ef4f1..36a68fa114e3e7b97b85585e40e3f74929110d79 100644 --- a/drivers/acpi/processor_core.c +++ b/drivers/acpi/processor_core.c @@ -840,17 +840,19 @@ static int is_processor_present(acpi_handle handle) status = acpi_evaluate_integer(handle, "_STA", NULL, &sta); - /* - * if a processor object does not have an _STA object, - * OSPM assumes that the processor is present. - */ - if (status == AE_NOT_FOUND) - return 1; if (ACPI_SUCCESS(status) && (sta & ACPI_STA_DEVICE_PRESENT)) return 1; - ACPI_EXCEPTION((AE_INFO, status, "Processor Device is not present")); + /* + * _STA is mandatory for a processor that supports hot plug + */ + if (status == AE_NOT_FOUND) + ACPI_DEBUG_PRINT((ACPI_DB_INFO, + "Processor does not support hot plug\n")); + else + ACPI_EXCEPTION((AE_INFO, status, + "Processor Device is not present")); return 0; } @@ -886,8 +888,8 @@ int acpi_processor_device_add(acpi_handle handle, struct acpi_device **device) return 0; } -static void -acpi_processor_hotplug_notify(acpi_handle handle, u32 event, void *data) +static void __ref acpi_processor_hotplug_notify(acpi_handle handle, + u32 event, void *data) { struct acpi_processor *pr; struct acpi_device *device = NULL; @@ -897,9 +899,10 @@ acpi_processor_hotplug_notify(acpi_handle handle, u32 event, void *data) switch (event) { case ACPI_NOTIFY_BUS_CHECK: case ACPI_NOTIFY_DEVICE_CHECK: - printk("Processor driver received %s event\n", + ACPI_DEBUG_PRINT((ACPI_DB_INFO, + "Processor driver received %s event\n", (event == ACPI_NOTIFY_BUS_CHECK) ? - "ACPI_NOTIFY_BUS_CHECK" : "ACPI_NOTIFY_DEVICE_CHECK"); + "ACPI_NOTIFY_BUS_CHECK" : "ACPI_NOTIFY_DEVICE_CHECK")); if (!is_processor_present(handle)) break; diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index 3fac011f9cf964082b463ef20913542ca9bce173..57570ac47803f4d590da5f8254547119ab10aec3 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c @@ -609,7 +609,8 @@ acpi_bus_get_ejd(acpi_handle handle, acpi_handle *ejd) status = acpi_evaluate_object(handle, "_EJD", NULL, &buffer); if (ACPI_SUCCESS(status)) { obj = buffer.pointer; - status = acpi_get_handle(NULL, obj->string.pointer, ejd); + status = acpi_get_handle(ACPI_ROOT_OBJECT, obj->string.pointer, + ejd); kfree(buffer.pointer); } return status; @@ -966,7 +967,7 @@ static void acpi_device_set_id(struct acpi_device *device, case ACPI_BUS_TYPE_DEVICE: status = acpi_get_object_info(handle, &buffer); if (ACPI_FAILURE(status)) { - printk(KERN_ERR PREFIX "%s: Error reading device info\n", __FUNCTION__); + printk(KERN_ERR PREFIX "%s: Error reading device info\n", __func__); return; } diff --git a/drivers/acpi/sleep/main.c b/drivers/acpi/sleep/main.c index 293a1cbb47c05776b543894bc32ee145de0153b7..d2f71a54726c5c988bdc680a892599966e0744df 100644 --- a/drivers/acpi/sleep/main.c +++ b/drivers/acpi/sleep/main.c @@ -504,7 +504,7 @@ static void acpi_power_off_prepare(void) static void acpi_power_off(void) { /* acpi_sleep_prepare(ACPI_STATE_S5) should have already been called */ - printk("%s called\n", __FUNCTION__); + printk("%s called\n", __func__); local_irq_disable(); acpi_enable_wakeup_device(ACPI_STATE_S5); acpi_enter_sleep_state(ACPI_STATE_S5); diff --git a/drivers/acpi/system.c b/drivers/acpi/system.c index 55cf4c05bb74edc7714ddb4a000b729395feb291..4749f379a915a4c4f6308f21b21de4205f399387 100644 --- a/drivers/acpi/system.c +++ b/drivers/acpi/system.c @@ -319,7 +319,7 @@ void acpi_irq_stats_init(void) goto fail; for (i = 0; i < num_counters; ++i) { - char buffer[10]; + char buffer[12]; char *name; if (i < num_gpes) diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c index 8d4b79b4f933c631281e23ce8b602e3bcbbf3d9f..c4e00ac8ea855ac980b05b5e6bf60b8e52b5016b 100644 --- a/drivers/acpi/thermal.c +++ b/drivers/acpi/thermal.c @@ -879,6 +879,8 @@ static void acpi_thermal_check(void *data) } /* sys I/F for generic thermal sysfs support */ +#define KELVIN_TO_MILLICELSIUS(t) (t * 100 - 273200) + static int thermal_get_temp(struct thermal_zone_device *thermal, char *buf) { struct acpi_thermal *tz = thermal->devdata; @@ -886,7 +888,7 @@ static int thermal_get_temp(struct thermal_zone_device *thermal, char *buf) if (!tz) return -EINVAL; - return sprintf(buf, "%ld\n", KELVIN_TO_CELSIUS(tz->temperature)); + return sprintf(buf, "%ld\n", KELVIN_TO_MILLICELSIUS(tz->temperature)); } static const char enabled[] = "kernel"; @@ -980,21 +982,21 @@ static int thermal_get_trip_temp(struct thermal_zone_device *thermal, if (tz->trips.critical.flags.valid) { if (!trip) - return sprintf(buf, "%ld\n", KELVIN_TO_CELSIUS( + return sprintf(buf, "%ld\n", KELVIN_TO_MILLICELSIUS( tz->trips.critical.temperature)); trip--; } if (tz->trips.hot.flags.valid) { if (!trip) - return sprintf(buf, "%ld\n", KELVIN_TO_CELSIUS( + return sprintf(buf, "%ld\n", KELVIN_TO_MILLICELSIUS( tz->trips.hot.temperature)); trip--; } if (tz->trips.passive.flags.valid) { if (!trip) - return sprintf(buf, "%ld\n", KELVIN_TO_CELSIUS( + return sprintf(buf, "%ld\n", KELVIN_TO_MILLICELSIUS( tz->trips.passive.temperature)); trip--; } @@ -1002,7 +1004,7 @@ static int thermal_get_trip_temp(struct thermal_zone_device *thermal, for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE && tz->trips.active[i].flags.valid; i++) { if (!trip) - return sprintf(buf, "%ld\n", KELVIN_TO_CELSIUS( + return sprintf(buf, "%ld\n", KELVIN_TO_MILLICELSIUS( tz->trips.active[i].temperature)); trip--; } diff --git a/drivers/acpi/toshiba_acpi.c b/drivers/acpi/toshiba_acpi.c index 9e8c20c6a0b7243e708876a4dfffa30dd8f47506..0a43c8e0eff323fe55f29846695c71e750ffedf3 100644 --- a/drivers/acpi/toshiba_acpi.c +++ b/drivers/acpi/toshiba_acpi.c @@ -99,6 +99,13 @@ MODULE_LICENSE("GPL"); #define HCI_VIDEO_OUT_CRT 0x2 #define HCI_VIDEO_OUT_TV 0x4 +static const struct acpi_device_id toshiba_device_ids[] = { + {"TOS6200", 0}, + {"TOS1900", 0}, + {"", 0}, +}; +MODULE_DEVICE_TABLE(acpi, toshiba_device_ids); + /* utility */ diff --git a/drivers/acpi/utilities/utdebug.c b/drivers/acpi/utilities/utdebug.c index c7e128e5369b2d5853acf17e8ff109dc2d1fe021..7361204b1eef2114ca22a65902dae2b6ae75276f 100644 --- a/drivers/acpi/utilities/utdebug.c +++ b/drivers/acpi/utilities/utdebug.c @@ -109,7 +109,7 @@ void acpi_ut_track_stack_ptr(void) * RETURN: Updated pointer to the function name * * DESCRIPTION: Remove the "Acpi" prefix from the function name, if present. - * This allows compiler macros such as __FUNCTION__ to be used + * This allows compiler macros such as __func__ to be used * with no change to the debug output. * ******************************************************************************/ diff --git a/drivers/acpi/utilities/utobject.c b/drivers/acpi/utilities/utobject.c index 76ee766c84f948ed2d8749f06486338a792f7e05..e08b3fa6639f593c0c1d4c893d591be26d36243c 100644 --- a/drivers/acpi/utilities/utobject.c +++ b/drivers/acpi/utilities/utobject.c @@ -432,7 +432,7 @@ acpi_ut_get_simple_object_size(union acpi_operand_object *internal_object, * element -- which is legal) */ if (!internal_object) { - *obj_length = 0; + *obj_length = sizeof(union acpi_object); return_ACPI_STATUS(AE_OK); } diff --git a/drivers/acpi/utils.c b/drivers/acpi/utils.c index eba55b7d6c95ad63479430fc3c63c57dce3a5b19..44ea60cf21c09c00adc1135394decbb4af2faa1d 100644 --- a/drivers/acpi/utils.c +++ b/drivers/acpi/utils.c @@ -407,6 +407,12 @@ acpi_evaluate_reference(acpi_handle handle, break; } + if (!element->reference.handle) { + printk(KERN_WARNING PREFIX "Invalid reference in" + " package %s\n", pathname); + status = AE_NULL_ENTRY; + break; + } /* Get the acpi_handle. */ list->handles[i] = element->reference.handle; diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c index 12cce69b5441e98a7bd8da23031dc250daaa88f1..1bc0c74f2755d1c3bbf8264c01a27dbd208ce227 100644 --- a/drivers/acpi/video.c +++ b/drivers/acpi/video.c @@ -713,7 +713,7 @@ static void acpi_video_device_find_cap(struct acpi_video_device *device) kfree(obj); - if (device->cap._BCL && device->cap._BCM && device->cap._BQC && max_level > 0){ + if (device->cap._BCL && device->cap._BCM && max_level > 0) { int result; static int count = 0; char *name; @@ -1201,7 +1201,7 @@ static int acpi_video_bus_ROM_seq_show(struct seq_file *seq, void *offset) if (!video) goto end; - printk(KERN_INFO PREFIX "Please implement %s\n", __FUNCTION__); + printk(KERN_INFO PREFIX "Please implement %s\n", __func__); seq_printf(seq, "\n"); end: diff --git a/drivers/acpi/wmi.c b/drivers/acpi/wmi.c index efacc9f8bfe31a0b9c84b5aec4ea11c8285dc527..c33b1c6e93b11b4b975c859de79abbf63b797593 100644 --- a/drivers/acpi/wmi.c +++ b/drivers/acpi/wmi.c @@ -293,7 +293,7 @@ struct acpi_buffer *out) { struct guid_block *block = NULL; struct wmi_block *wblock = NULL; - acpi_handle handle; + acpi_handle handle, wc_handle; acpi_status status, wc_status = AE_ERROR; struct acpi_object_list input, wc_input; union acpi_object wc_params[1], wq_params[1]; @@ -338,8 +338,10 @@ struct acpi_buffer *out) * expensive, but have no corresponding WCxx method. So we * should not fail if this happens. */ - wc_status = acpi_evaluate_object(handle, wc_method, - &wc_input, NULL); + wc_status = acpi_get_handle(handle, wc_method, &wc_handle); + if (ACPI_SUCCESS(wc_status)) + wc_status = acpi_evaluate_object(handle, wc_method, + &wc_input, NULL); } strcpy(method, "WQ"); @@ -351,7 +353,7 @@ struct acpi_buffer *out) * If ACPI_WMI_EXPENSIVE, call the relevant WCxx method, even if * the WQxx method failed - we should disable collection anyway. */ - if ((block->flags & ACPI_WMI_EXPENSIVE) && wc_status) { + if ((block->flags & ACPI_WMI_EXPENSIVE) && ACPI_SUCCESS(wc_status)) { wc_params[0].integer.value = 0; status = acpi_evaluate_object(handle, wc_method, &wc_input, NULL); diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig index ba8f7f4dfa1182cb1619007ea628c4ba08ade5e1..e469647330deb228b5c3ba24bca6fd35b9247a5c 100644 --- a/drivers/ata/Kconfig +++ b/drivers/ata/Kconfig @@ -538,6 +538,15 @@ config PATA_RADISYS If unsure, say N. +config PATA_RB500 + tristate "RouterBoard 500 PATA CompactFlash support" + depends on MIKROTIK_RB500 + help + This option enables support for the RouterBoard 500 + PATA CompactFlash controller. + + If unsure, say N. + config PATA_RZ1000 tristate "PC Tech RZ1000 PATA support" depends on PCI diff --git a/drivers/ata/Makefile b/drivers/ata/Makefile index 701651e37c89910f7b7b22e3cc0ae0c4b389f2ff..0511e6f0bb581be847fd1987a4b16019d0d11f73 100644 --- a/drivers/ata/Makefile +++ b/drivers/ata/Makefile @@ -55,6 +55,7 @@ obj-$(CONFIG_PATA_PDC2027X) += pata_pdc2027x.o obj-$(CONFIG_PATA_PDC_OLD) += pata_pdc202xx_old.o obj-$(CONFIG_PATA_QDI) += pata_qdi.o obj-$(CONFIG_PATA_RADISYS) += pata_radisys.o +obj-$(CONFIG_PATA_RB500) += pata_rb500_cf.o obj-$(CONFIG_PATA_RZ1000) += pata_rz1000.o obj-$(CONFIG_PATA_SC1200) += pata_sc1200.o obj-$(CONFIG_PATA_SERVERWORKS) += pata_serverworks.o diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index 1db93b6190744015e251c5d428b58a762cf3c39a..17ee6ed985d9198ad356a9b68efebf406a4b11f6 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c @@ -49,6 +49,10 @@ #define DRV_NAME "ahci" #define DRV_VERSION "3.0" +static int ahci_skip_host_reset; +module_param_named(skip_host_reset, ahci_skip_host_reset, int, 0444); +MODULE_PARM_DESC(skip_host_reset, "skip global host reset (0=don't skip, 1=skip)"); + static int ahci_enable_alpm(struct ata_port *ap, enum link_pm policy); static void ahci_disable_alpm(struct ata_port *ap); @@ -186,6 +190,7 @@ enum { AHCI_HFLAG_NO_MSI = (1 << 5), /* no PCI MSI */ AHCI_HFLAG_NO_PMP = (1 << 6), /* no PMP */ AHCI_HFLAG_NO_HOTPLUG = (1 << 7), /* ignore PxSERR.DIAG.N */ + AHCI_HFLAG_SECT255 = (1 << 8), /* max 255 sectors */ /* ap->flags bits */ @@ -255,6 +260,7 @@ static void ahci_vt8251_error_handler(struct ata_port *ap); static void ahci_p5wdh_error_handler(struct ata_port *ap); static void ahci_post_internal_cmd(struct ata_queued_cmd *qc); static int ahci_port_resume(struct ata_port *ap); +static void ahci_dev_config(struct ata_device *dev); static unsigned int ahci_fill_sg(struct ata_queued_cmd *qc, void *cmd_tbl); static void ahci_fill_cmd_slot(struct ahci_port_priv *pp, unsigned int tag, u32 opts); @@ -294,6 +300,8 @@ static const struct ata_port_operations ahci_ops = { .check_altstatus = ahci_check_status, .dev_select = ata_noop_dev_select, + .dev_config = ahci_dev_config, + .tf_read = ahci_tf_read, .qc_defer = sata_pmp_qc_defer_cmd_switch, @@ -425,7 +433,7 @@ static const struct ata_port_info ahci_port_info[] = { /* board_ahci_sb600 */ { AHCI_HFLAGS (AHCI_HFLAG_IGN_SERR_INTERNAL | - AHCI_HFLAG_32BIT_ONLY | AHCI_HFLAG_NO_PMP), + AHCI_HFLAG_SECT255 | AHCI_HFLAG_NO_PMP), .flags = AHCI_FLAG_COMMON, .link_flags = AHCI_LFLAG_COMMON, .pio_mask = 0x1f, /* pio0-4 */ @@ -563,6 +571,18 @@ static const struct pci_device_id ahci_pci_tbl[] = { { PCI_VDEVICE(NVIDIA, 0x0abd), board_ahci }, /* MCP79 */ { PCI_VDEVICE(NVIDIA, 0x0abe), board_ahci }, /* MCP79 */ { PCI_VDEVICE(NVIDIA, 0x0abf), board_ahci }, /* MCP79 */ + { PCI_VDEVICE(NVIDIA, 0x0bc8), board_ahci }, /* MCP7B */ + { PCI_VDEVICE(NVIDIA, 0x0bc9), board_ahci }, /* MCP7B */ + { PCI_VDEVICE(NVIDIA, 0x0bca), board_ahci }, /* MCP7B */ + { PCI_VDEVICE(NVIDIA, 0x0bcb), board_ahci }, /* MCP7B */ + { PCI_VDEVICE(NVIDIA, 0x0bcc), board_ahci }, /* MCP7B */ + { PCI_VDEVICE(NVIDIA, 0x0bcd), board_ahci }, /* MCP7B */ + { PCI_VDEVICE(NVIDIA, 0x0bce), board_ahci }, /* MCP7B */ + { PCI_VDEVICE(NVIDIA, 0x0bcf), board_ahci }, /* MCP7B */ + { PCI_VDEVICE(NVIDIA, 0x0bd0), board_ahci }, /* MCP7B */ + { PCI_VDEVICE(NVIDIA, 0x0bd1), board_ahci }, /* MCP7B */ + { PCI_VDEVICE(NVIDIA, 0x0bd2), board_ahci }, /* MCP7B */ + { PCI_VDEVICE(NVIDIA, 0x0bd3), board_ahci }, /* MCP7B */ /* SiS */ { PCI_VDEVICE(SI, 0x1184), board_ahci }, /* SiS 966 */ @@ -571,6 +591,7 @@ static const struct pci_device_id ahci_pci_tbl[] = { /* Marvell */ { PCI_VDEVICE(MARVELL, 0x6145), board_ahci_mv }, /* 6145 */ + { PCI_VDEVICE(MARVELL, 0x6121), board_ahci_mv }, /* 6121 */ /* Generic, PCI class code for AHCI */ { PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, @@ -645,6 +666,7 @@ static void ahci_save_initial_config(struct pci_dev *pdev, void __iomem *mmio = pcim_iomap_table(pdev)[AHCI_PCI_BAR]; u32 cap, port_map; int i; + int mv; /* make sure AHCI mode is enabled before accessing CAP */ ahci_enable_ahci(mmio); @@ -668,7 +690,7 @@ static void ahci_save_initial_config(struct pci_dev *pdev, cap &= ~HOST_CAP_NCQ; } - if ((cap && HOST_CAP_PMP) && (hpriv->flags & AHCI_HFLAG_NO_PMP)) { + if ((cap & HOST_CAP_PMP) && (hpriv->flags & AHCI_HFLAG_NO_PMP)) { dev_printk(KERN_INFO, &pdev->dev, "controller can't do PMP, turning off CAP_PMP\n"); cap &= ~HOST_CAP_PMP; @@ -680,12 +702,16 @@ static void ahci_save_initial_config(struct pci_dev *pdev, * presence register, as bit 4 (counting from 0) */ if (hpriv->flags & AHCI_HFLAG_MV_PATA) { + if (pdev->device == 0x6121) + mv = 0x3; + else + mv = 0xf; dev_printk(KERN_ERR, &pdev->dev, "MV_AHCI HACK: port_map %x -> %x\n", - hpriv->port_map, - hpriv->port_map & 0xf); + port_map, + port_map & mv); - port_map &= 0xf; + port_map &= mv; } /* cross check port_map and cap.n_ports */ @@ -1072,29 +1098,35 @@ static int ahci_reset_controller(struct ata_host *host) ahci_enable_ahci(mmio); /* global controller reset */ - tmp = readl(mmio + HOST_CTL); - if ((tmp & HOST_RESET) == 0) { - writel(tmp | HOST_RESET, mmio + HOST_CTL); - readl(mmio + HOST_CTL); /* flush */ - } + if (!ahci_skip_host_reset) { + tmp = readl(mmio + HOST_CTL); + if ((tmp & HOST_RESET) == 0) { + writel(tmp | HOST_RESET, mmio + HOST_CTL); + readl(mmio + HOST_CTL); /* flush */ + } - /* reset must complete within 1 second, or - * the hardware should be considered fried. - */ - ssleep(1); + /* reset must complete within 1 second, or + * the hardware should be considered fried. + */ + ssleep(1); - tmp = readl(mmio + HOST_CTL); - if (tmp & HOST_RESET) { - dev_printk(KERN_ERR, host->dev, - "controller reset failed (0x%x)\n", tmp); - return -EIO; - } + tmp = readl(mmio + HOST_CTL); + if (tmp & HOST_RESET) { + dev_printk(KERN_ERR, host->dev, + "controller reset failed (0x%x)\n", tmp); + return -EIO; + } - /* turn on AHCI mode */ - ahci_enable_ahci(mmio); + /* turn on AHCI mode */ + ahci_enable_ahci(mmio); - /* some registers might be cleared on reset. restore initial values */ - ahci_restore_initial_config(host); + /* Some registers might be cleared on reset. Restore + * initial values. + */ + ahci_restore_initial_config(host); + } else + dev_printk(KERN_INFO, host->dev, + "skipping global host reset\n"); if (pdev->vendor == PCI_VENDOR_ID_INTEL) { u16 tmp16; @@ -1146,9 +1178,14 @@ static void ahci_init_controller(struct ata_host *host) int i; void __iomem *port_mmio; u32 tmp; + int mv; if (hpriv->flags & AHCI_HFLAG_MV_PATA) { - port_mmio = __ahci_port_base(host, 4); + if (pdev->device == 0x6121) + mv = 2; + else + mv = 4; + port_mmio = __ahci_port_base(host, mv); writel(0, port_mmio + PORT_IRQ_MASK); @@ -1176,6 +1213,14 @@ static void ahci_init_controller(struct ata_host *host) VPRINTK("HOST_CTL 0x%x\n", tmp); } +static void ahci_dev_config(struct ata_device *dev) +{ + struct ahci_host_priv *hpriv = dev->link->ap->host->private_data; + + if (hpriv->flags & AHCI_HFLAG_SECT255) + dev->max_sectors = 255; +} + static unsigned int ahci_dev_classify(struct ata_port *ap) { void __iomem *port_mmio = ahci_port_base(ap); @@ -2217,7 +2262,10 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) if (rc) return rc; - rc = pcim_iomap_regions(pdev, 1 << AHCI_PCI_BAR, DRV_NAME); + /* AHCI controllers often implement SFF compatible interface. + * Grab all PCI BARs just in case. + */ + rc = pcim_iomap_regions_request_all(pdev, 1 << AHCI_PCI_BAR, DRV_NAME); if (rc == -EBUSY) pcim_pin_device(pdev); if (rc) diff --git a/drivers/ata/libata-acpi.c b/drivers/ata/libata-acpi.c index 9e8ec19260afa71ae5426b943fb4c17db6a6da19..bf98a566adac67c2ec49dc7fc4318fbf15cad68d 100644 --- a/drivers/ata/libata-acpi.c +++ b/drivers/ata/libata-acpi.c @@ -118,45 +118,77 @@ static void ata_acpi_associate_ide_port(struct ata_port *ap) ap->pflags |= ATA_PFLAG_INIT_GTM_VALID; } -static void ata_acpi_handle_hotplug(struct ata_port *ap, struct kobject *kobj, +static void ata_acpi_handle_hotplug(struct ata_port *ap, struct ata_device *dev, u32 event) { char event_string[12]; char *envp[] = { event_string, NULL }; - struct ata_eh_info *ehi = &ap->link.eh_info; - - if (event == 0 || event == 1) { - unsigned long flags; - spin_lock_irqsave(ap->lock, flags); - ata_ehi_clear_desc(ehi); - ata_ehi_push_desc(ehi, "ACPI event"); - ata_ehi_hotplugged(ehi); - ata_port_freeze(ap); - spin_unlock_irqrestore(ap->lock, flags); + struct ata_eh_info *ehi; + struct kobject *kobj = NULL; + int wait = 0; + unsigned long flags; + + if (!ap) + ap = dev->link->ap; + ehi = &ap->link.eh_info; + + spin_lock_irqsave(ap->lock, flags); + + switch (event) { + case ACPI_NOTIFY_BUS_CHECK: + case ACPI_NOTIFY_DEVICE_CHECK: + ata_ehi_push_desc(ehi, "ACPI event"); + ata_ehi_hotplugged(ehi); + ata_port_freeze(ap); + break; + + case ACPI_NOTIFY_EJECT_REQUEST: + ata_ehi_push_desc(ehi, "ACPI event"); + if (dev) + dev->flags |= ATA_DFLAG_DETACH; + else { + struct ata_link *tlink; + struct ata_device *tdev; + + ata_port_for_each_link(tlink, ap) + ata_link_for_each_dev(tdev, tlink) + tdev->flags |= ATA_DFLAG_DETACH; + } + + ata_port_schedule_eh(ap); + wait = 1; + break; } + if (dev) { + if (dev->sdev) + kobj = &dev->sdev->sdev_gendev.kobj; + } else + kobj = &ap->dev->kobj; + if (kobj) { sprintf(event_string, "BAY_EVENT=%d", event); kobject_uevent_env(kobj, KOBJ_CHANGE, envp); } + + spin_unlock_irqrestore(ap->lock, flags); + + if (wait) + ata_port_wait_eh(ap); } static void ata_acpi_dev_notify(acpi_handle handle, u32 event, void *data) { struct ata_device *dev = data; - struct kobject *kobj = NULL; - if (dev->sdev) - kobj = &dev->sdev->sdev_gendev.kobj; - - ata_acpi_handle_hotplug(dev->link->ap, kobj, event); + ata_acpi_handle_hotplug(NULL, dev, event); } static void ata_acpi_ap_notify(acpi_handle handle, u32 event, void *data) { struct ata_port *ap = data; - ata_acpi_handle_hotplug(ap, &ap->dev->kobj, event); + ata_acpi_handle_hotplug(ap, NULL, event); } /** @@ -191,20 +223,30 @@ void ata_acpi_associate(struct ata_host *host) else ata_acpi_associate_ide_port(ap); - if (ap->acpi_handle) - acpi_install_notify_handler (ap->acpi_handle, - ACPI_SYSTEM_NOTIFY, - ata_acpi_ap_notify, - ap); + if (ap->acpi_handle) { + acpi_install_notify_handler(ap->acpi_handle, + ACPI_SYSTEM_NOTIFY, + ata_acpi_ap_notify, ap); +#if defined(CONFIG_ACPI_DOCK) || defined(CONFIG_ACPI_DOCK_MODULE) + /* we might be on a docking station */ + register_hotplug_dock_device(ap->acpi_handle, + ata_acpi_ap_notify, ap); +#endif + } for (j = 0; j < ata_link_max_devices(&ap->link); j++) { struct ata_device *dev = &ap->link.device[j]; - if (dev->acpi_handle) - acpi_install_notify_handler (dev->acpi_handle, - ACPI_SYSTEM_NOTIFY, - ata_acpi_dev_notify, - dev); + if (dev->acpi_handle) { + acpi_install_notify_handler(dev->acpi_handle, + ACPI_SYSTEM_NOTIFY, + ata_acpi_dev_notify, dev); +#if defined(CONFIG_ACPI_DOCK) || defined(CONFIG_ACPI_DOCK_MODULE) + /* we might be on a docking station */ + register_hotplug_dock_device(dev->acpi_handle, + ata_acpi_dev_notify, dev); +#endif + } } } } @@ -382,7 +424,7 @@ static int ata_dev_get_GTF(struct ata_device *dev, struct ata_acpi_gtf **gtf) if (ata_msg_probe(ap)) ata_dev_printk(dev, KERN_DEBUG, "%s: ENTER: port#: %d\n", - __FUNCTION__, ap->port_no); + __func__, ap->port_no); /* _GTF has no input parameters */ status = acpi_evaluate_object(dev->acpi_handle, "_GTF", NULL, &output); @@ -402,7 +444,7 @@ static int ata_dev_get_GTF(struct ata_device *dev, struct ata_acpi_gtf **gtf) if (ata_msg_probe(ap)) ata_dev_printk(dev, KERN_DEBUG, "%s: Run _GTF: " "length or ptr is NULL (0x%llx, 0x%p)\n", - __FUNCTION__, + __func__, (unsigned long long)output.length, output.pointer); rc = -EINVAL; @@ -432,7 +474,7 @@ static int ata_dev_get_GTF(struct ata_device *dev, struct ata_acpi_gtf **gtf) if (ata_msg_probe(ap)) ata_dev_printk(dev, KERN_DEBUG, "%s: returning gtf=%p, gtf_count=%d\n", - __FUNCTION__, *gtf, rc); + __func__, *gtf, rc); } return rc; @@ -725,7 +767,7 @@ static int ata_acpi_push_id(struct ata_device *dev) if (ata_msg_probe(ap)) ata_dev_printk(dev, KERN_DEBUG, "%s: ix = %d, port#: %d\n", - __FUNCTION__, dev->devno, ap->port_no); + __func__, dev->devno, ap->port_no); /* Give the drive Identify data to the drive via the _SDD method */ /* _SDD: set up input parameters */ diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index fbc24358ada030bf3cc329682ee617374229dd3a..4bbe31f98ef8cffadb53a8c2b0962a8ac6f2c1bb 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -106,14 +106,15 @@ static struct ata_force_ent *ata_force_tbl; static int ata_force_tbl_size; static char ata_force_param_buf[PAGE_SIZE] __initdata; -module_param_string(force, ata_force_param_buf, sizeof(ata_force_param_buf), 0444); +/* param_buf is thrown away after initialization, disallow read */ +module_param_string(force, ata_force_param_buf, sizeof(ata_force_param_buf), 0); MODULE_PARM_DESC(force, "Force ATA configurations including cable type, link speed and transfer mode (see Documentation/kernel-parameters.txt for details)"); int atapi_enabled = 1; module_param(atapi_enabled, int, 0444); MODULE_PARM_DESC(atapi_enabled, "Enable discovery of ATAPI devices (0=off, 1=on)"); -int atapi_dmadir = 0; +static int atapi_dmadir = 0; module_param(atapi_dmadir, int, 0444); MODULE_PARM_DESC(atapi_dmadir, "Enable ATAPI DMADIR bridge support (0=off, 1=on)"); @@ -1719,7 +1720,7 @@ void ata_port_flush_task(struct ata_port *ap) cancel_rearming_delayed_work(&ap->port_task); if (ata_msg_ctl(ap)) - ata_port_printk(ap, KERN_DEBUG, "%s: EXIT\n", __FUNCTION__); + ata_port_printk(ap, KERN_DEBUG, "%s: EXIT\n", __func__); } static void ata_qc_complete_internal(struct ata_queued_cmd *qc) @@ -2056,7 +2057,7 @@ int ata_dev_read_id(struct ata_device *dev, unsigned int *p_class, int rc; if (ata_msg_ctl(ap)) - ata_dev_printk(dev, KERN_DEBUG, "%s: ENTER\n", __FUNCTION__); + ata_dev_printk(dev, KERN_DEBUG, "%s: ENTER\n", __func__); ata_dev_select(ap, dev->devno, 1, 1); /* select device 0/1 */ retry: @@ -2253,12 +2254,12 @@ int ata_dev_configure(struct ata_device *dev) if (!ata_dev_enabled(dev) && ata_msg_info(ap)) { ata_dev_printk(dev, KERN_INFO, "%s: ENTER/EXIT -- nodev\n", - __FUNCTION__); + __func__); return 0; } if (ata_msg_probe(ap)) - ata_dev_printk(dev, KERN_DEBUG, "%s: ENTER\n", __FUNCTION__); + ata_dev_printk(dev, KERN_DEBUG, "%s: ENTER\n", __func__); /* set horkage */ dev->horkage |= ata_dev_blacklisted(dev); @@ -2279,7 +2280,7 @@ int ata_dev_configure(struct ata_device *dev) ata_dev_printk(dev, KERN_DEBUG, "%s: cfg 49:%04x 82:%04x 83:%04x 84:%04x " "85:%04x 86:%04x 87:%04x 88:%04x\n", - __FUNCTION__, + __func__, id[49], id[82], id[83], id[84], id[85], id[86], id[87], id[88]); @@ -2511,13 +2512,13 @@ int ata_dev_configure(struct ata_device *dev) if (ata_msg_probe(ap)) ata_dev_printk(dev, KERN_DEBUG, "%s: EXIT, drv_stat = 0x%x\n", - __FUNCTION__, ata_chk_status(ap)); + __func__, ata_chk_status(ap)); return 0; err_out_nosup: if (ata_msg_probe(ap)) ata_dev_printk(dev, KERN_DEBUG, - "%s: EXIT, err\n", __FUNCTION__); + "%s: EXIT, err\n", __func__); return rc; } @@ -6567,6 +6568,8 @@ int ata_host_suspend(struct ata_host *host, pm_message_t mesg) ata_lpm_enable(host); rc = ata_host_request_pm(host, mesg, 0, ATA_EHI_QUIET, 1); + if (rc == 0) + host->dev->power.power_state = mesg; return rc; } @@ -6585,6 +6588,7 @@ void ata_host_resume(struct ata_host *host) { ata_host_request_pm(host, PMSG_ON, ATA_EH_SOFTRESET, ATA_EHI_NO_AUTOPSY | ATA_EHI_QUIET, 0); + host->dev->power.power_state = PMSG_ON; /* reenable link pm */ ata_lpm_disable(host); diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c index 698ce2cea52c6be6689158a27d2688043985398b..681252fd814360103ec60e268aeffc6087e58341 100644 --- a/drivers/ata/libata-eh.c +++ b/drivers/ata/libata-eh.c @@ -2150,6 +2150,15 @@ int ata_eh_reset(struct ata_link *link, int classify, ap->ops->set_piomode(ap, dev); } + if (!softreset && !hardreset) { + if (verbose) + ata_link_printk(link, KERN_INFO, "no reset method " + "available, skipping reset\n"); + if (!(lflags & ATA_LFLAG_ASSUME_CLASS)) + lflags |= ATA_LFLAG_ASSUME_ATA; + goto done; + } + /* Determine which reset to use and record in ehc->i.action. * prereset() may examine and modify it. */ @@ -2254,6 +2263,7 @@ int ata_eh_reset(struct ata_link *link, int classify, lflags |= ATA_LFLAG_ASSUME_ATA; } + done: ata_link_for_each_dev(dev, link) { /* After the reset, the device state is PIO 0 and the * controller state is undefined. Reset also wakes up diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index 0562b0a49f3b2acc474c3145ee0f48911eefe349..8f0e8f2bc628a283c0000b5cab3e43287aa4bb58 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c @@ -862,9 +862,10 @@ static int ata_scsi_dev_config(struct scsi_device *sdev, struct request_queue *q = sdev->request_queue; void *buf; - /* set the min alignment */ + /* set the min alignment and padding */ blk_queue_update_dma_alignment(sdev->request_queue, ATA_DMA_PAD_SZ - 1); + blk_queue_dma_pad(sdev->request_queue, ATA_DMA_PAD_SZ - 1); /* configure draining */ buf = kmalloc(ATAPI_MAX_DRAIN, q->bounce_gfp | GFP_KERNEL); @@ -1694,12 +1695,17 @@ void ata_scsi_rbuf_fill(struct ata_scsi_args *args, u8 *rbuf; unsigned int buflen, rc; struct scsi_cmnd *cmd = args->cmd; + unsigned long flags; + + local_irq_save(flags); buflen = ata_scsi_rbuf_get(cmd, &rbuf); memset(rbuf, 0, buflen); rc = actor(args, rbuf, buflen); ata_scsi_rbuf_put(cmd, rbuf); + local_irq_restore(flags); + if (rc == 0) cmd->result = SAM_STAT_GOOD; args->done(cmd); @@ -2473,6 +2479,9 @@ static void atapi_qc_complete(struct ata_queued_cmd *qc) if ((scsicmd[0] == INQUIRY) && ((scsicmd[1] & 0x03) == 0)) { u8 *buf = NULL; unsigned int buflen; + unsigned long flags; + + local_irq_save(flags); buflen = ata_scsi_rbuf_get(cmd, &buf); @@ -2490,6 +2499,8 @@ static void atapi_qc_complete(struct ata_queued_cmd *qc) } ata_scsi_rbuf_put(cmd, buf); + + local_irq_restore(flags); } cmd->result = SAM_STAT_GOOD; @@ -2528,7 +2539,7 @@ static unsigned int atapi_xlat(struct ata_queued_cmd *qc) } qc->tf.command = ATA_CMD_PACKET; - qc->nbytes = scsi_bufflen(scmd); + qc->nbytes = scsi_bufflen(scmd) + scmd->request->extra_len; /* check whether ATAPI DMA is safe */ if (!using_pio && ata_check_atapi_dma(qc)) @@ -2539,7 +2550,7 @@ static unsigned int atapi_xlat(struct ata_queued_cmd *qc) * want to set it properly, and for DMA where it is * effectively meaningless. */ - nbytes = min(scmd->request->raw_data_len, (unsigned int)63 * 1024); + nbytes = min(scmd->request->data_len, (unsigned int)63 * 1024); /* Most ATAPI devices which honor transfer chunk size don't * behave according to the spec when odd chunk size which @@ -2865,7 +2876,7 @@ static unsigned int ata_scsi_pass_thru(struct ata_queued_cmd *qc) * TODO: find out if we need to do more here to * cover scatter/gather case. */ - qc->nbytes = scsi_bufflen(scmd); + qc->nbytes = scsi_bufflen(scmd) + scmd->request->extra_len; /* request result TF and be quiet about device error */ qc->flags |= ATA_QCFLAG_RESULT_TF | ATA_QCFLAG_QUIET; diff --git a/drivers/ata/libata-sff.c b/drivers/ata/libata-sff.c index 60cd4b179766e9683e82b39552c3a5546afa4b44..20dc572fb45a1c1b780c8d8a8303b88643a6fbbd 100644 --- a/drivers/ata/libata-sff.c +++ b/drivers/ata/libata-sff.c @@ -56,7 +56,8 @@ u8 ata_irq_on(struct ata_port *ap) ap->ctl &= ~ATA_NIEN; ap->last_ctl = ap->ctl; - iowrite8(ap->ctl, ioaddr->ctl_addr); + if (ioaddr->ctl_addr) + iowrite8(ap->ctl, ioaddr->ctl_addr); tmp = ata_wait_idle(ap); ap->ops->irq_clear(ap); @@ -81,12 +82,14 @@ void ata_tf_load(struct ata_port *ap, const struct ata_taskfile *tf) unsigned int is_addr = tf->flags & ATA_TFLAG_ISADDR; if (tf->ctl != ap->last_ctl) { - iowrite8(tf->ctl, ioaddr->ctl_addr); + if (ioaddr->ctl_addr) + iowrite8(tf->ctl, ioaddr->ctl_addr); ap->last_ctl = tf->ctl; ata_wait_idle(ap); } if (is_addr && (tf->flags & ATA_TFLAG_LBA48)) { + WARN_ON(!ioaddr->ctl_addr); iowrite8(tf->hob_feature, ioaddr->feature_addr); iowrite8(tf->hob_nsect, ioaddr->nsect_addr); iowrite8(tf->hob_lbal, ioaddr->lbal_addr); @@ -167,14 +170,17 @@ void ata_tf_read(struct ata_port *ap, struct ata_taskfile *tf) tf->device = ioread8(ioaddr->device_addr); if (tf->flags & ATA_TFLAG_LBA48) { - iowrite8(tf->ctl | ATA_HOB, ioaddr->ctl_addr); - tf->hob_feature = ioread8(ioaddr->error_addr); - tf->hob_nsect = ioread8(ioaddr->nsect_addr); - tf->hob_lbal = ioread8(ioaddr->lbal_addr); - tf->hob_lbam = ioread8(ioaddr->lbam_addr); - tf->hob_lbah = ioread8(ioaddr->lbah_addr); - iowrite8(tf->ctl, ioaddr->ctl_addr); - ap->last_ctl = tf->ctl; + if (likely(ioaddr->ctl_addr)) { + iowrite8(tf->ctl | ATA_HOB, ioaddr->ctl_addr); + tf->hob_feature = ioread8(ioaddr->error_addr); + tf->hob_nsect = ioread8(ioaddr->nsect_addr); + tf->hob_lbal = ioread8(ioaddr->lbal_addr); + tf->hob_lbam = ioread8(ioaddr->lbam_addr); + tf->hob_lbah = ioread8(ioaddr->lbah_addr); + iowrite8(tf->ctl, ioaddr->ctl_addr); + ap->last_ctl = tf->ctl; + } else + WARN_ON(1); } } @@ -352,7 +358,8 @@ void ata_bmdma_freeze(struct ata_port *ap) ap->ctl |= ATA_NIEN; ap->last_ctl = ap->ctl; - iowrite8(ap->ctl, ioaddr->ctl_addr); + if (ioaddr->ctl_addr) + iowrite8(ap->ctl, ioaddr->ctl_addr); /* Under certain circumstances, some controllers raise IRQ on * ATA_NIEN manipulation. Also, many controllers fail to mask @@ -459,13 +466,14 @@ void ata_bmdma_drive_eh(struct ata_port *ap, ata_prereset_fn_t prereset, */ void ata_bmdma_error_handler(struct ata_port *ap) { - ata_reset_fn_t hardreset; + ata_reset_fn_t softreset = NULL, hardreset = NULL; - hardreset = NULL; + if (ap->ioaddr.ctl_addr) + softreset = ata_std_softreset; if (sata_scr_valid(&ap->link)) hardreset = sata_std_hardreset; - ata_bmdma_drive_eh(ap, ata_std_prereset, ata_std_softreset, hardreset, + ata_bmdma_drive_eh(ap, ata_std_prereset, softreset, hardreset, ata_std_postreset); } diff --git a/drivers/ata/libata.h b/drivers/ata/libata.h index 6036dedfe377579b494a85cff095a793d2b3331d..aa884f71a12a4733d9de5dab53a42650abdbfd84 100644 --- a/drivers/ata/libata.h +++ b/drivers/ata/libata.h @@ -56,7 +56,6 @@ enum { extern unsigned int ata_print_id; extern struct workqueue_struct *ata_aux_wq; extern int atapi_enabled; -extern int atapi_dmadir; extern int atapi_passthru16; extern int libata_fua; extern int libata_noacpi; diff --git a/drivers/ata/pata_ali.c b/drivers/ata/pata_ali.c index 7e68edf3c0f3fe9c5133396c698c96159956d646..8786455c901d9b220d6f7f3cb0540900500e927a 100644 --- a/drivers/ata/pata_ali.c +++ b/drivers/ata/pata_ali.c @@ -295,7 +295,7 @@ static void ali_lock_sectors(struct ata_device *adev) static int ali_check_atapi_dma(struct ata_queued_cmd *qc) { /* If its not a media command, its not worth it */ - if (qc->nbytes < 2048) + if (atapi_cmd_type(qc->cdb[0]) == ATAPI_MISC) return -EOPNOTSUPP; return 0; } diff --git a/drivers/ata/pata_hpt366.c b/drivers/ata/pata_hpt366.c index 0713872cf65c64c936c14a15aacda6c7f851f640..a742efa0da2b53cbde8409e87a6a57c01b503c76 100644 --- a/drivers/ata/pata_hpt366.c +++ b/drivers/ata/pata_hpt366.c @@ -27,7 +27,7 @@ #include #define DRV_NAME "pata_hpt366" -#define DRV_VERSION "0.6.1" +#define DRV_VERSION "0.6.2" struct hpt_clock { u8 xfer_speed; @@ -180,9 +180,9 @@ static unsigned long hpt366_filter(struct ata_device *adev, unsigned long mask) if (hpt_dma_blacklisted(adev, "UDMA", bad_ata33)) mask &= ~ATA_MASK_UDMA; if (hpt_dma_blacklisted(adev, "UDMA3", bad_ata66_3)) - mask &= ~(0x07 << ATA_SHIFT_UDMA); + mask &= ~(0xF8 << ATA_SHIFT_UDMA); if (hpt_dma_blacklisted(adev, "UDMA4", bad_ata66_4)) - mask &= ~(0x0F << ATA_SHIFT_UDMA); + mask &= ~(0xF0 << ATA_SHIFT_UDMA); } return ata_pci_default_filter(adev, mask); } diff --git a/drivers/ata/pata_hpt37x.c b/drivers/ata/pata_hpt37x.c index 68eb34929cecde9c7ed149f3fa5e1dc15c65fd3a..9a10878b2ad870049cbd0341dee7b30adacbf44c 100644 --- a/drivers/ata/pata_hpt37x.c +++ b/drivers/ata/pata_hpt37x.c @@ -24,7 +24,7 @@ #include #define DRV_NAME "pata_hpt37x" -#define DRV_VERSION "0.6.9" +#define DRV_VERSION "0.6.11" struct hpt_clock { u8 xfer_speed; @@ -281,7 +281,7 @@ static unsigned long hpt370_filter(struct ata_device *adev, unsigned long mask) if (hpt_dma_blacklisted(adev, "UDMA", bad_ata33)) mask &= ~ATA_MASK_UDMA; if (hpt_dma_blacklisted(adev, "UDMA100", bad_ata100_5)) - mask &= ~(0x1F << ATA_SHIFT_UDMA); + mask &= ~(0xE0 << ATA_SHIFT_UDMA); } return ata_pci_default_filter(adev, mask); } @@ -297,7 +297,7 @@ static unsigned long hpt370a_filter(struct ata_device *adev, unsigned long mask) { if (adev->class == ATA_DEV_ATA) { if (hpt_dma_blacklisted(adev, "UDMA100", bad_ata100_5)) - mask &= ~ (0x1F << ATA_SHIFT_UDMA); + mask &= ~(0xE0 << ATA_SHIFT_UDMA); } return ata_pci_default_filter(adev, mask); } diff --git a/drivers/ata/pata_pdc2027x.c b/drivers/ata/pata_pdc2027x.c index 028af5dbeed6a596c4e59fc259dabc28f98436de..511c89b9bae811bd9b9cc03843316db696bf0a58 100644 --- a/drivers/ata/pata_pdc2027x.c +++ b/drivers/ata/pata_pdc2027x.c @@ -39,7 +39,7 @@ #undef PDC_DEBUG #ifdef PDC_DEBUG -#define PDPRINTK(fmt, args...) printk(KERN_ERR "%s: " fmt, __FUNCTION__, ## args) +#define PDPRINTK(fmt, args...) printk(KERN_ERR "%s: " fmt, __func__, ## args) #else #define PDPRINTK(fmt, args...) #endif diff --git a/drivers/ata/pata_rb500_cf.c b/drivers/ata/pata_rb500_cf.c new file mode 100644 index 0000000000000000000000000000000000000000..4ce9b03fe6c845dc349cbe58144cad7f63ee362d --- /dev/null +++ b/drivers/ata/pata_rb500_cf.c @@ -0,0 +1,314 @@ +/* + * A low-level PATA driver to handle a Compact Flash connected on the + * Mikrotik's RouterBoard 532 board. + * + * Copyright (C) 2007 Gabor Juhos + * Copyright (C) 2008 Florian Fainelli + * + * This file was based on: drivers/ata/pata_ixp4xx_cf.c + * Copyright (C) 2006-07 Tower Technologies + * Author: Alessandro Zummo + * + * Also was based on the driver for Linux 2.4.xx published by Mikrotik for + * their RouterBoard 1xx and 5xx series devices. The original Mikrotik code + * seems not to have a license. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + */ + +#include +#include +#include + +#include +#include +#include + +#include +#include + +#include + +#define DRV_NAME "pata-rb500-cf" +#define DRV_VERSION "0.1.0" +#define DRV_DESC "PATA driver for RouterBOARD 532 Compact Flash" + +#define RB500_CF_MAXPORTS 1 +#define RB500_CF_IO_DELAY 400 + +#define RB500_CF_REG_CMD 0x0800 +#define RB500_CF_REG_CTRL 0x080E +#define RB500_CF_REG_DATA 0x0C00 + +struct rb500_cf_info { + void __iomem *iobase; + unsigned int gpio_line; + int frozen; + unsigned int irq; +}; + +/* ------------------------------------------------------------------------ */ + +static inline void rb500_pata_finish_io(struct ata_port *ap) +{ + struct ata_host *ah = ap->host; + struct rb500_cf_info *info = ah->private_data; + + ata_altstatus(ap); + ndelay(RB500_CF_IO_DELAY); + + set_irq_type(info->irq, IRQ_TYPE_LEVEL_HIGH); +} + +static void rb500_pata_exec_command(struct ata_port *ap, + const struct ata_taskfile *tf) +{ + writeb(tf->command, ap->ioaddr.command_addr); + rb500_pata_finish_io(ap); +} + +static void rb500_pata_data_xfer(struct ata_device *adev, unsigned char *buf, + unsigned int buflen, int write_data) +{ + struct ata_port *ap = adev->link->ap; + void __iomem *ioaddr = ap->ioaddr.data_addr; + + if (write_data) { + for (; buflen > 0; buflen--, buf++) + writeb(*buf, ioaddr); + } else { + for (; buflen > 0; buflen--, buf++) + *buf = readb(ioaddr); + } + + rb500_pata_finish_io(adev->link->ap); +} + +static void rb500_pata_freeze(struct ata_port *ap) +{ + struct rb500_cf_info *info = ap->host->private_data; + + info->frozen = 1; +} + +static void rb500_pata_thaw(struct ata_port *ap) +{ + struct rb500_cf_info *info = ap->host->private_data; + + info->frozen = 0; +} + +static irqreturn_t rb500_pata_irq_handler(int irq, void *dev_instance) +{ + struct ata_host *ah = dev_instance; + struct rb500_cf_info *info = ah->private_data; + + if (gpio_get_value(info->gpio_line)) { + set_irq_type(info->irq, IRQ_TYPE_LEVEL_LOW); + if (!info->frozen) + ata_interrupt(info->irq, dev_instance); + } else { + set_irq_type(info->irq, IRQ_TYPE_LEVEL_HIGH); + } + + return IRQ_HANDLED; +} + +static void rb500_pata_irq_clear(struct ata_port *ap) +{ +} + +static int rb500_pata_port_start(struct ata_port *ap) +{ + return 0; +} + +static struct ata_port_operations rb500_pata_port_ops = { + .tf_load = ata_tf_load, + .tf_read = ata_tf_read, + + .exec_command = rb500_pata_exec_command, + .check_status = ata_check_status, + .dev_select = ata_std_dev_select, + + .data_xfer = rb500_pata_data_xfer, + + .qc_prep = ata_qc_prep, + .qc_issue = ata_qc_issue_prot, + + .freeze = rb500_pata_freeze, + .thaw = rb500_pata_thaw, + .error_handler = ata_bmdma_error_handler, + + .irq_handler = rb500_pata_irq_handler, + .irq_clear = rb500_pata_irq_clear, + .irq_on = ata_irq_on, + + .port_start = rb500_pata_port_start, +}; + +/* ------------------------------------------------------------------------ */ + +static struct scsi_host_template rb500_pata_sht = { + .module = THIS_MODULE, + .name = DRV_NAME, + .ioctl = ata_scsi_ioctl, + .queuecommand = ata_scsi_queuecmd, + .slave_configure = ata_scsi_slave_config, + .slave_destroy = ata_scsi_slave_destroy, + .bios_param = ata_std_bios_param, + .proc_name = DRV_NAME, + + .can_queue = ATA_DEF_QUEUE, + .this_id = ATA_SHT_THIS_ID, + .sg_tablesize = LIBATA_MAX_PRD, + .dma_boundary = ATA_DMA_BOUNDARY, + .cmd_per_lun = ATA_SHT_CMD_PER_LUN, + .emulated = ATA_SHT_EMULATED, + .use_clustering = ATA_SHT_USE_CLUSTERING, +}; + +/* ------------------------------------------------------------------------ */ + +static void rb500_pata_setup_ports(struct ata_host *ah) +{ + struct rb500_cf_info *info = ah->private_data; + struct ata_port *ap; + + ap = ah->ports[0]; + + ap->ops = &rb500_pata_port_ops; + ap->pio_mask = 0x1f; /* PIO4 */ + ap->flags = ATA_FLAG_NO_LEGACY | ATA_FLAG_MMIO; + + ap->ioaddr.cmd_addr = info->iobase + RB500_CF_REG_CMD; + ap->ioaddr.ctl_addr = info->iobase + RB500_CF_REG_CTRL; + ap->ioaddr.altstatus_addr = info->iobase + RB500_CF_REG_CTRL; + + ata_std_ports(&ap->ioaddr); + + ap->ioaddr.data_addr = info->iobase + RB500_CF_REG_DATA; +} + +static __devinit int rb500_pata_driver_probe(struct platform_device *pdev) +{ + unsigned int irq; + int gpio; + struct resource *res; + struct ata_host *ah; + struct rb500_cf_info *info; + int ret; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) { + dev_err(&pdev->dev, "no IOMEM resource found\n"); + return -EINVAL; + } + + irq = platform_get_irq(pdev, 0); + if (irq <= 0) { + dev_err(&pdev->dev, "no IRQ resource found\n"); + return -ENOENT; + } + + gpio = irq_to_gpio(irq); + if (gpio < 0) { + dev_err(&pdev->dev, "no GPIO found for irq%d\n", irq); + return -ENOENT; + } + + ret = gpio_request(gpio, DRV_NAME); + if (ret) { + dev_err(&pdev->dev, "GPIO request failed\n"); + return ret; + } + + /* allocate host */ + ah = ata_host_alloc(&pdev->dev, RB500_CF_MAXPORTS); + if (!ah) + return -ENOMEM; + + platform_set_drvdata(pdev, ah); + + info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL); + if (!info) + return -ENOMEM; + + ah->private_data = info; + info->gpio_line = gpio; + info->irq = irq; + + info->iobase = devm_ioremap_nocache(&pdev->dev, res->start, + res->end - res->start + 1); + if (!info->iobase) + return -ENOMEM; + + ret = gpio_direction_input(gpio); + if (ret) { + dev_err(&pdev->dev, "unable to set GPIO direction, err=%d\n", + ret); + goto err_free_gpio; + } + + rb500_pata_setup_ports(ah); + + ret = ata_host_activate(ah, irq, rb500_pata_irq_handler, + IRQF_TRIGGER_LOW, &rb500_pata_sht); + if (ret) + goto err_free_gpio; + + return 0; + +err_free_gpio: + gpio_free(gpio); + + return ret; +} + +static __devexit int rb500_pata_driver_remove(struct platform_device *pdev) +{ + struct ata_host *ah = platform_get_drvdata(pdev); + struct rb500_cf_info *info = ah->private_data; + + ata_host_detach(ah); + gpio_free(info->gpio_line); + + return 0; +} + +static struct platform_driver rb500_pata_platform_driver = { + .probe = rb500_pata_driver_probe, + .remove = __devexit_p(rb500_pata_driver_remove), + .driver = { + .name = DRV_NAME, + .owner = THIS_MODULE, + }, +}; + +/* ------------------------------------------------------------------------ */ + +#define DRV_INFO DRV_DESC " version " DRV_VERSION + +static int __init rb500_pata_module_init(void) +{ + printk(KERN_INFO DRV_INFO "\n"); + + return platform_driver_register(&rb500_pata_platform_driver); +} + +static void __exit rb500_pata_module_exit(void) +{ + platform_driver_unregister(&rb500_pata_platform_driver); +} + +MODULE_AUTHOR("Gabor Juhos "); +MODULE_AUTHOR("Florian Fainelli "); +MODULE_DESCRIPTION(DRV_DESC); +MODULE_VERSION(DRV_VERSION); +MODULE_LICENSE("GPL"); + +module_init(rb500_pata_module_init); +module_exit(rb500_pata_module_exit); diff --git a/drivers/ata/pata_serverworks.c b/drivers/ata/pata_serverworks.c index 9c523fbf529ead0d92fe8c8d60356be5f0c5cbbd..a589c0fa0dbb699d3e1108f59b577cc645f4bfad 100644 --- a/drivers/ata/pata_serverworks.c +++ b/drivers/ata/pata_serverworks.c @@ -226,7 +226,7 @@ static unsigned long serverworks_csb_filter(struct ata_device *adev, unsigned lo for (i = 0; (p = csb_bad_ata100[i]) != NULL; i++) { if (!strcmp(p, model_num)) - mask &= ~(0x1F << ATA_SHIFT_UDMA); + mask &= ~(0xE0 << ATA_SHIFT_UDMA); } return ata_pci_default_filter(adev, mask); } diff --git a/drivers/ata/sata_svw.c b/drivers/ata/sata_svw.c index 69f651e0bc98dc9106917c9c46c90d6451da419a..840d1c4a7850e831651f897758a8005516799515 100644 --- a/drivers/ata/sata_svw.c +++ b/drivers/ata/sata_svw.c @@ -45,6 +45,8 @@ #include #include #include +#include +#include #include #ifdef CONFIG_PPC_OF @@ -59,6 +61,7 @@ enum { /* ap->flags bits */ K2_FLAG_SATA_8_PORTS = (1 << 24), K2_FLAG_NO_ATAPI_DMA = (1 << 25), + K2_FLAG_BAR_POS_3 = (1 << 26), /* Taskfile registers offsets */ K2_SATA_TF_CMD_OFFSET = 0x00, @@ -88,8 +91,10 @@ enum { /* Port stride */ K2_SATA_PORT_OFFSET = 0x100, - board_svw4 = 0, - board_svw8 = 1, + chip_svw4 = 0, + chip_svw8 = 1, + chip_svw42 = 2, /* bar 3 */ + chip_svw43 = 3, /* bar 5 */ }; static u8 k2_stat_check_status(struct ata_port *ap); @@ -97,10 +102,25 @@ static u8 k2_stat_check_status(struct ata_port *ap); static int k2_sata_check_atapi_dma(struct ata_queued_cmd *qc) { + u8 cmnd = qc->scsicmd->cmnd[0]; + if (qc->ap->flags & K2_FLAG_NO_ATAPI_DMA) return -1; /* ATAPI DMA not supported */ + else { + switch (cmnd) { + case READ_10: + case READ_12: + case READ_16: + case WRITE_10: + case WRITE_12: + case WRITE_16: + return 0; + + default: + return -1; + } - return 0; + } } static int k2_sata_scr_read(struct ata_port *ap, unsigned int sc_reg, u32 *val) @@ -354,7 +374,7 @@ static const struct ata_port_operations k2_sata_ops = { }; static const struct ata_port_info k2_port_info[] = { - /* board_svw4 */ + /* chip_svw4 */ { .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | ATA_FLAG_MMIO | K2_FLAG_NO_ATAPI_DMA, @@ -363,7 +383,7 @@ static const struct ata_port_info k2_port_info[] = { .udma_mask = ATA_UDMA6, .port_ops = &k2_sata_ops, }, - /* board_svw8 */ + /* chip_svw8 */ { .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | ATA_FLAG_MMIO | K2_FLAG_NO_ATAPI_DMA | @@ -373,6 +393,24 @@ static const struct ata_port_info k2_port_info[] = { .udma_mask = ATA_UDMA6, .port_ops = &k2_sata_ops, }, + /* chip_svw42 */ + { + .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | + ATA_FLAG_MMIO | K2_FLAG_BAR_POS_3, + .pio_mask = 0x1f, + .mwdma_mask = 0x07, + .udma_mask = ATA_UDMA6, + .port_ops = &k2_sata_ops, + }, + /* chip_svw43 */ + { + .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | + ATA_FLAG_MMIO, + .pio_mask = 0x1f, + .mwdma_mask = 0x07, + .udma_mask = ATA_UDMA6, + .port_ops = &k2_sata_ops, + }, }; static void k2_sata_setup_port(struct ata_ioports *port, void __iomem *base) @@ -402,7 +440,7 @@ static int k2_sata_init_one(struct pci_dev *pdev, const struct pci_device_id *en { &k2_port_info[ent->driver_data], NULL }; struct ata_host *host; void __iomem *mmio_base; - int n_ports, i, rc; + int n_ports, i, rc, bar_pos; if (!printed_version++) dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n"); @@ -416,6 +454,9 @@ static int k2_sata_init_one(struct pci_dev *pdev, const struct pci_device_id *en if (!host) return -ENOMEM; + bar_pos = 5; + if (ppi[0]->flags & K2_FLAG_BAR_POS_3) + bar_pos = 3; /* * If this driver happens to only be useful on Apple's K2, then * we should check that here as it has a normal Serverworks ID @@ -428,17 +469,23 @@ static int k2_sata_init_one(struct pci_dev *pdev, const struct pci_device_id *en * Check if we have resources mapped at all (second function may * have been disabled by firmware) */ - if (pci_resource_len(pdev, 5) == 0) + if (pci_resource_len(pdev, bar_pos) == 0) { + /* In IDE mode we need to pin the device to ensure that + pcim_release does not clear the busmaster bit in config + space, clearing causes busmaster DMA to fail on + ports 3 & 4 */ + pcim_pin_device(pdev); return -ENODEV; + } /* Request and iomap PCI regions */ - rc = pcim_iomap_regions(pdev, 1 << 5, DRV_NAME); + rc = pcim_iomap_regions(pdev, 1 << bar_pos, DRV_NAME); if (rc == -EBUSY) pcim_pin_device(pdev); if (rc) return rc; host->iomap = pcim_iomap_table(pdev); - mmio_base = host->iomap[5]; + mmio_base = host->iomap[bar_pos]; /* different controllers have different number of ports - currently 4 or 8 */ /* All ports are on the same function. Multi-function device is no @@ -483,11 +530,13 @@ static int k2_sata_init_one(struct pci_dev *pdev, const struct pci_device_id *en * controller * */ static const struct pci_device_id k2_sata_pci_tbl[] = { - { PCI_VDEVICE(SERVERWORKS, 0x0240), board_svw4 }, - { PCI_VDEVICE(SERVERWORKS, 0x0241), board_svw4 }, - { PCI_VDEVICE(SERVERWORKS, 0x0242), board_svw8 }, - { PCI_VDEVICE(SERVERWORKS, 0x024a), board_svw4 }, - { PCI_VDEVICE(SERVERWORKS, 0x024b), board_svw4 }, + { PCI_VDEVICE(SERVERWORKS, 0x0240), chip_svw4 }, + { PCI_VDEVICE(SERVERWORKS, 0x0241), chip_svw4 }, + { PCI_VDEVICE(SERVERWORKS, 0x0242), chip_svw8 }, + { PCI_VDEVICE(SERVERWORKS, 0x024a), chip_svw4 }, + { PCI_VDEVICE(SERVERWORKS, 0x024b), chip_svw4 }, + { PCI_VDEVICE(SERVERWORKS, 0x0410), chip_svw42 }, + { PCI_VDEVICE(SERVERWORKS, 0x0411), chip_svw43 }, { } }; diff --git a/drivers/atm/firestream.c b/drivers/atm/firestream.c index c662d686154a1ac64ad5b1c1e7deca1029fce0bc..47c57a4294b7c8beccb38ee7e4ed62fc388ad4fc 100644 --- a/drivers/atm/firestream.c +++ b/drivers/atm/firestream.c @@ -331,8 +331,8 @@ module_param(fs_keystream, int, 0); #define FS_DEBUG_QSIZE 0x00001000 -#define func_enter() fs_dprintk (FS_DEBUG_FLOW, "fs: enter %s\n", __FUNCTION__) -#define func_exit() fs_dprintk (FS_DEBUG_FLOW, "fs: exit %s\n", __FUNCTION__) +#define func_enter() fs_dprintk(FS_DEBUG_FLOW, "fs: enter %s\n", __func__) +#define func_exit() fs_dprintk(FS_DEBUG_FLOW, "fs: exit %s\n", __func__) static struct fs_dev *fs_boards = NULL; diff --git a/drivers/atm/fore200e.c b/drivers/atm/fore200e.c index f97e050338f04a0dd24431dafe194fb8600f3de9..432181ed7bb51d977d59e023d8668293e221ae9e 100644 --- a/drivers/atm/fore200e.c +++ b/drivers/atm/fore200e.c @@ -95,8 +95,8 @@ #if 1 #define ASSERT(expr) if (!(expr)) { \ printk(FORE200E "assertion failed! %s[%d]: %s\n", \ - __FUNCTION__, __LINE__, #expr); \ - panic(FORE200E "%s", __FUNCTION__); \ + __func__, __LINE__, #expr); \ + panic(FORE200E "%s", __func__); \ } #else #define ASSERT(expr) do {} while (0) @@ -1988,19 +1988,19 @@ fore200e_fetch_stats(struct fore200e* fore200e, struct sonet_stats __user *arg) if (fore200e_getstats(fore200e) < 0) return -EIO; - tmp.section_bip = cpu_to_be32(fore200e->stats->oc3.section_bip8_errors); - tmp.line_bip = cpu_to_be32(fore200e->stats->oc3.line_bip24_errors); - tmp.path_bip = cpu_to_be32(fore200e->stats->oc3.path_bip8_errors); - tmp.line_febe = cpu_to_be32(fore200e->stats->oc3.line_febe_errors); - tmp.path_febe = cpu_to_be32(fore200e->stats->oc3.path_febe_errors); - tmp.corr_hcs = cpu_to_be32(fore200e->stats->oc3.corr_hcs_errors); - tmp.uncorr_hcs = cpu_to_be32(fore200e->stats->oc3.ucorr_hcs_errors); - tmp.tx_cells = cpu_to_be32(fore200e->stats->aal0.cells_transmitted) + - cpu_to_be32(fore200e->stats->aal34.cells_transmitted) + - cpu_to_be32(fore200e->stats->aal5.cells_transmitted); - tmp.rx_cells = cpu_to_be32(fore200e->stats->aal0.cells_received) + - cpu_to_be32(fore200e->stats->aal34.cells_received) + - cpu_to_be32(fore200e->stats->aal5.cells_received); + tmp.section_bip = be32_to_cpu(fore200e->stats->oc3.section_bip8_errors); + tmp.line_bip = be32_to_cpu(fore200e->stats->oc3.line_bip24_errors); + tmp.path_bip = be32_to_cpu(fore200e->stats->oc3.path_bip8_errors); + tmp.line_febe = be32_to_cpu(fore200e->stats->oc3.line_febe_errors); + tmp.path_febe = be32_to_cpu(fore200e->stats->oc3.path_febe_errors); + tmp.corr_hcs = be32_to_cpu(fore200e->stats->oc3.corr_hcs_errors); + tmp.uncorr_hcs = be32_to_cpu(fore200e->stats->oc3.ucorr_hcs_errors); + tmp.tx_cells = be32_to_cpu(fore200e->stats->aal0.cells_transmitted) + + be32_to_cpu(fore200e->stats->aal34.cells_transmitted) + + be32_to_cpu(fore200e->stats->aal5.cells_transmitted); + tmp.rx_cells = be32_to_cpu(fore200e->stats->aal0.cells_received) + + be32_to_cpu(fore200e->stats->aal34.cells_received) + + be32_to_cpu(fore200e->stats->aal5.cells_received); if (arg) return copy_to_user(arg, &tmp, sizeof(struct sonet_stats)) ? -EFAULT : 0; @@ -2587,7 +2587,7 @@ fore200e_start_fw(struct fore200e* fore200e) static int __devinit fore200e_load_fw(struct fore200e* fore200e) { - u32* fw_data = (u32*) fore200e->bus->fw_data; + __le32* fw_data = (__le32*) fore200e->bus->fw_data; u32 fw_size = (u32) *fore200e->bus->fw_size / sizeof(u32); struct fw_header* fw_header = (struct fw_header*) fw_data; @@ -2965,8 +2965,8 @@ fore200e_proc_read(struct atm_dev *dev, loff_t* pos, char* page) " 4b5b:\n" " crc_header_errors:\t\t%10u\n" " framing_errors:\t\t%10u\n", - cpu_to_be32(fore200e->stats->phy.crc_header_errors), - cpu_to_be32(fore200e->stats->phy.framing_errors)); + be32_to_cpu(fore200e->stats->phy.crc_header_errors), + be32_to_cpu(fore200e->stats->phy.framing_errors)); if (!left--) return sprintf(page, "\n" @@ -2978,13 +2978,13 @@ fore200e_proc_read(struct atm_dev *dev, loff_t* pos, char* page) " path_febe_errors:\t\t%10u\n" " corr_hcs_errors:\t\t%10u\n" " ucorr_hcs_errors:\t\t%10u\n", - cpu_to_be32(fore200e->stats->oc3.section_bip8_errors), - cpu_to_be32(fore200e->stats->oc3.path_bip8_errors), - cpu_to_be32(fore200e->stats->oc3.line_bip24_errors), - cpu_to_be32(fore200e->stats->oc3.line_febe_errors), - cpu_to_be32(fore200e->stats->oc3.path_febe_errors), - cpu_to_be32(fore200e->stats->oc3.corr_hcs_errors), - cpu_to_be32(fore200e->stats->oc3.ucorr_hcs_errors)); + be32_to_cpu(fore200e->stats->oc3.section_bip8_errors), + be32_to_cpu(fore200e->stats->oc3.path_bip8_errors), + be32_to_cpu(fore200e->stats->oc3.line_bip24_errors), + be32_to_cpu(fore200e->stats->oc3.line_febe_errors), + be32_to_cpu(fore200e->stats->oc3.path_febe_errors), + be32_to_cpu(fore200e->stats->oc3.corr_hcs_errors), + be32_to_cpu(fore200e->stats->oc3.ucorr_hcs_errors)); if (!left--) return sprintf(page,"\n" @@ -2995,12 +2995,12 @@ fore200e_proc_read(struct atm_dev *dev, loff_t* pos, char* page) " vpi no conn:\t\t%10u\n" " vci out of range:\t\t%10u\n" " vci no conn:\t\t%10u\n", - cpu_to_be32(fore200e->stats->atm.cells_transmitted), - cpu_to_be32(fore200e->stats->atm.cells_received), - cpu_to_be32(fore200e->stats->atm.vpi_bad_range), - cpu_to_be32(fore200e->stats->atm.vpi_no_conn), - cpu_to_be32(fore200e->stats->atm.vci_bad_range), - cpu_to_be32(fore200e->stats->atm.vci_no_conn)); + be32_to_cpu(fore200e->stats->atm.cells_transmitted), + be32_to_cpu(fore200e->stats->atm.cells_received), + be32_to_cpu(fore200e->stats->atm.vpi_bad_range), + be32_to_cpu(fore200e->stats->atm.vpi_no_conn), + be32_to_cpu(fore200e->stats->atm.vci_bad_range), + be32_to_cpu(fore200e->stats->atm.vci_no_conn)); if (!left--) return sprintf(page,"\n" @@ -3008,9 +3008,9 @@ fore200e_proc_read(struct atm_dev *dev, loff_t* pos, char* page) " TX:\t\t\t%10u\n" " RX:\t\t\t%10u\n" " dropped:\t\t\t%10u\n", - cpu_to_be32(fore200e->stats->aal0.cells_transmitted), - cpu_to_be32(fore200e->stats->aal0.cells_received), - cpu_to_be32(fore200e->stats->aal0.cells_dropped)); + be32_to_cpu(fore200e->stats->aal0.cells_transmitted), + be32_to_cpu(fore200e->stats->aal0.cells_received), + be32_to_cpu(fore200e->stats->aal0.cells_dropped)); if (!left--) return sprintf(page,"\n" @@ -3026,15 +3026,15 @@ fore200e_proc_read(struct atm_dev *dev, loff_t* pos, char* page) " RX:\t\t\t%10u\n" " dropped:\t\t\t%10u\n" " protocol errors:\t\t%10u\n", - cpu_to_be32(fore200e->stats->aal34.cells_transmitted), - cpu_to_be32(fore200e->stats->aal34.cells_received), - cpu_to_be32(fore200e->stats->aal34.cells_dropped), - cpu_to_be32(fore200e->stats->aal34.cells_crc_errors), - cpu_to_be32(fore200e->stats->aal34.cells_protocol_errors), - cpu_to_be32(fore200e->stats->aal34.cspdus_transmitted), - cpu_to_be32(fore200e->stats->aal34.cspdus_received), - cpu_to_be32(fore200e->stats->aal34.cspdus_dropped), - cpu_to_be32(fore200e->stats->aal34.cspdus_protocol_errors)); + be32_to_cpu(fore200e->stats->aal34.cells_transmitted), + be32_to_cpu(fore200e->stats->aal34.cells_received), + be32_to_cpu(fore200e->stats->aal34.cells_dropped), + be32_to_cpu(fore200e->stats->aal34.cells_crc_errors), + be32_to_cpu(fore200e->stats->aal34.cells_protocol_errors), + be32_to_cpu(fore200e->stats->aal34.cspdus_transmitted), + be32_to_cpu(fore200e->stats->aal34.cspdus_received), + be32_to_cpu(fore200e->stats->aal34.cspdus_dropped), + be32_to_cpu(fore200e->stats->aal34.cspdus_protocol_errors)); if (!left--) return sprintf(page,"\n" @@ -3050,15 +3050,15 @@ fore200e_proc_read(struct atm_dev *dev, loff_t* pos, char* page) " dropped:\t\t\t%10u\n" " CRC errors:\t\t%10u\n" " protocol errors:\t\t%10u\n", - cpu_to_be32(fore200e->stats->aal5.cells_transmitted), - cpu_to_be32(fore200e->stats->aal5.cells_received), - cpu_to_be32(fore200e->stats->aal5.cells_dropped), - cpu_to_be32(fore200e->stats->aal5.congestion_experienced), - cpu_to_be32(fore200e->stats->aal5.cspdus_transmitted), - cpu_to_be32(fore200e->stats->aal5.cspdus_received), - cpu_to_be32(fore200e->stats->aal5.cspdus_dropped), - cpu_to_be32(fore200e->stats->aal5.cspdus_crc_errors), - cpu_to_be32(fore200e->stats->aal5.cspdus_protocol_errors)); + be32_to_cpu(fore200e->stats->aal5.cells_transmitted), + be32_to_cpu(fore200e->stats->aal5.cells_received), + be32_to_cpu(fore200e->stats->aal5.cells_dropped), + be32_to_cpu(fore200e->stats->aal5.congestion_experienced), + be32_to_cpu(fore200e->stats->aal5.cspdus_transmitted), + be32_to_cpu(fore200e->stats->aal5.cspdus_received), + be32_to_cpu(fore200e->stats->aal5.cspdus_dropped), + be32_to_cpu(fore200e->stats->aal5.cspdus_crc_errors), + be32_to_cpu(fore200e->stats->aal5.cspdus_protocol_errors)); if (!left--) return sprintf(page,"\n" @@ -3069,11 +3069,11 @@ fore200e_proc_read(struct atm_dev *dev, loff_t* pos, char* page) " large b2:\t\t\t%10u\n" " RX PDUs:\t\t\t%10u\n" " TX PDUs:\t\t\t%10lu\n", - cpu_to_be32(fore200e->stats->aux.small_b1_failed), - cpu_to_be32(fore200e->stats->aux.large_b1_failed), - cpu_to_be32(fore200e->stats->aux.small_b2_failed), - cpu_to_be32(fore200e->stats->aux.large_b2_failed), - cpu_to_be32(fore200e->stats->aux.rpd_alloc_failed), + be32_to_cpu(fore200e->stats->aux.small_b1_failed), + be32_to_cpu(fore200e->stats->aux.large_b1_failed), + be32_to_cpu(fore200e->stats->aux.small_b2_failed), + be32_to_cpu(fore200e->stats->aux.large_b2_failed), + be32_to_cpu(fore200e->stats->aux.rpd_alloc_failed), fore200e->tx_sat); if (!left--) diff --git a/drivers/atm/fore200e.h b/drivers/atm/fore200e.h index b85a54613dea0d290ffa84f2d41838104ad407b0..183841cc8fdf4f462f74840cabacc58e8cb8906f 100644 --- a/drivers/atm/fore200e.h +++ b/drivers/atm/fore200e.h @@ -349,90 +349,90 @@ typedef struct oc3_block { /* physical encoding statistics */ typedef struct stats_phy { - u32 crc_header_errors; /* cells received with bad header CRC */ - u32 framing_errors; /* cells received with bad framing */ - u32 pad[ 2 ]; /* i960 padding */ + __be32 crc_header_errors; /* cells received with bad header CRC */ + __be32 framing_errors; /* cells received with bad framing */ + __be32 pad[ 2 ]; /* i960 padding */ } stats_phy_t; /* OC-3 statistics */ typedef struct stats_oc3 { - u32 section_bip8_errors; /* section 8 bit interleaved parity */ - u32 path_bip8_errors; /* path 8 bit interleaved parity */ - u32 line_bip24_errors; /* line 24 bit interleaved parity */ - u32 line_febe_errors; /* line far end block errors */ - u32 path_febe_errors; /* path far end block errors */ - u32 corr_hcs_errors; /* correctable header check sequence */ - u32 ucorr_hcs_errors; /* uncorrectable header check sequence */ - u32 pad[ 1 ]; /* i960 padding */ + __be32 section_bip8_errors; /* section 8 bit interleaved parity */ + __be32 path_bip8_errors; /* path 8 bit interleaved parity */ + __be32 line_bip24_errors; /* line 24 bit interleaved parity */ + __be32 line_febe_errors; /* line far end block errors */ + __be32 path_febe_errors; /* path far end block errors */ + __be32 corr_hcs_errors; /* correctable header check sequence */ + __be32 ucorr_hcs_errors; /* uncorrectable header check sequence */ + __be32 pad[ 1 ]; /* i960 padding */ } stats_oc3_t; /* ATM statistics */ typedef struct stats_atm { - u32 cells_transmitted; /* cells transmitted */ - u32 cells_received; /* cells received */ - u32 vpi_bad_range; /* cell drops: VPI out of range */ - u32 vpi_no_conn; /* cell drops: no connection for VPI */ - u32 vci_bad_range; /* cell drops: VCI out of range */ - u32 vci_no_conn; /* cell drops: no connection for VCI */ - u32 pad[ 2 ]; /* i960 padding */ + __be32 cells_transmitted; /* cells transmitted */ + __be32 cells_received; /* cells received */ + __be32 vpi_bad_range; /* cell drops: VPI out of range */ + __be32 vpi_no_conn; /* cell drops: no connection for VPI */ + __be32 vci_bad_range; /* cell drops: VCI out of range */ + __be32 vci_no_conn; /* cell drops: no connection for VCI */ + __be32 pad[ 2 ]; /* i960 padding */ } stats_atm_t; /* AAL0 statistics */ typedef struct stats_aal0 { - u32 cells_transmitted; /* cells transmitted */ - u32 cells_received; /* cells received */ - u32 cells_dropped; /* cells dropped */ - u32 pad[ 1 ]; /* i960 padding */ + __be32 cells_transmitted; /* cells transmitted */ + __be32 cells_received; /* cells received */ + __be32 cells_dropped; /* cells dropped */ + __be32 pad[ 1 ]; /* i960 padding */ } stats_aal0_t; /* AAL3/4 statistics */ typedef struct stats_aal34 { - u32 cells_transmitted; /* cells transmitted from segmented PDUs */ - u32 cells_received; /* cells reassembled into PDUs */ - u32 cells_crc_errors; /* payload CRC error count */ - u32 cells_protocol_errors; /* SAR or CS layer protocol errors */ - u32 cells_dropped; /* cells dropped: partial reassembly */ - u32 cspdus_transmitted; /* CS PDUs transmitted */ - u32 cspdus_received; /* CS PDUs received */ - u32 cspdus_protocol_errors; /* CS layer protocol errors */ - u32 cspdus_dropped; /* reassembled PDUs drop'd (in cells) */ - u32 pad[ 3 ]; /* i960 padding */ + __be32 cells_transmitted; /* cells transmitted from segmented PDUs */ + __be32 cells_received; /* cells reassembled into PDUs */ + __be32 cells_crc_errors; /* payload CRC error count */ + __be32 cells_protocol_errors; /* SAR or CS layer protocol errors */ + __be32 cells_dropped; /* cells dropped: partial reassembly */ + __be32 cspdus_transmitted; /* CS PDUs transmitted */ + __be32 cspdus_received; /* CS PDUs received */ + __be32 cspdus_protocol_errors; /* CS layer protocol errors */ + __be32 cspdus_dropped; /* reassembled PDUs drop'd (in cells) */ + __be32 pad[ 3 ]; /* i960 padding */ } stats_aal34_t; /* AAL5 statistics */ typedef struct stats_aal5 { - u32 cells_transmitted; /* cells transmitted from segmented SDUs */ - u32 cells_received; /* cells reassembled into SDUs */ - u32 cells_dropped; /* reassembled PDUs dropped (in cells) */ - u32 congestion_experienced; /* CRC error and length wrong */ - u32 cspdus_transmitted; /* CS PDUs transmitted */ - u32 cspdus_received; /* CS PDUs received */ - u32 cspdus_crc_errors; /* CS PDUs CRC errors */ - u32 cspdus_protocol_errors; /* CS layer protocol errors */ - u32 cspdus_dropped; /* reassembled PDUs dropped */ - u32 pad[ 3 ]; /* i960 padding */ + __be32 cells_transmitted; /* cells transmitted from segmented SDUs */ + __be32 cells_received; /* cells reassembled into SDUs */ + __be32 cells_dropped; /* reassembled PDUs dropped (in cells) */ + __be32 congestion_experienced; /* CRC error and length wrong */ + __be32 cspdus_transmitted; /* CS PDUs transmitted */ + __be32 cspdus_received; /* CS PDUs received */ + __be32 cspdus_crc_errors; /* CS PDUs CRC errors */ + __be32 cspdus_protocol_errors; /* CS layer protocol errors */ + __be32 cspdus_dropped; /* reassembled PDUs dropped */ + __be32 pad[ 3 ]; /* i960 padding */ } stats_aal5_t; /* auxiliary statistics */ typedef struct stats_aux { - u32 small_b1_failed; /* receive BD allocation failures */ - u32 large_b1_failed; /* receive BD allocation failures */ - u32 small_b2_failed; /* receive BD allocation failures */ - u32 large_b2_failed; /* receive BD allocation failures */ - u32 rpd_alloc_failed; /* receive PDU allocation failures */ - u32 receive_carrier; /* no carrier = 0, carrier = 1 */ - u32 pad[ 2 ]; /* i960 padding */ + __be32 small_b1_failed; /* receive BD allocation failures */ + __be32 large_b1_failed; /* receive BD allocation failures */ + __be32 small_b2_failed; /* receive BD allocation failures */ + __be32 large_b2_failed; /* receive BD allocation failures */ + __be32 rpd_alloc_failed; /* receive PDU allocation failures */ + __be32 receive_carrier; /* no carrier = 0, carrier = 1 */ + __be32 pad[ 2 ]; /* i960 padding */ } stats_aux_t; @@ -643,10 +643,10 @@ typedef struct host_bsq { /* header of the firmware image */ typedef struct fw_header { - u32 magic; /* magic number */ - u32 version; /* firmware version id */ - u32 load_offset; /* fw load offset in board memory */ - u32 start_offset; /* fw execution start address in board memory */ + __le32 magic; /* magic number */ + __le32 version; /* firmware version id */ + __le32 load_offset; /* fw load offset in board memory */ + __le32 start_offset; /* fw execution start address in board memory */ } fw_header_t; #define FW_HEADER_MAGIC 0x65726f66 /* 'fore' */ diff --git a/drivers/atm/idt77252.c b/drivers/atm/idt77252.c index eee54c0cde6819ad064ada9cb619bdb3954f0052..b967919fb7e2e91a763ab8a6c53307f21cbfa443 100644 --- a/drivers/atm/idt77252.c +++ b/drivers/atm/idt77252.c @@ -555,7 +555,7 @@ idt77252_tx_dump(struct idt77252_dev *card) struct vc_map *vc; int i; - printk("%s\n", __FUNCTION__); + printk("%s\n", __func__); for (i = 0; i < card->tct_size; i++) { vc = card->vcs[i]; if (!vc) @@ -1035,7 +1035,7 @@ dequeue_rx(struct idt77252_dev *card, struct rsq_entry *rsqe) skb = sb_pool_skb(card, le32_to_cpu(rsqe->word_2)); if (skb == NULL) { printk("%s: NULL skb in %s, rsqe: %08x %08x %08x %08x\n", - card->name, __FUNCTION__, + card->name, __func__, le32_to_cpu(rsqe->word_1), le32_to_cpu(rsqe->word_2), le32_to_cpu(rsqe->word_3), le32_to_cpu(rsqe->word_4)); return; @@ -1873,7 +1873,7 @@ add_rx_skb(struct idt77252_dev *card, int queue, return; if (sb_pool_add(card, skb, queue)) { - printk("%s: SB POOL full\n", __FUNCTION__); + printk("%s: SB POOL full\n", __func__); goto outfree; } @@ -1883,7 +1883,7 @@ add_rx_skb(struct idt77252_dev *card, int queue, IDT77252_PRV_PADDR(skb) = paddr; if (push_rx_skb(card, skb, queue)) { - printk("%s: FB QUEUE full\n", __FUNCTION__); + printk("%s: FB QUEUE full\n", __func__); goto outunmap; } } @@ -3821,12 +3821,12 @@ static int __init idt77252_init(void) { struct sk_buff *skb; - printk("%s: at %p\n", __FUNCTION__, idt77252_init); + printk("%s: at %p\n", __func__, idt77252_init); if (sizeof(skb->cb) < sizeof(struct atm_skb_data) + sizeof(struct idt77252_skb_prv)) { printk(KERN_ERR "%s: skb->cb is too small (%lu < %lu)\n", - __FUNCTION__, (unsigned long) sizeof(skb->cb), + __func__, (unsigned long) sizeof(skb->cb), (unsigned long) sizeof(struct atm_skb_data) + sizeof(struct idt77252_skb_prv)); return -EIO; diff --git a/drivers/base/core.c b/drivers/base/core.c index 9c0070b5bd3e75d828a44d405dca4695b70e6ef6..7de543d1d0b4337328f95c502915d99b3a4fa871 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c @@ -621,7 +621,8 @@ static struct kobject *get_device_parent(struct device *dev, static void cleanup_glue_dir(struct device *dev, struct kobject *glue_dir) { /* see if we live in a "glue" directory */ - if (!dev->class || glue_dir->kset != &dev->class->class_dirs) + if (!glue_dir || !dev->class || + glue_dir->kset != &dev->class->class_dirs) return; kobject_put(glue_dir); @@ -770,17 +771,10 @@ int device_add(struct device *dev) struct class_interface *class_intf; int error; - error = pm_sleep_lock(); - if (error) { - dev_warn(dev, "Suspicious %s during suspend\n", __FUNCTION__); - dump_stack(); - return error; - } - dev = get_device(dev); if (!dev || !strlen(dev->bus_id)) { error = -EINVAL; - goto Error; + goto Done; } pr_debug("device: '%s': %s\n", dev->bus_id, __FUNCTION__); @@ -843,11 +837,9 @@ int device_add(struct device *dev) } Done: put_device(dev); - pm_sleep_unlock(); return error; BusError: device_pm_remove(dev); - dpm_sysfs_remove(dev); PMError: if (dev->bus) blocking_notifier_call_chain(&dev->bus->p->bus_notifier, diff --git a/drivers/base/platform.c b/drivers/base/platform.c index efaf282c438c4108b1f01c41dc6b873c0fde669d..911ec600fe71dec287cf922441a8cf53855ecf3f 100644 --- a/drivers/base/platform.c +++ b/drivers/base/platform.c @@ -648,7 +648,7 @@ u64 dma_get_required_mask(struct device *dev) high_totalram += high_totalram - 1; mask = (((u64)high_totalram) << 32) + 0xffffffff; } - return mask & *dev->dma_mask; + return mask; } EXPORT_SYMBOL_GPL(dma_get_required_mask); #endif diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c index ee9d1c8db0d6215c407a18d4a015e3e0ebb56c53..d887d5cb5bef74496f323a84d94b691ab24a2550 100644 --- a/drivers/base/power/main.c +++ b/drivers/base/power/main.c @@ -48,7 +48,6 @@ */ LIST_HEAD(dpm_active); -static LIST_HEAD(dpm_locked); static LIST_HEAD(dpm_off); static LIST_HEAD(dpm_off_irq); static LIST_HEAD(dpm_destroy); @@ -81,28 +80,6 @@ void device_pm_add(struct device *dev) */ void device_pm_remove(struct device *dev) { - /* - * If this function is called during a suspend, it will be blocked, - * because we're holding the device's semaphore at that time, which may - * lead to a deadlock. In that case we want to print a warning. - * However, it may also be called by unregister_dropped_devices() with - * the device's semaphore released, in which case the warning should - * not be printed. - */ - if (down_trylock(&dev->sem)) { - if (down_read_trylock(&pm_sleep_rwsem)) { - /* No suspend in progress, wait on dev->sem */ - down(&dev->sem); - up_read(&pm_sleep_rwsem); - } else { - /* Suspend in progress, we may deadlock */ - dev_warn(dev, "Suspicious %s during suspend\n", - __FUNCTION__); - dump_stack(); - /* The user has been warned ... */ - down(&dev->sem); - } - } pr_debug("PM: Removing info for %s:%s\n", dev->bus ? dev->bus->name : "No Bus", kobject_name(&dev->kobj)); @@ -110,7 +87,6 @@ void device_pm_remove(struct device *dev) dpm_sysfs_remove(dev); list_del_init(&dev->power.entry); mutex_unlock(&dpm_list_mtx); - up(&dev->sem); } /** @@ -230,6 +206,8 @@ static int resume_device(struct device *dev) TRACE_DEVICE(dev); TRACE_RESUME(0); + down(&dev->sem); + if (dev->bus && dev->bus->resume) { dev_dbg(dev,"resuming\n"); error = dev->bus->resume(dev); @@ -245,6 +223,8 @@ static int resume_device(struct device *dev) error = dev->class->resume(dev); } + up(&dev->sem); + TRACE_RESUME(error); return error; } @@ -266,7 +246,7 @@ static void dpm_resume(void) struct list_head *entry = dpm_off.next; struct device *dev = to_device(entry); - list_move_tail(entry, &dpm_locked); + list_move_tail(entry, &dpm_active); mutex_unlock(&dpm_list_mtx); resume_device(dev); mutex_lock(&dpm_list_mtx); @@ -274,25 +254,6 @@ static void dpm_resume(void) mutex_unlock(&dpm_list_mtx); } -/** - * unlock_all_devices - Release each device's semaphore - * - * Go through the dpm_off list. Put each device on the dpm_active - * list and unlock it. - */ -static void unlock_all_devices(void) -{ - mutex_lock(&dpm_list_mtx); - while (!list_empty(&dpm_locked)) { - struct list_head *entry = dpm_locked.prev; - struct device *dev = to_device(entry); - - list_move(entry, &dpm_active); - up(&dev->sem); - } - mutex_unlock(&dpm_list_mtx); -} - /** * unregister_dropped_devices - Unregister devices scheduled for removal * @@ -305,7 +266,6 @@ static void unregister_dropped_devices(void) struct list_head *entry = dpm_destroy.next; struct device *dev = to_device(entry); - up(&dev->sem); mutex_unlock(&dpm_list_mtx); /* This also removes the device from the list */ device_unregister(dev); @@ -324,7 +284,6 @@ void device_resume(void) { might_sleep(); dpm_resume(); - unlock_all_devices(); unregister_dropped_devices(); up_write(&pm_sleep_rwsem); } @@ -388,18 +347,15 @@ int device_power_down(pm_message_t state) struct list_head *entry = dpm_off.prev; struct device *dev = to_device(entry); - list_del_init(&dev->power.entry); error = suspend_device_late(dev, state); if (error) { printk(KERN_ERR "Could not power down device %s: " "error %d\n", kobject_name(&dev->kobj), error); - if (list_empty(&dev->power.entry)) - list_add(&dev->power.entry, &dpm_off); break; } - if (list_empty(&dev->power.entry)) - list_add(&dev->power.entry, &dpm_off_irq); + if (!list_empty(&dev->power.entry)) + list_move(&dev->power.entry, &dpm_off_irq); } if (!error) @@ -419,6 +375,8 @@ static int suspend_device(struct device *dev, pm_message_t state) { int error = 0; + down(&dev->sem); + if (dev->power.power_state.event) { dev_dbg(dev, "PM: suspend %d-->%d\n", dev->power.power_state.event, state.event); @@ -441,6 +399,9 @@ static int suspend_device(struct device *dev, pm_message_t state) error = dev->bus->suspend(dev, state); suspend_report_result(dev->bus->suspend, error); } + + up(&dev->sem); + return error; } @@ -461,13 +422,13 @@ static int dpm_suspend(pm_message_t state) int error = 0; mutex_lock(&dpm_list_mtx); - while (!list_empty(&dpm_locked)) { - struct list_head *entry = dpm_locked.prev; + while (!list_empty(&dpm_active)) { + struct list_head *entry = dpm_active.prev; struct device *dev = to_device(entry); - list_del_init(&dev->power.entry); mutex_unlock(&dpm_list_mtx); error = suspend_device(dev, state); + mutex_lock(&dpm_list_mtx); if (error) { printk(KERN_ERR "Could not suspend device %s: " "error %d%s\n", @@ -476,50 +437,16 @@ static int dpm_suspend(pm_message_t state) (error == -EAGAIN ? " (please convert to suspend_late)" : "")); - mutex_lock(&dpm_list_mtx); - if (list_empty(&dev->power.entry)) - list_add(&dev->power.entry, &dpm_locked); break; } - mutex_lock(&dpm_list_mtx); - if (list_empty(&dev->power.entry)) - list_add(&dev->power.entry, &dpm_off); + if (!list_empty(&dev->power.entry)) + list_move(&dev->power.entry, &dpm_off); } mutex_unlock(&dpm_list_mtx); return error; } -/** - * lock_all_devices - Acquire every device's semaphore - * - * Go through the dpm_active list. Carefully lock each device's - * semaphore and put it in on the dpm_locked list. - */ -static void lock_all_devices(void) -{ - mutex_lock(&dpm_list_mtx); - while (!list_empty(&dpm_active)) { - struct list_head *entry = dpm_active.next; - struct device *dev = to_device(entry); - - /* Required locking order is dev->sem first, - * then dpm_list_mutex. Hence this awkward code. - */ - get_device(dev); - mutex_unlock(&dpm_list_mtx); - down(&dev->sem); - mutex_lock(&dpm_list_mtx); - - if (list_empty(entry)) - up(&dev->sem); /* Device was removed */ - else - list_move_tail(entry, &dpm_locked); - put_device(dev); - } - mutex_unlock(&dpm_list_mtx); -} - /** * device_suspend - Save state and stop all devices in system. * @state: new power management state @@ -533,7 +460,6 @@ int device_suspend(pm_message_t state) might_sleep(); down_write(&pm_sleep_rwsem); - lock_all_devices(); error = dpm_suspend(state); if (error) device_resume(); diff --git a/drivers/base/sys.c b/drivers/base/sys.c index 2f79c55acdcc6af406a9e03b469a4853eefee808..8e13fd9421635753f7b634ba4177b5df003a074f 100644 --- a/drivers/base/sys.c +++ b/drivers/base/sys.c @@ -133,6 +133,7 @@ int sysdev_class_register(struct sysdev_class * cls) pr_debug("Registering sysdev class '%s'\n", kobject_name(&cls->kset.kobj)); INIT_LIST_HEAD(&cls->drivers); + memset(&cls->kset.kobj, 0x00, sizeof(struct kobject)); cls->kset.kobj.parent = &system_kset->kobj; cls->kset.kobj.ktype = &ktype_sysdev_class; cls->kset.kobj.kset = system_kset; @@ -227,6 +228,9 @@ int sysdev_register(struct sys_device * sysdev) pr_debug("Registering sys device '%s'\n", kobject_name(&sysdev->kobj)); + /* initialize the kobject to 0, in case it had previously been used */ + memset(&sysdev->kobj, 0x00, sizeof(struct kobject)); + /* Make sure the kset is set */ sysdev->kobj.kset = &cls->kset; diff --git a/drivers/base/transport_class.c b/drivers/base/transport_class.c index f25e7c6b2d27301990eb6bc133015b5889a754e9..40bca48abc12dcfa18de9e92c8e4327fb1bf6845 100644 --- a/drivers/base/transport_class.c +++ b/drivers/base/transport_class.c @@ -126,9 +126,7 @@ static int transport_setup_classdev(struct attribute_container *cont, } /** - * transport_setup_device - declare a new dev for transport class association - * but don't make it visible yet. - * + * transport_setup_device - declare a new dev for transport class association but don't make it visible yet. * @dev: the generic device representing the entity being added * * Usually, dev represents some component in the HBA system (either diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c index 9715be3f2487c161493f231ee2ef739806cdddc4..55bd35c0f082344a1d33822d081fcd7f9a104663 100644 --- a/drivers/block/cciss.c +++ b/drivers/block/cciss.c @@ -33,6 +33,7 @@ #include #include #include +#include #include #include #include @@ -131,7 +132,6 @@ static struct board_type products[] = { /*define how many times we will try a command because of bus resets */ #define MAX_CMD_RETRIES 3 -#define READ_AHEAD 1024 #define MAX_CTLR 32 /* Originally cciss driver only supports 8 major numbers */ @@ -174,8 +174,6 @@ static int sendcmd_withirq(__u8 cmd, int ctlr, void *buff, size_t size, static void fail_all_cmds(unsigned long ctlr); #ifdef CONFIG_PROC_FS -static int cciss_proc_get_info(char *buffer, char **start, off_t offset, - int length, int *eof, void *data); static void cciss_procinit(int i); #else static void cciss_procinit(int i) @@ -240,24 +238,46 @@ static inline CommandList_struct *removeQ(CommandList_struct **Qptr, */ #define ENG_GIG 1000000000 #define ENG_GIG_FACTOR (ENG_GIG/512) +#define ENGAGE_SCSI "engage scsi" static const char *raid_label[] = { "0", "4", "1(1+0)", "5", "5+1", "ADG", "UNKNOWN" }; static struct proc_dir_entry *proc_cciss; -static int cciss_proc_get_info(char *buffer, char **start, off_t offset, - int length, int *eof, void *data) +static void cciss_seq_show_header(struct seq_file *seq) { - off_t pos = 0; - off_t len = 0; - int size, i, ctlr; - ctlr_info_t *h = (ctlr_info_t *) data; - drive_info_struct *drv; - unsigned long flags; - sector_t vol_sz, vol_sz_frac; + ctlr_info_t *h = seq->private; + + seq_printf(seq, "%s: HP %s Controller\n" + "Board ID: 0x%08lx\n" + "Firmware Version: %c%c%c%c\n" + "IRQ: %d\n" + "Logical drives: %d\n" + "Current Q depth: %d\n" + "Current # commands on controller: %d\n" + "Max Q depth since init: %d\n" + "Max # commands on controller since init: %d\n" + "Max SG entries since init: %d\n", + h->devname, + h->product_name, + (unsigned long)h->board_id, + h->firm_ver[0], h->firm_ver[1], h->firm_ver[2], + h->firm_ver[3], (unsigned int)h->intr[SIMPLE_MODE_INT], + h->num_luns, + h->Qdepth, h->commands_outstanding, + h->maxQsinceinit, h->max_outstanding, h->maxSG); - ctlr = h->ctlr; +#ifdef CONFIG_CISS_SCSI_TAPE + cciss_seq_tape_report(seq, h->ctlr); +#endif /* CONFIG_CISS_SCSI_TAPE */ +} + +static void *cciss_seq_start(struct seq_file *seq, loff_t *pos) +{ + ctlr_info_t *h = seq->private; + unsigned ctlr = h->ctlr; + unsigned long flags; /* prevent displaying bogus info during configuration * or deconfiguration of a logical volume @@ -265,115 +285,155 @@ static int cciss_proc_get_info(char *buffer, char **start, off_t offset, spin_lock_irqsave(CCISS_LOCK(ctlr), flags); if (h->busy_configuring) { spin_unlock_irqrestore(CCISS_LOCK(ctlr), flags); - return -EBUSY; + return ERR_PTR(-EBUSY); } h->busy_configuring = 1; spin_unlock_irqrestore(CCISS_LOCK(ctlr), flags); - size = sprintf(buffer, "%s: HP %s Controller\n" - "Board ID: 0x%08lx\n" - "Firmware Version: %c%c%c%c\n" - "IRQ: %d\n" - "Logical drives: %d\n" - "Max sectors: %d\n" - "Current Q depth: %d\n" - "Current # commands on controller: %d\n" - "Max Q depth since init: %d\n" - "Max # commands on controller since init: %d\n" - "Max SG entries since init: %d\n\n", - h->devname, - h->product_name, - (unsigned long)h->board_id, - h->firm_ver[0], h->firm_ver[1], h->firm_ver[2], - h->firm_ver[3], (unsigned int)h->intr[SIMPLE_MODE_INT], - h->num_luns, - h->cciss_max_sectors, - h->Qdepth, h->commands_outstanding, - h->maxQsinceinit, h->max_outstanding, h->maxSG); - - pos += size; - len += size; - cciss_proc_tape_report(ctlr, buffer, &pos, &len); - for (i = 0; i <= h->highest_lun; i++) { - - drv = &h->drv[i]; - if (drv->heads == 0) - continue; + if (*pos == 0) + cciss_seq_show_header(seq); - vol_sz = drv->nr_blocks; - vol_sz_frac = sector_div(vol_sz, ENG_GIG_FACTOR); - vol_sz_frac *= 100; - sector_div(vol_sz_frac, ENG_GIG_FACTOR); + return pos; +} + +static int cciss_seq_show(struct seq_file *seq, void *v) +{ + sector_t vol_sz, vol_sz_frac; + ctlr_info_t *h = seq->private; + unsigned ctlr = h->ctlr; + loff_t *pos = v; + drive_info_struct *drv = &h->drv[*pos]; + + if (*pos > h->highest_lun) + return 0; + + if (drv->heads == 0) + return 0; + + vol_sz = drv->nr_blocks; + vol_sz_frac = sector_div(vol_sz, ENG_GIG_FACTOR); + vol_sz_frac *= 100; + sector_div(vol_sz_frac, ENG_GIG_FACTOR); + + if (drv->raid_level > 5) + drv->raid_level = RAID_UNKNOWN; + seq_printf(seq, "cciss/c%dd%d:" + "\t%4u.%02uGB\tRAID %s\n", + ctlr, (int) *pos, (int)vol_sz, (int)vol_sz_frac, + raid_label[drv->raid_level]); + return 0; +} + +static void *cciss_seq_next(struct seq_file *seq, void *v, loff_t *pos) +{ + ctlr_info_t *h = seq->private; + + if (*pos > h->highest_lun) + return NULL; + *pos += 1; + + return pos; +} + +static void cciss_seq_stop(struct seq_file *seq, void *v) +{ + ctlr_info_t *h = seq->private; + + /* Only reset h->busy_configuring if we succeeded in setting + * it during cciss_seq_start. */ + if (v == ERR_PTR(-EBUSY)) + return; - if (drv->raid_level > 5) - drv->raid_level = RAID_UNKNOWN; - size = sprintf(buffer + len, "cciss/c%dd%d:" - "\t%4u.%02uGB\tRAID %s\n", - ctlr, i, (int)vol_sz, (int)vol_sz_frac, - raid_label[drv->raid_level]); - pos += size; - len += size; - } - - *eof = 1; - *start = buffer + offset; - len -= offset; - if (len > length) - len = length; h->busy_configuring = 0; - return len; } -static int -cciss_proc_write(struct file *file, const char __user *buffer, - unsigned long count, void *data) +static struct seq_operations cciss_seq_ops = { + .start = cciss_seq_start, + .show = cciss_seq_show, + .next = cciss_seq_next, + .stop = cciss_seq_stop, +}; + +static int cciss_seq_open(struct inode *inode, struct file *file) { - unsigned char cmd[80]; - int len; -#ifdef CONFIG_CISS_SCSI_TAPE - ctlr_info_t *h = (ctlr_info_t *) data; - int rc; + int ret = seq_open(file, &cciss_seq_ops); + struct seq_file *seq = file->private_data; + + if (!ret) + seq->private = PDE(inode)->data; + + return ret; +} + +static ssize_t +cciss_proc_write(struct file *file, const char __user *buf, + size_t length, loff_t *ppos) +{ + int err; + char *buffer; + +#ifndef CONFIG_CISS_SCSI_TAPE + return -EINVAL; #endif - if (count > sizeof(cmd) - 1) + if (!buf || length > PAGE_SIZE - 1) return -EINVAL; - if (copy_from_user(cmd, buffer, count)) - return -EFAULT; - cmd[count] = '\0'; - len = strlen(cmd); // above 3 lines ensure safety - if (len && cmd[len - 1] == '\n') - cmd[--len] = '\0'; -# ifdef CONFIG_CISS_SCSI_TAPE - if (strcmp("engage scsi", cmd) == 0) { + + buffer = (char *)__get_free_page(GFP_KERNEL); + if (!buffer) + return -ENOMEM; + + err = -EFAULT; + if (copy_from_user(buffer, buf, length)) + goto out; + buffer[length] = '\0'; + +#ifdef CONFIG_CISS_SCSI_TAPE + if (strncmp(ENGAGE_SCSI, buffer, sizeof ENGAGE_SCSI - 1) == 0) { + struct seq_file *seq = file->private_data; + ctlr_info_t *h = seq->private; + int rc; + rc = cciss_engage_scsi(h->ctlr); if (rc != 0) - return -rc; - return count; - } + err = -rc; + else + err = length; + } else +#endif /* CONFIG_CISS_SCSI_TAPE */ + err = -EINVAL; /* might be nice to have "disengage" too, but it's not safely possible. (only 1 module use count, lock issues.) */ -# endif - return -EINVAL; + +out: + free_page((unsigned long)buffer); + return err; } -/* - * Get us a file in /proc/cciss that says something about each controller. - * Create /proc/cciss if it doesn't exist yet. - */ +static struct file_operations cciss_proc_fops = { + .owner = THIS_MODULE, + .open = cciss_seq_open, + .read = seq_read, + .llseek = seq_lseek, + .release = seq_release, + .write = cciss_proc_write, +}; + static void __devinit cciss_procinit(int i) { struct proc_dir_entry *pde; - if (proc_cciss == NULL) { + if (proc_cciss == NULL) proc_cciss = proc_mkdir("cciss", proc_root_driver); - if (!proc_cciss) - return; - } + if (!proc_cciss) + return; + pde = proc_create(hba[i]->devname, S_IWUSR | S_IRUSR | S_IRGRP | + S_IROTH, proc_cciss, + &cciss_proc_fops); + if (!pde) + return; - pde = create_proc_read_entry(hba[i]->devname, - S_IWUSR | S_IRUSR | S_IRGRP | S_IROTH, - proc_cciss, cciss_proc_get_info, hba[i]); - pde->write_proc = cciss_proc_write; + pde->data = hba[i]; } #endif /* CONFIG_PROC_FS */ @@ -1341,7 +1401,6 @@ geo_inq: disk->private_data = &h->drv[drv_index]; /* Set up queue information */ - disk->queue->backing_dev_info.ra_pages = READ_AHEAD; blk_queue_bounce_limit(disk->queue, hba[ctlr]->pdev->dma_mask); /* This is a hardware imposed limit. */ @@ -3434,7 +3493,6 @@ static int __devinit cciss_init_one(struct pci_dev *pdev, } drv->queue = q; - q->backing_dev_info.ra_pages = READ_AHEAD; blk_queue_bounce_limit(q, hba[i]->pdev->dma_mask); /* This is a hardware imposed limit. */ diff --git a/drivers/block/cciss_scsi.c b/drivers/block/cciss_scsi.c index 55178e9973a094fe08fd23bf040c237e58695a02..45ac09300eb338c50f372bd51f2532e8bdec8d1b 100644 --- a/drivers/block/cciss_scsi.c +++ b/drivers/block/cciss_scsi.c @@ -1404,21 +1404,18 @@ cciss_engage_scsi(int ctlr) } static void -cciss_proc_tape_report(int ctlr, unsigned char *buffer, off_t *pos, off_t *len) +cciss_seq_tape_report(struct seq_file *seq, int ctlr) { unsigned long flags; - int size; - - *pos = *pos -1; *len = *len - 1; // cut off the last trailing newline CPQ_TAPE_LOCK(ctlr, flags); - size = sprintf(buffer + *len, + seq_printf(seq, "Sequential access devices: %d\n\n", ccissscsi[ctlr].ndevices); CPQ_TAPE_UNLOCK(ctlr, flags); - *pos += size; *len += size; } + /* Need at least one of these error handlers to keep ../scsi/hosts.c from * complaining. Doing a host- or bus-reset can't do anything good here. * Despite what it might say in scsi_error.c, there may well be commands @@ -1498,6 +1495,5 @@ static int cciss_eh_abort_handler(struct scsi_cmnd *scsicmd) #define cciss_scsi_setup(cntl_num) #define cciss_unregister_scsi(ctlr) #define cciss_register_scsi(ctlr) -#define cciss_proc_tape_report(ctlr, buffer, pos, len) #endif /* CONFIG_CISS_SCSI_TAPE */ diff --git a/drivers/block/floppy.c b/drivers/block/floppy.c index 32c79a55511bd174f3effd63af4e5bd7bc594b68..7652e87d60c52cb7c2a18053198fd205ec1ef9b2 100644 --- a/drivers/block/floppy.c +++ b/drivers/block/floppy.c @@ -217,7 +217,6 @@ static int use_virtual_dma; */ static DEFINE_SPINLOCK(floppy_lock); -static struct completion device_release; static unsigned short virtual_dma_port = 0x3f0; irqreturn_t floppy_interrupt(int irq, void *dev_id); @@ -4144,7 +4143,6 @@ DEVICE_ATTR(cmos,S_IRUGO,floppy_cmos_show,NULL); static void floppy_device_release(struct device *dev) { - complete(&device_release); } static struct platform_device floppy_device[N_DRIVE]; @@ -4539,7 +4537,6 @@ void cleanup_module(void) { int drive; - init_completion(&device_release); blk_unregister_region(MKDEV(FLOPPY_MAJOR, 0), 256); unregister_blkdev(FLOPPY_MAJOR, "fd"); @@ -4564,8 +4561,6 @@ void cleanup_module(void) /* eject disk, if any */ fd_eject(0); - - wait_for_completion(&device_release); } module_param(floppy, charp, 0); diff --git a/drivers/block/pktcdvd.c b/drivers/block/pktcdvd.c index 674cd66dcabaae261ca0e97c5ab61a1f272b2db5..18feb1c7c33b1b03ec0d394767e252b466000876 100644 --- a/drivers/block/pktcdvd.c +++ b/drivers/block/pktcdvd.c @@ -849,7 +849,8 @@ static int pkt_flush_cache(struct pktcdvd_device *pd) /* * speed is given as the normal factor, e.g. 4 for 4x */ -static int pkt_set_speed(struct pktcdvd_device *pd, unsigned write_speed, unsigned read_speed) +static noinline_for_stack int pkt_set_speed(struct pktcdvd_device *pd, + unsigned write_speed, unsigned read_speed) { struct packet_command cgc; struct request_sense sense; @@ -1776,7 +1777,8 @@ static int pkt_get_track_info(struct pktcdvd_device *pd, __u16 track, __u8 type, return pkt_generic_packet(pd, &cgc); } -static int pkt_get_last_written(struct pktcdvd_device *pd, long *last_written) +static noinline_for_stack int pkt_get_last_written(struct pktcdvd_device *pd, + long *last_written) { disc_information di; track_information ti; @@ -1813,7 +1815,7 @@ static int pkt_get_last_written(struct pktcdvd_device *pd, long *last_written) /* * write mode select package based on pd->settings */ -static int pkt_set_write_settings(struct pktcdvd_device *pd) +static noinline_for_stack int pkt_set_write_settings(struct pktcdvd_device *pd) { struct packet_command cgc; struct request_sense sense; @@ -1972,7 +1974,7 @@ static int pkt_writable_disc(struct pktcdvd_device *pd, disc_information *di) return 1; } -static int pkt_probe_settings(struct pktcdvd_device *pd) +static noinline_for_stack int pkt_probe_settings(struct pktcdvd_device *pd) { struct packet_command cgc; unsigned char buf[12]; @@ -2071,7 +2073,8 @@ static int pkt_probe_settings(struct pktcdvd_device *pd) /* * enable/disable write caching on drive */ -static int pkt_write_caching(struct pktcdvd_device *pd, int set) +static noinline_for_stack int pkt_write_caching(struct pktcdvd_device *pd, + int set) { struct packet_command cgc; struct request_sense sense; @@ -2116,7 +2119,8 @@ static int pkt_lock_door(struct pktcdvd_device *pd, int lockflag) /* * Returns drive maximum write speed */ -static int pkt_get_max_speed(struct pktcdvd_device *pd, unsigned *write_speed) +static noinline_for_stack int pkt_get_max_speed(struct pktcdvd_device *pd, + unsigned *write_speed) { struct packet_command cgc; struct request_sense sense; @@ -2177,7 +2181,8 @@ static char us_clv_to_speed[16] = { /* * reads the maximum media speed from ATIP */ -static int pkt_media_speed(struct pktcdvd_device *pd, unsigned *speed) +static noinline_for_stack int pkt_media_speed(struct pktcdvd_device *pd, + unsigned *speed) { struct packet_command cgc; struct request_sense sense; @@ -2249,7 +2254,7 @@ static int pkt_media_speed(struct pktcdvd_device *pd, unsigned *speed) } } -static int pkt_perform_opc(struct pktcdvd_device *pd) +static noinline_for_stack int pkt_perform_opc(struct pktcdvd_device *pd) { struct packet_command cgc; struct request_sense sense; diff --git a/drivers/block/viodasd.c b/drivers/block/viodasd.c index 9e61fca46117e618677483aa74c2ac90c310352c..41ca721d2523fec5987e02db1e9e7a26f35f60bb 100644 --- a/drivers/block/viodasd.c +++ b/drivers/block/viodasd.c @@ -528,8 +528,7 @@ static int block_event_to_scatterlist(const struct vioblocklpevent *bevent, numsg = VIOMAXBLOCKDMA; *total_len = 0; - memset(sg, 0, sizeof(sg[0]) * VIOMAXBLOCKDMA); - + sg_init_table(sg, VIOMAXBLOCKDMA); for (i = 0; (i < numsg) && (rw_data->dma_info[i].len > 0); ++i) { sg_dma_address(&sg[i]) = rw_data->dma_info[i].token; sg_dma_len(&sg[i]) = rw_data->dma_info[i].len; diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c index 3b1a68d6eddb3c0860794c778a643340b59ec920..0cfbe8c594a55c208a7727cc20a86db0e33ba704 100644 --- a/drivers/block/virtio_blk.c +++ b/drivers/block/virtio_blk.c @@ -238,6 +238,7 @@ static int virtblk_probe(struct virtio_device *vdev) vblk->disk->first_minor = index_to_minor(index); vblk->disk->private_data = vblk; vblk->disk->fops = &virtblk_fops; + vblk->disk->driverfs_dev = &vdev->dev; index++; /* If barriers are supported, tell block layer that queue is ordered */ diff --git a/drivers/bluetooth/hci_usb.c b/drivers/bluetooth/hci_usb.c index 372c7ef633dab53471c5d3e0dda7ac4dc49fdeff..8b884f87d8b7be56d4a290469cab518ebac62ba9 100644 --- a/drivers/bluetooth/hci_usb.c +++ b/drivers/bluetooth/hci_usb.c @@ -116,6 +116,7 @@ static struct usb_device_id blacklist_ids[] = { { USB_DEVICE(0x0a5c, 0x2009), .driver_info = HCI_BCM92035 }, /* Broadcom BCM2045 */ + { USB_DEVICE(0x0a5c, 0x2039), .driver_info = HCI_RESET | HCI_WRONG_SCO_MTU }, { USB_DEVICE(0x0a5c, 0x2101), .driver_info = HCI_RESET | HCI_WRONG_SCO_MTU }, /* IBM/Lenovo ThinkPad with Broadcom chip */ @@ -148,6 +149,9 @@ static struct usb_device_id blacklist_ids[] = { { USB_DEVICE(0x0400, 0x0807), .driver_info = HCI_BROKEN_ISOC }, { USB_DEVICE(0x0400, 0x080a), .driver_info = HCI_BROKEN_ISOC }, + /* CONWISE Technology based adapters with buggy SCO support */ + { USB_DEVICE(0x0e5e, 0x6622), .driver_info = HCI_BROKEN_ISOC }, + /* Belkin F8T012 and F8T013 devices */ { USB_DEVICE(0x050d, 0x0012), .driver_info = HCI_RESET | HCI_WRONG_SCO_MTU }, { USB_DEVICE(0x050d, 0x0013), .driver_info = HCI_RESET | HCI_WRONG_SCO_MTU }, diff --git a/drivers/cdrom/cdrom.c b/drivers/cdrom/cdrom.c index db259e60289b51ca84b46f56f67a741b0c473c16..12f5baea439bbf8a85874188b4e2dbeb4d79459a 100644 --- a/drivers/cdrom/cdrom.c +++ b/drivers/cdrom/cdrom.c @@ -1152,8 +1152,8 @@ clean_up_and_return: /* This code is similar to that in open_for_data. The routine is called whenever an audio play operation is requested. */ -int check_for_audio_disc(struct cdrom_device_info * cdi, - struct cdrom_device_ops * cdo) +static int check_for_audio_disc(struct cdrom_device_info * cdi, + struct cdrom_device_ops * cdo) { int ret; tracktype tracks; diff --git a/drivers/char/defkeymap.c_shipped b/drivers/char/defkeymap.c_shipped index 0aa419a617674dfe20bb6d8dfe09aa706ad5cf18..d2208dfe3f678443bf7e8547e89ff0c9445b03c4 100644 --- a/drivers/char/defkeymap.c_shipped +++ b/drivers/char/defkeymap.c_shipped @@ -223,40 +223,40 @@ char *func_table[MAX_NR_FUNC] = { }; struct kbdiacruc accent_table[MAX_DIACR] = { - {'`', 'A', '\300'}, {'`', 'a', '\340'}, - {'\'', 'A', '\301'}, {'\'', 'a', '\341'}, - {'^', 'A', '\302'}, {'^', 'a', '\342'}, - {'~', 'A', '\303'}, {'~', 'a', '\343'}, - {'"', 'A', '\304'}, {'"', 'a', '\344'}, - {'O', 'A', '\305'}, {'o', 'a', '\345'}, - {'0', 'A', '\305'}, {'0', 'a', '\345'}, - {'A', 'A', '\305'}, {'a', 'a', '\345'}, - {'A', 'E', '\306'}, {'a', 'e', '\346'}, - {',', 'C', '\307'}, {',', 'c', '\347'}, - {'`', 'E', '\310'}, {'`', 'e', '\350'}, - {'\'', 'E', '\311'}, {'\'', 'e', '\351'}, - {'^', 'E', '\312'}, {'^', 'e', '\352'}, - {'"', 'E', '\313'}, {'"', 'e', '\353'}, - {'`', 'I', '\314'}, {'`', 'i', '\354'}, - {'\'', 'I', '\315'}, {'\'', 'i', '\355'}, - {'^', 'I', '\316'}, {'^', 'i', '\356'}, - {'"', 'I', '\317'}, {'"', 'i', '\357'}, - {'-', 'D', '\320'}, {'-', 'd', '\360'}, - {'~', 'N', '\321'}, {'~', 'n', '\361'}, - {'`', 'O', '\322'}, {'`', 'o', '\362'}, - {'\'', 'O', '\323'}, {'\'', 'o', '\363'}, - {'^', 'O', '\324'}, {'^', 'o', '\364'}, - {'~', 'O', '\325'}, {'~', 'o', '\365'}, - {'"', 'O', '\326'}, {'"', 'o', '\366'}, - {'/', 'O', '\330'}, {'/', 'o', '\370'}, - {'`', 'U', '\331'}, {'`', 'u', '\371'}, - {'\'', 'U', '\332'}, {'\'', 'u', '\372'}, - {'^', 'U', '\333'}, {'^', 'u', '\373'}, - {'"', 'U', '\334'}, {'"', 'u', '\374'}, - {'\'', 'Y', '\335'}, {'\'', 'y', '\375'}, - {'T', 'H', '\336'}, {'t', 'h', '\376'}, - {'s', 's', '\337'}, {'"', 'y', '\377'}, - {'s', 'z', '\337'}, {'i', 'j', '\377'}, + {'`', 'A', 0300}, {'`', 'a', 0340}, + {'\'', 'A', 0301}, {'\'', 'a', 0341}, + {'^', 'A', 0302}, {'^', 'a', 0342}, + {'~', 'A', 0303}, {'~', 'a', 0343}, + {'"', 'A', 0304}, {'"', 'a', 0344}, + {'O', 'A', 0305}, {'o', 'a', 0345}, + {'0', 'A', 0305}, {'0', 'a', 0345}, + {'A', 'A', 0305}, {'a', 'a', 0345}, + {'A', 'E', 0306}, {'a', 'e', 0346}, + {',', 'C', 0307}, {',', 'c', 0347}, + {'`', 'E', 0310}, {'`', 'e', 0350}, + {'\'', 'E', 0311}, {'\'', 'e', 0351}, + {'^', 'E', 0312}, {'^', 'e', 0352}, + {'"', 'E', 0313}, {'"', 'e', 0353}, + {'`', 'I', 0314}, {'`', 'i', 0354}, + {'\'', 'I', 0315}, {'\'', 'i', 0355}, + {'^', 'I', 0316}, {'^', 'i', 0356}, + {'"', 'I', 0317}, {'"', 'i', 0357}, + {'-', 'D', 0320}, {'-', 'd', 0360}, + {'~', 'N', 0321}, {'~', 'n', 0361}, + {'`', 'O', 0322}, {'`', 'o', 0362}, + {'\'', 'O', 0323}, {'\'', 'o', 0363}, + {'^', 'O', 0324}, {'^', 'o', 0364}, + {'~', 'O', 0325}, {'~', 'o', 0365}, + {'"', 'O', 0326}, {'"', 'o', 0366}, + {'/', 'O', 0330}, {'/', 'o', 0370}, + {'`', 'U', 0331}, {'`', 'u', 0371}, + {'\'', 'U', 0332}, {'\'', 'u', 0372}, + {'^', 'U', 0333}, {'^', 'u', 0373}, + {'"', 'U', 0334}, {'"', 'u', 0374}, + {'\'', 'Y', 0335}, {'\'', 'y', 0375}, + {'T', 'H', 0336}, {'t', 'h', 0376}, + {'s', 's', 0337}, {'"', 'y', 0377}, + {'s', 'z', 0337}, {'i', 'j', 0377}, }; unsigned int accent_table_size = 68; diff --git a/drivers/char/esp.c b/drivers/char/esp.c index c01e26d9ee5ecfff6d51b7de24e8abf536b86d38..f3fe620673440e267172e957f174028933beacbc 100644 --- a/drivers/char/esp.c +++ b/drivers/char/esp.c @@ -2484,6 +2484,7 @@ static int __init espserial_init(void) return 0; } + spin_lock_init(&info->lock); /* rx_trigger, tx_trigger are needed by autoconfig */ info->config.rx_trigger = rx_trigger; info->config.tx_trigger = tx_trigger; diff --git a/drivers/char/isicom.c b/drivers/char/isicom.c index 85d596a3c18c35b7248b4ee98fcaba65c60abcf0..eba2883b630ede817677c54a7cfe3e94f1582be1 100644 --- a/drivers/char/isicom.c +++ b/drivers/char/isicom.c @@ -1527,7 +1527,7 @@ static int __devinit reset_card(struct pci_dev *pdev, msleep(10); portcount = inw(base + 0x2); - if (!inw(base + 0xe) & 0x1 || (portcount != 0 && portcount != 4 && + if (!(inw(base + 0xe) & 0x1) || (portcount != 0 && portcount != 4 && portcount != 8 && portcount != 16)) { dev_err(&pdev->dev, "ISILoad:PCI Card%d reset failure.\n", card + 1); diff --git a/drivers/char/nozomi.c b/drivers/char/nozomi.c index dfaab2322de32c09a0adeab709cf5613ca9a0d5f..6d0dc5f9b6bbc015b4b4323d02fb6ed83b7e81e9 100644 --- a/drivers/char/nozomi.c +++ b/drivers/char/nozomi.c @@ -190,6 +190,14 @@ enum card_type { F32_8 = 8192, /* 3072 bytes downl. + 1024 bytes uplink * 2 -> 8192 */ }; +/* Initialization states a card can be in */ +enum card_state { + NOZOMI_STATE_UKNOWN = 0, + NOZOMI_STATE_ENABLED = 1, /* pci device enabled */ + NOZOMI_STATE_ALLOCATED = 2, /* config setup done */ + NOZOMI_STATE_READY = 3, /* flowcontrols received */ +}; + /* Two different toggle channels exist */ enum channel_type { CH_A = 0, @@ -385,6 +393,7 @@ struct nozomi { spinlock_t spin_mutex; /* secures access to registers and tty */ unsigned int index_start; + enum card_state state; u32 open_ttys; }; @@ -686,6 +695,7 @@ static int nozomi_read_config_table(struct nozomi *dc) dc->last_ier = dc->last_ier | CTRL_DL; writew(dc->last_ier, dc->reg_ier); + dc->state = NOZOMI_STATE_ALLOCATED; dev_info(&dc->pdev->dev, "Initialization OK!\n"); return 1; } @@ -944,6 +954,14 @@ static int receive_flow_control(struct nozomi *dc) case CTRL_APP2: port = PORT_APP2; enable_ier = APP2_DL; + if (dc->state == NOZOMI_STATE_ALLOCATED) { + /* + * After card initialization the flow control + * received for APP2 is always the last + */ + dc->state = NOZOMI_STATE_READY; + dev_info(&dc->pdev->dev, "Device READY!\n"); + } break; default: dev_err(&dc->pdev->dev, @@ -1366,22 +1384,12 @@ static int __devinit nozomi_card_init(struct pci_dev *pdev, dc->pdev = pdev; - /* Find out what card type it is */ - nozomi_get_card_type(dc); - ret = pci_enable_device(dc->pdev); if (ret) { dev_err(&pdev->dev, "Failed to enable PCI Device\n"); goto err_free; } - start = pci_resource_start(dc->pdev, 0); - if (start == 0) { - dev_err(&pdev->dev, "No I/O address for card detected\n"); - ret = -ENODEV; - goto err_disable_device; - } - ret = pci_request_regions(dc->pdev, NOZOMI_NAME); if (ret) { dev_err(&pdev->dev, "I/O address 0x%04x already in use\n", @@ -1389,6 +1397,16 @@ static int __devinit nozomi_card_init(struct pci_dev *pdev, goto err_disable_device; } + start = pci_resource_start(dc->pdev, 0); + if (start == 0) { + dev_err(&pdev->dev, "No I/O address for card detected\n"); + ret = -ENODEV; + goto err_rel_regs; + } + + /* Find out what card type it is */ + nozomi_get_card_type(dc); + dc->base_addr = ioremap(start, dc->card_type); if (!dc->base_addr) { dev_err(&pdev->dev, "Unable to map card MMIO\n"); @@ -1425,6 +1443,14 @@ static int __devinit nozomi_card_init(struct pci_dev *pdev, dc->index_start = ndev_idx * MAX_PORT; ndevs[ndev_idx] = dc; + pci_set_drvdata(pdev, dc); + + /* Enable RESET interrupt */ + dc->last_ier = RESET; + iowrite16(dc->last_ier, dc->reg_ier); + + dc->state = NOZOMI_STATE_ENABLED; + for (i = 0; i < MAX_PORT; i++) { mutex_init(&dc->port[i].tty_sem); dc->port[i].tty_open_count = 0; @@ -1433,12 +1459,6 @@ static int __devinit nozomi_card_init(struct pci_dev *pdev, &pdev->dev); } - /* Enable RESET interrupt. */ - dc->last_ier = RESET; - writew(dc->last_ier, dc->reg_ier); - - pci_set_drvdata(pdev, dc); - return 0; err_free_sbuf: @@ -1553,7 +1573,7 @@ static int ntty_open(struct tty_struct *tty, struct file *file) struct nozomi *dc = get_dc_by_tty(tty); unsigned long flags; - if (!port || !dc) + if (!port || !dc || dc->state != NOZOMI_STATE_READY) return -ENODEV; if (mutex_lock_interruptible(&port->tty_sem)) @@ -1716,6 +1736,10 @@ static int ntty_tiocmget(struct tty_struct *tty, struct file *file) static int ntty_tiocmset(struct tty_struct *tty, struct file *file, unsigned int set, unsigned int clear) { + struct nozomi *dc = get_dc_by_tty(tty); + unsigned long flags; + + spin_lock_irqsave(&dc->spin_mutex, flags); if (set & TIOCM_RTS) set_rts(tty, 1); else if (clear & TIOCM_RTS) @@ -1725,6 +1749,7 @@ static int ntty_tiocmset(struct tty_struct *tty, struct file *file, set_dtr(tty, 1); else if (clear & TIOCM_DTR) set_dtr(tty, 0); + spin_unlock_irqrestore(&dc->spin_mutex, flags); return 0; } @@ -1762,7 +1787,7 @@ static int ntty_ioctl_tiocgicount(struct port *port, void __user *argp) icount.brk = cnow.brk; icount.buf_overrun = cnow.buf_overrun; - return copy_to_user(argp, &icount, sizeof(icount)); + return copy_to_user(argp, &icount, sizeof(icount)) ? -EFAULT : 0; } static int ntty_ioctl(struct tty_struct *tty, struct file *file, diff --git a/drivers/char/pcmcia/ipwireless/network.c b/drivers/char/pcmcia/ipwireless/network.c index ff35230058d36e7fd235b73b8884f2bb799f497c..d793e68b3e0d913030402978e46a05eedd8abf40 100644 --- a/drivers/char/pcmcia/ipwireless/network.c +++ b/drivers/char/pcmcia/ipwireless/network.c @@ -377,13 +377,16 @@ void ipwireless_network_packet_received(struct ipw_network *network, for (i = 0; i < MAX_ASSOCIATED_TTYS; i++) { struct ipw_tty *tty = network->associated_ttys[channel_idx][i]; + if (!tty) + continue; + /* * If it's associated with a tty (other than the RAS channel * when we're online), then send the data to that tty. The RAS * channel's data is handled above - it always goes through * ppp_generic. */ - if (tty && channel_idx == IPW_CHANNEL_RAS + if (channel_idx == IPW_CHANNEL_RAS && (network->ras_control_lines & IPW_CONTROL_LINE_DCD) != 0 && ipwireless_tty_is_modem(tty)) { diff --git a/drivers/char/riscom8.c b/drivers/char/riscom8.c index 8fc4fe4e38f1bdb728f751955aa69d3f9fb06dd8..3f9d0a9ac36d5988408f29a133e5a9c8fa1763ae 100644 --- a/drivers/char/riscom8.c +++ b/drivers/char/riscom8.c @@ -1620,14 +1620,8 @@ static int __init rc_init_drivers(void) static void rc_release_drivers(void) { - unsigned long flags; - - spin_lock_irqsave(&riscom_lock, flags); - tty_unregister_driver(riscom_driver); put_tty_driver(riscom_driver); - - spin_unlock_irqrestore(&riscom_lock, flags); } #ifndef MODULE @@ -1715,7 +1709,7 @@ static int __init riscom8_init_module (void) if (iobase || iobase1 || iobase2 || iobase3) { for(i = 0; i < RC_NBOARD; i++) - rc_board[0].base = 0; + rc_board[i].base = 0; } if (iobase) diff --git a/drivers/char/rtc.c b/drivers/char/rtc.c index 78b151c4d20f94b0bccecc1acb3540e14b77cdc9..5c3142b6f1fcdf102a92b79dec3b9d000b4d4a3b 100644 --- a/drivers/char/rtc.c +++ b/drivers/char/rtc.c @@ -110,8 +110,8 @@ static int rtc_has_irq = 1; #define hpet_set_rtc_irq_bit(arg) 0 #define hpet_rtc_timer_init() do { } while (0) #define hpet_rtc_dropped_irq() 0 -#define hpet_register_irq_handler(h) 0 -#define hpet_unregister_irq_handler(h) 0 +#define hpet_register_irq_handler(h) ({ 0; }) +#define hpet_unregister_irq_handler(h) ({ 0; }) #ifdef RTC_IRQ static irqreturn_t hpet_rtc_interrupt(int irq, void *dev_id) { diff --git a/drivers/char/specialix.c b/drivers/char/specialix.c index c0e08c7bca2f4ef713c966eeed532164d33282e6..5ff83df67b447d18054bf45359c183d18fdb9e5a 100644 --- a/drivers/char/specialix.c +++ b/drivers/char/specialix.c @@ -2109,7 +2109,6 @@ static void sx_throttle(struct tty_struct * tty) sx_out(bp, CD186x_CAR, port_No(port)); spin_unlock_irqrestore(&bp->lock, flags); if (I_IXOFF(tty)) { - spin_unlock_irqrestore(&bp->lock, flags); sx_wait_CCR(bp); spin_lock_irqsave(&bp->lock, flags); sx_out(bp, CD186x_CCR, CCR_SSCH2); diff --git a/drivers/char/vt.c b/drivers/char/vt.c index 367be917506117b08d2407b7f74beb55432701d4..9b58b894f823764ac9c0e3d3620b4a2080404fba 100644 --- a/drivers/char/vt.c +++ b/drivers/char/vt.c @@ -702,6 +702,7 @@ void redraw_screen(struct vc_data *vc, int is_switch) if (is_switch) { set_leds(); compute_shiftstate(); + notify_update(vc); } } diff --git a/drivers/char/xilinx_hwicap/buffer_icap.c b/drivers/char/xilinx_hwicap/buffer_icap.c index dfea2bde162b8c43349681e01580834cfe084983..f577daedb630d1babb74c8e7c9e9e3d5458d052c 100644 --- a/drivers/char/xilinx_hwicap/buffer_icap.c +++ b/drivers/char/xilinx_hwicap/buffer_icap.c @@ -73,8 +73,8 @@ #define XHI_BUFFER_START 0 /** - * buffer_icap_get_status: Get the contents of the status register. - * @parameter base_address: is the base address of the device + * buffer_icap_get_status - Get the contents of the status register. + * @base_address: is the base address of the device * * The status register contains the ICAP status and the done bit. * @@ -94,9 +94,9 @@ static inline u32 buffer_icap_get_status(void __iomem *base_address) } /** - * buffer_icap_get_bram: Reads data from the storage buffer bram. - * @parameter base_address: contains the base address of the component. - * @parameter offset: The word offset from which the data should be read. + * buffer_icap_get_bram - Reads data from the storage buffer bram. + * @base_address: contains the base address of the component. + * @offset: The word offset from which the data should be read. * * A bram is used as a configuration memory cache. One frame of data can * be stored in this "storage buffer". @@ -108,8 +108,8 @@ static inline u32 buffer_icap_get_bram(void __iomem *base_address, } /** - * buffer_icap_busy: Return true if the icap device is busy - * @parameter base_address: is the base address of the device + * buffer_icap_busy - Return true if the icap device is busy + * @base_address: is the base address of the device * * The queries the low order bit of the status register, which * indicates whether the current configuration or readback operation @@ -121,8 +121,8 @@ static inline bool buffer_icap_busy(void __iomem *base_address) } /** - * buffer_icap_busy: Return true if the icap device is not busy - * @parameter base_address: is the base address of the device + * buffer_icap_busy - Return true if the icap device is not busy + * @base_address: is the base address of the device * * The queries the low order bit of the status register, which * indicates whether the current configuration or readback operation @@ -134,9 +134,9 @@ static inline bool buffer_icap_done(void __iomem *base_address) } /** - * buffer_icap_set_size: Set the size register. - * @parameter base_address: is the base address of the device - * @parameter data: The size in bytes. + * buffer_icap_set_size - Set the size register. + * @base_address: is the base address of the device + * @data: The size in bytes. * * The size register holds the number of 8 bit bytes to transfer between * bram and the icap (or icap to bram). @@ -148,9 +148,9 @@ static inline void buffer_icap_set_size(void __iomem *base_address, } /** - * buffer_icap_mSetoffsetReg: Set the bram offset register. - * @parameter base_address: contains the base address of the device. - * @parameter data: is the value to be written to the data register. + * buffer_icap_set_offset - Set the bram offset register. + * @base_address: contains the base address of the device. + * @data: is the value to be written to the data register. * * The bram offset register holds the starting bram address to transfer * data from during configuration or write data to during readback. @@ -162,9 +162,9 @@ static inline void buffer_icap_set_offset(void __iomem *base_address, } /** - * buffer_icap_set_rnc: Set the RNC (Readback not Configure) register. - * @parameter base_address: contains the base address of the device. - * @parameter data: is the value to be written to the data register. + * buffer_icap_set_rnc - Set the RNC (Readback not Configure) register. + * @base_address: contains the base address of the device. + * @data: is the value to be written to the data register. * * The RNC register determines the direction of the data transfer. It * controls whether a configuration or readback take place. Writing to @@ -178,10 +178,10 @@ static inline void buffer_icap_set_rnc(void __iomem *base_address, } /** - * buffer_icap_set_bram: Write data to the storage buffer bram. - * @parameter base_address: contains the base address of the component. - * @parameter offset: The word offset at which the data should be written. - * @parameter data: The value to be written to the bram offset. + * buffer_icap_set_bram - Write data to the storage buffer bram. + * @base_address: contains the base address of the component. + * @offset: The word offset at which the data should be written. + * @data: The value to be written to the bram offset. * * A bram is used as a configuration memory cache. One frame of data can * be stored in this "storage buffer". @@ -193,10 +193,10 @@ static inline void buffer_icap_set_bram(void __iomem *base_address, } /** - * buffer_icap_device_read: Transfer bytes from ICAP to the storage buffer. - * @parameter drvdata: a pointer to the drvdata. - * @parameter offset: The storage buffer start address. - * @parameter count: The number of words (32 bit) to read from the + * buffer_icap_device_read - Transfer bytes from ICAP to the storage buffer. + * @drvdata: a pointer to the drvdata. + * @offset: The storage buffer start address. + * @count: The number of words (32 bit) to read from the * device (ICAP). **/ static int buffer_icap_device_read(struct hwicap_drvdata *drvdata, @@ -227,10 +227,10 @@ static int buffer_icap_device_read(struct hwicap_drvdata *drvdata, }; /** - * buffer_icap_device_write: Transfer bytes from ICAP to the storage buffer. - * @parameter drvdata: a pointer to the drvdata. - * @parameter offset: The storage buffer start address. - * @parameter count: The number of words (32 bit) to read from the + * buffer_icap_device_write - Transfer bytes from ICAP to the storage buffer. + * @drvdata: a pointer to the drvdata. + * @offset: The storage buffer start address. + * @count: The number of words (32 bit) to read from the * device (ICAP). **/ static int buffer_icap_device_write(struct hwicap_drvdata *drvdata, @@ -261,8 +261,8 @@ static int buffer_icap_device_write(struct hwicap_drvdata *drvdata, }; /** - * buffer_icap_reset: Reset the logic of the icap device. - * @parameter drvdata: a pointer to the drvdata. + * buffer_icap_reset - Reset the logic of the icap device. + * @drvdata: a pointer to the drvdata. * * Writing to the status register resets the ICAP logic in an internal * version of the core. For the version of the core published in EDK, @@ -274,10 +274,10 @@ void buffer_icap_reset(struct hwicap_drvdata *drvdata) } /** - * buffer_icap_set_configuration: Load a partial bitstream from system memory. - * @parameter drvdata: a pointer to the drvdata. - * @parameter data: Kernel address of the partial bitstream. - * @parameter size: the size of the partial bitstream in 32 bit words. + * buffer_icap_set_configuration - Load a partial bitstream from system memory. + * @drvdata: a pointer to the drvdata. + * @data: Kernel address of the partial bitstream. + * @size: the size of the partial bitstream in 32 bit words. **/ int buffer_icap_set_configuration(struct hwicap_drvdata *drvdata, u32 *data, u32 size) @@ -333,10 +333,10 @@ int buffer_icap_set_configuration(struct hwicap_drvdata *drvdata, u32 *data, }; /** - * buffer_icap_get_configuration: Read configuration data from the device. - * @parameter drvdata: a pointer to the drvdata. - * @parameter data: Address of the data representing the partial bitstream - * @parameter size: the size of the partial bitstream in 32 bit words. + * buffer_icap_get_configuration - Read configuration data from the device. + * @drvdata: a pointer to the drvdata. + * @data: Address of the data representing the partial bitstream + * @size: the size of the partial bitstream in 32 bit words. **/ int buffer_icap_get_configuration(struct hwicap_drvdata *drvdata, u32 *data, u32 size) diff --git a/drivers/char/xilinx_hwicap/fifo_icap.c b/drivers/char/xilinx_hwicap/fifo_icap.c index 0988314694a6a59ce45aaca43986e203c3e20d1b..6f45dbd47125636a44af08d8b2dab33a70e3bf4c 100644 --- a/drivers/char/xilinx_hwicap/fifo_icap.c +++ b/drivers/char/xilinx_hwicap/fifo_icap.c @@ -94,9 +94,9 @@ /** - * fifo_icap_fifo_write: Write data to the write FIFO. - * @parameter drvdata: a pointer to the drvdata. - * @parameter data: the 32-bit value to be written to the FIFO. + * fifo_icap_fifo_write - Write data to the write FIFO. + * @drvdata: a pointer to the drvdata. + * @data: the 32-bit value to be written to the FIFO. * * This function will silently fail if the fifo is full. **/ @@ -108,8 +108,8 @@ static inline void fifo_icap_fifo_write(struct hwicap_drvdata *drvdata, } /** - * fifo_icap_fifo_read: Read data from the Read FIFO. - * @parameter drvdata: a pointer to the drvdata. + * fifo_icap_fifo_read - Read data from the Read FIFO. + * @drvdata: a pointer to the drvdata. * * This function will silently fail if the fifo is empty. **/ @@ -121,9 +121,9 @@ static inline u32 fifo_icap_fifo_read(struct hwicap_drvdata *drvdata) } /** - * fifo_icap_set_read_size: Set the the size register. - * @parameter drvdata: a pointer to the drvdata. - * @parameter data: the size of the following read transaction, in words. + * fifo_icap_set_read_size - Set the the size register. + * @drvdata: a pointer to the drvdata. + * @data: the size of the following read transaction, in words. **/ static inline void fifo_icap_set_read_size(struct hwicap_drvdata *drvdata, u32 data) @@ -132,8 +132,8 @@ static inline void fifo_icap_set_read_size(struct hwicap_drvdata *drvdata, } /** - * fifo_icap_start_config: Initiate a configuration (write) to the device. - * @parameter drvdata: a pointer to the drvdata. + * fifo_icap_start_config - Initiate a configuration (write) to the device. + * @drvdata: a pointer to the drvdata. **/ static inline void fifo_icap_start_config(struct hwicap_drvdata *drvdata) { @@ -142,8 +142,8 @@ static inline void fifo_icap_start_config(struct hwicap_drvdata *drvdata) } /** - * fifo_icap_start_readback: Initiate a readback from the device. - * @parameter drvdata: a pointer to the drvdata. + * fifo_icap_start_readback - Initiate a readback from the device. + * @drvdata: a pointer to the drvdata. **/ static inline void fifo_icap_start_readback(struct hwicap_drvdata *drvdata) { @@ -152,8 +152,8 @@ static inline void fifo_icap_start_readback(struct hwicap_drvdata *drvdata) } /** - * fifo_icap_busy: Return true if the ICAP is still processing a transaction. - * @parameter drvdata: a pointer to the drvdata. + * fifo_icap_busy - Return true if the ICAP is still processing a transaction. + * @drvdata: a pointer to the drvdata. **/ static inline u32 fifo_icap_busy(struct hwicap_drvdata *drvdata) { @@ -163,8 +163,8 @@ static inline u32 fifo_icap_busy(struct hwicap_drvdata *drvdata) } /** - * fifo_icap_write_fifo_vacancy: Query the write fifo available space. - * @parameter drvdata: a pointer to the drvdata. + * fifo_icap_write_fifo_vacancy - Query the write fifo available space. + * @drvdata: a pointer to the drvdata. * * Return the number of words that can be safely pushed into the write fifo. **/ @@ -175,8 +175,8 @@ static inline u32 fifo_icap_write_fifo_vacancy( } /** - * fifo_icap_read_fifo_occupancy: Query the read fifo available data. - * @parameter drvdata: a pointer to the drvdata. + * fifo_icap_read_fifo_occupancy - Query the read fifo available data. + * @drvdata: a pointer to the drvdata. * * Return the number of words that can be safely read from the read fifo. **/ @@ -187,11 +187,11 @@ static inline u32 fifo_icap_read_fifo_occupancy( } /** - * fifo_icap_set_configuration: Send configuration data to the ICAP. - * @parameter drvdata: a pointer to the drvdata. - * @parameter frame_buffer: a pointer to the data to be written to the + * fifo_icap_set_configuration - Send configuration data to the ICAP. + * @drvdata: a pointer to the drvdata. + * @frame_buffer: a pointer to the data to be written to the * ICAP device. - * @parameter num_words: the number of words (32 bit) to write to the ICAP + * @num_words: the number of words (32 bit) to write to the ICAP * device. * This function writes the given user data to the Write FIFO in @@ -266,10 +266,10 @@ int fifo_icap_set_configuration(struct hwicap_drvdata *drvdata, } /** - * fifo_icap_get_configuration: Read configuration data from the device. - * @parameter drvdata: a pointer to the drvdata. - * @parameter data: Address of the data representing the partial bitstream - * @parameter size: the size of the partial bitstream in 32 bit words. + * fifo_icap_get_configuration - Read configuration data from the device. + * @drvdata: a pointer to the drvdata. + * @data: Address of the data representing the partial bitstream + * @size: the size of the partial bitstream in 32 bit words. * * This function reads the specified number of words from the ICAP device in * the polled mode. @@ -335,8 +335,8 @@ int fifo_icap_get_configuration(struct hwicap_drvdata *drvdata, } /** - * buffer_icap_reset: Reset the logic of the icap device. - * @parameter drvdata: a pointer to the drvdata. + * buffer_icap_reset - Reset the logic of the icap device. + * @drvdata: a pointer to the drvdata. * * This function forces the software reset of the complete HWICAP device. * All the registers will return to the default value and the FIFO is also @@ -360,8 +360,8 @@ void fifo_icap_reset(struct hwicap_drvdata *drvdata) } /** - * fifo_icap_flush_fifo: This function flushes the FIFOs in the device. - * @parameter drvdata: a pointer to the drvdata. + * fifo_icap_flush_fifo - This function flushes the FIFOs in the device. + * @drvdata: a pointer to the drvdata. */ void fifo_icap_flush_fifo(struct hwicap_drvdata *drvdata) { diff --git a/drivers/char/xilinx_hwicap/xilinx_hwicap.c b/drivers/char/xilinx_hwicap/xilinx_hwicap.c index 24f6aef0fd3ceb605a0e4ba6cbf4def597360084..2284fa2a5a5726c52c873e4f13caff36cfab5f3b 100644 --- a/drivers/char/xilinx_hwicap/xilinx_hwicap.c +++ b/drivers/char/xilinx_hwicap/xilinx_hwicap.c @@ -84,7 +84,7 @@ #include #include #include -#include +#include #include #include #include @@ -119,6 +119,7 @@ module_param(xhwicap_minor, int, S_IRUGO); /* An array, which is set to true when the device is registered. */ static bool probed_devices[HWICAP_DEVICES]; +static struct mutex icap_sem; static struct class *icap_class; @@ -199,14 +200,14 @@ static const struct config_registers v5_config_registers = { }; /** - * hwicap_command_desync: Send a DESYNC command to the ICAP port. - * @parameter drvdata: a pointer to the drvdata. + * hwicap_command_desync - Send a DESYNC command to the ICAP port. + * @drvdata: a pointer to the drvdata. * * This command desynchronizes the ICAP After this command, a * bitstream containing a NULL packet, followed by a SYNCH packet is * required before the ICAP will recognize commands. */ -int hwicap_command_desync(struct hwicap_drvdata *drvdata) +static int hwicap_command_desync(struct hwicap_drvdata *drvdata) { u32 buffer[4]; u32 index = 0; @@ -228,51 +229,18 @@ int hwicap_command_desync(struct hwicap_drvdata *drvdata) } /** - * hwicap_command_capture: Send a CAPTURE command to the ICAP port. - * @parameter drvdata: a pointer to the drvdata. - * - * This command captures all of the flip flop states so they will be - * available during readback. One can use this command instead of - * enabling the CAPTURE block in the design. - */ -int hwicap_command_capture(struct hwicap_drvdata *drvdata) -{ - u32 buffer[7]; - u32 index = 0; - - /* - * Create the data to be written to the ICAP. - */ - buffer[index++] = XHI_DUMMY_PACKET; - buffer[index++] = XHI_SYNC_PACKET; - buffer[index++] = XHI_NOOP_PACKET; - buffer[index++] = hwicap_type_1_write(drvdata->config_regs->CMD) | 1; - buffer[index++] = XHI_CMD_GCAPTURE; - buffer[index++] = XHI_DUMMY_PACKET; - buffer[index++] = XHI_DUMMY_PACKET; - - /* - * Write the data to the FIFO and intiate the transfer of data - * present in the FIFO to the ICAP device. - */ - return drvdata->config->set_configuration(drvdata, - &buffer[0], index); - -} - -/** - * hwicap_get_configuration_register: Query a configuration register. - * @parameter drvdata: a pointer to the drvdata. - * @parameter reg: a constant which represents the configuration + * hwicap_get_configuration_register - Query a configuration register. + * @drvdata: a pointer to the drvdata. + * @reg: a constant which represents the configuration * register value to be returned. * Examples: XHI_IDCODE, XHI_FLR. - * @parameter RegData: returns the value of the register. + * @reg_data: returns the value of the register. * * Sends a query packet to the ICAP and then receives the response. * The icap is left in Synched state. */ -int hwicap_get_configuration_register(struct hwicap_drvdata *drvdata, - u32 reg, u32 *RegData) +static int hwicap_get_configuration_register(struct hwicap_drvdata *drvdata, + u32 reg, u32 *reg_data) { int status; u32 buffer[6]; @@ -300,14 +268,14 @@ int hwicap_get_configuration_register(struct hwicap_drvdata *drvdata, /* * Read the configuration register */ - status = drvdata->config->get_configuration(drvdata, RegData, 1); + status = drvdata->config->get_configuration(drvdata, reg_data, 1); if (status) return status; return 0; } -int hwicap_initialize_hwicap(struct hwicap_drvdata *drvdata) +static int hwicap_initialize_hwicap(struct hwicap_drvdata *drvdata) { int status; u32 idcode; @@ -344,7 +312,7 @@ int hwicap_initialize_hwicap(struct hwicap_drvdata *drvdata) } static ssize_t -hwicap_read(struct file *file, char *buf, size_t count, loff_t *ppos) +hwicap_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) { struct hwicap_drvdata *drvdata = file->private_data; ssize_t bytes_to_read = 0; @@ -353,8 +321,9 @@ hwicap_read(struct file *file, char *buf, size_t count, loff_t *ppos) u32 bytes_remaining; int status; - if (down_interruptible(&drvdata->sem)) - return -ERESTARTSYS; + status = mutex_lock_interruptible(&drvdata->sem); + if (status) + return status; if (drvdata->read_buffer_in_use) { /* If there are leftover bytes in the buffer, just */ @@ -370,8 +339,9 @@ hwicap_read(struct file *file, char *buf, size_t count, loff_t *ppos) goto error; } drvdata->read_buffer_in_use -= bytes_to_read; - memcpy(drvdata->read_buffer + bytes_to_read, - drvdata->read_buffer, 4 - bytes_to_read); + memmove(drvdata->read_buffer, + drvdata->read_buffer + bytes_to_read, + 4 - bytes_to_read); } else { /* Get new data from the ICAP, and return was was requested. */ kbuf = (u32 *) get_zeroed_page(GFP_KERNEL); @@ -414,18 +384,20 @@ hwicap_read(struct file *file, char *buf, size_t count, loff_t *ppos) status = -EFAULT; goto error; } - memcpy(kbuf, drvdata->read_buffer, bytes_remaining); + memcpy(drvdata->read_buffer, + kbuf, + bytes_remaining); drvdata->read_buffer_in_use = bytes_remaining; free_page((unsigned long)kbuf); } status = bytes_to_read; error: - up(&drvdata->sem); + mutex_unlock(&drvdata->sem); return status; } static ssize_t -hwicap_write(struct file *file, const char *buf, +hwicap_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) { struct hwicap_drvdata *drvdata = file->private_data; @@ -435,8 +407,9 @@ hwicap_write(struct file *file, const char *buf, ssize_t len; ssize_t status; - if (down_interruptible(&drvdata->sem)) - return -ERESTARTSYS; + status = mutex_lock_interruptible(&drvdata->sem); + if (status) + return status; left += drvdata->write_buffer_in_use; @@ -465,7 +438,7 @@ hwicap_write(struct file *file, const char *buf, memcpy(kbuf, drvdata->write_buffer, drvdata->write_buffer_in_use); if (copy_from_user( - (((char *)kbuf) + (drvdata->write_buffer_in_use)), + (((char *)kbuf) + drvdata->write_buffer_in_use), buf + written, len - (drvdata->write_buffer_in_use))) { free_page((unsigned long)kbuf); @@ -508,7 +481,7 @@ hwicap_write(struct file *file, const char *buf, free_page((unsigned long)kbuf); status = written; error: - up(&drvdata->sem); + mutex_unlock(&drvdata->sem); return status; } @@ -519,8 +492,9 @@ static int hwicap_open(struct inode *inode, struct file *file) drvdata = container_of(inode->i_cdev, struct hwicap_drvdata, cdev); - if (down_interruptible(&drvdata->sem)) - return -ERESTARTSYS; + status = mutex_lock_interruptible(&drvdata->sem); + if (status) + return status; if (drvdata->is_open) { status = -EBUSY; @@ -539,7 +513,7 @@ static int hwicap_open(struct inode *inode, struct file *file) drvdata->is_open = 1; error: - up(&drvdata->sem); + mutex_unlock(&drvdata->sem); return status; } @@ -549,8 +523,7 @@ static int hwicap_release(struct inode *inode, struct file *file) int i; int status = 0; - if (down_interruptible(&drvdata->sem)) - return -ERESTARTSYS; + mutex_lock(&drvdata->sem); if (drvdata->write_buffer_in_use) { /* Flush write buffer. */ @@ -569,7 +542,7 @@ static int hwicap_release(struct inode *inode, struct file *file) error: drvdata->is_open = 0; - up(&drvdata->sem); + mutex_unlock(&drvdata->sem); return status; } @@ -592,31 +565,36 @@ static int __devinit hwicap_setup(struct device *dev, int id, dev_info(dev, "Xilinx icap port driver\n"); + mutex_lock(&icap_sem); + if (id < 0) { for (id = 0; id < HWICAP_DEVICES; id++) if (!probed_devices[id]) break; } if (id < 0 || id >= HWICAP_DEVICES) { + mutex_unlock(&icap_sem); dev_err(dev, "%s%i too large\n", DRIVER_NAME, id); return -EINVAL; } if (probed_devices[id]) { + mutex_unlock(&icap_sem); dev_err(dev, "cannot assign to %s%i; it is already in use\n", DRIVER_NAME, id); return -EBUSY; } probed_devices[id] = 1; + mutex_unlock(&icap_sem); devt = MKDEV(xhwicap_major, xhwicap_minor + id); - drvdata = kmalloc(sizeof(struct hwicap_drvdata), GFP_KERNEL); + drvdata = kzalloc(sizeof(struct hwicap_drvdata), GFP_KERNEL); if (!drvdata) { dev_err(dev, "Couldn't allocate device private record\n"); - return -ENOMEM; + retval = -ENOMEM; + goto failed0; } - memset((void *)drvdata, 0, sizeof(struct hwicap_drvdata)); dev_set_drvdata(dev, (void *)drvdata); if (!regs_res) { @@ -648,7 +626,7 @@ static int __devinit hwicap_setup(struct device *dev, int id, drvdata->config = config; drvdata->config_regs = config_regs; - init_MUTEX(&drvdata->sem); + mutex_init(&drvdata->sem); drvdata->is_open = 0; dev_info(dev, "ioremap %lx to %p with size %x\n", @@ -663,7 +641,7 @@ static int __devinit hwicap_setup(struct device *dev, int id, goto failed3; } /* devfs_mk_cdev(devt, S_IFCHR|S_IRUGO|S_IWUGO, DRIVER_NAME); */ - class_device_create(icap_class, NULL, devt, NULL, DRIVER_NAME); + device_create(icap_class, dev, devt, "%s%d", DRIVER_NAME, id); return 0; /* success */ failed3: @@ -675,6 +653,11 @@ static int __devinit hwicap_setup(struct device *dev, int id, failed1: kfree(drvdata); + failed0: + mutex_lock(&icap_sem); + probed_devices[id] = 0; + mutex_unlock(&icap_sem); + return retval; } @@ -699,14 +682,16 @@ static int __devexit hwicap_remove(struct device *dev) if (!drvdata) return 0; - class_device_destroy(icap_class, drvdata->devt); + device_destroy(icap_class, drvdata->devt); cdev_del(&drvdata->cdev); iounmap(drvdata->base_address); release_mem_region(drvdata->mem_start, drvdata->mem_size); kfree(drvdata); dev_set_drvdata(dev, NULL); - probed_devices[MINOR(dev->devt)-xhwicap_minor] = 0; + mutex_lock(&icap_sem); + probed_devices[MINOR(dev->devt)-xhwicap_minor] = 0; + mutex_unlock(&icap_sem); return 0; /* success */ } @@ -821,28 +806,29 @@ static struct of_platform_driver hwicap_of_driver = { }; /* Registration helpers to keep the number of #ifdefs to a minimum */ -static inline int __devinit hwicap_of_register(void) +static inline int __init hwicap_of_register(void) { pr_debug("hwicap: calling of_register_platform_driver()\n"); return of_register_platform_driver(&hwicap_of_driver); } -static inline void __devexit hwicap_of_unregister(void) +static inline void __exit hwicap_of_unregister(void) { of_unregister_platform_driver(&hwicap_of_driver); } #else /* CONFIG_OF */ /* CONFIG_OF not enabled; do nothing helpers */ -static inline int __devinit hwicap_of_register(void) { return 0; } -static inline void __devexit hwicap_of_unregister(void) { } +static inline int __init hwicap_of_register(void) { return 0; } +static inline void __exit hwicap_of_unregister(void) { } #endif /* CONFIG_OF */ -static int __devinit hwicap_module_init(void) +static int __init hwicap_module_init(void) { dev_t devt; int retval; icap_class = class_create(THIS_MODULE, "xilinx_config"); + mutex_init(&icap_sem); if (xhwicap_major) { devt = MKDEV(xhwicap_major, xhwicap_minor); @@ -883,7 +869,7 @@ static int __devinit hwicap_module_init(void) return retval; } -static void __devexit hwicap_module_cleanup(void) +static void __exit hwicap_module_cleanup(void) { dev_t devt = MKDEV(xhwicap_major, xhwicap_minor); diff --git a/drivers/char/xilinx_hwicap/xilinx_hwicap.h b/drivers/char/xilinx_hwicap/xilinx_hwicap.h index ae771cac16298b1c675e3f9de902880898e75a78..405fee7e189bd72da5ff8d08514ad141a03771f3 100644 --- a/drivers/char/xilinx_hwicap/xilinx_hwicap.h +++ b/drivers/char/xilinx_hwicap/xilinx_hwicap.h @@ -48,9 +48,9 @@ struct hwicap_drvdata { u8 write_buffer[4]; u32 read_buffer_in_use; /* Always in [0,3] */ u8 read_buffer[4]; - u32 mem_start; /* phys. address of the control registers */ - u32 mem_end; /* phys. address of the control registers */ - u32 mem_size; + resource_size_t mem_start;/* phys. address of the control registers */ + resource_size_t mem_end; /* phys. address of the control registers */ + resource_size_t mem_size; void __iomem *base_address;/* virt. address of the control registers */ struct device *dev; @@ -61,7 +61,7 @@ struct hwicap_drvdata { const struct config_registers *config_regs; void *private_data; bool is_open; - struct semaphore sem; + struct mutex sem; }; struct hwicap_driver_config { @@ -164,29 +164,29 @@ struct config_registers { #define XHI_DISABLED_AUTO_CRC 0x0000DEFCUL /** - * hwicap_type_1_read: Generates a Type 1 read packet header. - * @parameter: Register is the address of the register to be read back. + * hwicap_type_1_read - Generates a Type 1 read packet header. + * @reg: is the address of the register to be read back. * * Generates a Type 1 read packet header, which is used to indirectly * read registers in the configuration logic. This packet must then * be sent through the icap device, and a return packet received with * the information. **/ -static inline u32 hwicap_type_1_read(u32 Register) +static inline u32 hwicap_type_1_read(u32 reg) { return (XHI_TYPE_1 << XHI_TYPE_SHIFT) | - (Register << XHI_REGISTER_SHIFT) | + (reg << XHI_REGISTER_SHIFT) | (XHI_OP_READ << XHI_OP_SHIFT); } /** - * hwicap_type_1_write: Generates a Type 1 write packet header - * @parameter: Register is the address of the register to be read back. + * hwicap_type_1_write - Generates a Type 1 write packet header + * @reg: is the address of the register to be read back. **/ -static inline u32 hwicap_type_1_write(u32 Register) +static inline u32 hwicap_type_1_write(u32 reg) { return (XHI_TYPE_1 << XHI_TYPE_SHIFT) | - (Register << XHI_REGISTER_SHIFT) | + (reg << XHI_REGISTER_SHIFT) | (XHI_OP_WRITE << XHI_OP_SHIFT); } diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index 89a29cd9378379a00f80e6899eadbac949f03fde..35a26a3e5f6804d977563ddd5ef03db8e8ea5f5c 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c @@ -671,13 +671,13 @@ static ssize_t show(struct kobject * kobj, struct attribute * attr ,char * buf) { struct cpufreq_policy * policy = to_policy(kobj); struct freq_attr * fattr = to_attr(attr); - ssize_t ret; + ssize_t ret = -EINVAL; policy = cpufreq_cpu_get(policy->cpu); if (!policy) - return -EINVAL; + goto no_policy; if (lock_policy_rwsem_read(policy->cpu) < 0) - return -EINVAL; + goto fail; if (fattr->show) ret = fattr->show(policy, buf); @@ -685,8 +685,9 @@ static ssize_t show(struct kobject * kobj, struct attribute * attr ,char * buf) ret = -EIO; unlock_policy_rwsem_read(policy->cpu); - +fail: cpufreq_cpu_put(policy); +no_policy: return ret; } @@ -695,13 +696,13 @@ static ssize_t store(struct kobject * kobj, struct attribute * attr, { struct cpufreq_policy * policy = to_policy(kobj); struct freq_attr * fattr = to_attr(attr); - ssize_t ret; + ssize_t ret = -EINVAL; policy = cpufreq_cpu_get(policy->cpu); if (!policy) - return -EINVAL; + goto no_policy; if (lock_policy_rwsem_write(policy->cpu) < 0) - return -EINVAL; + goto fail; if (fattr->store) ret = fattr->store(policy, buf, count); @@ -709,8 +710,9 @@ static ssize_t store(struct kobject * kobj, struct attribute * attr, ret = -EIO; unlock_policy_rwsem_write(policy->cpu); - +fail: cpufreq_cpu_put(policy); +no_policy: return ret; } @@ -1775,7 +1777,7 @@ static int __cpuinit cpufreq_cpu_callback(struct notifier_block *nfb, return NOTIFY_OK; } -static struct notifier_block __cpuinitdata cpufreq_cpu_notifier = +static struct notifier_block __refdata cpufreq_cpu_notifier = { .notifier_call = cpufreq_cpu_callback, }; diff --git a/drivers/cpufreq/cpufreq_stats.c b/drivers/cpufreq/cpufreq_stats.c index 1b8312b0200675e81722def6d6b51134594e1250..070421a5480e731116ed58845e5ac424cfaf0aba 100644 --- a/drivers/cpufreq/cpufreq_stats.c +++ b/drivers/cpufreq/cpufreq_stats.c @@ -323,7 +323,7 @@ static int __cpuinit cpufreq_stat_cpu_callback(struct notifier_block *nfb, return NOTIFY_OK; } -static struct notifier_block cpufreq_stat_cpu_notifier __cpuinitdata = +static struct notifier_block cpufreq_stat_cpu_notifier __refdata = { .notifier_call = cpufreq_stat_cpu_callback, }; diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig index a703deffb7954cd3a1fd4831adaa48403b1b06ba..27340a7b19dddb8129f8ca85e8c24cc90075b6c3 100644 --- a/drivers/dma/Kconfig +++ b/drivers/dma/Kconfig @@ -4,7 +4,7 @@ menuconfig DMADEVICES bool "DMA Engine support" - depends on (PCI && X86) || ARCH_IOP32X || ARCH_IOP33X || ARCH_IOP13XX + depends on (PCI && X86) || ARCH_IOP32X || ARCH_IOP33X || ARCH_IOP13XX || PPC depends on !HIGHMEM64G help DMA engines can do asynchronous data transfers without @@ -37,6 +37,23 @@ config INTEL_IOP_ADMA help Enable support for the Intel(R) IOP Series RAID engines. +config FSL_DMA + bool "Freescale MPC85xx/MPC83xx DMA support" + depends on PPC + select DMA_ENGINE + ---help--- + Enable support for the Freescale DMA engine. Now, it support + MPC8560/40, MPC8555, MPC8548 and MPC8641 processors. + The MPC8349, MPC8360 is also supported. + +config FSL_DMA_SELFTEST + bool "Enable the self test for each DMA channel" + depends on FSL_DMA + default y + ---help--- + Enable the self test for each DMA channel. A self test will be + performed after the channel probed to ensure the DMA works well. + config DMA_ENGINE bool diff --git a/drivers/dma/Makefile b/drivers/dma/Makefile index b152cd84e123653b8ecb2f4fe58ea45f3459ce4b..c8036d94590277d24f994a82c61fccbe51a89f07 100644 --- a/drivers/dma/Makefile +++ b/drivers/dma/Makefile @@ -3,3 +3,4 @@ obj-$(CONFIG_NET_DMA) += iovlock.o obj-$(CONFIG_INTEL_IOATDMA) += ioatdma.o ioatdma-objs := ioat.o ioat_dma.o ioat_dca.o obj-$(CONFIG_INTEL_IOP_ADMA) += iop-adma.o +obj-$(CONFIG_FSL_DMA) += fsldma.o diff --git a/drivers/dma/dmaengine.c b/drivers/dma/dmaengine.c index 29965231b9127e6e9e658997f26b72ffb69c4d3c..8db0e7f9d3f44c959bd8aac097a7448b95395721 100644 --- a/drivers/dma/dmaengine.c +++ b/drivers/dma/dmaengine.c @@ -357,7 +357,7 @@ int dma_async_device_register(struct dma_device *device) !device->device_prep_dma_zero_sum); BUG_ON(dma_has_cap(DMA_MEMSET, device->cap_mask) && !device->device_prep_dma_memset); - BUG_ON(dma_has_cap(DMA_ZERO_SUM, device->cap_mask) && + BUG_ON(dma_has_cap(DMA_INTERRUPT, device->cap_mask) && !device->device_prep_dma_interrupt); BUG_ON(!device->device_alloc_chan_resources); diff --git a/drivers/dma/fsldma.c b/drivers/dma/fsldma.c new file mode 100644 index 0000000000000000000000000000000000000000..ad2f938597e21a06f7c751eedabc97bdab37b6d9 --- /dev/null +++ b/drivers/dma/fsldma.c @@ -0,0 +1,1097 @@ +/* + * Freescale MPC85xx, MPC83xx DMA Engine support + * + * Copyright (C) 2007 Freescale Semiconductor, Inc. All rights reserved. + * + * Author: + * Zhang Wei , Jul 2007 + * Ebony Zhu , May 2007 + * + * Description: + * DMA engine driver for Freescale MPC8540 DMA controller, which is + * also fit for MPC8560, MPC8555, MPC8548, MPC8641, and etc. + * The support for MPC8349 DMA contorller is also added. + * + * This 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 +#include +#include +#include +#include +#include +#include +#include +#include + +#include "fsldma.h" + +static void dma_init(struct fsl_dma_chan *fsl_chan) +{ + /* Reset the channel */ + DMA_OUT(fsl_chan, &fsl_chan->reg_base->mr, 0, 32); + + switch (fsl_chan->feature & FSL_DMA_IP_MASK) { + case FSL_DMA_IP_85XX: + /* Set the channel to below modes: + * EIE - Error interrupt enable + * EOSIE - End of segments interrupt enable (basic mode) + * EOLNIE - End of links interrupt enable + */ + DMA_OUT(fsl_chan, &fsl_chan->reg_base->mr, FSL_DMA_MR_EIE + | FSL_DMA_MR_EOLNIE | FSL_DMA_MR_EOSIE, 32); + break; + case FSL_DMA_IP_83XX: + /* Set the channel to below modes: + * EOTIE - End-of-transfer interrupt enable + */ + DMA_OUT(fsl_chan, &fsl_chan->reg_base->mr, FSL_DMA_MR_EOTIE, + 32); + break; + } + +} + +static void set_sr(struct fsl_dma_chan *fsl_chan, u32 val) +{ + DMA_OUT(fsl_chan, &fsl_chan->reg_base->sr, val, 32); +} + +static u32 get_sr(struct fsl_dma_chan *fsl_chan) +{ + return DMA_IN(fsl_chan, &fsl_chan->reg_base->sr, 32); +} + +static void set_desc_cnt(struct fsl_dma_chan *fsl_chan, + struct fsl_dma_ld_hw *hw, u32 count) +{ + hw->count = CPU_TO_DMA(fsl_chan, count, 32); +} + +static void set_desc_src(struct fsl_dma_chan *fsl_chan, + struct fsl_dma_ld_hw *hw, dma_addr_t src) +{ + u64 snoop_bits; + + snoop_bits = ((fsl_chan->feature & FSL_DMA_IP_MASK) == FSL_DMA_IP_85XX) + ? ((u64)FSL_DMA_SATR_SREADTYPE_SNOOP_READ << 32) : 0; + hw->src_addr = CPU_TO_DMA(fsl_chan, snoop_bits | src, 64); +} + +static void set_desc_dest(struct fsl_dma_chan *fsl_chan, + struct fsl_dma_ld_hw *hw, dma_addr_t dest) +{ + u64 snoop_bits; + + snoop_bits = ((fsl_chan->feature & FSL_DMA_IP_MASK) == FSL_DMA_IP_85XX) + ? ((u64)FSL_DMA_DATR_DWRITETYPE_SNOOP_WRITE << 32) : 0; + hw->dst_addr = CPU_TO_DMA(fsl_chan, snoop_bits | dest, 64); +} + +static void set_desc_next(struct fsl_dma_chan *fsl_chan, + struct fsl_dma_ld_hw *hw, dma_addr_t next) +{ + u64 snoop_bits; + + snoop_bits = ((fsl_chan->feature & FSL_DMA_IP_MASK) == FSL_DMA_IP_83XX) + ? FSL_DMA_SNEN : 0; + hw->next_ln_addr = CPU_TO_DMA(fsl_chan, snoop_bits | next, 64); +} + +static void set_cdar(struct fsl_dma_chan *fsl_chan, dma_addr_t addr) +{ + DMA_OUT(fsl_chan, &fsl_chan->reg_base->cdar, addr | FSL_DMA_SNEN, 64); +} + +static dma_addr_t get_cdar(struct fsl_dma_chan *fsl_chan) +{ + return DMA_IN(fsl_chan, &fsl_chan->reg_base->cdar, 64) & ~FSL_DMA_SNEN; +} + +static void set_ndar(struct fsl_dma_chan *fsl_chan, dma_addr_t addr) +{ + DMA_OUT(fsl_chan, &fsl_chan->reg_base->ndar, addr, 64); +} + +static dma_addr_t get_ndar(struct fsl_dma_chan *fsl_chan) +{ + return DMA_IN(fsl_chan, &fsl_chan->reg_base->ndar, 64); +} + +static int dma_is_idle(struct fsl_dma_chan *fsl_chan) +{ + u32 sr = get_sr(fsl_chan); + return (!(sr & FSL_DMA_SR_CB)) || (sr & FSL_DMA_SR_CH); +} + +static void dma_start(struct fsl_dma_chan *fsl_chan) +{ + u32 mr_set = 0;; + + if (fsl_chan->feature & FSL_DMA_CHAN_PAUSE_EXT) { + DMA_OUT(fsl_chan, &fsl_chan->reg_base->bcr, 0, 32); + mr_set |= FSL_DMA_MR_EMP_EN; + } else + DMA_OUT(fsl_chan, &fsl_chan->reg_base->mr, + DMA_IN(fsl_chan, &fsl_chan->reg_base->mr, 32) + & ~FSL_DMA_MR_EMP_EN, 32); + + if (fsl_chan->feature & FSL_DMA_CHAN_START_EXT) + mr_set |= FSL_DMA_MR_EMS_EN; + else + mr_set |= FSL_DMA_MR_CS; + + DMA_OUT(fsl_chan, &fsl_chan->reg_base->mr, + DMA_IN(fsl_chan, &fsl_chan->reg_base->mr, 32) + | mr_set, 32); +} + +static void dma_halt(struct fsl_dma_chan *fsl_chan) +{ + int i = 0; + DMA_OUT(fsl_chan, &fsl_chan->reg_base->mr, + DMA_IN(fsl_chan, &fsl_chan->reg_base->mr, 32) | FSL_DMA_MR_CA, + 32); + DMA_OUT(fsl_chan, &fsl_chan->reg_base->mr, + DMA_IN(fsl_chan, &fsl_chan->reg_base->mr, 32) & ~(FSL_DMA_MR_CS + | FSL_DMA_MR_EMS_EN | FSL_DMA_MR_CA), 32); + + while (!dma_is_idle(fsl_chan) && (i++ < 100)) + udelay(10); + if (i >= 100 && !dma_is_idle(fsl_chan)) + dev_err(fsl_chan->dev, "DMA halt timeout!\n"); +} + +static void set_ld_eol(struct fsl_dma_chan *fsl_chan, + struct fsl_desc_sw *desc) +{ + desc->hw.next_ln_addr = CPU_TO_DMA(fsl_chan, + DMA_TO_CPU(fsl_chan, desc->hw.next_ln_addr, 64) | FSL_DMA_EOL, + 64); +} + +static void append_ld_queue(struct fsl_dma_chan *fsl_chan, + struct fsl_desc_sw *new_desc) +{ + struct fsl_desc_sw *queue_tail = to_fsl_desc(fsl_chan->ld_queue.prev); + + if (list_empty(&fsl_chan->ld_queue)) + return; + + /* Link to the new descriptor physical address and + * Enable End-of-segment interrupt for + * the last link descriptor. + * (the previous node's next link descriptor) + * + * For FSL_DMA_IP_83xx, the snoop enable bit need be set. + */ + queue_tail->hw.next_ln_addr = CPU_TO_DMA(fsl_chan, + new_desc->async_tx.phys | FSL_DMA_EOSIE | + (((fsl_chan->feature & FSL_DMA_IP_MASK) + == FSL_DMA_IP_83XX) ? FSL_DMA_SNEN : 0), 64); +} + +/** + * fsl_chan_set_src_loop_size - Set source address hold transfer size + * @fsl_chan : Freescale DMA channel + * @size : Address loop size, 0 for disable loop + * + * The set source address hold transfer size. The source + * address hold or loop transfer size is when the DMA transfer + * data from source address (SA), if the loop size is 4, the DMA will + * read data from SA, SA + 1, SA + 2, SA + 3, then loop back to SA, + * SA + 1 ... and so on. + */ +static void fsl_chan_set_src_loop_size(struct fsl_dma_chan *fsl_chan, int size) +{ + switch (size) { + case 0: + DMA_OUT(fsl_chan, &fsl_chan->reg_base->mr, + DMA_IN(fsl_chan, &fsl_chan->reg_base->mr, 32) & + (~FSL_DMA_MR_SAHE), 32); + break; + case 1: + case 2: + case 4: + case 8: + DMA_OUT(fsl_chan, &fsl_chan->reg_base->mr, + DMA_IN(fsl_chan, &fsl_chan->reg_base->mr, 32) | + FSL_DMA_MR_SAHE | (__ilog2(size) << 14), + 32); + break; + } +} + +/** + * fsl_chan_set_dest_loop_size - Set destination address hold transfer size + * @fsl_chan : Freescale DMA channel + * @size : Address loop size, 0 for disable loop + * + * The set destination address hold transfer size. The destination + * address hold or loop transfer size is when the DMA transfer + * data to destination address (TA), if the loop size is 4, the DMA will + * write data to TA, TA + 1, TA + 2, TA + 3, then loop back to TA, + * TA + 1 ... and so on. + */ +static void fsl_chan_set_dest_loop_size(struct fsl_dma_chan *fsl_chan, int size) +{ + switch (size) { + case 0: + DMA_OUT(fsl_chan, &fsl_chan->reg_base->mr, + DMA_IN(fsl_chan, &fsl_chan->reg_base->mr, 32) & + (~FSL_DMA_MR_DAHE), 32); + break; + case 1: + case 2: + case 4: + case 8: + DMA_OUT(fsl_chan, &fsl_chan->reg_base->mr, + DMA_IN(fsl_chan, &fsl_chan->reg_base->mr, 32) | + FSL_DMA_MR_DAHE | (__ilog2(size) << 16), + 32); + break; + } +} + +/** + * fsl_chan_toggle_ext_pause - Toggle channel external pause status + * @fsl_chan : Freescale DMA channel + * @size : Pause control size, 0 for disable external pause control. + * The maximum is 1024. + * + * The Freescale DMA channel can be controlled by the external + * signal DREQ#. The pause control size is how many bytes are allowed + * to transfer before pausing the channel, after which a new assertion + * of DREQ# resumes channel operation. + */ +static void fsl_chan_toggle_ext_pause(struct fsl_dma_chan *fsl_chan, int size) +{ + if (size > 1024) + return; + + if (size) { + DMA_OUT(fsl_chan, &fsl_chan->reg_base->mr, + DMA_IN(fsl_chan, &fsl_chan->reg_base->mr, 32) + | ((__ilog2(size) << 24) & 0x0f000000), + 32); + fsl_chan->feature |= FSL_DMA_CHAN_PAUSE_EXT; + } else + fsl_chan->feature &= ~FSL_DMA_CHAN_PAUSE_EXT; +} + +/** + * fsl_chan_toggle_ext_start - Toggle channel external start status + * @fsl_chan : Freescale DMA channel + * @enable : 0 is disabled, 1 is enabled. + * + * If enable the external start, the channel can be started by an + * external DMA start pin. So the dma_start() does not start the + * transfer immediately. The DMA channel will wait for the + * control pin asserted. + */ +static void fsl_chan_toggle_ext_start(struct fsl_dma_chan *fsl_chan, int enable) +{ + if (enable) + fsl_chan->feature |= FSL_DMA_CHAN_START_EXT; + else + fsl_chan->feature &= ~FSL_DMA_CHAN_START_EXT; +} + +static dma_cookie_t fsl_dma_tx_submit(struct dma_async_tx_descriptor *tx) +{ + struct fsl_desc_sw *desc = tx_to_fsl_desc(tx); + struct fsl_dma_chan *fsl_chan = to_fsl_chan(tx->chan); + unsigned long flags; + dma_cookie_t cookie; + + /* cookie increment and adding to ld_queue must be atomic */ + spin_lock_irqsave(&fsl_chan->desc_lock, flags); + + cookie = fsl_chan->common.cookie; + cookie++; + if (cookie < 0) + cookie = 1; + desc->async_tx.cookie = cookie; + fsl_chan->common.cookie = desc->async_tx.cookie; + + append_ld_queue(fsl_chan, desc); + list_splice_init(&desc->async_tx.tx_list, fsl_chan->ld_queue.prev); + + spin_unlock_irqrestore(&fsl_chan->desc_lock, flags); + + return cookie; +} + +/** + * fsl_dma_alloc_descriptor - Allocate descriptor from channel's DMA pool. + * @fsl_chan : Freescale DMA channel + * + * Return - The descriptor allocated. NULL for failed. + */ +static struct fsl_desc_sw *fsl_dma_alloc_descriptor( + struct fsl_dma_chan *fsl_chan) +{ + dma_addr_t pdesc; + struct fsl_desc_sw *desc_sw; + + desc_sw = dma_pool_alloc(fsl_chan->desc_pool, GFP_ATOMIC, &pdesc); + if (desc_sw) { + memset(desc_sw, 0, sizeof(struct fsl_desc_sw)); + dma_async_tx_descriptor_init(&desc_sw->async_tx, + &fsl_chan->common); + desc_sw->async_tx.tx_submit = fsl_dma_tx_submit; + INIT_LIST_HEAD(&desc_sw->async_tx.tx_list); + desc_sw->async_tx.phys = pdesc; + } + + return desc_sw; +} + + +/** + * fsl_dma_alloc_chan_resources - Allocate resources for DMA channel. + * @fsl_chan : Freescale DMA channel + * + * This function will create a dma pool for descriptor allocation. + * + * Return - The number of descriptors allocated. + */ +static int fsl_dma_alloc_chan_resources(struct dma_chan *chan) +{ + struct fsl_dma_chan *fsl_chan = to_fsl_chan(chan); + LIST_HEAD(tmp_list); + + /* We need the descriptor to be aligned to 32bytes + * for meeting FSL DMA specification requirement. + */ + fsl_chan->desc_pool = dma_pool_create("fsl_dma_engine_desc_pool", + fsl_chan->dev, sizeof(struct fsl_desc_sw), + 32, 0); + if (!fsl_chan->desc_pool) { + dev_err(fsl_chan->dev, "No memory for channel %d " + "descriptor dma pool.\n", fsl_chan->id); + return 0; + } + + return 1; +} + +/** + * fsl_dma_free_chan_resources - Free all resources of the channel. + * @fsl_chan : Freescale DMA channel + */ +static void fsl_dma_free_chan_resources(struct dma_chan *chan) +{ + struct fsl_dma_chan *fsl_chan = to_fsl_chan(chan); + struct fsl_desc_sw *desc, *_desc; + unsigned long flags; + + dev_dbg(fsl_chan->dev, "Free all channel resources.\n"); + spin_lock_irqsave(&fsl_chan->desc_lock, flags); + list_for_each_entry_safe(desc, _desc, &fsl_chan->ld_queue, node) { +#ifdef FSL_DMA_LD_DEBUG + dev_dbg(fsl_chan->dev, + "LD %p will be released.\n", desc); +#endif + list_del(&desc->node); + /* free link descriptor */ + dma_pool_free(fsl_chan->desc_pool, desc, desc->async_tx.phys); + } + spin_unlock_irqrestore(&fsl_chan->desc_lock, flags); + dma_pool_destroy(fsl_chan->desc_pool); +} + +static struct dma_async_tx_descriptor * +fsl_dma_prep_interrupt(struct dma_chan *chan) +{ + struct fsl_dma_chan *fsl_chan; + struct fsl_desc_sw *new; + + if (!chan) + return NULL; + + fsl_chan = to_fsl_chan(chan); + + new = fsl_dma_alloc_descriptor(fsl_chan); + if (!new) { + dev_err(fsl_chan->dev, "No free memory for link descriptor\n"); + return NULL; + } + + new->async_tx.cookie = -EBUSY; + new->async_tx.ack = 0; + + /* Set End-of-link to the last link descriptor of new list*/ + set_ld_eol(fsl_chan, new); + + return &new->async_tx; +} + +static struct dma_async_tx_descriptor *fsl_dma_prep_memcpy( + struct dma_chan *chan, dma_addr_t dma_dest, dma_addr_t dma_src, + size_t len, unsigned long flags) +{ + struct fsl_dma_chan *fsl_chan; + struct fsl_desc_sw *first = NULL, *prev = NULL, *new; + size_t copy; + LIST_HEAD(link_chain); + + if (!chan) + return NULL; + + if (!len) + return NULL; + + fsl_chan = to_fsl_chan(chan); + + do { + + /* Allocate the link descriptor from DMA pool */ + new = fsl_dma_alloc_descriptor(fsl_chan); + if (!new) { + dev_err(fsl_chan->dev, + "No free memory for link descriptor\n"); + return NULL; + } +#ifdef FSL_DMA_LD_DEBUG + dev_dbg(fsl_chan->dev, "new link desc alloc %p\n", new); +#endif + + copy = min(len, (size_t)FSL_DMA_BCR_MAX_CNT); + + set_desc_cnt(fsl_chan, &new->hw, copy); + set_desc_src(fsl_chan, &new->hw, dma_src); + set_desc_dest(fsl_chan, &new->hw, dma_dest); + + if (!first) + first = new; + else + set_desc_next(fsl_chan, &prev->hw, new->async_tx.phys); + + new->async_tx.cookie = 0; + new->async_tx.ack = 1; + + prev = new; + len -= copy; + dma_src += copy; + dma_dest += copy; + + /* Insert the link descriptor to the LD ring */ + list_add_tail(&new->node, &first->async_tx.tx_list); + } while (len); + + new->async_tx.ack = 0; /* client is in control of this ack */ + new->async_tx.cookie = -EBUSY; + + /* Set End-of-link to the last link descriptor of new list*/ + set_ld_eol(fsl_chan, new); + + return first ? &first->async_tx : NULL; +} + +/** + * fsl_dma_update_completed_cookie - Update the completed cookie. + * @fsl_chan : Freescale DMA channel + */ +static void fsl_dma_update_completed_cookie(struct fsl_dma_chan *fsl_chan) +{ + struct fsl_desc_sw *cur_desc, *desc; + dma_addr_t ld_phy; + + ld_phy = get_cdar(fsl_chan) & FSL_DMA_NLDA_MASK; + + if (ld_phy) { + cur_desc = NULL; + list_for_each_entry(desc, &fsl_chan->ld_queue, node) + if (desc->async_tx.phys == ld_phy) { + cur_desc = desc; + break; + } + + if (cur_desc && cur_desc->async_tx.cookie) { + if (dma_is_idle(fsl_chan)) + fsl_chan->completed_cookie = + cur_desc->async_tx.cookie; + else + fsl_chan->completed_cookie = + cur_desc->async_tx.cookie - 1; + } + } +} + +/** + * fsl_chan_ld_cleanup - Clean up link descriptors + * @fsl_chan : Freescale DMA channel + * + * This function clean up the ld_queue of DMA channel. + * If 'in_intr' is set, the function will move the link descriptor to + * the recycle list. Otherwise, free it directly. + */ +static void fsl_chan_ld_cleanup(struct fsl_dma_chan *fsl_chan) +{ + struct fsl_desc_sw *desc, *_desc; + unsigned long flags; + + spin_lock_irqsave(&fsl_chan->desc_lock, flags); + + dev_dbg(fsl_chan->dev, "chan completed_cookie = %d\n", + fsl_chan->completed_cookie); + list_for_each_entry_safe(desc, _desc, &fsl_chan->ld_queue, node) { + dma_async_tx_callback callback; + void *callback_param; + + if (dma_async_is_complete(desc->async_tx.cookie, + fsl_chan->completed_cookie, fsl_chan->common.cookie) + == DMA_IN_PROGRESS) + break; + + callback = desc->async_tx.callback; + callback_param = desc->async_tx.callback_param; + + /* Remove from ld_queue list */ + list_del(&desc->node); + + dev_dbg(fsl_chan->dev, "link descriptor %p will be recycle.\n", + desc); + dma_pool_free(fsl_chan->desc_pool, desc, desc->async_tx.phys); + + /* Run the link descriptor callback function */ + if (callback) { + spin_unlock_irqrestore(&fsl_chan->desc_lock, flags); + dev_dbg(fsl_chan->dev, "link descriptor %p callback\n", + desc); + callback(callback_param); + spin_lock_irqsave(&fsl_chan->desc_lock, flags); + } + } + spin_unlock_irqrestore(&fsl_chan->desc_lock, flags); +} + +/** + * fsl_chan_xfer_ld_queue - Transfer link descriptors in channel ld_queue. + * @fsl_chan : Freescale DMA channel + */ +static void fsl_chan_xfer_ld_queue(struct fsl_dma_chan *fsl_chan) +{ + struct list_head *ld_node; + dma_addr_t next_dest_addr; + unsigned long flags; + + if (!dma_is_idle(fsl_chan)) + return; + + dma_halt(fsl_chan); + + /* If there are some link descriptors + * not transfered in queue. We need to start it. + */ + spin_lock_irqsave(&fsl_chan->desc_lock, flags); + + /* Find the first un-transfer desciptor */ + for (ld_node = fsl_chan->ld_queue.next; + (ld_node != &fsl_chan->ld_queue) + && (dma_async_is_complete( + to_fsl_desc(ld_node)->async_tx.cookie, + fsl_chan->completed_cookie, + fsl_chan->common.cookie) == DMA_SUCCESS); + ld_node = ld_node->next); + + spin_unlock_irqrestore(&fsl_chan->desc_lock, flags); + + if (ld_node != &fsl_chan->ld_queue) { + /* Get the ld start address from ld_queue */ + next_dest_addr = to_fsl_desc(ld_node)->async_tx.phys; + dev_dbg(fsl_chan->dev, "xfer LDs staring from %p\n", + (void *)next_dest_addr); + set_cdar(fsl_chan, next_dest_addr); + dma_start(fsl_chan); + } else { + set_cdar(fsl_chan, 0); + set_ndar(fsl_chan, 0); + } +} + +/** + * fsl_dma_memcpy_issue_pending - Issue the DMA start command + * @fsl_chan : Freescale DMA channel + */ +static void fsl_dma_memcpy_issue_pending(struct dma_chan *chan) +{ + struct fsl_dma_chan *fsl_chan = to_fsl_chan(chan); + +#ifdef FSL_DMA_LD_DEBUG + struct fsl_desc_sw *ld; + unsigned long flags; + + spin_lock_irqsave(&fsl_chan->desc_lock, flags); + if (list_empty(&fsl_chan->ld_queue)) { + spin_unlock_irqrestore(&fsl_chan->desc_lock, flags); + return; + } + + dev_dbg(fsl_chan->dev, "--memcpy issue--\n"); + list_for_each_entry(ld, &fsl_chan->ld_queue, node) { + int i; + dev_dbg(fsl_chan->dev, "Ch %d, LD %08x\n", + fsl_chan->id, ld->async_tx.phys); + for (i = 0; i < 8; i++) + dev_dbg(fsl_chan->dev, "LD offset %d: %08x\n", + i, *(((u32 *)&ld->hw) + i)); + } + dev_dbg(fsl_chan->dev, "----------------\n"); + spin_unlock_irqrestore(&fsl_chan->desc_lock, flags); +#endif + + fsl_chan_xfer_ld_queue(fsl_chan); +} + +static void fsl_dma_dependency_added(struct dma_chan *chan) +{ + struct fsl_dma_chan *fsl_chan = to_fsl_chan(chan); + + fsl_chan_ld_cleanup(fsl_chan); +} + +/** + * fsl_dma_is_complete - Determine the DMA status + * @fsl_chan : Freescale DMA channel + */ +static enum dma_status fsl_dma_is_complete(struct dma_chan *chan, + dma_cookie_t cookie, + dma_cookie_t *done, + dma_cookie_t *used) +{ + struct fsl_dma_chan *fsl_chan = to_fsl_chan(chan); + dma_cookie_t last_used; + dma_cookie_t last_complete; + + fsl_chan_ld_cleanup(fsl_chan); + + last_used = chan->cookie; + last_complete = fsl_chan->completed_cookie; + + if (done) + *done = last_complete; + + if (used) + *used = last_used; + + return dma_async_is_complete(cookie, last_complete, last_used); +} + +static irqreturn_t fsl_dma_chan_do_interrupt(int irq, void *data) +{ + struct fsl_dma_chan *fsl_chan = (struct fsl_dma_chan *)data; + u32 stat; + + stat = get_sr(fsl_chan); + dev_dbg(fsl_chan->dev, "event: channel %d, stat = 0x%x\n", + fsl_chan->id, stat); + set_sr(fsl_chan, stat); /* Clear the event register */ + + stat &= ~(FSL_DMA_SR_CB | FSL_DMA_SR_CH); + if (!stat) + return IRQ_NONE; + + if (stat & FSL_DMA_SR_TE) + dev_err(fsl_chan->dev, "Transfer Error!\n"); + + /* If the link descriptor segment transfer finishes, + * we will recycle the used descriptor. + */ + if (stat & FSL_DMA_SR_EOSI) { + dev_dbg(fsl_chan->dev, "event: End-of-segments INT\n"); + dev_dbg(fsl_chan->dev, "event: clndar %p, nlndar %p\n", + (void *)get_cdar(fsl_chan), (void *)get_ndar(fsl_chan)); + stat &= ~FSL_DMA_SR_EOSI; + fsl_dma_update_completed_cookie(fsl_chan); + } + + /* If it current transfer is the end-of-transfer, + * we should clear the Channel Start bit for + * prepare next transfer. + */ + if (stat & (FSL_DMA_SR_EOLNI | FSL_DMA_SR_EOCDI)) { + dev_dbg(fsl_chan->dev, "event: End-of-link INT\n"); + stat &= ~FSL_DMA_SR_EOLNI; + fsl_chan_xfer_ld_queue(fsl_chan); + } + + if (stat) + dev_dbg(fsl_chan->dev, "event: unhandled sr 0x%02x\n", + stat); + + dev_dbg(fsl_chan->dev, "event: Exit\n"); + tasklet_schedule(&fsl_chan->tasklet); + return IRQ_HANDLED; +} + +static irqreturn_t fsl_dma_do_interrupt(int irq, void *data) +{ + struct fsl_dma_device *fdev = (struct fsl_dma_device *)data; + u32 gsr; + int ch_nr; + + gsr = (fdev->feature & FSL_DMA_BIG_ENDIAN) ? in_be32(fdev->reg_base) + : in_le32(fdev->reg_base); + ch_nr = (32 - ffs(gsr)) / 8; + + return fdev->chan[ch_nr] ? fsl_dma_chan_do_interrupt(irq, + fdev->chan[ch_nr]) : IRQ_NONE; +} + +static void dma_do_tasklet(unsigned long data) +{ + struct fsl_dma_chan *fsl_chan = (struct fsl_dma_chan *)data; + fsl_chan_ld_cleanup(fsl_chan); +} + +#ifdef FSL_DMA_CALLBACKTEST +static void fsl_dma_callback_test(struct fsl_dma_chan *fsl_chan) +{ + if (fsl_chan) + dev_info(fsl_chan->dev, "selftest: callback is ok!\n"); +} +#endif + +#ifdef CONFIG_FSL_DMA_SELFTEST +static int fsl_dma_self_test(struct fsl_dma_chan *fsl_chan) +{ + struct dma_chan *chan; + int err = 0; + dma_addr_t dma_dest, dma_src; + dma_cookie_t cookie; + u8 *src, *dest; + int i; + size_t test_size; + struct dma_async_tx_descriptor *tx1, *tx2, *tx3; + + test_size = 4096; + + src = kmalloc(test_size * 2, GFP_KERNEL); + if (!src) { + dev_err(fsl_chan->dev, + "selftest: Cannot alloc memory for test!\n"); + err = -ENOMEM; + goto out; + } + + dest = src + test_size; + + for (i = 0; i < test_size; i++) + src[i] = (u8) i; + + chan = &fsl_chan->common; + + if (fsl_dma_alloc_chan_resources(chan) < 1) { + dev_err(fsl_chan->dev, + "selftest: Cannot alloc resources for DMA\n"); + err = -ENODEV; + goto out; + } + + /* TX 1 */ + dma_src = dma_map_single(fsl_chan->dev, src, test_size / 2, + DMA_TO_DEVICE); + dma_dest = dma_map_single(fsl_chan->dev, dest, test_size / 2, + DMA_FROM_DEVICE); + tx1 = fsl_dma_prep_memcpy(chan, dma_dest, dma_src, test_size / 2, 0); + async_tx_ack(tx1); + + cookie = fsl_dma_tx_submit(tx1); + fsl_dma_memcpy_issue_pending(chan); + msleep(2); + + if (fsl_dma_is_complete(chan, cookie, NULL, NULL) != DMA_SUCCESS) { + dev_err(fsl_chan->dev, "selftest: Time out!\n"); + err = -ENODEV; + goto out; + } + + /* Test free and re-alloc channel resources */ + fsl_dma_free_chan_resources(chan); + + if (fsl_dma_alloc_chan_resources(chan) < 1) { + dev_err(fsl_chan->dev, + "selftest: Cannot alloc resources for DMA\n"); + err = -ENODEV; + goto free_resources; + } + + /* Continue to test + * TX 2 + */ + dma_src = dma_map_single(fsl_chan->dev, src + test_size / 2, + test_size / 4, DMA_TO_DEVICE); + dma_dest = dma_map_single(fsl_chan->dev, dest + test_size / 2, + test_size / 4, DMA_FROM_DEVICE); + tx2 = fsl_dma_prep_memcpy(chan, dma_dest, dma_src, test_size / 4, 0); + async_tx_ack(tx2); + + /* TX 3 */ + dma_src = dma_map_single(fsl_chan->dev, src + test_size * 3 / 4, + test_size / 4, DMA_TO_DEVICE); + dma_dest = dma_map_single(fsl_chan->dev, dest + test_size * 3 / 4, + test_size / 4, DMA_FROM_DEVICE); + tx3 = fsl_dma_prep_memcpy(chan, dma_dest, dma_src, test_size / 4, 0); + async_tx_ack(tx3); + + /* Test exchanging the prepared tx sort */ + cookie = fsl_dma_tx_submit(tx3); + cookie = fsl_dma_tx_submit(tx2); + +#ifdef FSL_DMA_CALLBACKTEST + if (dma_has_cap(DMA_INTERRUPT, ((struct fsl_dma_device *) + dev_get_drvdata(fsl_chan->dev->parent))->common.cap_mask)) { + tx3->callback = fsl_dma_callback_test; + tx3->callback_param = fsl_chan; + } +#endif + fsl_dma_memcpy_issue_pending(chan); + msleep(2); + + if (fsl_dma_is_complete(chan, cookie, NULL, NULL) != DMA_SUCCESS) { + dev_err(fsl_chan->dev, "selftest: Time out!\n"); + err = -ENODEV; + goto free_resources; + } + + err = memcmp(src, dest, test_size); + if (err) { + for (i = 0; (*(src + i) == *(dest + i)) && (i < test_size); + i++); + dev_err(fsl_chan->dev, "selftest: Test failed, data %d/%ld is " + "error! src 0x%x, dest 0x%x\n", + i, (long)test_size, *(src + i), *(dest + i)); + } + +free_resources: + fsl_dma_free_chan_resources(chan); +out: + kfree(src); + return err; +} +#endif + +static int __devinit of_fsl_dma_chan_probe(struct of_device *dev, + const struct of_device_id *match) +{ + struct fsl_dma_device *fdev; + struct fsl_dma_chan *new_fsl_chan; + int err; + + fdev = dev_get_drvdata(dev->dev.parent); + BUG_ON(!fdev); + + /* alloc channel */ + new_fsl_chan = kzalloc(sizeof(struct fsl_dma_chan), GFP_KERNEL); + if (!new_fsl_chan) { + dev_err(&dev->dev, "No free memory for allocating " + "dma channels!\n"); + err = -ENOMEM; + goto err; + } + + /* get dma channel register base */ + err = of_address_to_resource(dev->node, 0, &new_fsl_chan->reg); + if (err) { + dev_err(&dev->dev, "Can't get %s property 'reg'\n", + dev->node->full_name); + goto err; + } + + new_fsl_chan->feature = *(u32 *)match->data; + + if (!fdev->feature) + fdev->feature = new_fsl_chan->feature; + + /* If the DMA device's feature is different than its channels', + * report the bug. + */ + WARN_ON(fdev->feature != new_fsl_chan->feature); + + new_fsl_chan->dev = &dev->dev; + new_fsl_chan->reg_base = ioremap(new_fsl_chan->reg.start, + new_fsl_chan->reg.end - new_fsl_chan->reg.start + 1); + + new_fsl_chan->id = ((new_fsl_chan->reg.start - 0x100) & 0xfff) >> 7; + if (new_fsl_chan->id > FSL_DMA_MAX_CHANS_PER_DEVICE) { + dev_err(&dev->dev, "There is no %d channel!\n", + new_fsl_chan->id); + err = -EINVAL; + goto err; + } + fdev->chan[new_fsl_chan->id] = new_fsl_chan; + tasklet_init(&new_fsl_chan->tasklet, dma_do_tasklet, + (unsigned long)new_fsl_chan); + + /* Init the channel */ + dma_init(new_fsl_chan); + + /* Clear cdar registers */ + set_cdar(new_fsl_chan, 0); + + switch (new_fsl_chan->feature & FSL_DMA_IP_MASK) { + case FSL_DMA_IP_85XX: + new_fsl_chan->toggle_ext_start = fsl_chan_toggle_ext_start; + new_fsl_chan->toggle_ext_pause = fsl_chan_toggle_ext_pause; + case FSL_DMA_IP_83XX: + new_fsl_chan->set_src_loop_size = fsl_chan_set_src_loop_size; + new_fsl_chan->set_dest_loop_size = fsl_chan_set_dest_loop_size; + } + + spin_lock_init(&new_fsl_chan->desc_lock); + INIT_LIST_HEAD(&new_fsl_chan->ld_queue); + + new_fsl_chan->common.device = &fdev->common; + + /* Add the channel to DMA device channel list */ + list_add_tail(&new_fsl_chan->common.device_node, + &fdev->common.channels); + fdev->common.chancnt++; + + new_fsl_chan->irq = irq_of_parse_and_map(dev->node, 0); + if (new_fsl_chan->irq != NO_IRQ) { + err = request_irq(new_fsl_chan->irq, + &fsl_dma_chan_do_interrupt, IRQF_SHARED, + "fsldma-channel", new_fsl_chan); + if (err) { + dev_err(&dev->dev, "DMA channel %s request_irq error " + "with return %d\n", dev->node->full_name, err); + goto err; + } + } + +#ifdef CONFIG_FSL_DMA_SELFTEST + err = fsl_dma_self_test(new_fsl_chan); + if (err) + goto err; +#endif + + dev_info(&dev->dev, "#%d (%s), irq %d\n", new_fsl_chan->id, + match->compatible, new_fsl_chan->irq); + + return 0; +err: + dma_halt(new_fsl_chan); + iounmap(new_fsl_chan->reg_base); + free_irq(new_fsl_chan->irq, new_fsl_chan); + list_del(&new_fsl_chan->common.device_node); + kfree(new_fsl_chan); + return err; +} + +const u32 mpc8540_dma_ip_feature = FSL_DMA_IP_85XX | FSL_DMA_BIG_ENDIAN; +const u32 mpc8349_dma_ip_feature = FSL_DMA_IP_83XX | FSL_DMA_LITTLE_ENDIAN; + +static struct of_device_id of_fsl_dma_chan_ids[] = { + { + .compatible = "fsl,mpc8540-dma-channel", + .data = (void *)&mpc8540_dma_ip_feature, + }, + { + .compatible = "fsl,mpc8349-dma-channel", + .data = (void *)&mpc8349_dma_ip_feature, + }, + {} +}; + +static struct of_platform_driver of_fsl_dma_chan_driver = { + .name = "of-fsl-dma-channel", + .match_table = of_fsl_dma_chan_ids, + .probe = of_fsl_dma_chan_probe, +}; + +static __init int of_fsl_dma_chan_init(void) +{ + return of_register_platform_driver(&of_fsl_dma_chan_driver); +} + +static int __devinit of_fsl_dma_probe(struct of_device *dev, + const struct of_device_id *match) +{ + int err; + unsigned int irq; + struct fsl_dma_device *fdev; + + fdev = kzalloc(sizeof(struct fsl_dma_device), GFP_KERNEL); + if (!fdev) { + dev_err(&dev->dev, "No enough memory for 'priv'\n"); + err = -ENOMEM; + goto err; + } + fdev->dev = &dev->dev; + INIT_LIST_HEAD(&fdev->common.channels); + + /* get DMA controller register base */ + err = of_address_to_resource(dev->node, 0, &fdev->reg); + if (err) { + dev_err(&dev->dev, "Can't get %s property 'reg'\n", + dev->node->full_name); + goto err; + } + + dev_info(&dev->dev, "Probe the Freescale DMA driver for %s " + "controller at %p...\n", + match->compatible, (void *)fdev->reg.start); + fdev->reg_base = ioremap(fdev->reg.start, fdev->reg.end + - fdev->reg.start + 1); + + dma_cap_set(DMA_MEMCPY, fdev->common.cap_mask); + dma_cap_set(DMA_INTERRUPT, fdev->common.cap_mask); + fdev->common.device_alloc_chan_resources = fsl_dma_alloc_chan_resources; + fdev->common.device_free_chan_resources = fsl_dma_free_chan_resources; + fdev->common.device_prep_dma_interrupt = fsl_dma_prep_interrupt; + fdev->common.device_prep_dma_memcpy = fsl_dma_prep_memcpy; + fdev->common.device_is_tx_complete = fsl_dma_is_complete; + fdev->common.device_issue_pending = fsl_dma_memcpy_issue_pending; + fdev->common.device_dependency_added = fsl_dma_dependency_added; + fdev->common.dev = &dev->dev; + + irq = irq_of_parse_and_map(dev->node, 0); + if (irq != NO_IRQ) { + err = request_irq(irq, &fsl_dma_do_interrupt, IRQF_SHARED, + "fsldma-device", fdev); + if (err) { + dev_err(&dev->dev, "DMA device request_irq error " + "with return %d\n", err); + goto err; + } + } + + dev_set_drvdata(&(dev->dev), fdev); + of_platform_bus_probe(dev->node, of_fsl_dma_chan_ids, &dev->dev); + + dma_async_device_register(&fdev->common); + return 0; + +err: + iounmap(fdev->reg_base); + kfree(fdev); + return err; +} + +static struct of_device_id of_fsl_dma_ids[] = { + { .compatible = "fsl,mpc8540-dma", }, + { .compatible = "fsl,mpc8349-dma", }, + {} +}; + +static struct of_platform_driver of_fsl_dma_driver = { + .name = "of-fsl-dma", + .match_table = of_fsl_dma_ids, + .probe = of_fsl_dma_probe, +}; + +static __init int of_fsl_dma_init(void) +{ + return of_register_platform_driver(&of_fsl_dma_driver); +} + +subsys_initcall(of_fsl_dma_chan_init); +subsys_initcall(of_fsl_dma_init); diff --git a/drivers/dma/fsldma.h b/drivers/dma/fsldma.h new file mode 100644 index 0000000000000000000000000000000000000000..ba78c42121ba3c695adfb2c5f50c68d5d6acd644 --- /dev/null +++ b/drivers/dma/fsldma.h @@ -0,0 +1,189 @@ +/* + * Copyright (C) 2007 Freescale Semiconductor, Inc. All rights reserved. + * + * Author: + * Zhang Wei , Jul 2007 + * Ebony Zhu , May 2007 + * + * This is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + */ +#ifndef __DMA_FSLDMA_H +#define __DMA_FSLDMA_H + +#include +#include +#include + +/* Define data structures needed by Freescale + * MPC8540 and MPC8349 DMA controller. + */ +#define FSL_DMA_MR_CS 0x00000001 +#define FSL_DMA_MR_CC 0x00000002 +#define FSL_DMA_MR_CA 0x00000008 +#define FSL_DMA_MR_EIE 0x00000040 +#define FSL_DMA_MR_XFE 0x00000020 +#define FSL_DMA_MR_EOLNIE 0x00000100 +#define FSL_DMA_MR_EOLSIE 0x00000080 +#define FSL_DMA_MR_EOSIE 0x00000200 +#define FSL_DMA_MR_CDSM 0x00000010 +#define FSL_DMA_MR_CTM 0x00000004 +#define FSL_DMA_MR_EMP_EN 0x00200000 +#define FSL_DMA_MR_EMS_EN 0x00040000 +#define FSL_DMA_MR_DAHE 0x00002000 +#define FSL_DMA_MR_SAHE 0x00001000 + +/* Special MR definition for MPC8349 */ +#define FSL_DMA_MR_EOTIE 0x00000080 + +#define FSL_DMA_SR_CH 0x00000020 +#define FSL_DMA_SR_CB 0x00000004 +#define FSL_DMA_SR_TE 0x00000080 +#define FSL_DMA_SR_EOSI 0x00000002 +#define FSL_DMA_SR_EOLSI 0x00000001 +#define FSL_DMA_SR_EOCDI 0x00000001 +#define FSL_DMA_SR_EOLNI 0x00000008 + +#define FSL_DMA_SATR_SBPATMU 0x20000000 +#define FSL_DMA_SATR_STRANSINT_RIO 0x00c00000 +#define FSL_DMA_SATR_SREADTYPE_SNOOP_READ 0x00050000 +#define FSL_DMA_SATR_SREADTYPE_BP_IORH 0x00020000 +#define FSL_DMA_SATR_SREADTYPE_BP_NREAD 0x00040000 +#define FSL_DMA_SATR_SREADTYPE_BP_MREAD 0x00070000 + +#define FSL_DMA_DATR_DBPATMU 0x20000000 +#define FSL_DMA_DATR_DTRANSINT_RIO 0x00c00000 +#define FSL_DMA_DATR_DWRITETYPE_SNOOP_WRITE 0x00050000 +#define FSL_DMA_DATR_DWRITETYPE_BP_FLUSH 0x00010000 + +#define FSL_DMA_EOL ((u64)0x1) +#define FSL_DMA_SNEN ((u64)0x10) +#define FSL_DMA_EOSIE 0x8 +#define FSL_DMA_NLDA_MASK (~(u64)0x1f) + +#define FSL_DMA_BCR_MAX_CNT 0x03ffffffu + +#define FSL_DMA_DGSR_TE 0x80 +#define FSL_DMA_DGSR_CH 0x20 +#define FSL_DMA_DGSR_PE 0x10 +#define FSL_DMA_DGSR_EOLNI 0x08 +#define FSL_DMA_DGSR_CB 0x04 +#define FSL_DMA_DGSR_EOSI 0x02 +#define FSL_DMA_DGSR_EOLSI 0x01 + +struct fsl_dma_ld_hw { + u64 __bitwise src_addr; + u64 __bitwise dst_addr; + u64 __bitwise next_ln_addr; + u32 __bitwise count; + u32 __bitwise reserve; +} __attribute__((aligned(32))); + +struct fsl_desc_sw { + struct fsl_dma_ld_hw hw; + struct list_head node; + struct dma_async_tx_descriptor async_tx; + struct list_head *ld; + void *priv; +} __attribute__((aligned(32))); + +struct fsl_dma_chan_regs { + u32 __bitwise mr; /* 0x00 - Mode Register */ + u32 __bitwise sr; /* 0x04 - Status Register */ + u64 __bitwise cdar; /* 0x08 - Current descriptor address register */ + u64 __bitwise sar; /* 0x10 - Source Address Register */ + u64 __bitwise dar; /* 0x18 - Destination Address Register */ + u32 __bitwise bcr; /* 0x20 - Byte Count Register */ + u64 __bitwise ndar; /* 0x24 - Next Descriptor Address Register */ +}; + +struct fsl_dma_chan; +#define FSL_DMA_MAX_CHANS_PER_DEVICE 4 + +struct fsl_dma_device { + void __iomem *reg_base; /* DGSR register base */ + struct resource reg; /* Resource for register */ + struct device *dev; + struct dma_device common; + struct fsl_dma_chan *chan[FSL_DMA_MAX_CHANS_PER_DEVICE]; + u32 feature; /* The same as DMA channels */ +}; + +/* Define macros for fsl_dma_chan->feature property */ +#define FSL_DMA_LITTLE_ENDIAN 0x00000000 +#define FSL_DMA_BIG_ENDIAN 0x00000001 + +#define FSL_DMA_IP_MASK 0x00000ff0 +#define FSL_DMA_IP_85XX 0x00000010 +#define FSL_DMA_IP_83XX 0x00000020 + +#define FSL_DMA_CHAN_PAUSE_EXT 0x00001000 +#define FSL_DMA_CHAN_START_EXT 0x00002000 + +struct fsl_dma_chan { + struct fsl_dma_chan_regs __iomem *reg_base; + dma_cookie_t completed_cookie; /* The maximum cookie completed */ + spinlock_t desc_lock; /* Descriptor operation lock */ + struct list_head ld_queue; /* Link descriptors queue */ + struct dma_chan common; /* DMA common channel */ + struct dma_pool *desc_pool; /* Descriptors pool */ + struct device *dev; /* Channel device */ + struct resource reg; /* Resource for register */ + int irq; /* Channel IRQ */ + int id; /* Raw id of this channel */ + struct tasklet_struct tasklet; + u32 feature; + + void (*toggle_ext_pause)(struct fsl_dma_chan *fsl_chan, int size); + void (*toggle_ext_start)(struct fsl_dma_chan *fsl_chan, int enable); + void (*set_src_loop_size)(struct fsl_dma_chan *fsl_chan, int size); + void (*set_dest_loop_size)(struct fsl_dma_chan *fsl_chan, int size); +}; + +#define to_fsl_chan(chan) container_of(chan, struct fsl_dma_chan, common) +#define to_fsl_desc(lh) container_of(lh, struct fsl_desc_sw, node) +#define tx_to_fsl_desc(tx) container_of(tx, struct fsl_desc_sw, async_tx) + +#ifndef __powerpc64__ +static u64 in_be64(const u64 __iomem *addr) +{ + return ((u64)in_be32((u32 *)addr) << 32) | (in_be32((u32 *)addr + 1)); +} + +static void out_be64(u64 __iomem *addr, u64 val) +{ + out_be32((u32 *)addr, val >> 32); + out_be32((u32 *)addr + 1, (u32)val); +} + +/* There is no asm instructions for 64 bits reverse loads and stores */ +static u64 in_le64(const u64 __iomem *addr) +{ + return ((u64)in_le32((u32 *)addr + 1) << 32) | (in_le32((u32 *)addr)); +} + +static void out_le64(u64 __iomem *addr, u64 val) +{ + out_le32((u32 *)addr + 1, val >> 32); + out_le32((u32 *)addr, (u32)val); +} +#endif + +#define DMA_IN(fsl_chan, addr, width) \ + (((fsl_chan)->feature & FSL_DMA_BIG_ENDIAN) ? \ + in_be##width(addr) : in_le##width(addr)) +#define DMA_OUT(fsl_chan, addr, val, width) \ + (((fsl_chan)->feature & FSL_DMA_BIG_ENDIAN) ? \ + out_be##width(addr, val) : out_le##width(addr, val)) + +#define DMA_TO_CPU(fsl_chan, d, width) \ + (((fsl_chan)->feature & FSL_DMA_BIG_ENDIAN) ? \ + be##width##_to_cpu(d) : le##width##_to_cpu(d)) +#define CPU_TO_DMA(fsl_chan, c, width) \ + (((fsl_chan)->feature & FSL_DMA_BIG_ENDIAN) ? \ + cpu_to_be##width(c) : cpu_to_le##width(c)) + +#endif /* __DMA_FSLDMA_H */ diff --git a/drivers/dma/ioat_dma.c b/drivers/dma/ioat_dma.c index dff38accc5c1df47193a73b4fb81e467012d80b6..4017d9e7acd2a2b68020e2584c71dc654dd20cae 100644 --- a/drivers/dma/ioat_dma.c +++ b/drivers/dma/ioat_dma.c @@ -714,6 +714,7 @@ static struct dma_async_tx_descriptor *ioat1_dma_prep_memcpy( new->len = len; new->dst = dma_dest; new->src = dma_src; + new->async_tx.ack = 0; return &new->async_tx; } else return NULL; @@ -741,6 +742,7 @@ static struct dma_async_tx_descriptor *ioat2_dma_prep_memcpy( new->len = len; new->dst = dma_dest; new->src = dma_src; + new->async_tx.ack = 0; return &new->async_tx; } else return NULL; diff --git a/drivers/dma/iop-adma.c b/drivers/dma/iop-adma.c index 3986d54492bde18d2b0d45d2e64a449dac5af227..f82b0906d4666bb79483dd1d5f5d64109e164907 100644 --- a/drivers/dma/iop-adma.c +++ b/drivers/dma/iop-adma.c @@ -140,7 +140,7 @@ static void __iop_adma_slot_cleanup(struct iop_adma_chan *iop_chan) int busy = iop_chan_is_busy(iop_chan); int seen_current = 0, slot_cnt = 0, slots_per_op = 0; - dev_dbg(iop_chan->device->common.dev, "%s\n", __FUNCTION__); + dev_dbg(iop_chan->device->common.dev, "%s\n", __func__); /* free completed slots from the chain starting with * the oldest descriptor */ @@ -438,7 +438,7 @@ iop_adma_tx_submit(struct dma_async_tx_descriptor *tx) spin_unlock_bh(&iop_chan->lock); dev_dbg(iop_chan->device->common.dev, "%s cookie: %d slot: %d\n", - __FUNCTION__, sw_desc->async_tx.cookie, sw_desc->idx); + __func__, sw_desc->async_tx.cookie, sw_desc->idx); return cookie; } @@ -520,7 +520,7 @@ iop_adma_prep_dma_interrupt(struct dma_chan *chan) struct iop_adma_desc_slot *sw_desc, *grp_start; int slot_cnt, slots_per_op; - dev_dbg(iop_chan->device->common.dev, "%s\n", __FUNCTION__); + dev_dbg(iop_chan->device->common.dev, "%s\n", __func__); spin_lock_bh(&iop_chan->lock); slot_cnt = iop_chan_interrupt_slot_count(&slots_per_op, iop_chan); @@ -548,7 +548,7 @@ iop_adma_prep_dma_memcpy(struct dma_chan *chan, dma_addr_t dma_dest, BUG_ON(unlikely(len > IOP_ADMA_MAX_BYTE_COUNT)); dev_dbg(iop_chan->device->common.dev, "%s len: %u\n", - __FUNCTION__, len); + __func__, len); spin_lock_bh(&iop_chan->lock); slot_cnt = iop_chan_memcpy_slot_count(len, &slots_per_op); @@ -580,7 +580,7 @@ iop_adma_prep_dma_memset(struct dma_chan *chan, dma_addr_t dma_dest, BUG_ON(unlikely(len > IOP_ADMA_MAX_BYTE_COUNT)); dev_dbg(iop_chan->device->common.dev, "%s len: %u\n", - __FUNCTION__, len); + __func__, len); spin_lock_bh(&iop_chan->lock); slot_cnt = iop_chan_memset_slot_count(len, &slots_per_op); @@ -614,7 +614,7 @@ iop_adma_prep_dma_xor(struct dma_chan *chan, dma_addr_t dma_dest, dev_dbg(iop_chan->device->common.dev, "%s src_cnt: %d len: %u flags: %lx\n", - __FUNCTION__, src_cnt, len, flags); + __func__, src_cnt, len, flags); spin_lock_bh(&iop_chan->lock); slot_cnt = iop_chan_xor_slot_count(len, src_cnt, &slots_per_op); @@ -648,7 +648,7 @@ iop_adma_prep_dma_zero_sum(struct dma_chan *chan, dma_addr_t *dma_src, return NULL; dev_dbg(iop_chan->device->common.dev, "%s src_cnt: %d len: %u\n", - __FUNCTION__, src_cnt, len); + __func__, src_cnt, len); spin_lock_bh(&iop_chan->lock); slot_cnt = iop_chan_zero_sum_slot_count(len, src_cnt, &slots_per_op); @@ -659,7 +659,7 @@ iop_adma_prep_dma_zero_sum(struct dma_chan *chan, dma_addr_t *dma_src, iop_desc_set_zero_sum_byte_count(grp_start, len); grp_start->xor_check_result = result; pr_debug("\t%s: grp_start->xor_check_result: %p\n", - __FUNCTION__, grp_start->xor_check_result); + __func__, grp_start->xor_check_result); sw_desc->unmap_src_cnt = src_cnt; sw_desc->unmap_len = len; while (src_cnt--) @@ -700,7 +700,7 @@ static void iop_adma_free_chan_resources(struct dma_chan *chan) iop_chan->last_used = NULL; dev_dbg(iop_chan->device->common.dev, "%s slots_allocated %d\n", - __FUNCTION__, iop_chan->slots_allocated); + __func__, iop_chan->slots_allocated); spin_unlock_bh(&iop_chan->lock); /* one is ok since we left it on there on purpose */ @@ -753,7 +753,7 @@ static irqreturn_t iop_adma_eot_handler(int irq, void *data) { struct iop_adma_chan *chan = data; - dev_dbg(chan->device->common.dev, "%s\n", __FUNCTION__); + dev_dbg(chan->device->common.dev, "%s\n", __func__); tasklet_schedule(&chan->irq_tasklet); @@ -766,7 +766,7 @@ static irqreturn_t iop_adma_eoc_handler(int irq, void *data) { struct iop_adma_chan *chan = data; - dev_dbg(chan->device->common.dev, "%s\n", __FUNCTION__); + dev_dbg(chan->device->common.dev, "%s\n", __func__); tasklet_schedule(&chan->irq_tasklet); @@ -823,7 +823,7 @@ static int __devinit iop_adma_memcpy_self_test(struct iop_adma_device *device) int err = 0; struct iop_adma_chan *iop_chan; - dev_dbg(device->common.dev, "%s\n", __FUNCTION__); + dev_dbg(device->common.dev, "%s\n", __func__); src = kzalloc(sizeof(u8) * IOP_ADMA_TEST_SIZE, GFP_KERNEL); if (!src) @@ -906,7 +906,7 @@ iop_adma_xor_zero_sum_self_test(struct iop_adma_device *device) int err = 0; struct iop_adma_chan *iop_chan; - dev_dbg(device->common.dev, "%s\n", __FUNCTION__); + dev_dbg(device->common.dev, "%s\n", __func__); for (src_idx = 0; src_idx < IOP_ADMA_NUM_SRC_TEST; src_idx++) { xor_srcs[src_idx] = alloc_page(GFP_KERNEL); @@ -1159,7 +1159,7 @@ static int __devinit iop_adma_probe(struct platform_device *pdev) } dev_dbg(&pdev->dev, "%s: allocted descriptor pool virt %p phys %p\n", - __FUNCTION__, adev->dma_desc_pool_virt, + __func__, adev->dma_desc_pool_virt, (void *) adev->dma_desc_pool); adev->id = plat_data->hw_id; @@ -1289,7 +1289,7 @@ static void iop_chan_start_null_memcpy(struct iop_adma_chan *iop_chan) dma_cookie_t cookie; int slot_cnt, slots_per_op; - dev_dbg(iop_chan->device->common.dev, "%s\n", __FUNCTION__); + dev_dbg(iop_chan->device->common.dev, "%s\n", __func__); spin_lock_bh(&iop_chan->lock); slot_cnt = iop_chan_memcpy_slot_count(0, &slots_per_op); @@ -1346,7 +1346,7 @@ static void iop_chan_start_null_xor(struct iop_adma_chan *iop_chan) dma_cookie_t cookie; int slot_cnt, slots_per_op; - dev_dbg(iop_chan->device->common.dev, "%s\n", __FUNCTION__); + dev_dbg(iop_chan->device->common.dev, "%s\n", __func__); spin_lock_bh(&iop_chan->lock); slot_cnt = iop_chan_xor_slot_count(0, 2, &slots_per_op); diff --git a/drivers/firewire/Kconfig b/drivers/firewire/Kconfig index fe9e768cfbc4d28aa462d73fb60d79b689d160e9..25bdc2dd9ce10cf5cb8bfe2fd19ac130c27cdb33 100644 --- a/drivers/firewire/Kconfig +++ b/drivers/firewire/Kconfig @@ -1,5 +1,3 @@ -# -*- shell-script -*- - comment "An alternative FireWire stack is available with EXPERIMENTAL=y" depends on EXPERIMENTAL=n @@ -21,27 +19,7 @@ config FIREWIRE NOTE: You should only build ONE of the stacks, unless you REALLY know what - you are doing. If you install both, you should configure them only as - modules rather than link them statically, and you should blacklist one - of the concurrent low-level drivers in /etc/modprobe.conf. Add either - - blacklist firewire-ohci - or - blacklist ohci1394 - - there depending on which driver you DON'T want to have auto-loaded. - You can optionally do the same with the other IEEE 1394/ FireWire - drivers. - - If you have an old modprobe which doesn't implement the blacklist - directive, use either - - install firewire-ohci /bin/true - or - install ohci1394 /bin/true - - and so on, depending on which modules you DON't want to have - auto-loaded. + you are doing. config FIREWIRE_OHCI tristate "Support for OHCI FireWire host controllers" @@ -57,8 +35,24 @@ config FIREWIRE_OHCI NOTE: - If you also build ohci1394 of the classic stack, blacklist either - ohci1394 or firewire-ohci to let hotplug load only the desired driver. + You should only build ohci1394 or firewire-ohci, but not both. + If you nevertheless want to install both, you should configure them + only as modules and blacklist the driver(s) which you don't want to + have auto-loaded. Add either + + blacklist firewire-ohci + or + blacklist ohci1394 + blacklist video1394 + blacklist dv1394 + + to /etc/modprobe.conf or /etc/modprobe.d/* and update modprobe.conf + depending on your distribution. The latter two modules should be + blacklisted together with ohci1394 because they depend on ohci1394. + + If you have an old modprobe which doesn't implement the blacklist + directive, use "install modulename /bin/true" for the modules to be + blacklisted. config FIREWIRE_SBP2 tristate "Support for storage devices (SBP-2 protocol driver)" @@ -75,9 +69,3 @@ config FIREWIRE_SBP2 You should also enable support for disks, CD-ROMs, etc. in the SCSI configuration section. - - NOTE: - - If you also build sbp2 of the classic stack, blacklist either sbp2 - or firewire-sbp2 to let hotplug load only the desired driver. - diff --git a/drivers/firewire/fw-card.c b/drivers/firewire/fw-card.c index 3e9719948a8e7817658496929115fe52bda45473..a03462750b95ee0045408a5c8d669ba7bc3d461d 100644 --- a/drivers/firewire/fw-card.c +++ b/drivers/firewire/fw-card.c @@ -18,6 +18,7 @@ #include #include +#include #include #include #include @@ -214,17 +215,29 @@ static void fw_card_bm_work(struct work_struct *work) { struct fw_card *card = container_of(work, struct fw_card, work.work); - struct fw_device *root; + struct fw_device *root_device; + struct fw_node *root_node, *local_node; struct bm_data bmd; unsigned long flags; int root_id, new_root_id, irm_id, gap_count, generation, grace; int do_reset = 0; spin_lock_irqsave(&card->lock, flags); + local_node = card->local_node; + root_node = card->root_node; + + if (local_node == NULL) { + spin_unlock_irqrestore(&card->lock, flags); + return; + } + fw_node_get(local_node); + fw_node_get(root_node); generation = card->generation; - root = card->root_node->data; - root_id = card->root_node->node_id; + root_device = root_node->data; + if (root_device) + fw_device_get(root_device); + root_id = root_node->node_id; grace = time_after(jiffies, card->reset_jiffies + DIV_ROUND_UP(HZ, 10)); if (card->bm_generation + 1 == generation || @@ -243,14 +256,14 @@ fw_card_bm_work(struct work_struct *work) irm_id = card->irm_node->node_id; if (!card->irm_node->link_on) { - new_root_id = card->local_node->node_id; + new_root_id = local_node->node_id; fw_notify("IRM has link off, making local node (%02x) root.\n", new_root_id); goto pick_me; } bmd.lock.arg = cpu_to_be32(0x3f); - bmd.lock.data = cpu_to_be32(card->local_node->node_id); + bmd.lock.data = cpu_to_be32(local_node->node_id); spin_unlock_irqrestore(&card->lock, flags); @@ -267,12 +280,12 @@ fw_card_bm_work(struct work_struct *work) * Another bus reset happened. Just return, * the BM work has been rescheduled. */ - return; + goto out; } if (bmd.rcode == RCODE_COMPLETE && bmd.old != 0x3f) /* Somebody else is BM, let them do the work. */ - return; + goto out; spin_lock_irqsave(&card->lock, flags); if (bmd.rcode != RCODE_COMPLETE) { @@ -282,7 +295,7 @@ fw_card_bm_work(struct work_struct *work) * do a bus reset and pick the local node as * root, and thus, IRM. */ - new_root_id = card->local_node->node_id; + new_root_id = local_node->node_id; fw_notify("BM lock failed, making local node (%02x) root.\n", new_root_id); goto pick_me; @@ -295,7 +308,7 @@ fw_card_bm_work(struct work_struct *work) */ spin_unlock_irqrestore(&card->lock, flags); schedule_delayed_work(&card->work, DIV_ROUND_UP(HZ, 10)); - return; + goto out; } /* @@ -305,20 +318,20 @@ fw_card_bm_work(struct work_struct *work) */ card->bm_generation = generation; - if (root == NULL) { + if (root_device == NULL) { /* * Either link_on is false, or we failed to read the * config rom. In either case, pick another root. */ - new_root_id = card->local_node->node_id; - } else if (atomic_read(&root->state) != FW_DEVICE_RUNNING) { + new_root_id = local_node->node_id; + } else if (atomic_read(&root_device->state) != FW_DEVICE_RUNNING) { /* * If we haven't probed this device yet, bail out now * and let's try again once that's done. */ spin_unlock_irqrestore(&card->lock, flags); - return; - } else if (root->config_rom[2] & BIB_CMC) { + goto out; + } else if (root_device->config_rom[2] & BIB_CMC) { /* * FIXME: I suppose we should set the cmstr bit in the * STATE_CLEAR register of this node, as described in @@ -332,7 +345,7 @@ fw_card_bm_work(struct work_struct *work) * successfully read the config rom, but it's not * cycle master capable. */ - new_root_id = card->local_node->node_id; + new_root_id = local_node->node_id; } pick_me: @@ -341,8 +354,8 @@ fw_card_bm_work(struct work_struct *work) * the typically much larger 1394b beta repeater delays though. */ if (!card->beta_repeaters_present && - card->root_node->max_hops < ARRAY_SIZE(gap_count_table)) - gap_count = gap_count_table[card->root_node->max_hops]; + root_node->max_hops < ARRAY_SIZE(gap_count_table)) + gap_count = gap_count_table[root_node->max_hops]; else gap_count = 63; @@ -364,6 +377,11 @@ fw_card_bm_work(struct work_struct *work) fw_send_phy_config(card, new_root_id, generation, gap_count); fw_core_initiate_bus_reset(card, 1); } + out: + if (root_device) + fw_device_put(root_device); + fw_node_put(root_node); + fw_node_put(local_node); } static void @@ -381,6 +399,7 @@ fw_card_initialize(struct fw_card *card, const struct fw_card_driver *driver, static atomic_t index = ATOMIC_INIT(-1); kref_init(&card->kref); + atomic_set(&card->device_count, 0); card->index = atomic_inc_return(&index); card->driver = driver; card->device = device; @@ -511,8 +530,14 @@ fw_core_remove_card(struct fw_card *card) card->driver = &dummy_driver; fw_destroy_nodes(card); - flush_scheduled_work(); + /* + * Wait for all device workqueue jobs to finish. Otherwise the + * firewire-core module could be unloaded before the jobs ran. + */ + while (atomic_read(&card->device_count) > 0) + msleep(100); + cancel_delayed_work_sync(&card->work); fw_flush_transactions(card); del_timer_sync(&card->flush_timer); diff --git a/drivers/firewire/fw-cdev.c b/drivers/firewire/fw-cdev.c index 7e73cbaa4121047ffe6eb7c5f137357e0739c58e..46bc197a047fe84329f4ec868e351ae0438cac2e 100644 --- a/drivers/firewire/fw-cdev.c +++ b/drivers/firewire/fw-cdev.c @@ -109,15 +109,17 @@ static int fw_device_op_open(struct inode *inode, struct file *file) struct client *client; unsigned long flags; - device = fw_device_from_devt(inode->i_rdev); + device = fw_device_get_by_devt(inode->i_rdev); if (device == NULL) return -ENODEV; client = kzalloc(sizeof(*client), GFP_KERNEL); - if (client == NULL) + if (client == NULL) { + fw_device_put(device); return -ENOMEM; + } - client->device = fw_device_get(device); + client->device = device; INIT_LIST_HEAD(&client->event_list); INIT_LIST_HEAD(&client->resource_list); spin_lock_init(&client->lock); @@ -644,6 +646,10 @@ static int ioctl_create_iso_context(struct client *client, void *buffer) struct fw_cdev_create_iso_context *request = buffer; struct fw_iso_context *context; + /* We only support one context at this time. */ + if (client->iso_context != NULL) + return -EBUSY; + if (request->channel > 63) return -EINVAL; @@ -790,8 +796,9 @@ static int ioctl_start_iso(struct client *client, void *buffer) { struct fw_cdev_start_iso *request = buffer; - if (request->handle != 0) + if (client->iso_context == NULL || request->handle != 0) return -EINVAL; + if (client->iso_context->type == FW_ISO_CONTEXT_RECEIVE) { if (request->tags == 0 || request->tags > 15) return -EINVAL; @@ -808,7 +815,7 @@ static int ioctl_stop_iso(struct client *client, void *buffer) { struct fw_cdev_stop_iso *request = buffer; - if (request->handle != 0) + if (client->iso_context == NULL || request->handle != 0) return -EINVAL; return fw_iso_context_stop(client->iso_context); diff --git a/drivers/firewire/fw-device.c b/drivers/firewire/fw-device.c index de9066e69adfbeea440d31cec1c0945f337db728..870125a3638e5a8e647684de358b4be5f4290491 100644 --- a/drivers/firewire/fw-device.c +++ b/drivers/firewire/fw-device.c @@ -150,21 +150,10 @@ struct bus_type fw_bus_type = { }; EXPORT_SYMBOL(fw_bus_type); -struct fw_device *fw_device_get(struct fw_device *device) -{ - get_device(&device->device); - - return device; -} - -void fw_device_put(struct fw_device *device) -{ - put_device(&device->device); -} - static void fw_device_release(struct device *dev) { struct fw_device *device = fw_device(dev); + struct fw_card *card = device->card; unsigned long flags; /* @@ -176,9 +165,9 @@ static void fw_device_release(struct device *dev) spin_unlock_irqrestore(&device->card->lock, flags); fw_node_put(device->node); - fw_card_put(device->card); kfree(device->config_rom); kfree(device); + atomic_dec(&card->device_count); } int fw_device_enable_phys_dma(struct fw_device *device) @@ -358,12 +347,9 @@ static ssize_t guid_show(struct device *dev, struct device_attribute *attr, char *buf) { struct fw_device *device = fw_device(dev); - u64 guid; - - guid = ((u64)device->config_rom[3] << 32) | device->config_rom[4]; - return snprintf(buf, PAGE_SIZE, "0x%016llx\n", - (unsigned long long)guid); + return snprintf(buf, PAGE_SIZE, "0x%08x%08x\n", + device->config_rom[3], device->config_rom[4]); } static struct device_attribute fw_device_attributes[] = { @@ -610,12 +596,14 @@ static DECLARE_RWSEM(idr_rwsem); static DEFINE_IDR(fw_device_idr); int fw_cdev_major; -struct fw_device *fw_device_from_devt(dev_t devt) +struct fw_device *fw_device_get_by_devt(dev_t devt) { struct fw_device *device; down_read(&idr_rwsem); device = idr_find(&fw_device_idr, MINOR(devt)); + if (device) + fw_device_get(device); up_read(&idr_rwsem); return device; @@ -627,13 +615,14 @@ static void fw_device_shutdown(struct work_struct *work) container_of(work, struct fw_device, work.work); int minor = MINOR(device->device.devt); - down_write(&idr_rwsem); - idr_remove(&fw_device_idr, minor); - up_write(&idr_rwsem); - fw_device_cdev_remove(device); device_for_each_child(&device->device, NULL, shutdown_unit); device_unregister(&device->device); + + down_write(&idr_rwsem); + idr_remove(&fw_device_idr, minor); + up_write(&idr_rwsem); + fw_device_put(device); } static struct device_type fw_device_type = { @@ -668,7 +657,8 @@ static void fw_device_init(struct work_struct *work) */ if (read_bus_info_block(device, device->generation) < 0) { - if (device->config_rom_retries < MAX_RETRIES) { + if (device->config_rom_retries < MAX_RETRIES && + atomic_read(&device->state) == FW_DEVICE_INITIALIZING) { device->config_rom_retries++; schedule_delayed_work(&device->work, RETRY_DELAY); } else { @@ -682,10 +672,13 @@ static void fw_device_init(struct work_struct *work) } err = -ENOMEM; + + fw_device_get(device); down_write(&idr_rwsem); if (idr_pre_get(&fw_device_idr, GFP_KERNEL)) err = idr_get_new(&fw_device_idr, device, &minor); up_write(&idr_rwsem); + if (err < 0) goto error; @@ -717,13 +710,22 @@ static void fw_device_init(struct work_struct *work) */ if (atomic_cmpxchg(&device->state, FW_DEVICE_INITIALIZING, - FW_DEVICE_RUNNING) == FW_DEVICE_SHUTDOWN) + FW_DEVICE_RUNNING) == FW_DEVICE_SHUTDOWN) { fw_device_shutdown(&device->work.work); - else - fw_notify("created new fw device %s " - "(%d config rom retries, S%d00)\n", - device->device.bus_id, device->config_rom_retries, - 1 << device->max_speed); + } else { + if (device->config_rom_retries) + fw_notify("created device %s: GUID %08x%08x, S%d00, " + "%d config ROM retries\n", + device->device.bus_id, + device->config_rom[3], device->config_rom[4], + 1 << device->max_speed, + device->config_rom_retries); + else + fw_notify("created device %s: GUID %08x%08x, S%d00\n", + device->device.bus_id, + device->config_rom[3], device->config_rom[4], + 1 << device->max_speed); + } /* * Reschedule the IRM work if we just finished reading the @@ -741,7 +743,9 @@ static void fw_device_init(struct work_struct *work) idr_remove(&fw_device_idr, minor); up_write(&idr_rwsem); error: - put_device(&device->device); + fw_device_put(device); /* fw_device_idr's reference */ + + put_device(&device->device); /* our reference */ } static int update_unit(struct device *dev, void *data) @@ -791,7 +795,8 @@ void fw_node_event(struct fw_card *card, struct fw_node *node, int event) */ device_initialize(&device->device); atomic_set(&device->state, FW_DEVICE_INITIALIZING); - device->card = fw_card_get(card); + atomic_inc(&card->device_count); + device->card = card; device->node = fw_node_get(node); device->node_id = node->node_id; device->generation = card->generation; diff --git a/drivers/firewire/fw-device.h b/drivers/firewire/fw-device.h index 0854fe2bc11085943d0b7edcdef5884d8996c60c..78ecd3991b7f230ac83aa07ac6ef47e98dbcf310 100644 --- a/drivers/firewire/fw-device.h +++ b/drivers/firewire/fw-device.h @@ -76,14 +76,26 @@ fw_device_is_shutdown(struct fw_device *device) return atomic_read(&device->state) == FW_DEVICE_SHUTDOWN; } -struct fw_device *fw_device_get(struct fw_device *device); -void fw_device_put(struct fw_device *device); +static inline struct fw_device * +fw_device_get(struct fw_device *device) +{ + get_device(&device->device); + + return device; +} + +static inline void +fw_device_put(struct fw_device *device) +{ + put_device(&device->device); +} + +struct fw_device *fw_device_get_by_devt(dev_t devt); int fw_device_enable_phys_dma(struct fw_device *device); void fw_device_cdev_update(struct fw_device *device); void fw_device_cdev_remove(struct fw_device *device); -struct fw_device *fw_device_from_devt(dev_t devt); extern int fw_cdev_major; struct fw_unit { diff --git a/drivers/firewire/fw-ohci.c b/drivers/firewire/fw-ohci.c index 7ebad3c14cb80bbd62b930551494400c901f81f0..996d61f0d4602cf0cd942aea5daf54e08739c1cb 100644 --- a/drivers/firewire/fw-ohci.c +++ b/drivers/firewire/fw-ohci.c @@ -33,6 +33,10 @@ #include #include +#ifdef CONFIG_PPC_PMAC +#include +#endif + #include "fw-ohci.h" #include "fw-transaction.h" @@ -175,6 +179,7 @@ struct fw_ohci { int generation; int request_generation; u32 bus_seconds; + bool old_uninorth; /* * Spinlock for accessing fw_ohci data. Never call out of @@ -276,19 +281,13 @@ static int ar_context_add_page(struct ar_context *ctx) { struct device *dev = ctx->ohci->card.device; struct ar_buffer *ab; - dma_addr_t ab_bus; + dma_addr_t uninitialized_var(ab_bus); size_t offset; - ab = (struct ar_buffer *) __get_free_page(GFP_ATOMIC); + ab = dma_alloc_coherent(dev, PAGE_SIZE, &ab_bus, GFP_ATOMIC); if (ab == NULL) return -ENOMEM; - ab_bus = dma_map_single(dev, ab, PAGE_SIZE, DMA_BIDIRECTIONAL); - if (dma_mapping_error(ab_bus)) { - free_page((unsigned long) ab); - return -ENOMEM; - } - memset(&ab->descriptor, 0, sizeof(ab->descriptor)); ab->descriptor.control = cpu_to_le16(DESCRIPTOR_INPUT_MORE | DESCRIPTOR_STATUS | @@ -299,8 +298,6 @@ static int ar_context_add_page(struct ar_context *ctx) ab->descriptor.res_count = cpu_to_le16(PAGE_SIZE - offset); ab->descriptor.branch_address = 0; - dma_sync_single_for_device(dev, ab_bus, PAGE_SIZE, DMA_BIDIRECTIONAL); - ctx->last_buffer->descriptor.branch_address = cpu_to_le32(ab_bus | 1); ctx->last_buffer->next = ab; ctx->last_buffer = ab; @@ -311,15 +308,22 @@ static int ar_context_add_page(struct ar_context *ctx) return 0; } +#if defined(CONFIG_PPC_PMAC) && defined(CONFIG_PPC32) +#define cond_le32_to_cpu(v) \ + (ohci->old_uninorth ? (__force __u32)(v) : le32_to_cpu(v)) +#else +#define cond_le32_to_cpu(v) le32_to_cpu(v) +#endif + static __le32 *handle_ar_packet(struct ar_context *ctx, __le32 *buffer) { struct fw_ohci *ohci = ctx->ohci; struct fw_packet p; u32 status, length, tcode; - p.header[0] = le32_to_cpu(buffer[0]); - p.header[1] = le32_to_cpu(buffer[1]); - p.header[2] = le32_to_cpu(buffer[2]); + p.header[0] = cond_le32_to_cpu(buffer[0]); + p.header[1] = cond_le32_to_cpu(buffer[1]); + p.header[2] = cond_le32_to_cpu(buffer[2]); tcode = (p.header[0] >> 4) & 0x0f; switch (tcode) { @@ -331,7 +335,7 @@ static __le32 *handle_ar_packet(struct ar_context *ctx, __le32 *buffer) break; case TCODE_READ_BLOCK_REQUEST : - p.header[3] = le32_to_cpu(buffer[3]); + p.header[3] = cond_le32_to_cpu(buffer[3]); p.header_length = 16; p.payload_length = 0; break; @@ -340,7 +344,7 @@ static __le32 *handle_ar_packet(struct ar_context *ctx, __le32 *buffer) case TCODE_READ_BLOCK_RESPONSE: case TCODE_LOCK_REQUEST: case TCODE_LOCK_RESPONSE: - p.header[3] = le32_to_cpu(buffer[3]); + p.header[3] = cond_le32_to_cpu(buffer[3]); p.header_length = 16; p.payload_length = p.header[3] >> 16; break; @@ -357,7 +361,7 @@ static __le32 *handle_ar_packet(struct ar_context *ctx, __le32 *buffer) /* FIXME: What to do about evt_* errors? */ length = (p.header_length + p.payload_length + 3) / 4; - status = le32_to_cpu(buffer[length]); + status = cond_le32_to_cpu(buffer[length]); p.ack = ((status >> 16) & 0x1f) - 16; p.speed = (status >> 21) & 0x7; @@ -375,7 +379,7 @@ static __le32 *handle_ar_packet(struct ar_context *ctx, __le32 *buffer) */ if (p.ack + 16 == 0x09) - ohci->request_generation = (buffer[2] >> 16) & 0xff; + ohci->request_generation = (p.header[2] >> 16) & 0xff; else if (ctx == &ohci->ar_request_ctx) fw_core_handle_request(&ohci->card, &p); else @@ -397,6 +401,7 @@ static void ar_context_tasklet(unsigned long data) if (d->res_count == 0) { size_t size, rest, offset; + dma_addr_t buffer_bus; /* * This descriptor is finished and we may have a @@ -405,9 +410,7 @@ static void ar_context_tasklet(unsigned long data) */ offset = offsetof(struct ar_buffer, data); - dma_unmap_single(ohci->card.device, - le32_to_cpu(ab->descriptor.data_address) - offset, - PAGE_SIZE, DMA_BIDIRECTIONAL); + buffer_bus = le32_to_cpu(ab->descriptor.data_address) - offset; buffer = ab; ab = ab->next; @@ -423,7 +426,8 @@ static void ar_context_tasklet(unsigned long data) while (buffer < end) buffer = handle_ar_packet(ctx, buffer); - free_page((unsigned long)buffer); + dma_free_coherent(ohci->card.device, PAGE_SIZE, + buffer, buffer_bus); ar_context_add_page(ctx); } else { buffer = ctx->pointer; @@ -532,7 +536,7 @@ static int context_add_buffer(struct context *ctx) { struct descriptor_buffer *desc; - dma_addr_t bus_addr; + dma_addr_t uninitialized_var(bus_addr); int offset; /* @@ -1022,13 +1026,14 @@ static void bus_reset_tasklet(unsigned long data) */ self_id_count = (reg_read(ohci, OHCI1394_SelfIDCount) >> 3) & 0x3ff; - generation = (le32_to_cpu(ohci->self_id_cpu[0]) >> 16) & 0xff; + generation = (cond_le32_to_cpu(ohci->self_id_cpu[0]) >> 16) & 0xff; rmb(); for (i = 1, j = 0; j < self_id_count; i += 2, j++) { if (ohci->self_id_cpu[i] != ~ohci->self_id_cpu[i + 1]) fw_error("inconsistent self IDs\n"); - ohci->self_id_buffer[j] = le32_to_cpu(ohci->self_id_cpu[i]); + ohci->self_id_buffer[j] = + cond_le32_to_cpu(ohci->self_id_cpu[i]); } rmb(); @@ -1316,7 +1321,7 @@ ohci_set_config_rom(struct fw_card *card, u32 *config_rom, size_t length) unsigned long flags; int retval = -EBUSY; __be32 *next_config_rom; - dma_addr_t next_config_rom_bus; + dma_addr_t uninitialized_var(next_config_rom_bus); ohci = fw_ohci(card); @@ -1487,7 +1492,7 @@ static int handle_ir_dualbuffer_packet(struct context *context, void *p, *end; int i; - if (db->first_res_count > 0 && db->second_res_count > 0) { + if (db->first_res_count != 0 && db->second_res_count != 0) { if (ctx->excess_bytes <= le16_to_cpu(db->second_req_count)) { /* This descriptor isn't done yet, stop iteration. */ return 0; @@ -1513,7 +1518,7 @@ static int handle_ir_dualbuffer_packet(struct context *context, memcpy(ctx->header + i + 4, p + 8, ctx->base.header_size - 4); i += ctx->base.header_size; ctx->excess_bytes += - (le32_to_cpu(*(u32 *)(p + 4)) >> 16) & 0xffff; + (le32_to_cpu(*(__le32 *)(p + 4)) >> 16) & 0xffff; p += ctx->base.header_size + 4; } ctx->header_length = i; @@ -2048,6 +2053,18 @@ pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) int err; size_t size; +#ifdef CONFIG_PPC_PMAC + /* Necessary on some machines if fw-ohci was loaded/ unloaded before */ + if (machine_is(powermac)) { + struct device_node *ofn = pci_device_to_OF_node(dev); + + if (ofn) { + pmac_call_feature(PMAC_FTR_1394_CABLE_POWER, ofn, 0, 1); + pmac_call_feature(PMAC_FTR_1394_ENABLE, ofn, 0, 1); + } + } +#endif /* CONFIG_PPC_PMAC */ + ohci = kzalloc(sizeof(*ohci), GFP_KERNEL); if (ohci == NULL) { fw_error("Could not malloc fw_ohci data.\n"); @@ -2066,6 +2083,10 @@ pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) pci_write_config_dword(dev, OHCI1394_PCI_HCI_Control, 0); pci_set_drvdata(dev, ohci); +#if defined(CONFIG_PPC_PMAC) && defined(CONFIG_PPC32) + ohci->old_uninorth = dev->vendor == PCI_VENDOR_ID_APPLE && + dev->device == PCI_DEVICE_ID_APPLE_UNI_N_FW; +#endif spin_lock_init(&ohci->lock); tasklet_init(&ohci->bus_reset_tasklet, @@ -2182,6 +2203,19 @@ static void pci_remove(struct pci_dev *dev) pci_disable_device(dev); fw_card_put(&ohci->card); +#ifdef CONFIG_PPC_PMAC + /* On UniNorth, power down the cable and turn off the chip clock + * to save power on laptops */ + if (machine_is(powermac)) { + struct device_node *ofn = pci_device_to_OF_node(dev); + + if (ofn) { + pmac_call_feature(PMAC_FTR_1394_ENABLE, ofn, 0, 0); + pmac_call_feature(PMAC_FTR_1394_CABLE_POWER, ofn, 0, 0); + } + } +#endif /* CONFIG_PPC_PMAC */ + fw_notify("Removed fw-ohci device.\n"); } @@ -2202,6 +2236,16 @@ static int pci_suspend(struct pci_dev *pdev, pm_message_t state) if (err) fw_error("pci_set_power_state failed with %d\n", err); +/* PowerMac suspend code comes last */ +#ifdef CONFIG_PPC_PMAC + if (machine_is(powermac)) { + struct device_node *ofn = pci_device_to_OF_node(pdev); + + if (ofn) + pmac_call_feature(PMAC_FTR_1394_ENABLE, ofn, 0, 0); + } +#endif /* CONFIG_PPC_PMAC */ + return 0; } @@ -2210,6 +2254,16 @@ static int pci_resume(struct pci_dev *pdev) struct fw_ohci *ohci = pci_get_drvdata(pdev); int err; +/* PowerMac resume code comes first */ +#ifdef CONFIG_PPC_PMAC + if (machine_is(powermac)) { + struct device_node *ofn = pci_device_to_OF_node(pdev); + + if (ofn) + pmac_call_feature(PMAC_FTR_1394_ENABLE, ofn, 0, 1); + } +#endif /* CONFIG_PPC_PMAC */ + pci_set_power_state(pdev, PCI_D0); pci_restore_state(pdev); err = pci_enable_device(pdev); diff --git a/drivers/firewire/fw-sbp2.c b/drivers/firewire/fw-sbp2.c index 19ece9b6d7425906d6cff48cee2ebfba172f5141..62b4e47d0cc00bb19e58de01c3722c522bd2e55a 100644 --- a/drivers/firewire/fw-sbp2.c +++ b/drivers/firewire/fw-sbp2.c @@ -28,14 +28,15 @@ * and many others. */ +#include +#include +#include +#include #include +#include #include #include -#include -#include #include -#include -#include #include #include #include @@ -47,9 +48,9 @@ #include #include -#include "fw-transaction.h" -#include "fw-topology.h" #include "fw-device.h" +#include "fw-topology.h" +#include "fw-transaction.h" /* * So far only bridges from Oxford Semiconductor are known to support @@ -82,6 +83,9 @@ MODULE_PARM_DESC(exclusive_login, "Exclusive login to sbp2 device " * Avoids access beyond actual disk limits on devices with an off-by-one bug. * Don't use this with devices which don't have this bug. * + * - delay inquiry + * Wait extra SBP2_INQUIRY_DELAY seconds after login before SCSI inquiry. + * * - override internal blacklist * Instead of adding to the built-in blacklist, use only the workarounds * specified in the module load parameter. @@ -91,6 +95,8 @@ MODULE_PARM_DESC(exclusive_login, "Exclusive login to sbp2 device " #define SBP2_WORKAROUND_INQUIRY_36 0x2 #define SBP2_WORKAROUND_MODE_SENSE_8 0x4 #define SBP2_WORKAROUND_FIX_CAPACITY 0x8 +#define SBP2_WORKAROUND_DELAY_INQUIRY 0x10 +#define SBP2_INQUIRY_DELAY 12 #define SBP2_WORKAROUND_OVERRIDE 0x100 static int sbp2_param_workarounds; @@ -100,6 +106,7 @@ MODULE_PARM_DESC(workarounds, "Work around device bugs (default = 0" ", 36 byte inquiry = " __stringify(SBP2_WORKAROUND_INQUIRY_36) ", skip mode page 8 = " __stringify(SBP2_WORKAROUND_MODE_SENSE_8) ", fix capacity = " __stringify(SBP2_WORKAROUND_FIX_CAPACITY) + ", delay inquiry = " __stringify(SBP2_WORKAROUND_DELAY_INQUIRY) ", override internal blacklist = " __stringify(SBP2_WORKAROUND_OVERRIDE) ", or a combination)"); @@ -115,7 +122,6 @@ static const char sbp2_driver_name[] = "sbp2"; struct sbp2_logical_unit { struct sbp2_target *tgt; struct list_head link; - struct scsi_device *sdev; struct fw_address_handler address_handler; struct list_head orb_list; @@ -132,6 +138,8 @@ struct sbp2_logical_unit { int generation; int retries; struct delayed_work work; + bool has_sdev; + bool blocked; }; /* @@ -141,16 +149,18 @@ struct sbp2_logical_unit { struct sbp2_target { struct kref kref; struct fw_unit *unit; + const char *bus_id; + struct list_head lu_list; u64 management_agent_address; int directory_id; int node_id; int address_high; - - unsigned workarounds; - struct list_head lu_list; - + unsigned int workarounds; unsigned int mgt_orb_timeout; + + int dont_block; /* counter for each logical unit */ + int blocked; /* ditto */ }; /* @@ -160,9 +170,10 @@ struct sbp2_target { */ #define SBP2_MIN_LOGIN_ORB_TIMEOUT 5000U /* Timeout in ms */ #define SBP2_MAX_LOGIN_ORB_TIMEOUT 40000U /* Timeout in ms */ -#define SBP2_ORB_TIMEOUT 2000 /* Timeout in ms */ +#define SBP2_ORB_TIMEOUT 2000U /* Timeout in ms */ #define SBP2_ORB_NULL 0x80000000 #define SBP2_MAX_SG_ELEMENT_LENGTH 0xf000 +#define SBP2_RETRY_LIMIT 0xf /* 15 retries */ #define SBP2_DIRECTION_TO_MEDIA 0x0 #define SBP2_DIRECTION_FROM_MEDIA 0x1 @@ -297,7 +308,7 @@ struct sbp2_command_orb { static const struct { u32 firmware_revision; u32 model; - unsigned workarounds; + unsigned int workarounds; } sbp2_workarounds_table[] = { /* DViCO Momobay CX-1 with TSB42AA9 bridge */ { .firmware_revision = 0x002800, @@ -305,6 +316,11 @@ static const struct { .workarounds = SBP2_WORKAROUND_INQUIRY_36 | SBP2_WORKAROUND_MODE_SENSE_8, }, + /* DViCO Momobay FX-3A with TSB42AA9A bridge */ { + .firmware_revision = 0x002800, + .model = 0x000000, + .workarounds = SBP2_WORKAROUND_DELAY_INQUIRY, + }, /* Initio bridges, actually only needed for some older ones */ { .firmware_revision = 0x000200, .model = ~0, @@ -315,6 +331,11 @@ static const struct { .model = ~0, .workarounds = SBP2_WORKAROUND_128K_MAX_TRANS, }, + /* Datafab MD2-FW2 with Symbios/LSILogic SYM13FW500 bridge */ { + .firmware_revision = 0x002600, + .model = ~0, + .workarounds = SBP2_WORKAROUND_128K_MAX_TRANS, + }, /* * There are iPods (2nd gen, 3rd gen) with model_id == 0, but @@ -501,6 +522,9 @@ sbp2_send_management_orb(struct sbp2_logical_unit *lu, int node_id, unsigned int timeout; int retval = -ENOMEM; + if (function == SBP2_LOGOUT_REQUEST && fw_device_is_shutdown(device)) + return 0; + orb = kzalloc(sizeof(*orb), GFP_ATOMIC); if (orb == NULL) return -ENOMEM; @@ -553,20 +577,20 @@ sbp2_send_management_orb(struct sbp2_logical_unit *lu, int node_id, retval = -EIO; if (sbp2_cancel_orbs(lu) == 0) { - fw_error("orb reply timed out, rcode=0x%02x\n", - orb->base.rcode); + fw_error("%s: orb reply timed out, rcode=0x%02x\n", + lu->tgt->bus_id, orb->base.rcode); goto out; } if (orb->base.rcode != RCODE_COMPLETE) { - fw_error("management write failed, rcode 0x%02x\n", - orb->base.rcode); + fw_error("%s: management write failed, rcode 0x%02x\n", + lu->tgt->bus_id, orb->base.rcode); goto out; } if (STATUS_GET_RESPONSE(orb->status) != 0 || STATUS_GET_SBP_STATUS(orb->status) != 0) { - fw_error("error status: %d:%d\n", + fw_error("%s: error status: %d:%d\n", lu->tgt->bus_id, STATUS_GET_RESPONSE(orb->status), STATUS_GET_SBP_STATUS(orb->status)); goto out; @@ -590,29 +614,158 @@ sbp2_send_management_orb(struct sbp2_logical_unit *lu, int node_id, static void complete_agent_reset_write(struct fw_card *card, int rcode, - void *payload, size_t length, void *data) + void *payload, size_t length, void *done) { - struct fw_transaction *t = data; + complete(done); +} - kfree(t); +static void sbp2_agent_reset(struct sbp2_logical_unit *lu) +{ + struct fw_device *device = fw_device(lu->tgt->unit->device.parent); + DECLARE_COMPLETION_ONSTACK(done); + struct fw_transaction t; + static u32 z; + + fw_send_request(device->card, &t, TCODE_WRITE_QUADLET_REQUEST, + lu->tgt->node_id, lu->generation, device->max_speed, + lu->command_block_agent_address + SBP2_AGENT_RESET, + &z, sizeof(z), complete_agent_reset_write, &done); + wait_for_completion(&done); } -static int sbp2_agent_reset(struct sbp2_logical_unit *lu) +static void +complete_agent_reset_write_no_wait(struct fw_card *card, int rcode, + void *payload, size_t length, void *data) +{ + kfree(data); +} + +static void sbp2_agent_reset_no_wait(struct sbp2_logical_unit *lu) { struct fw_device *device = fw_device(lu->tgt->unit->device.parent); struct fw_transaction *t; - static u32 zero; + static u32 z; - t = kzalloc(sizeof(*t), GFP_ATOMIC); + t = kmalloc(sizeof(*t), GFP_ATOMIC); if (t == NULL) - return -ENOMEM; + return; fw_send_request(device->card, t, TCODE_WRITE_QUADLET_REQUEST, lu->tgt->node_id, lu->generation, device->max_speed, lu->command_block_agent_address + SBP2_AGENT_RESET, - &zero, sizeof(zero), complete_agent_reset_write, t); + &z, sizeof(z), complete_agent_reset_write_no_wait, t); +} - return 0; +static void sbp2_set_generation(struct sbp2_logical_unit *lu, int generation) +{ + struct fw_card *card = fw_device(lu->tgt->unit->device.parent)->card; + unsigned long flags; + + /* serialize with comparisons of lu->generation and card->generation */ + spin_lock_irqsave(&card->lock, flags); + lu->generation = generation; + spin_unlock_irqrestore(&card->lock, flags); +} + +static inline void sbp2_allow_block(struct sbp2_logical_unit *lu) +{ + /* + * We may access dont_block without taking card->lock here: + * All callers of sbp2_allow_block() and all callers of sbp2_unblock() + * are currently serialized against each other. + * And a wrong result in sbp2_conditionally_block()'s access of + * dont_block is rather harmless, it simply misses its first chance. + */ + --lu->tgt->dont_block; +} + +/* + * Blocks lu->tgt if all of the following conditions are met: + * - Login, INQUIRY, and high-level SCSI setup of all of the target's + * logical units have been finished (indicated by dont_block == 0). + * - lu->generation is stale. + * + * Note, scsi_block_requests() must be called while holding card->lock, + * otherwise it might foil sbp2_[conditionally_]unblock()'s attempt to + * unblock the target. + */ +static void sbp2_conditionally_block(struct sbp2_logical_unit *lu) +{ + struct sbp2_target *tgt = lu->tgt; + struct fw_card *card = fw_device(tgt->unit->device.parent)->card; + struct Scsi_Host *shost = + container_of((void *)tgt, struct Scsi_Host, hostdata[0]); + unsigned long flags; + + spin_lock_irqsave(&card->lock, flags); + if (!tgt->dont_block && !lu->blocked && + lu->generation != card->generation) { + lu->blocked = true; + if (++tgt->blocked == 1) { + scsi_block_requests(shost); + fw_notify("blocked %s\n", lu->tgt->bus_id); + } + } + spin_unlock_irqrestore(&card->lock, flags); +} + +/* + * Unblocks lu->tgt as soon as all its logical units can be unblocked. + * Note, it is harmless to run scsi_unblock_requests() outside the + * card->lock protected section. On the other hand, running it inside + * the section might clash with shost->host_lock. + */ +static void sbp2_conditionally_unblock(struct sbp2_logical_unit *lu) +{ + struct sbp2_target *tgt = lu->tgt; + struct fw_card *card = fw_device(tgt->unit->device.parent)->card; + struct Scsi_Host *shost = + container_of((void *)tgt, struct Scsi_Host, hostdata[0]); + unsigned long flags; + bool unblock = false; + + spin_lock_irqsave(&card->lock, flags); + if (lu->blocked && lu->generation == card->generation) { + lu->blocked = false; + unblock = --tgt->blocked == 0; + } + spin_unlock_irqrestore(&card->lock, flags); + + if (unblock) { + scsi_unblock_requests(shost); + fw_notify("unblocked %s\n", lu->tgt->bus_id); + } +} + +/* + * Prevents future blocking of tgt and unblocks it. + * Note, it is harmless to run scsi_unblock_requests() outside the + * card->lock protected section. On the other hand, running it inside + * the section might clash with shost->host_lock. + */ +static void sbp2_unblock(struct sbp2_target *tgt) +{ + struct fw_card *card = fw_device(tgt->unit->device.parent)->card; + struct Scsi_Host *shost = + container_of((void *)tgt, struct Scsi_Host, hostdata[0]); + unsigned long flags; + + spin_lock_irqsave(&card->lock, flags); + ++tgt->dont_block; + spin_unlock_irqrestore(&card->lock, flags); + + scsi_unblock_requests(shost); +} + +static int sbp2_lun2int(u16 lun) +{ + struct scsi_lun eight_bytes_lun; + + memset(&eight_bytes_lun, 0, sizeof(eight_bytes_lun)); + eight_bytes_lun.scsi_lun[0] = (lun >> 8) & 0xff; + eight_bytes_lun.scsi_lun[1] = lun & 0xff; + + return scsilun_to_int(&eight_bytes_lun); } static void sbp2_release_target(struct kref *kref) @@ -621,26 +774,31 @@ static void sbp2_release_target(struct kref *kref) struct sbp2_logical_unit *lu, *next; struct Scsi_Host *shost = container_of((void *)tgt, struct Scsi_Host, hostdata[0]); + struct scsi_device *sdev; struct fw_device *device = fw_device(tgt->unit->device.parent); - list_for_each_entry_safe(lu, next, &tgt->lu_list, link) { - if (lu->sdev) - scsi_remove_device(lu->sdev); + /* prevent deadlocks */ + sbp2_unblock(tgt); - if (!fw_device_is_shutdown(device)) - sbp2_send_management_orb(lu, tgt->node_id, - lu->generation, SBP2_LOGOUT_REQUEST, - lu->login_id, NULL); + list_for_each_entry_safe(lu, next, &tgt->lu_list, link) { + sdev = scsi_device_lookup(shost, 0, 0, sbp2_lun2int(lu->lun)); + if (sdev) { + scsi_remove_device(sdev); + scsi_device_put(sdev); + } + sbp2_send_management_orb(lu, tgt->node_id, lu->generation, + SBP2_LOGOUT_REQUEST, lu->login_id, NULL); fw_core_remove_address_handler(&lu->address_handler); list_del(&lu->link); kfree(lu); } scsi_remove_host(shost); - fw_notify("released %s\n", tgt->unit->device.bus_id); + fw_notify("released %s\n", tgt->bus_id); put_device(&tgt->unit->device); scsi_host_put(shost); + fw_device_put(device); } static struct workqueue_struct *sbp2_wq; @@ -660,39 +818,72 @@ static void sbp2_target_put(struct sbp2_target *tgt) kref_put(&tgt->kref, sbp2_release_target); } +static void +complete_set_busy_timeout(struct fw_card *card, int rcode, + void *payload, size_t length, void *done) +{ + complete(done); +} + +static void sbp2_set_busy_timeout(struct sbp2_logical_unit *lu) +{ + struct fw_device *device = fw_device(lu->tgt->unit->device.parent); + DECLARE_COMPLETION_ONSTACK(done); + struct fw_transaction t; + static __be32 busy_timeout; + + /* FIXME: we should try to set dual-phase cycle_limit too */ + busy_timeout = cpu_to_be32(SBP2_RETRY_LIMIT); + + fw_send_request(device->card, &t, TCODE_WRITE_QUADLET_REQUEST, + lu->tgt->node_id, lu->generation, device->max_speed, + CSR_REGISTER_BASE + CSR_BUSY_TIMEOUT, &busy_timeout, + sizeof(busy_timeout), complete_set_busy_timeout, &done); + wait_for_completion(&done); +} + static void sbp2_reconnect(struct work_struct *work); static void sbp2_login(struct work_struct *work) { struct sbp2_logical_unit *lu = container_of(work, struct sbp2_logical_unit, work.work); - struct Scsi_Host *shost = - container_of((void *)lu->tgt, struct Scsi_Host, hostdata[0]); + struct sbp2_target *tgt = lu->tgt; + struct fw_device *device = fw_device(tgt->unit->device.parent); + struct Scsi_Host *shost; struct scsi_device *sdev; - struct scsi_lun eight_bytes_lun; - struct fw_unit *unit = lu->tgt->unit; - struct fw_device *device = fw_device(unit->device.parent); struct sbp2_login_response response; int generation, node_id, local_node_id; + if (fw_device_is_shutdown(device)) + goto out; + generation = device->generation; smp_rmb(); /* node_id must not be older than generation */ node_id = device->node_id; local_node_id = device->card->node_id; + /* If this is a re-login attempt, log out, or we might be rejected. */ + if (lu->has_sdev) + sbp2_send_management_orb(lu, device->node_id, generation, + SBP2_LOGOUT_REQUEST, lu->login_id, NULL); + if (sbp2_send_management_orb(lu, node_id, generation, SBP2_LOGIN_REQUEST, lu->lun, &response) < 0) { - if (lu->retries++ < 5) + if (lu->retries++ < 5) { sbp2_queue_work(lu, DIV_ROUND_UP(HZ, 5)); - else - fw_error("failed to login to %s LUN %04x\n", - unit->device.bus_id, lu->lun); + } else { + fw_error("%s: failed to login to LUN %04x\n", + tgt->bus_id, lu->lun); + /* Let any waiting I/O fail from now on. */ + sbp2_unblock(lu->tgt); + } goto out; } - lu->generation = generation; - lu->tgt->node_id = node_id; - lu->tgt->address_high = local_node_id << 16; + tgt->node_id = node_id; + tgt->address_high = local_node_id << 16; + sbp2_set_generation(lu, generation); /* Get command block agent offset and login id. */ lu->command_block_agent_address = @@ -700,37 +891,67 @@ static void sbp2_login(struct work_struct *work) response.command_block_agent.low; lu->login_id = LOGIN_RESPONSE_GET_LOGIN_ID(response); - fw_notify("logged in to %s LUN %04x (%d retries)\n", - unit->device.bus_id, lu->lun, lu->retries); + fw_notify("%s: logged in to LUN %04x (%d retries)\n", + tgt->bus_id, lu->lun, lu->retries); -#if 0 - /* FIXME: The linux1394 sbp2 does this last step. */ - sbp2_set_busy_timeout(scsi_id); -#endif + /* set appropriate retry limit(s) in BUSY_TIMEOUT register */ + sbp2_set_busy_timeout(lu); PREPARE_DELAYED_WORK(&lu->work, sbp2_reconnect); sbp2_agent_reset(lu); - memset(&eight_bytes_lun, 0, sizeof(eight_bytes_lun)); - eight_bytes_lun.scsi_lun[0] = (lu->lun >> 8) & 0xff; - eight_bytes_lun.scsi_lun[1] = lu->lun & 0xff; + /* This was a re-login. */ + if (lu->has_sdev) { + sbp2_cancel_orbs(lu); + sbp2_conditionally_unblock(lu); + goto out; + } - sdev = __scsi_add_device(shost, 0, 0, - scsilun_to_int(&eight_bytes_lun), lu); - if (IS_ERR(sdev)) { - sbp2_send_management_orb(lu, node_id, generation, - SBP2_LOGOUT_REQUEST, lu->login_id, NULL); - /* - * Set this back to sbp2_login so we fall back and - * retry login on bus reset. - */ - PREPARE_DELAYED_WORK(&lu->work, sbp2_login); - } else { - lu->sdev = sdev; + if (lu->tgt->workarounds & SBP2_WORKAROUND_DELAY_INQUIRY) + ssleep(SBP2_INQUIRY_DELAY); + + shost = container_of((void *)tgt, struct Scsi_Host, hostdata[0]); + sdev = __scsi_add_device(shost, 0, 0, sbp2_lun2int(lu->lun), lu); + /* + * FIXME: We are unable to perform reconnects while in sbp2_login(). + * Therefore __scsi_add_device() will get into trouble if a bus reset + * happens in parallel. It will either fail or leave us with an + * unusable sdev. As a workaround we check for this and retry the + * whole login and SCSI probing. + */ + + /* Reported error during __scsi_add_device() */ + if (IS_ERR(sdev)) + goto out_logout_login; + + /* Unreported error during __scsi_add_device() */ + smp_rmb(); /* get current card generation */ + if (generation != device->card->generation) { + scsi_remove_device(sdev); scsi_device_put(sdev); + goto out_logout_login; } + + /* No error during __scsi_add_device() */ + lu->has_sdev = true; + scsi_device_put(sdev); + sbp2_allow_block(lu); + goto out; + + out_logout_login: + smp_rmb(); /* generation may have changed */ + generation = device->generation; + smp_rmb(); /* node_id must not be older than generation */ + + sbp2_send_management_orb(lu, device->node_id, generation, + SBP2_LOGOUT_REQUEST, lu->login_id, NULL); + /* + * If a bus reset happened, sbp2_update will have requeued + * lu->work already. Reset the work from reconnect to login. + */ + PREPARE_DELAYED_WORK(&lu->work, sbp2_login); out: - sbp2_target_put(lu->tgt); + sbp2_target_put(tgt); } static int sbp2_add_logical_unit(struct sbp2_target *tgt, int lun_entry) @@ -751,10 +972,12 @@ static int sbp2_add_logical_unit(struct sbp2_target *tgt, int lun_entry) return -ENOMEM; } - lu->tgt = tgt; - lu->sdev = NULL; - lu->lun = lun_entry & 0xffff; - lu->retries = 0; + lu->tgt = tgt; + lu->lun = lun_entry & 0xffff; + lu->retries = 0; + lu->has_sdev = false; + lu->blocked = false; + ++tgt->dont_block; INIT_LIST_HEAD(&lu->orb_list); INIT_DELAYED_WORK(&lu->work, sbp2_login); @@ -813,7 +1036,7 @@ static int sbp2_scan_unit_dir(struct sbp2_target *tgt, u32 *directory, if (timeout > tgt->mgt_orb_timeout) fw_notify("%s: config rom contains %ds " "management ORB timeout, limiting " - "to %ds\n", tgt->unit->device.bus_id, + "to %ds\n", tgt->bus_id, timeout / 1000, tgt->mgt_orb_timeout / 1000); break; @@ -836,12 +1059,12 @@ static void sbp2_init_workarounds(struct sbp2_target *tgt, u32 model, u32 firmware_revision) { int i; - unsigned w = sbp2_param_workarounds; + unsigned int w = sbp2_param_workarounds; if (w) fw_notify("Please notify linux1394-devel@lists.sourceforge.net " "if you need the workarounds parameter for %s\n", - tgt->unit->device.bus_id); + tgt->bus_id); if (w & SBP2_WORKAROUND_OVERRIDE) goto out; @@ -863,8 +1086,7 @@ static void sbp2_init_workarounds(struct sbp2_target *tgt, u32 model, if (w) fw_notify("Workarounds for %s: 0x%x " "(firmware_revision 0x%06x, model_id 0x%06x)\n", - tgt->unit->device.bus_id, - w, firmware_revision, model); + tgt->bus_id, w, firmware_revision, model); tgt->workarounds = w; } @@ -888,6 +1110,7 @@ static int sbp2_probe(struct device *dev) tgt->unit = unit; kref_init(&tgt->kref); INIT_LIST_HEAD(&tgt->lu_list); + tgt->bus_id = unit->device.bus_id; if (fw_device_enable_phys_dma(device) < 0) goto fail_shost_put; @@ -895,6 +1118,8 @@ static int sbp2_probe(struct device *dev) if (scsi_add_host(shost, &unit->device) < 0) goto fail_shost_put; + fw_device_get(device); + /* Initialize to values that won't match anything in our table. */ firmware_revision = 0xff000000; model = 0xff000000; @@ -938,10 +1163,13 @@ static void sbp2_reconnect(struct work_struct *work) { struct sbp2_logical_unit *lu = container_of(work, struct sbp2_logical_unit, work.work); - struct fw_unit *unit = lu->tgt->unit; - struct fw_device *device = fw_device(unit->device.parent); + struct sbp2_target *tgt = lu->tgt; + struct fw_device *device = fw_device(tgt->unit->device.parent); int generation, node_id, local_node_id; + if (fw_device_is_shutdown(device)) + goto out; + generation = device->generation; smp_rmb(); /* node_id must not be older than generation */ node_id = device->node_id; @@ -950,10 +1178,17 @@ static void sbp2_reconnect(struct work_struct *work) if (sbp2_send_management_orb(lu, node_id, generation, SBP2_RECONNECT_REQUEST, lu->login_id, NULL) < 0) { - if (lu->retries++ >= 5) { - fw_error("failed to reconnect to %s\n", - unit->device.bus_id); - /* Fall back and try to log in again. */ + /* + * If reconnect was impossible even though we are in the + * current generation, fall back and try to log in again. + * + * We could check for "Function rejected" status, but + * looking at the bus generation as simpler and more general. + */ + smp_rmb(); /* get current card generation */ + if (generation == device->card->generation || + lu->retries++ >= 5) { + fw_error("%s: failed to reconnect\n", tgt->bus_id); lu->retries = 0; PREPARE_DELAYED_WORK(&lu->work, sbp2_login); } @@ -961,17 +1196,18 @@ static void sbp2_reconnect(struct work_struct *work) goto out; } - lu->generation = generation; - lu->tgt->node_id = node_id; - lu->tgt->address_high = local_node_id << 16; + tgt->node_id = node_id; + tgt->address_high = local_node_id << 16; + sbp2_set_generation(lu, generation); - fw_notify("reconnected to %s LUN %04x (%d retries)\n", - unit->device.bus_id, lu->lun, lu->retries); + fw_notify("%s: reconnected to LUN %04x (%d retries)\n", + tgt->bus_id, lu->lun, lu->retries); sbp2_agent_reset(lu); sbp2_cancel_orbs(lu); + sbp2_conditionally_unblock(lu); out: - sbp2_target_put(lu->tgt); + sbp2_target_put(tgt); } static void sbp2_update(struct fw_unit *unit) @@ -986,6 +1222,7 @@ static void sbp2_update(struct fw_unit *unit) * Iteration over tgt->lu_list is therefore safe here. */ list_for_each_entry(lu, &tgt->lu_list, link) { + sbp2_conditionally_block(lu); lu->retries = 0; sbp2_queue_work(lu, 0); } @@ -1063,7 +1300,7 @@ complete_command_orb(struct sbp2_orb *base_orb, struct sbp2_status *status) if (status != NULL) { if (STATUS_GET_DEAD(*status)) - sbp2_agent_reset(orb->lu); + sbp2_agent_reset_no_wait(orb->lu); switch (STATUS_GET_RESPONSE(*status)) { case SBP2_STATUS_REQUEST_COMPLETE: @@ -1089,6 +1326,7 @@ complete_command_orb(struct sbp2_orb *base_orb, struct sbp2_status *status) * or when sending the write (less likely). */ result = DID_BUS_BUSY << 16; + sbp2_conditionally_block(orb->lu); } dma_unmap_single(device->card->device, orb->base.request_bus, @@ -1197,7 +1435,7 @@ static int sbp2_scsi_queuecommand(struct scsi_cmnd *cmd, scsi_done_fn_t done) struct sbp2_logical_unit *lu = cmd->device->hostdata; struct fw_device *device = fw_device(lu->tgt->unit->device.parent); struct sbp2_command_orb *orb; - unsigned max_payload; + unsigned int max_payload; int retval = SCSI_MLQUEUE_HOST_BUSY; /* @@ -1275,6 +1513,10 @@ static int sbp2_scsi_slave_alloc(struct scsi_device *sdev) { struct sbp2_logical_unit *lu = sdev->hostdata; + /* (Re-)Adding logical units via the SCSI stack is not supported. */ + if (!lu) + return -ENOSYS; + sdev->allow_restart = 1; /* @@ -1319,7 +1561,7 @@ static int sbp2_scsi_abort(struct scsi_cmnd *cmd) { struct sbp2_logical_unit *lu = cmd->device->hostdata; - fw_notify("sbp2_scsi_abort\n"); + fw_notify("%s: sbp2_scsi_abort\n", lu->tgt->bus_id); sbp2_agent_reset(lu); sbp2_cancel_orbs(lu); diff --git a/drivers/firewire/fw-topology.c b/drivers/firewire/fw-topology.c index 172c1867e9aa358c19cbb47afa85478a448ef510..d2c7a3d7e1cbb7711e8c76af6a76f448ea9d59f1 100644 --- a/drivers/firewire/fw-topology.c +++ b/drivers/firewire/fw-topology.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include "fw-transaction.h" #include "fw-topology.h" @@ -383,6 +384,7 @@ void fw_destroy_nodes(struct fw_card *card) card->color++; if (card->local_node != NULL) for_each_fw_node(card, card->local_node, report_lost_node); + card->local_node = NULL; spin_unlock_irqrestore(&card->lock, flags); } @@ -423,8 +425,8 @@ update_tree(struct fw_card *card, struct fw_node *root) node1 = fw_node(list1.next); while (&node0->link != &list0) { + WARN_ON(node0->port_count != node1->port_count); - /* assert(node0->port_count == node1->port_count); */ if (node0->link_on && !node1->link_on) event = FW_NODE_LINK_OFF; else if (!node0->link_on && node1->link_on) diff --git a/drivers/firewire/fw-transaction.c b/drivers/firewire/fw-transaction.c index 7fcc59dedf08cfa038d652336d1f85383614ccd3..99529e59a0b13e4f5173205f5ab4d338ce6ebe3b 100644 --- a/drivers/firewire/fw-transaction.c +++ b/drivers/firewire/fw-transaction.c @@ -751,7 +751,7 @@ handle_topology_map(struct fw_card *card, struct fw_request *request, void *payload, size_t length, void *callback_data) { int i, start, end; - u32 *map; + __be32 *map; if (!TCODE_IS_READ_REQUEST(tcode)) { fw_send_response(card, request, RCODE_TYPE_ERROR); diff --git a/drivers/firewire/fw-transaction.h b/drivers/firewire/fw-transaction.h index fa7967b57408586359f70ae5bc610f39d7a55223..a43bb22912f9da9488fd83a2060b80c78bdfe55b 100644 --- a/drivers/firewire/fw-transaction.h +++ b/drivers/firewire/fw-transaction.h @@ -26,6 +26,7 @@ #include #include #include +#include #define TCODE_IS_READ_REQUEST(tcode) (((tcode) & ~1) == 4) #define TCODE_IS_BLOCK_PACKET(tcode) (((tcode) & 1) != 0) @@ -85,12 +86,12 @@ static inline void fw_memcpy_from_be32(void *_dst, void *_src, size_t size) { - u32 *dst = _dst; - u32 *src = _src; + u32 *dst = _dst; + __be32 *src = _src; int i; for (i = 0; i < size / 4; i++) - dst[i] = cpu_to_be32(src[i]); + dst[i] = be32_to_cpu(src[i]); } static inline void @@ -219,6 +220,7 @@ extern struct bus_type fw_bus_type; struct fw_card { const struct fw_card_driver *driver; struct device *device; + atomic_t device_count; struct kref kref; int node_id; diff --git a/drivers/gpio/pca953x.c b/drivers/gpio/pca953x.c index 92583cd4bffd21b2b47966f4c3ddc1fd9766e850..6e72fd31184d8aa95021f897ee436af3bdd7b833 100644 --- a/drivers/gpio/pca953x.c +++ b/drivers/gpio/pca953x.c @@ -184,6 +184,7 @@ static void pca953x_setup_gpio(struct pca953x_chip *chip, int gpios) gc->direction_output = pca953x_gpio_direction_output; gc->get = pca953x_gpio_get_value; gc->set = pca953x_gpio_set_value; + gc->can_sleep = 1; gc->base = chip->gpio_start; gc->ngpio = gpios; diff --git a/drivers/i2c/busses/i2c-amd756.c b/drivers/i2c/busses/i2c-amd756.c index 573abe4408426fb6ce288cc3ada689e956fdc35e..2fa43183d3759bc8b2d1ea284ca30984aee44fad 100644 --- a/drivers/i2c/busses/i2c-amd756.c +++ b/drivers/i2c/busses/i2c-amd756.c @@ -335,7 +335,7 @@ static int __devinit amd756_probe(struct pci_dev *pdev, u8 temp; /* driver_data might come from user-space, so check it */ - if (id->driver_data > ARRAY_SIZE(chipname)) + if (id->driver_data >= ARRAY_SIZE(chipname)) return -EINVAL; if (amd756_ioport) { diff --git a/drivers/i2c/chips/Makefile b/drivers/i2c/chips/Makefile index 501f00cea78284cc1c5e731ceb3b8a1c7fbcd2b8..e47aca0ca5aebda2bb70bc44d3f625a827301ea2 100644 --- a/drivers/i2c/chips/Makefile +++ b/drivers/i2c/chips/Makefile @@ -1,6 +1,13 @@ # # Makefile for miscellaneous I2C chip drivers. # +# Think twice before you add a new driver to this directory. +# Device drivers are better grouped according to the functionality they +# implement rather than to the bus they are connected to. In particular: +# * Hardware monitoring chip drivers go to drivers/hwmon +# * RTC chip drivers go to drivers/rtc +# * I/O expander drivers go to drivers/gpio +# obj-$(CONFIG_DS1682) += ds1682.o obj-$(CONFIG_SENSORS_EEPROM) += eeprom.o diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c index 96da22e9a5a44dbe32b247694a2b72bdea20c0d8..fd84b2a363381a6571a09d883cc3d7fe3cc676fa 100644 --- a/drivers/i2c/i2c-core.c +++ b/drivers/i2c/i2c-core.c @@ -90,12 +90,16 @@ static int i2c_device_probe(struct device *dev) { struct i2c_client *client = to_i2c_client(dev); struct i2c_driver *driver = to_i2c_driver(dev->driver); + int status; if (!driver->probe) return -ENODEV; client->driver = driver; dev_dbg(dev, "probe\n"); - return driver->probe(client); + status = driver->probe(client); + if (status) + client->driver = NULL; + return status; } static int i2c_device_remove(struct device *dev) diff --git a/drivers/ide/Kconfig b/drivers/ide/Kconfig index df752e690e4739f595dee6dde3c103db522da5fa..eed6d8e1b5c7abfbff3d693bc072bb3040ea3e1e 100644 --- a/drivers/ide/Kconfig +++ b/drivers/ide/Kconfig @@ -50,7 +50,7 @@ menuconfig IDE To compile this driver as a module, choose M here: the module will be called ide. - For further information, please read . + For further information, please read . If unsure, say Y. @@ -77,7 +77,7 @@ config BLK_DEV_IDE Useful information about large (>540 MB) IDE disks, multiple interfaces, what to do if ATA/IDE devices are not automatically detected, sound card ATA/IDE ports, module support, and other - topics, is contained in . For detailed + topics, is contained in . For detailed information about hard drives, consult the Disk-HOWTO and the Multi-Disk-HOWTO, available from . @@ -87,7 +87,7 @@ config BLK_DEV_IDE . To compile this driver as a module, choose M here and read - . The module will be called ide-mod. + . The module will be called ide-mod. Do not compile this driver as a module if your root file system (the one containing the directory /) is located on an IDE device. @@ -98,7 +98,7 @@ config BLK_DEV_IDE if BLK_DEV_IDE -comment "Please see Documentation/ide.txt for help/info on IDE drives" +comment "Please see Documentation/ide/ide.txt for help/info on IDE drives" config BLK_DEV_IDE_SATA bool "Support for SATA (deprecated; conflicts with libata SATA driver)" @@ -235,8 +235,8 @@ config BLK_DEV_IDETAPE along with other IDE devices, as "hdb" or "hdc", or something similar, and will be mapped to a character device such as "ht0" (check the boot messages with dmesg). Be sure to consult the - and files - for usage information. + and + files for usage information. To compile this driver as a module, choose M here: the module will be called ide-tape. @@ -358,7 +358,7 @@ config BLK_DEV_CMD640 The CMD640 chip is also used on add-in cards by Acculogic, and on the "CSA-6400E PCI to IDE controller" that some people have. For - details, read . + details, read . config BLK_DEV_CMD640_ENHANCED bool "CMD640 enhanced support" @@ -366,7 +366,7 @@ config BLK_DEV_CMD640_ENHANCED help This option includes support for setting/autotuning PIO modes and prefetch on CMD640 IDE interfaces. For details, read - . If you have a CMD640 IDE interface + . If you have a CMD640 IDE interface and your BIOS does not already do this for you, then say Y here. Otherwise say N. @@ -1069,9 +1069,9 @@ config BLK_DEV_ALI14XX This driver is enabled at runtime using the "ali14xx.probe" kernel boot parameter. It enables support for the secondary IDE interface of the ALI M1439/1443/1445/1487/1489 chipsets, and permits faster - I/O speeds to be set as well. See the files - and - for more info. + I/O speeds to be set as well. + See the files and + for more info. config BLK_DEV_DTC2278 tristate "DTC-2278 support" @@ -1079,7 +1079,7 @@ config BLK_DEV_DTC2278 This driver is enabled at runtime using the "dtc2278.probe" kernel boot parameter. It enables support for the secondary IDE interface of the DTC-2278 card, and permits faster I/O speeds to be set as - well. See the and + well. See the and files for more info. config BLK_DEV_HT6560B @@ -1088,7 +1088,7 @@ config BLK_DEV_HT6560B This driver is enabled at runtime using the "ht6560b.probe" kernel boot parameter. It enables support for the secondary IDE interface of the Holtek card, and permits faster I/O speeds to be set as well. - See the and + See the and files for more info. config BLK_DEV_QD65XX @@ -1096,7 +1096,7 @@ config BLK_DEV_QD65XX help This driver is enabled at runtime using the "qd65xx.probe" kernel boot parameter. It permits faster I/O speeds to be set. See the - and + and for more info. config BLK_DEV_UMC8672 @@ -1105,7 +1105,7 @@ config BLK_DEV_UMC8672 This driver is enabled at runtime using the "umc8672.probe" kernel boot parameter. It enables support for the secondary IDE interface of the UMC-8672, and permits faster I/O speeds to be set as well. - See the files and + See the files and for more info. endif diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c index 310e497b58380d5d348c29d9d890204e1cf47edf..c8d0e8715997475abe51e683ee5b5aff2f44109c 100644 --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c @@ -670,8 +670,8 @@ static void cdrom_buffer_sectors (ide_drive_t *drive, unsigned long sector, * and attempt to recover if there are problems. Returns 0 if everything's * ok; nonzero if the request has been terminated. */ -static -int ide_cd_check_ireason(ide_drive_t *drive, int len, int ireason, int rw) +static int ide_cd_check_ireason(ide_drive_t *drive, struct request *rq, + int len, int ireason, int rw) { /* * ireason == 0: the drive wants to receive data from us @@ -701,6 +701,9 @@ int ide_cd_check_ireason(ide_drive_t *drive, int len, int ireason, int rw) drive->name, __FUNCTION__, ireason); } + if (rq->cmd_type == REQ_TYPE_ATA_PC) + rq->cmd_flags |= REQ_FAILED; + cdrom_end_request(drive, 0); return -1; } @@ -1071,11 +1074,11 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive) /* * check which way to transfer data */ - if (blk_fs_request(rq) || blk_pc_request(rq)) { - if (ide_cd_check_ireason(drive, len, ireason, write)) - return ide_stopped; + if (ide_cd_check_ireason(drive, rq, len, ireason, write)) + return ide_stopped; - if (blk_fs_request(rq) && write == 0) { + if (blk_fs_request(rq)) { + if (write == 0) { int nskip; if (ide_cd_check_transfer_size(drive, len)) { @@ -1101,16 +1104,9 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive) if (ireason == 0) { write = 1; xferfunc = HWIF(drive)->atapi_output_bytes; - } else if (ireason == 2 || (ireason == 1 && - (blk_fs_request(rq) || blk_pc_request(rq)))) { + } else { write = 0; xferfunc = HWIF(drive)->atapi_input_bytes; - } else { - printk(KERN_ERR "%s: %s: The drive " - "appears confused (ireason = 0x%02x). " - "Trying to recover by ending request.\n", - drive->name, __FUNCTION__, ireason); - goto end_request; } /* @@ -1182,11 +1178,10 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive) else rq->data += blen; } + if (!write && blk_sense_request(rq)) + rq->sense_len += blen; } - if (write && blk_sense_request(rq)) - rq->sense_len += thislen; - /* * pad, if necessary */ @@ -1931,6 +1926,7 @@ static const struct cd_list_entry ide_cd_quirks_list[] = { { "MATSHITADVD-ROM SR-8186", NULL, IDE_CD_FLAG_PLAY_AUDIO_OK }, { "MATSHITADVD-ROM SR-8176", NULL, IDE_CD_FLAG_PLAY_AUDIO_OK }, { "MATSHITADVD-ROM SR-8174", NULL, IDE_CD_FLAG_PLAY_AUDIO_OK }, + { "Optiarc DVD RW AD-5200A", NULL, IDE_CD_FLAG_PLAY_AUDIO_OK }, { NULL, NULL, 0 } }; diff --git a/drivers/ide/ide-cd_ioctl.c b/drivers/ide/ide-cd_ioctl.c index b68284de4e85a2fbbb968c102ee5d8b3eddd6b22..6d147ce6782f17b8d8f1b2667891bc6dd3ff8076 100644 --- a/drivers/ide/ide-cd_ioctl.c +++ b/drivers/ide/ide-cd_ioctl.c @@ -457,6 +457,10 @@ int ide_cdrom_packet(struct cdrom_device_info *cdi, layer. the packet must be complete, as we do not touch it at all. */ ide_cd_init_rq(drive, &req); + + if (cgc->data_direction == CGC_DATA_WRITE) + req.cmd_flags |= REQ_RW; + memcpy(req.cmd, cgc->cmd, CDROM_PACKET_SIZE); if (cgc->sense) memset(cgc->sense, 0, sizeof(struct request_sense)); diff --git a/drivers/ide/ide-disk.c b/drivers/ide/ide-disk.c index 8f5bed471050d955713f5d5230aa7327ad993dec..39501d130256109ad50d06a6b904249e9163f08a 100644 --- a/drivers/ide/ide-disk.c +++ b/drivers/ide/ide-disk.c @@ -867,7 +867,7 @@ static void idedisk_setup (ide_drive_t *drive) /* Only print cache size when it was specified */ if (id->buf_size) - printk (" w/%dKiB Cache", id->buf_size/2); + printk(KERN_CONT " w/%dKiB Cache", id->buf_size / 2); printk(KERN_CONT ", CHS=%d/%d/%d\n", drive->bios_cyl, drive->bios_head, drive->bios_sect); @@ -949,7 +949,8 @@ static void ide_device_shutdown(ide_drive_t *drive) return; } - printk("Shutdown: %s\n", drive->name); + printk(KERN_INFO "Shutdown: %s\n", drive->name); + drive->gendev.bus->suspend(&drive->gendev, PMSG_SUSPEND); } diff --git a/drivers/ide/ide-dma.c b/drivers/ide/ide-dma.c index d0e7b537353e38ea1bb23ff6f0604f0d93777752..d61e5788d310f06dc42c12d7f7cd507e8fa10a39 100644 --- a/drivers/ide/ide-dma.c +++ b/drivers/ide/ide-dma.c @@ -1,9 +1,13 @@ /* + * IDE DMA support (including IDE PCI BM-DMA). + * * Copyright (C) 1995-1998 Mark Lord * Copyright (C) 1999-2000 Andre Hedrick * Copyright (C) 2004, 2007 Bartlomiej Zolnierkiewicz * * May be copied or modified under the terms of the GNU General Public License + * + * DMA is supported for all IDE devices (disk drives, cdroms, tapes, floppies). */ /* @@ -11,49 +15,6 @@ */ /* - * This module provides support for the bus-master IDE DMA functions - * of various PCI chipsets, including the Intel PIIX (i82371FB for - * the 430 FX chipset), the PIIX3 (i82371SB for the 430 HX/VX and - * 440 chipsets), and the PIIX4 (i82371AB for the 430 TX chipset) - * ("PIIX" stands for "PCI ISA IDE Xcellerator"). - * - * Pretty much the same code works for other IDE PCI bus-mastering chipsets. - * - * DMA is supported for all IDE devices (disk drives, cdroms, tapes, floppies). - * - * By default, DMA support is prepared for use, but is currently enabled only - * for drives which already have DMA enabled (UltraDMA or mode 2 multi/single), - * or which are recognized as "good" (see table below). Drives with only mode0 - * or mode1 (multi/single) DMA should also work with this chipset/driver - * (eg. MC2112A) but are not enabled by default. - * - * Use "hdparm -i" to view modes supported by a given drive. - * - * The hdparm-3.5 (or later) utility can be used for manually enabling/disabling - * DMA support, but must be (re-)compiled against this kernel version or later. - * - * To enable DMA, use "hdparm -d1 /dev/hd?" on a per-drive basis after booting. - * If problems arise, ide.c will disable DMA operation after a few retries. - * This error recovery mechanism works and has been extremely well exercised. - * - * IDE drives, depending on their vintage, may support several different modes - * of DMA operation. The boot-time modes are indicated with a "*" in - * the "hdparm -i" listing, and can be changed with *knowledgeable* use of - * the "hdparm -X" feature. There is seldom a need to do this, as drives - * normally power-up with their "best" PIO/DMA modes enabled. - * - * Testing has been done with a rather extensive number of drives, - * with Quantum & Western Digital models generally outperforming the pack, - * and Fujitsu & Conner (and some Seagate which are really Conner) drives - * showing more lackluster throughput. - * - * Keep an eye on /var/adm/messages for "DMA disabled" messages. - * - * Some people have reported trouble with Intel Zappa motherboards. - * This can be fixed by upgrading the AMI BIOS to version 1.00.04.BS0, - * available from ftp://ftp.intel.com/pub/bios/10004bs0.exe - * (thanks to Glen Morrell for researching this). - * * Thanks to "Christopher J. Reimer" for * fixing the problem with the BIOS on some Acer motherboards. * @@ -65,11 +26,6 @@ * * Most importantly, thanks to Robert Bringman * for supplying a Promise UDMA board & WD UDMA drive for this work! - * - * And, yes, Intel Zappa boards really *do* use both PIIX IDE ports. - * - * ATA-66/100 and recovery functions, I forgot the rest...... - * */ #include @@ -757,7 +713,7 @@ static int ide_tune_dma(ide_drive_t *drive) } if (hwif->host_flags & IDE_HFLAG_NO_SET_MODE) - return 0; + return 1; if (ide_set_dma_mode(drive, speed)) return 0; diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c index 4a2cb28682263d6a3c3a861490dfbe770d96c2d6..194ecb0049eb1ed37c3dde4c00d3a83273c1dc88 100644 --- a/drivers/ide/ide-probe.c +++ b/drivers/ide/ide-probe.c @@ -756,7 +756,8 @@ static int ide_probe_port(ide_hwif_t *hwif) BUG_ON(hwif->present); - if (hwif->noprobe) + if (hwif->noprobe || + (hwif->drives[0].noprobe && hwif->drives[1].noprobe)) return -EACCES; /* diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c index 0598ecfd5f3706b0402182875f324474361bbf5b..43e0e05577763b4bcd166dc4d14128dd94dac9d2 100644 --- a/drivers/ide/ide-tape.c +++ b/drivers/ide/ide-tape.c @@ -3765,6 +3765,11 @@ static int ide_tape_probe(ide_drive_t *drive) g->fops = &idetape_block_ops; ide_register_region(g); + printk(KERN_WARNING "It is possible that this driver does not have any" + " users anymore and, as a result, it will be REMOVED soon." + " Please notify Bart or Boris" + " in case you still need it.\n"); + return 0; out_free_tape: diff --git a/drivers/ide/ide.c b/drivers/ide/ide.c index 477833f0daf501cbb1a67150e6523818a1fc38f6..9976f9d627d401113e5244fd5e20cfc01043fb01 100644 --- a/drivers/ide/ide.c +++ b/drivers/ide/ide.c @@ -590,11 +590,6 @@ void ide_unregister(unsigned int index, int init_default, int restore) hwif->extra_ports = 0; } - /* - * Note that we only release the standard ports, - * and do not even try to handle any extra ports - * allocated for weird IDE interface chipsets. - */ ide_hwif_release_regions(hwif); /* copy original settings */ @@ -672,7 +667,6 @@ int ide_register_hw(hw_regs_t *hw, void (*quirkproc)(ide_drive_t *), do { hwif = ide_deprecated_find_port(hw->io_ports[IDE_DATA_OFFSET]); - index = hwif->index; if (hwif) goto found; for (index = 0; index < MAX_HWIFS; index++) @@ -680,6 +674,7 @@ int ide_register_hw(hw_regs_t *hw, void (*quirkproc)(ide_drive_t *), } while (retry--); return -1; found: + index = hwif->index; if (hwif->present) ide_unregister(index, 0, 1); else if (!hwif->hold) @@ -1036,10 +1031,9 @@ int generic_ide_ioctl(ide_drive_t *drive, struct file *file, struct block_device drive->nice1 = (arg >> IDE_NICE_1) & 1; return 0; case HDIO_DRIVE_RESET: - { - unsigned long flags; - if (!capable(CAP_SYS_ADMIN)) return -EACCES; - + if (!capable(CAP_SYS_ADMIN)) + return -EACCES; + /* * Abort the current command on the * group if there is one, taking @@ -1058,17 +1052,15 @@ int generic_ide_ioctl(ide_drive_t *drive, struct file *file, struct block_device ide_abort(drive, "drive reset"); BUG_ON(HWGROUP(drive)->handler); - + /* Ensure nothing gets queued after we drop the lock. Reset will clear the busy */ - + HWGROUP(drive)->busy = 1; spin_unlock_irqrestore(&ide_lock, flags); (void) ide_do_reset(drive); return 0; - } - case HDIO_GET_BUSSTATE: if (!capable(CAP_SYS_ADMIN)) return -EACCES; @@ -1188,7 +1180,7 @@ static int __initdata is_chipset_set[MAX_HWIFS]; * ide_setup() gets called VERY EARLY during initialization, * to handle kernel "command line" strings beginning with "hdx=" or "ide". * - * Remember to update Documentation/ide.txt if you change something here. + * Remember to update Documentation/ide/ide.txt if you change something here. */ static int __init ide_setup(char *s) { @@ -1449,7 +1441,7 @@ static int __init ide_setup(char *s) case -1: /* "noprobe" */ hwif->noprobe = 1; - goto done; + goto obsolete_option; case 1: /* base */ vals[1] = vals[0] + 0x206; /* default ctl */ diff --git a/drivers/ide/legacy/qd65xx.c b/drivers/ide/legacy/qd65xx.c index bba29df5f21d6094660c777724c38ef9d2de454b..2f4f47ad602f61ca8ec3614d484dcc5939a46c05 100644 --- a/drivers/ide/legacy/qd65xx.c +++ b/drivers/ide/legacy/qd65xx.c @@ -334,43 +334,6 @@ static void __init qd6580_port_init_devs(ide_hwif_t *hwif) hwif->drives[1].drive_data = t2; } -/* - * qd_unsetup: - * - * called to unsetup an ata channel : back to default values, unlinks tuning - */ -/* -static void __exit qd_unsetup(ide_hwif_t *hwif) -{ - u8 config = hwif->config_data; - int base = hwif->select_data; - void *set_pio_mode = (void *)hwif->set_pio_mode; - - if (hwif->chipset != ide_qd65xx) - return; - - printk(KERN_NOTICE "%s: back to defaults\n", hwif->name); - - hwif->selectproc = NULL; - hwif->set_pio_mode = NULL; - - if (set_pio_mode == (void *)qd6500_set_pio_mode) { - // will do it for both - outb(QD6500_DEF_DATA, QD_TIMREG(&hwif->drives[0])); - } else if (set_pio_mode == (void *)qd6580_set_pio_mode) { - if (QD_CONTROL(hwif) & QD_CONTR_SEC_DISABLED) { - outb(QD6580_DEF_DATA, QD_TIMREG(&hwif->drives[0])); - outb(QD6580_DEF_DATA2, QD_TIMREG(&hwif->drives[1])); - } else { - outb(hwif->channel ? QD6580_DEF_DATA2 : QD6580_DEF_DATA, QD_TIMREG(&hwif->drives[0])); - } - } else { - printk(KERN_WARNING "Unknown qd65xx tuning fonction !\n"); - printk(KERN_WARNING "keeping settings !\n"); - } -} -*/ - static const struct ide_port_info qd65xx_port_info __initdata = { .chipset = ide_qd65xx, .host_flags = IDE_HFLAG_IO_32BIT | @@ -444,6 +407,8 @@ static int __init qd_probe(int base) printk(KERN_DEBUG "qd6580: config=%#x, control=%#x, ID3=%u\n", config, control, QD_ID3); + outb(QD_DEF_CONTR, QD_CONTROL_PORT); + if (control & QD_CONTR_SEC_DISABLED) { /* secondary disabled */ @@ -460,8 +425,6 @@ static int __init qd_probe(int base) ide_device_add(idx, &qd65xx_port_info); - outb(QD_DEF_CONTR, QD_CONTROL_PORT); - return 1; } else { ide_hwif_t *mate; @@ -487,8 +450,6 @@ static int __init qd_probe(int base) ide_device_add(idx, &qd65xx_port_info); - outb(QD_DEF_CONTR, QD_CONTROL_PORT); - return 0; /* no other qd65xx possible */ } } diff --git a/drivers/ide/pci/cmd640.c b/drivers/ide/pci/cmd640.c index bd24dad3cfc6b2a82c990120ff7e10ac567599ab..ec667982809c18ae8ddf59bc5023190134cb33c1 100644 --- a/drivers/ide/pci/cmd640.c +++ b/drivers/ide/pci/cmd640.c @@ -787,7 +787,8 @@ static int __init cmd640x_init(void) /* * Try to enable the secondary interface, if not already enabled */ - if (cmd_hwif1->noprobe) { + if (cmd_hwif1->noprobe || + (cmd_hwif1->drives[0].noprobe && cmd_hwif1->drives[1].noprobe)) { port2 = "not probed"; } else { b = get_cmd640_reg(CNTRL); diff --git a/drivers/ide/pci/hpt366.c b/drivers/ide/pci/hpt366.c index d0f7bb8b8adf1d881fe4d2f7c5f86106dc4b63d1..6357bb6269ab42bfc14623006e0fef089484ae08 100644 --- a/drivers/ide/pci/hpt366.c +++ b/drivers/ide/pci/hpt366.c @@ -1570,10 +1570,12 @@ static int __devinit hpt366_init_one(struct pci_dev *dev, const struct pci_devic if (rev < 3) info = &hpt36x; else { - static const struct hpt_info *hpt37x_info[] = - { &hpt370, &hpt370a, &hpt372, &hpt372n }; - - info = hpt37x_info[min_t(u8, rev, 6) - 3]; + switch (min_t(u8, rev, 6)) { + case 3: info = &hpt370; break; + case 4: info = &hpt370a; break; + case 5: info = &hpt372; break; + case 6: info = &hpt372n; break; + } idx++; } break; @@ -1626,7 +1628,7 @@ static int __devinit hpt366_init_one(struct pci_dev *dev, const struct pci_devic return ide_setup_pci_device(dev, &d); } -static const struct pci_device_id hpt366_pci_tbl[] = { +static const struct pci_device_id hpt366_pci_tbl[] __devinitconst = { { PCI_VDEVICE(TTI, PCI_DEVICE_ID_TTI_HPT366), 0 }, { PCI_VDEVICE(TTI, PCI_DEVICE_ID_TTI_HPT372), 1 }, { PCI_VDEVICE(TTI, PCI_DEVICE_ID_TTI_HPT302), 2 }, diff --git a/drivers/ieee1394/sbp2.c b/drivers/ieee1394/sbp2.c index 28e155a9e2a5a6bc8e424e2e1dc235f94fac2c26..f53f72daae34322390be1c8ca52849996e30c3e5 100644 --- a/drivers/ieee1394/sbp2.c +++ b/drivers/ieee1394/sbp2.c @@ -183,6 +183,9 @@ MODULE_PARM_DESC(exclusive_login, "Exclusive login to sbp2 device " * Avoids access beyond actual disk limits on devices with an off-by-one bug. * Don't use this with devices which don't have this bug. * + * - delay inquiry + * Wait extra SBP2_INQUIRY_DELAY seconds after login before SCSI inquiry. + * * - override internal blacklist * Instead of adding to the built-in blacklist, use only the workarounds * specified in the module load parameter. @@ -195,6 +198,7 @@ MODULE_PARM_DESC(workarounds, "Work around device bugs (default = 0" ", 36 byte inquiry = " __stringify(SBP2_WORKAROUND_INQUIRY_36) ", skip mode page 8 = " __stringify(SBP2_WORKAROUND_MODE_SENSE_8) ", fix capacity = " __stringify(SBP2_WORKAROUND_FIX_CAPACITY) + ", delay inquiry = " __stringify(SBP2_WORKAROUND_DELAY_INQUIRY) ", override internal blacklist = " __stringify(SBP2_WORKAROUND_OVERRIDE) ", or a combination)"); @@ -357,6 +361,11 @@ static const struct { .workarounds = SBP2_WORKAROUND_INQUIRY_36 | SBP2_WORKAROUND_MODE_SENSE_8, }, + /* DViCO Momobay FX-3A with TSB42AA9A bridge */ { + .firmware_revision = 0x002800, + .model_id = 0x000000, + .workarounds = SBP2_WORKAROUND_DELAY_INQUIRY, + }, /* Initio bridges, actually only needed for some older ones */ { .firmware_revision = 0x000200, .model_id = SBP2_ROM_VALUE_WILDCARD, @@ -367,6 +376,11 @@ static const struct { .model_id = SBP2_ROM_VALUE_WILDCARD, .workarounds = SBP2_WORKAROUND_128K_MAX_TRANS, }, + /* Datafab MD2-FW2 with Symbios/LSILogic SYM13FW500 bridge */ { + .firmware_revision = 0x002600, + .model_id = SBP2_ROM_VALUE_WILDCARD, + .workarounds = SBP2_WORKAROUND_128K_MAX_TRANS, + }, /* iPod 4th generation */ { .firmware_revision = 0x0a2700, .model_id = 0x000021, @@ -914,6 +928,9 @@ static int sbp2_start_device(struct sbp2_lu *lu) sbp2_agent_reset(lu, 1); sbp2_max_speed_and_size(lu); + if (lu->workarounds & SBP2_WORKAROUND_DELAY_INQUIRY) + ssleep(SBP2_INQUIRY_DELAY); + error = scsi_add_device(lu->shost, 0, lu->ud->id, 0); if (error) { SBP2_ERR("scsi_add_device failed"); @@ -1962,6 +1979,9 @@ static int sbp2scsi_slave_alloc(struct scsi_device *sdev) { struct sbp2_lu *lu = (struct sbp2_lu *)sdev->host->hostdata[0]; + if (sdev->lun != 0 || sdev->id != lu->ud->id || sdev->channel != 0) + return -ENODEV; + lu->sdev = sdev; sdev->allow_restart = 1; diff --git a/drivers/ieee1394/sbp2.h b/drivers/ieee1394/sbp2.h index d2ecb0d8a1bba4e577eef7c03dbcbb8df5ee0eee..80d8e097b0651487a17d8b6e1fd5105ce79706aa 100644 --- a/drivers/ieee1394/sbp2.h +++ b/drivers/ieee1394/sbp2.h @@ -343,6 +343,8 @@ enum sbp2lu_state_types { #define SBP2_WORKAROUND_INQUIRY_36 0x2 #define SBP2_WORKAROUND_MODE_SENSE_8 0x4 #define SBP2_WORKAROUND_FIX_CAPACITY 0x8 +#define SBP2_WORKAROUND_DELAY_INQUIRY 0x10 +#define SBP2_INQUIRY_DELAY 12 #define SBP2_WORKAROUND_OVERRIDE 0x100 #endif /* SBP2_H */ diff --git a/drivers/infiniband/core/cm.c b/drivers/infiniband/core/cm.c index b10ade92efedfedbc6b0519c82ea9c3858f94fd8..4df405157086f458aae293a837a83d0983556210 100644 --- a/drivers/infiniband/core/cm.c +++ b/drivers/infiniband/core/cm.c @@ -3759,6 +3759,7 @@ static void cm_remove_one(struct ib_device *device) port = cm_dev->port[i-1]; ib_modify_port(device, port->port_num, 0, &port_modify); ib_unregister_mad_agent(port->mad_agent); + flush_workqueue(cm.wq); cm_remove_port_fs(port); } kobject_put(&cm_dev->dev_obj); @@ -3813,6 +3814,7 @@ static void __exit ib_cm_cleanup(void) cancel_delayed_work(&timewait_info->work.work); spin_unlock_irq(&cm.lock); + ib_unregister_client(&cm_client); destroy_workqueue(cm.wq); list_for_each_entry_safe(timewait_info, tmp, &cm.timewait_list, list) { @@ -3820,7 +3822,6 @@ static void __exit ib_cm_cleanup(void) kfree(timewait_info); } - ib_unregister_client(&cm_client); class_unregister(&cm_class); idr_destroy(&cm.local_id_table); } diff --git a/drivers/infiniband/core/fmr_pool.c b/drivers/infiniband/core/fmr_pool.c index 7f00347364f7a4b07f4b0237cb77ab45983c2732..06d502c06a4d834f3f953b6d13304882422902a4 100644 --- a/drivers/infiniband/core/fmr_pool.c +++ b/drivers/infiniband/core/fmr_pool.c @@ -139,7 +139,7 @@ static inline struct ib_pool_fmr *ib_fmr_cache_lookup(struct ib_fmr_pool *pool, static void ib_fmr_batch_release(struct ib_fmr_pool *pool) { int ret; - struct ib_pool_fmr *fmr, *next; + struct ib_pool_fmr *fmr; LIST_HEAD(unmap_list); LIST_HEAD(fmr_list); @@ -158,20 +158,6 @@ static void ib_fmr_batch_release(struct ib_fmr_pool *pool) #endif } - /* - * The free_list may hold FMRs that have been put there - * because they haven't reached the max_remap count. - * Invalidate their mapping as well. - */ - list_for_each_entry_safe(fmr, next, &pool->free_list, list) { - if (fmr->remap_count == 0) - continue; - hlist_del_init(&fmr->cache_node); - fmr->remap_count = 0; - list_add_tail(&fmr->fmr->list, &fmr_list); - list_move(&fmr->list, &unmap_list); - } - list_splice(&pool->dirty_list, &unmap_list); INIT_LIST_HEAD(&pool->dirty_list); pool->dirty_len = 0; @@ -384,6 +370,11 @@ void ib_destroy_fmr_pool(struct ib_fmr_pool *pool) i = 0; list_for_each_entry_safe(fmr, tmp, &pool->free_list, list) { + if (fmr->remap_count) { + INIT_LIST_HEAD(&fmr_list); + list_add_tail(&fmr->fmr->list, &fmr_list); + ib_unmap_fmr(&fmr_list); + } ib_dealloc_fmr(fmr->fmr); list_del(&fmr->list); kfree(fmr); @@ -407,8 +398,23 @@ EXPORT_SYMBOL(ib_destroy_fmr_pool); */ int ib_flush_fmr_pool(struct ib_fmr_pool *pool) { - int serial = atomic_inc_return(&pool->req_ser); + int serial; + struct ib_pool_fmr *fmr, *next; + + /* + * The free_list holds FMRs that may have been used + * but have not been remapped enough times to be dirty. + * Put them on the dirty list now so that the cleanup + * thread will reap them too. + */ + spin_lock_irq(&pool->pool_lock); + list_for_each_entry_safe(fmr, next, &pool->free_list, list) { + if (fmr->remap_count > 0) + list_move(&fmr->list, &pool->dirty_list); + } + spin_unlock_irq(&pool->pool_lock); + serial = atomic_inc_return(&pool->req_ser); wake_up_process(pool->thread); if (wait_event_interruptible(pool->force_wait, diff --git a/drivers/infiniband/core/iwcm.c b/drivers/infiniband/core/iwcm.c index 223b1aa7d92b40f17b2367cc0166f2afc994d8e8..81c9195b512a1e5d63ae610bb3961e14a097f49e 100644 --- a/drivers/infiniband/core/iwcm.c +++ b/drivers/infiniband/core/iwcm.c @@ -839,6 +839,7 @@ static void cm_work_handler(struct work_struct *_work) unsigned long flags; int empty; int ret = 0; + int destroy_id; spin_lock_irqsave(&cm_id_priv->lock, flags); empty = list_empty(&cm_id_priv->work_list); @@ -857,9 +858,9 @@ static void cm_work_handler(struct work_struct *_work) destroy_cm_id(&cm_id_priv->id); } BUG_ON(atomic_read(&cm_id_priv->refcount)==0); + destroy_id = test_bit(IWCM_F_CALLBACK_DESTROY, &cm_id_priv->flags); if (iwcm_deref_id(cm_id_priv)) { - if (test_bit(IWCM_F_CALLBACK_DESTROY, - &cm_id_priv->flags)) { + if (destroy_id) { BUG_ON(!list_empty(&cm_id_priv->work_list)); free_cm_id(cm_id_priv); } diff --git a/drivers/infiniband/hw/cxgb3/iwch_mem.c b/drivers/infiniband/hw/cxgb3/iwch_mem.c index 73bfd1656f86434bae2c36215a6d073607a07a7c..b8797c66676d6837b265f816e55d923d450047be 100644 --- a/drivers/infiniband/hw/cxgb3/iwch_mem.c +++ b/drivers/infiniband/hw/cxgb3/iwch_mem.c @@ -136,14 +136,8 @@ int build_phys_page_list(struct ib_phys_buf *buffer_list, /* Find largest page shift we can use to cover buffers */ for (*shift = PAGE_SHIFT; *shift < 27; ++(*shift)) - if (num_phys_buf > 1) { - if ((1ULL << *shift) & mask) - break; - } else - if (1ULL << *shift >= - buffer_list[0].size + - (buffer_list[0].addr & ((1ULL << *shift) - 1))) - break; + if ((1ULL << *shift) & mask) + break; buffer_list[0].size += buffer_list[0].addr & ((1ULL << *shift) - 1); buffer_list[0].addr &= ~0ull << *shift; diff --git a/drivers/infiniband/hw/cxgb3/iwch_provider.c b/drivers/infiniband/hw/cxgb3/iwch_provider.c index df1838f8f94d9b59b700fa1212fb622b5f1e3811..b2ea9210467f264cf574f74e6a44861e82dd0407 100644 --- a/drivers/infiniband/hw/cxgb3/iwch_provider.c +++ b/drivers/infiniband/hw/cxgb3/iwch_provider.c @@ -189,7 +189,7 @@ static struct ib_cq *iwch_create_cq(struct ib_device *ibdev, int entries, int ve return ERR_PTR(-ENOMEM); } chp->rhp = rhp; - chp->ibcq.cqe = (1 << chp->cq.size_log2) - 1; + chp->ibcq.cqe = 1 << chp->cq.size_log2; spin_lock_init(&chp->lock); atomic_set(&chp->refcnt, 1); init_waitqueue_head(&chp->wait); @@ -819,8 +819,11 @@ static struct ib_qp *iwch_create_qp(struct ib_pd *pd, kfree(qhp); return ERR_PTR(-ENOMEM); } + attrs->cap.max_recv_wr = rqsize - 1; attrs->cap.max_send_wr = sqsize; + attrs->cap.max_inline_data = T3_MAX_INLINE; + qhp->rhp = rhp; qhp->attr.pd = php->pdid; qhp->attr.scq = ((struct iwch_cq *) attrs->send_cq)->cq.cqid; diff --git a/drivers/infiniband/hw/ipath/ipath_common.h b/drivers/infiniband/hw/ipath/ipath_common.h index 414621095540e4eb38d18708109bd550a7b7a0c0..591901aab6b75839e9242c0743c8938e14fabd82 100644 --- a/drivers/infiniband/hw/ipath/ipath_common.h +++ b/drivers/infiniband/hw/ipath/ipath_common.h @@ -75,7 +75,7 @@ #define IPATH_IB_LINKDOWN 0 #define IPATH_IB_LINKARM 1 #define IPATH_IB_LINKACTIVE 2 -#define IPATH_IB_LINKINIT 3 +#define IPATH_IB_LINKDOWN_ONLY 3 #define IPATH_IB_LINKDOWN_SLEEP 4 #define IPATH_IB_LINKDOWN_DISABLE 5 #define IPATH_IB_LINK_LOOPBACK 6 /* enable local loopback */ diff --git a/drivers/infiniband/hw/ipath/ipath_driver.c b/drivers/infiniband/hw/ipath/ipath_driver.c index d5ff6ca2db30aaaba1ecb0265c9527e7c917621f..ca4d0acc6786768177126ca15af89407fbba235a 100644 --- a/drivers/infiniband/hw/ipath/ipath_driver.c +++ b/drivers/infiniband/hw/ipath/ipath_driver.c @@ -851,8 +851,7 @@ void ipath_disarm_piobufs(struct ipath_devdata *dd, unsigned first, * -ETIMEDOUT state can have multiple states set, for any of several * transitions. */ -static int ipath_wait_linkstate(struct ipath_devdata *dd, u32 state, - int msecs) +int ipath_wait_linkstate(struct ipath_devdata *dd, u32 state, int msecs) { dd->ipath_state_wanted = state; wait_event_interruptible_timeout(ipath_state_wait, @@ -1656,8 +1655,8 @@ void ipath_cancel_sends(struct ipath_devdata *dd, int restore_sendctrl) static void ipath_set_ib_lstate(struct ipath_devdata *dd, int which) { static const char *what[4] = { - [0] = "DOWN", - [INFINIPATH_IBCC_LINKCMD_INIT] = "INIT", + [0] = "NOP", + [INFINIPATH_IBCC_LINKCMD_DOWN] = "DOWN", [INFINIPATH_IBCC_LINKCMD_ARMED] = "ARMED", [INFINIPATH_IBCC_LINKCMD_ACTIVE] = "ACTIVE" }; @@ -1672,9 +1671,9 @@ static void ipath_set_ib_lstate(struct ipath_devdata *dd, int which) (dd, dd->ipath_kregs->kr_ibcstatus) >> INFINIPATH_IBCS_LINKTRAININGSTATE_SHIFT) & INFINIPATH_IBCS_LINKTRAININGSTATE_MASK]); - /* flush all queued sends when going to DOWN or INIT, to be sure that + /* flush all queued sends when going to DOWN to be sure that * they don't block MAD packets */ - if (!linkcmd || linkcmd == INFINIPATH_IBCC_LINKCMD_INIT) + if (linkcmd == INFINIPATH_IBCC_LINKCMD_DOWN) ipath_cancel_sends(dd, 1); ipath_write_kreg(dd, dd->ipath_kregs->kr_ibcctrl, @@ -1687,6 +1686,13 @@ int ipath_set_linkstate(struct ipath_devdata *dd, u8 newstate) int ret; switch (newstate) { + case IPATH_IB_LINKDOWN_ONLY: + ipath_set_ib_lstate(dd, INFINIPATH_IBCC_LINKCMD_DOWN << + INFINIPATH_IBCC_LINKCMD_SHIFT); + /* don't wait */ + ret = 0; + goto bail; + case IPATH_IB_LINKDOWN: ipath_set_ib_lstate(dd, INFINIPATH_IBCC_LINKINITCMD_POLL << INFINIPATH_IBCC_LINKINITCMD_SHIFT); @@ -1709,16 +1715,6 @@ int ipath_set_linkstate(struct ipath_devdata *dd, u8 newstate) ret = 0; goto bail; - case IPATH_IB_LINKINIT: - if (dd->ipath_flags & IPATH_LINKINIT) { - ret = 0; - goto bail; - } - ipath_set_ib_lstate(dd, INFINIPATH_IBCC_LINKCMD_INIT << - INFINIPATH_IBCC_LINKCMD_SHIFT); - lstate = IPATH_LINKINIT; - break; - case IPATH_IB_LINKARM: if (dd->ipath_flags & IPATH_LINKARMED) { ret = 0; diff --git a/drivers/infiniband/hw/ipath/ipath_kernel.h b/drivers/infiniband/hw/ipath/ipath_kernel.h index 4cc0f95ea8777ee7aaf040e1089fe48d9d7cba66..ecf3f7ff77177837012af805c673b81b6b3a9bd9 100644 --- a/drivers/infiniband/hw/ipath/ipath_kernel.h +++ b/drivers/infiniband/hw/ipath/ipath_kernel.h @@ -767,6 +767,7 @@ void ipath_kreceive(struct ipath_portdata *); int ipath_setrcvhdrsize(struct ipath_devdata *, unsigned); int ipath_reset_device(int); void ipath_get_faststats(unsigned long); +int ipath_wait_linkstate(struct ipath_devdata *, u32, int); int ipath_set_linkstate(struct ipath_devdata *, u8); int ipath_set_mtu(struct ipath_devdata *, u16); int ipath_set_lid(struct ipath_devdata *, u32, u8); diff --git a/drivers/infiniband/hw/ipath/ipath_mad.c b/drivers/infiniband/hw/ipath/ipath_mad.c index d98d5f103700faab9fd94373f18604d61c214115..b34b91d3723a58f4a2e58f0d6233ed3e264f9338 100644 --- a/drivers/infiniband/hw/ipath/ipath_mad.c +++ b/drivers/infiniband/hw/ipath/ipath_mad.c @@ -555,10 +555,7 @@ static int recv_subn_set_portinfo(struct ib_smp *smp, /* FALLTHROUGH */ case IB_PORT_DOWN: if (lstate == 0) - if (get_linkdowndefaultstate(dd)) - lstate = IPATH_IB_LINKDOWN_SLEEP; - else - lstate = IPATH_IB_LINKDOWN; + lstate = IPATH_IB_LINKDOWN_ONLY; else if (lstate == 1) lstate = IPATH_IB_LINKDOWN_SLEEP; else if (lstate == 2) @@ -568,6 +565,8 @@ static int recv_subn_set_portinfo(struct ib_smp *smp, else goto err; ipath_set_linkstate(dd, lstate); + ipath_wait_linkstate(dd, IPATH_LINKINIT | IPATH_LINKARMED | + IPATH_LINKACTIVE, 1000); break; case IB_PORT_ARMED: ipath_set_linkstate(dd, IPATH_IB_LINKARM); diff --git a/drivers/infiniband/hw/ipath/ipath_qp.c b/drivers/infiniband/hw/ipath/ipath_qp.c index 80dc623cee403637c5d828cc33a519204b869b1d..087ed316647952a13118f7e190e414017f8a0f30 100644 --- a/drivers/infiniband/hw/ipath/ipath_qp.c +++ b/drivers/infiniband/hw/ipath/ipath_qp.c @@ -329,8 +329,9 @@ struct ipath_qp *ipath_lookup_qpn(struct ipath_qp_table *qpt, u32 qpn) /** * ipath_reset_qp - initialize the QP state to the reset state * @qp: the QP to reset + * @type: the QP type */ -static void ipath_reset_qp(struct ipath_qp *qp) +static void ipath_reset_qp(struct ipath_qp *qp, enum ib_qp_type type) { qp->remote_qpn = 0; qp->qkey = 0; @@ -342,7 +343,7 @@ static void ipath_reset_qp(struct ipath_qp *qp) qp->s_psn = 0; qp->r_psn = 0; qp->r_msn = 0; - if (qp->ibqp.qp_type == IB_QPT_RC) { + if (type == IB_QPT_RC) { qp->s_state = IB_OPCODE_RC_SEND_LAST; qp->r_state = IB_OPCODE_RC_SEND_LAST; } else { @@ -414,7 +415,7 @@ int ipath_error_qp(struct ipath_qp *qp, enum ib_wc_status err) wc.wr_id = qp->r_wr_id; wc.opcode = IB_WC_RECV; wc.status = err; - ipath_cq_enter(to_icq(qp->ibqp.send_cq), &wc, 1); + ipath_cq_enter(to_icq(qp->ibqp.recv_cq), &wc, 1); } wc.status = IB_WC_WR_FLUSH_ERR; @@ -534,7 +535,7 @@ int ipath_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, switch (new_state) { case IB_QPS_RESET: - ipath_reset_qp(qp); + ipath_reset_qp(qp, ibqp->qp_type); break; case IB_QPS_ERR: @@ -647,7 +648,7 @@ int ipath_query_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, attr->port_num = 1; attr->timeout = qp->timeout; attr->retry_cnt = qp->s_retry_cnt; - attr->rnr_retry = qp->s_rnr_retry; + attr->rnr_retry = qp->s_rnr_retry_cnt; attr->alt_port_num = 0; attr->alt_timeout = 0; @@ -839,7 +840,7 @@ struct ib_qp *ipath_create_qp(struct ib_pd *ibpd, goto bail_qp; } qp->ip = NULL; - ipath_reset_qp(qp); + ipath_reset_qp(qp, init_attr->qp_type); break; default: diff --git a/drivers/infiniband/hw/ipath/ipath_rc.c b/drivers/infiniband/hw/ipath/ipath_rc.c index 459e46e2c016b93926c2221fc2a3f73a2deeaefd..40f3e37d7adc3e883a8b3eff1a4c05cf7d7820f2 100644 --- a/drivers/infiniband/hw/ipath/ipath_rc.c +++ b/drivers/infiniband/hw/ipath/ipath_rc.c @@ -1196,6 +1196,10 @@ static inline void ipath_rc_rcv_resp(struct ipath_ibdev *dev, list_move_tail(&qp->timerwait, &dev->pending[dev->pending_index]); spin_unlock(&dev->pending_lock); + + if (opcode == OP(RDMA_READ_RESPONSE_MIDDLE)) + qp->s_retry = qp->s_retry_cnt; + /* * Update the RDMA receive state but do the copy w/o * holding the locks and blocking interrupts. diff --git a/drivers/infiniband/hw/ipath/ipath_registers.h b/drivers/infiniband/hw/ipath/ipath_registers.h index 6d2a17f9c1da919193e260160033ad57bf3e05f8..92ad73a7fff0f20f353a1f63e2efe0bd265e0ce3 100644 --- a/drivers/infiniband/hw/ipath/ipath_registers.h +++ b/drivers/infiniband/hw/ipath/ipath_registers.h @@ -185,7 +185,7 @@ #define INFINIPATH_IBCC_LINKINITCMD_SLEEP 3 #define INFINIPATH_IBCC_LINKINITCMD_SHIFT 16 #define INFINIPATH_IBCC_LINKCMD_MASK 0x3ULL -#define INFINIPATH_IBCC_LINKCMD_INIT 1 /* move to 0x11 */ +#define INFINIPATH_IBCC_LINKCMD_DOWN 1 /* move to 0x11 */ #define INFINIPATH_IBCC_LINKCMD_ARMED 2 /* move to 0x21 */ #define INFINIPATH_IBCC_LINKCMD_ACTIVE 3 /* move to 0x31 */ #define INFINIPATH_IBCC_LINKCMD_SHIFT 18 diff --git a/drivers/infiniband/hw/nes/nes.c b/drivers/infiniband/hw/nes/nes.c index 7f8853b44ee173579d2af89d54c09acfa5117ff9..b2112f5a422fbd8bcf6d993f707a0b8b604ad5e1 100644 --- a/drivers/infiniband/hw/nes/nes.c +++ b/drivers/infiniband/hw/nes/nes.c @@ -567,12 +567,12 @@ static int __devinit nes_probe(struct pci_dev *pcidev, const struct pci_device_i /* Init the adapter */ nesdev->nesadapter = nes_init_adapter(nesdev, hw_rev); - nesdev->nesadapter->et_rx_coalesce_usecs_irq = interrupt_mod_interval; if (!nesdev->nesadapter) { printk(KERN_ERR PFX "Unable to initialize adapter.\n"); ret = -ENOMEM; goto bail5; } + nesdev->nesadapter->et_rx_coalesce_usecs_irq = interrupt_mod_interval; /* nesdev->base_doorbell_index = nesdev->nesadapter->pd_config_base[PCI_FUNC(nesdev->pcidev->devfn)]; */ diff --git a/drivers/infiniband/hw/nes/nes.h b/drivers/infiniband/hw/nes/nes.h index fd57e8a1582f210383044ab7748eabbccdcf662d..a48b288618ece5d569644915455e51251e4d5e97 100644 --- a/drivers/infiniband/hw/nes/nes.h +++ b/drivers/infiniband/hw/nes/nes.h @@ -285,6 +285,21 @@ struct nes_device { }; +static inline __le32 get_crc_value(struct nes_v4_quad *nes_quad) +{ + u32 crc_value; + crc_value = crc32c(~0, (void *)nes_quad, sizeof (struct nes_v4_quad)); + + /* + * With commit ef19454b ("[LIB] crc32c: Keep intermediate crc + * state in cpu order"), behavior of crc32c changes on + * big-endian platforms. Our algorithm expects the previous + * behavior; otherwise we have RDMA connection establishment + * issue on big-endian. + */ + return cpu_to_le32(crc_value); +} + static inline void set_wqe_64bit_value(__le32 *wqe_words, u32 index, u64 value) { diff --git a/drivers/infiniband/hw/nes/nes_cm.c b/drivers/infiniband/hw/nes/nes_cm.c index bd5cfeaac203df2da0f09ea63ff2fc5e5c9b0c0f..39adb267fb1553fb45d96104b361eb6442ba8658 100644 --- a/drivers/infiniband/hw/nes/nes_cm.c +++ b/drivers/infiniband/hw/nes/nes_cm.c @@ -370,11 +370,11 @@ int schedule_nes_timer(struct nes_cm_node *cm_node, struct sk_buff *skb, int ret = 0; u32 was_timer_set; + if (!cm_node) + return -EINVAL; new_send = kzalloc(sizeof(*new_send), GFP_ATOMIC); if (!new_send) return -1; - if (!cm_node) - return -EINVAL; /* new_send->timetosend = currenttime */ new_send->retrycount = NES_DEFAULT_RETRYS; @@ -947,6 +947,7 @@ static int mini_cm_dec_refcnt_listen(struct nes_cm_core *cm_core, nes_debug(NES_DBG_CM, "destroying listener (%p)\n", listener); kfree(listener); + listener = NULL; ret = 0; cm_listens_destroyed++; } else { @@ -2319,6 +2320,7 @@ int nes_accept(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param) struct iw_cm_event cm_event; struct nes_hw_qp_wqe *wqe; struct nes_v4_quad nes_quad; + u32 crc_value; int ret; ibqp = nes_get_qp(cm_id->device, conn_param->qpn); @@ -2435,8 +2437,8 @@ int nes_accept(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param) nes_quad.TcpPorts[1] = cm_id->local_addr.sin_port; /* Produce hash key */ - nesqp->hte_index = cpu_to_be32( - crc32c(~0, (void *)&nes_quad, sizeof(nes_quad)) ^ 0xffffffff); + crc_value = get_crc_value(&nes_quad); + nesqp->hte_index = cpu_to_be32(crc_value ^ 0xffffffff); nes_debug(NES_DBG_CM, "HTE Index = 0x%08X, CRC = 0x%08X\n", nesqp->hte_index, nesqp->hte_index & adapter->hte_index_mask); @@ -2750,6 +2752,7 @@ void cm_event_connected(struct nes_cm_event *event) struct iw_cm_event cm_event; struct nes_hw_qp_wqe *wqe; struct nes_v4_quad nes_quad; + u32 crc_value; int ret; /* get all our handles */ @@ -2827,8 +2830,8 @@ void cm_event_connected(struct nes_cm_event *event) nes_quad.TcpPorts[1] = cm_id->local_addr.sin_port; /* Produce hash key */ - nesqp->hte_index = cpu_to_be32( - crc32c(~0, (void *)&nes_quad, sizeof(nes_quad)) ^ 0xffffffff); + crc_value = get_crc_value(&nes_quad); + nesqp->hte_index = cpu_to_be32(crc_value ^ 0xffffffff); nes_debug(NES_DBG_CM, "HTE Index = 0x%08X, After CRC = 0x%08X\n", nesqp->hte_index, nesqp->hte_index & nesadapter->hte_index_mask); diff --git a/drivers/infiniband/hw/nes/nes_hw.c b/drivers/infiniband/hw/nes/nes_hw.c index 7c4c0fbf0abd3ff9322a07888afe5cb00d4c34d2..49e53e4c1ebef475bf5337bb346472c98a8ec72f 100644 --- a/drivers/infiniband/hw/nes/nes_hw.c +++ b/drivers/infiniband/hw/nes/nes_hw.c @@ -156,15 +156,14 @@ static void nes_nic_tune_timer(struct nes_device *nesdev) spin_lock_irqsave(&nesadapter->periodic_timer_lock, flags); - if (shared_timer->cq_count_old < cq_count) { - if (cq_count > shared_timer->threshold_low) - shared_timer->cq_direction_downward=0; - } - if (shared_timer->cq_count_old >= cq_count) + if (shared_timer->cq_count_old <= cq_count) + shared_timer->cq_direction_downward = 0; + else shared_timer->cq_direction_downward++; shared_timer->cq_count_old = cq_count; if (shared_timer->cq_direction_downward > NES_NIC_CQ_DOWNWARD_TREND) { - if (cq_count <= shared_timer->threshold_low) { + if (cq_count <= shared_timer->threshold_low && + shared_timer->threshold_low > 4) { shared_timer->threshold_low = shared_timer->threshold_low/2; shared_timer->cq_direction_downward=0; nesdev->currcq_count = 0; @@ -1728,7 +1727,6 @@ int nes_napi_isr(struct nes_device *nesdev) nesdev->int_req &= ~NES_INT_TIMER; nes_write32(nesdev->regs+NES_INTF_INT_MASK, ~(nesdev->intf_int_req)); nes_write32(nesdev->regs+NES_INT_MASK, ~nesdev->int_req); - nesadapter->tune_timer.timer_in_use_old = 0; } nesdev->deepcq_count = 0; return 1; @@ -1867,7 +1865,6 @@ void nes_dpc(unsigned long param) nesdev->int_req &= ~NES_INT_TIMER; nes_write32(nesdev->regs + NES_INTF_INT_MASK, ~(nesdev->intf_int_req)); nes_write32(nesdev->regs+NES_INT_MASK, ~nesdev->int_req); - nesdev->nesadapter->tune_timer.timer_in_use_old = 0; } else { nes_write32(nesdev->regs+NES_INT_MASK, 0x0000ffff|(~nesdev->int_req)); } diff --git a/drivers/infiniband/hw/nes/nes_hw.h b/drivers/infiniband/hw/nes/nes_hw.h index 1e10df550c9ea49e3a2f04414a61bbb941f97ac2..b7e2844f096b620489c0b338e65e400937c16c4a 100644 --- a/drivers/infiniband/hw/nes/nes_hw.h +++ b/drivers/infiniband/hw/nes/nes_hw.h @@ -962,7 +962,7 @@ struct nes_arp_entry { #define DEFAULT_JUMBO_NES_QL_LOW 12 #define DEFAULT_JUMBO_NES_QL_TARGET 40 #define DEFAULT_JUMBO_NES_QL_HIGH 128 -#define NES_NIC_CQ_DOWNWARD_TREND 8 +#define NES_NIC_CQ_DOWNWARD_TREND 16 struct nes_hw_tune_timer { //u16 cq_count; diff --git a/drivers/infiniband/hw/nes/nes_verbs.c b/drivers/infiniband/hw/nes/nes_verbs.c index 4dafbe16e82a8366aed841269c3d54535c091cfc..a651e9d9f0efdba6e38612b738f9455ccf2a1bcf 100644 --- a/drivers/infiniband/hw/nes/nes_verbs.c +++ b/drivers/infiniband/hw/nes/nes_verbs.c @@ -929,7 +929,7 @@ static struct ib_pd *nes_alloc_pd(struct ib_device *ibdev, NES_MAX_USER_DB_REGIONS, nesucontext->first_free_db); nes_debug(NES_DBG_PD, "find_first_zero_biton doorbells returned %u, mapping pd_id %u.\n", nespd->mmap_db_index, nespd->pd_id); - if (nespd->mmap_db_index > NES_MAX_USER_DB_REGIONS) { + if (nespd->mmap_db_index >= NES_MAX_USER_DB_REGIONS) { nes_debug(NES_DBG_PD, "mmap_db_index > MAX\n"); nes_free_resource(nesadapter, nesadapter->allocated_pds, pd_num); kfree(nespd); @@ -1327,7 +1327,7 @@ static struct ib_qp *nes_create_qp(struct ib_pd *ibpd, (long long unsigned int)req.user_wqe_buffers); nes_free_resource(nesadapter, nesadapter->allocated_qps, qp_num); kfree(nesqp->allocated_buffer); - return ERR_PTR(-ENOMEM); + return ERR_PTR(-EFAULT); } } @@ -1674,6 +1674,7 @@ static struct ib_cq *nes_create_cq(struct ib_device *ibdev, int entries, } nes_debug(NES_DBG_CQ, "CQ Virtual Address = %08lX, size = %u.\n", (unsigned long)req.user_cq_buffer, entries); + err = 1; list_for_each_entry(nespbl, &nes_ucontext->cq_reg_mem_list, list) { if (nespbl->user_base == (unsigned long )req.user_cq_buffer) { list_del(&nespbl->list); @@ -1686,7 +1687,7 @@ static struct ib_cq *nes_create_cq(struct ib_device *ibdev, int entries, if (err) { nes_free_resource(nesadapter, nesadapter->allocated_cqs, cq_num); kfree(nescq); - return ERR_PTR(err); + return ERR_PTR(-EFAULT); } pbl_entries = nespbl->pbl_size >> 3; @@ -1831,9 +1832,6 @@ static struct ib_cq *nes_create_cq(struct ib_device *ibdev, int entries, spin_unlock_irqrestore(&nesdev->cqp.lock, flags); } } - nes_debug(NES_DBG_CQ, "iWARP CQ%u create timeout expired, major code = 0x%04X," - " minor code = 0x%04X\n", - nescq->hw_cq.cq_number, cqp_request->major_code, cqp_request->minor_code); if (!context) pci_free_consistent(nesdev->pcidev, nescq->cq_mem_size, mem, nescq->hw_cq.cq_pbase); diff --git a/drivers/infiniband/ulp/ipoib/ipoib_cm.c b/drivers/infiniband/ulp/ipoib/ipoib_cm.c index 52b1bebfa74482dc2586667e6c35c68f4b5e5c04..2490b2d79dbb739713422c07fc4457700500928b 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_cm.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_cm.c @@ -38,6 +38,7 @@ #include #include #include +#include #include "ipoib.h" @@ -637,6 +638,7 @@ static inline int post_send(struct ipoib_dev_priv *priv, priv->tx_sge[0].addr = addr; priv->tx_sge[0].length = len; + priv->tx_wr.num_sge = 1; priv->tx_wr.wr_id = wr_id | IPOIB_OP_CM; return ib_post_send(tx->qp, &priv->tx_wr, &bad_wr); @@ -1030,13 +1032,13 @@ static int ipoib_cm_tx_init(struct ipoib_cm_tx *p, u32 qpn, struct ipoib_dev_priv *priv = netdev_priv(p->dev); int ret; - p->tx_ring = kzalloc(ipoib_sendq_size * sizeof *p->tx_ring, - GFP_KERNEL); + p->tx_ring = vmalloc(ipoib_sendq_size * sizeof *p->tx_ring); if (!p->tx_ring) { ipoib_warn(priv, "failed to allocate tx ring\n"); ret = -ENOMEM; goto err_tx; } + memset(p->tx_ring, 0, ipoib_sendq_size * sizeof *p->tx_ring); p->qp = ipoib_cm_create_tx_qp(p->dev, p); if (IS_ERR(p->qp)) { @@ -1077,6 +1079,7 @@ err_id: ib_destroy_qp(p->qp); err_qp: p->qp = NULL; + vfree(p->tx_ring); err_tx: return ret; } @@ -1127,7 +1130,7 @@ timeout: if (p->qp) ib_destroy_qp(p->qp); - kfree(p->tx_ring); + vfree(p->tx_ring); kfree(p); } diff --git a/drivers/infiniband/ulp/ipoib/ipoib_main.c b/drivers/infiniband/ulp/ipoib/ipoib_main.c index f96477a8ca5ac96121ae618d24153870e23f4a48..57282048865c1c66c9df6a061fefb3cfba07defb 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_main.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_main.c @@ -41,6 +41,7 @@ #include #include #include +#include #include /* For ARPHRD_xxx */ @@ -887,13 +888,13 @@ int ipoib_dev_init(struct net_device *dev, struct ib_device *ca, int port) goto out; } - priv->tx_ring = kzalloc(ipoib_sendq_size * sizeof *priv->tx_ring, - GFP_KERNEL); + priv->tx_ring = vmalloc(ipoib_sendq_size * sizeof *priv->tx_ring); if (!priv->tx_ring) { printk(KERN_WARNING "%s: failed to allocate TX ring (%d entries)\n", ca->name, ipoib_sendq_size); goto out_rx_ring_cleanup; } + memset(priv->tx_ring, 0, ipoib_sendq_size * sizeof *priv->tx_ring); /* priv->tx_head, tx_tail & tx_outstanding are already 0 */ @@ -903,7 +904,7 @@ int ipoib_dev_init(struct net_device *dev, struct ib_device *ca, int port) return 0; out_tx_ring_cleanup: - kfree(priv->tx_ring); + vfree(priv->tx_ring); out_rx_ring_cleanup: kfree(priv->rx_ring); @@ -928,7 +929,7 @@ void ipoib_dev_cleanup(struct net_device *dev) ipoib_ib_dev_cleanup(dev); kfree(priv->rx_ring); - kfree(priv->tx_ring); + vfree(priv->tx_ring); priv->rx_ring = NULL; priv->tx_ring = NULL; diff --git a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c index 2628339e3a9973b01402250f8e6bf73be5d37c04..31a53c5bcb1317cd52dc2be80dd3f43238184d6e 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c @@ -650,7 +650,7 @@ void ipoib_mcast_send(struct net_device *dev, void *mgid, struct sk_buff *skb) */ spin_lock(&priv->lock); - if (!test_bit(IPOIB_MCAST_STARTED, &priv->flags) || + if (!test_bit(IPOIB_FLAG_OPER_UP, &priv->flags) || !priv->broadcast || !test_bit(IPOIB_MCAST_FLAG_ATTACHED, &priv->broadcast->flags)) { ++dev->stats.tx_dropped; diff --git a/drivers/infiniband/ulp/iser/iser_verbs.c b/drivers/infiniband/ulp/iser/iser_verbs.c index 714b8db02b297b48c37abd37f1fc13891c2cbcaa..993f0a8ff28f838105fdf7298999e6fcb1404b92 100644 --- a/drivers/infiniband/ulp/iser/iser_verbs.c +++ b/drivers/infiniband/ulp/iser/iser_verbs.c @@ -237,36 +237,32 @@ static int iser_free_ib_conn_res(struct iser_conn *ib_conn) static struct iser_device *iser_device_find_by_ib_device(struct rdma_cm_id *cma_id) { - struct list_head *p_list; - struct iser_device *device = NULL; + struct iser_device *device; mutex_lock(&ig.device_list_mutex); - p_list = ig.device_list.next; - while (p_list != &ig.device_list) { - device = list_entry(p_list, struct iser_device, ig_list); + list_for_each_entry(device, &ig.device_list, ig_list) /* find if there's a match using the node GUID */ if (device->ib_device->node_guid == cma_id->device->node_guid) - break; - } + goto inc_refcnt; - if (device == NULL) { - device = kzalloc(sizeof *device, GFP_KERNEL); - if (device == NULL) - goto out; - /* assign this device to the device */ - device->ib_device = cma_id->device; - /* init the device and link it into ig device list */ - if (iser_create_device_ib_res(device)) { - kfree(device); - device = NULL; - goto out; - } - list_add(&device->ig_list, &ig.device_list); + device = kzalloc(sizeof *device, GFP_KERNEL); + if (device == NULL) + goto out; + + /* assign this device to the device */ + device->ib_device = cma_id->device; + /* init the device and link it into ig device list */ + if (iser_create_device_ib_res(device)) { + kfree(device); + device = NULL; + goto out; } -out: - BUG_ON(device == NULL); + list_add(&device->ig_list, &ig.device_list); + +inc_refcnt: device->refcount++; +out: mutex_unlock(&ig.device_list_mutex); return device; } @@ -372,6 +368,12 @@ static void iser_addr_handler(struct rdma_cm_id *cma_id) int ret; device = iser_device_find_by_ib_device(cma_id); + if (!device) { + iser_err("device lookup/creation failed\n"); + iser_connect_error(cma_id); + return; + } + ib_conn = (struct iser_conn *)cma_id->context; ib_conn->device = device; @@ -380,7 +382,6 @@ static void iser_addr_handler(struct rdma_cm_id *cma_id) iser_err("resolve route failed: %d\n", ret); iser_connect_error(cma_id); } - return; } static void iser_route_handler(struct rdma_cm_id *cma_id) diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig index 8b10d9f23bef29c7fd3acb8c3cd56566447ee96f..c5263d63aca3a2cc56914f7651f44d56bf8c8a32 100644 --- a/drivers/input/misc/Kconfig +++ b/drivers/input/misc/Kconfig @@ -42,14 +42,14 @@ config INPUT_M68K_BEEP config INPUT_APANEL tristate "Fujitsu Lifebook Application Panel buttons" - depends on X86 - select I2C_I801 + depends on X86 && I2C && LEDS_CLASS select INPUT_POLLDEV select CHECK_SIGNATURE help Say Y here for support of the Application Panel buttons, used on Fujitsu Lifebook. These are attached to the mainboard through - an SMBus interface managed by the I2C Intel ICH (i801) driver. + an SMBus interface managed by the I2C Intel ICH (i801) driver, + which you should also build for this kernel. To compile this driver as a module, choose M here: the module will be called apanel. diff --git a/drivers/input/serio/i8042.h b/drivers/input/serio/i8042.h index dd22d91f8b39bd1c16abf0a755096fb7af44147f..c972e5d03a3fa6ce2a1e42c13333fb7cb02cf4ab 100644 --- a/drivers/input/serio/i8042.h +++ b/drivers/input/serio/i8042.h @@ -16,7 +16,7 @@ #if defined(CONFIG_MACH_JAZZ) #include "i8042-jazzio.h" -#elif defined(CONFIG_SGI_IP22) +#elif defined(CONFIG_SGI_HAS_I8042) #include "i8042-ip22io.h" #elif defined(CONFIG_PPC) #include "i8042-ppcio.h" diff --git a/drivers/isdn/gigaset/common.c b/drivers/isdn/gigaset/common.c index aacedec4986fc7e98cc9f827b935274acc645a41..827c32c167951aa3235477992697909ccd770944 100644 --- a/drivers/isdn/gigaset/common.c +++ b/drivers/isdn/gigaset/common.c @@ -637,7 +637,6 @@ struct cardstate *gigaset_initcs(struct gigaset_driver *drv, int channels, err("maximum number of devices exceeded"); return NULL; } - mutex_init(&cs->mutex); gig_dbg(DEBUG_INIT, "allocating bcs[0..%d]", channels - 1); cs->bcs = kmalloc(channels * sizeof(struct bc_state), GFP_KERNEL); @@ -898,8 +897,10 @@ int gigaset_shutdown(struct cardstate *cs) { mutex_lock(&cs->mutex); - if (!(cs->flags & VALID_MINOR)) + if (!(cs->flags & VALID_MINOR)) { + mutex_unlock(&cs->mutex); return -1; + } cs->waiting = 1; @@ -1086,6 +1087,7 @@ struct gigaset_driver *gigaset_initdriver(unsigned minor, unsigned minors, drv->cs[i].driver = drv; drv->cs[i].ops = drv->ops; drv->cs[i].minor_index = i; + mutex_init(&drv->cs[i].mutex); } gigaset_if_initdriver(drv, procname, devname); diff --git a/drivers/isdn/hisax/hisax_fcpcipnp.c b/drivers/isdn/hisax/hisax_fcpcipnp.c index 7993e01f9fc5cd08e22e0caac469e7208b2e3930..76043dedba5b442bc0e66e70a59bb1772a63400d 100644 --- a/drivers/isdn/hisax/hisax_fcpcipnp.c +++ b/drivers/isdn/hisax/hisax_fcpcipnp.c @@ -723,23 +723,6 @@ static int __devinit fcpcipnp_setup(struct fritz_adapter *adapter) if (!request_region(adapter->io, 32, "fcpcipnp")) goto err; - switch (adapter->type) { - case AVM_FRITZ_PCIV2: - retval = request_irq(adapter->irq, fcpci2_irq, IRQF_SHARED, - "fcpcipnp", adapter); - break; - case AVM_FRITZ_PCI: - retval = request_irq(adapter->irq, fcpci_irq, IRQF_SHARED, - "fcpcipnp", adapter); - break; - case AVM_FRITZ_PNP: - retval = request_irq(adapter->irq, fcpci_irq, 0, - "fcpcipnp", adapter); - break; - } - if (retval) - goto err_region; - switch (adapter->type) { case AVM_FRITZ_PCIV2: case AVM_FRITZ_PCI: @@ -794,6 +777,23 @@ static int __devinit fcpcipnp_setup(struct fritz_adapter *adapter) outb(0, adapter->io + AVM_STATUS0); mdelay(10); + switch (adapter->type) { + case AVM_FRITZ_PCIV2: + retval = request_irq(adapter->irq, fcpci2_irq, IRQF_SHARED, + "fcpcipnp", adapter); + break; + case AVM_FRITZ_PCI: + retval = request_irq(adapter->irq, fcpci_irq, IRQF_SHARED, + "fcpcipnp", adapter); + break; + case AVM_FRITZ_PNP: + retval = request_irq(adapter->irq, fcpci_irq, 0, + "fcpcipnp", adapter); + break; + } + if (retval) + goto err_region; + switch (adapter->type) { case AVM_FRITZ_PCIV2: fcpci2_init(adapter); diff --git a/drivers/isdn/i4l/isdn_common.c b/drivers/isdn/i4l/isdn_common.c index 9cef6fcf587b6baaef9df48c3616779262d6d3a9..d4ad6992f776c895d637b72c779b04fd5dd7915e 100644 --- a/drivers/isdn/i4l/isdn_common.c +++ b/drivers/isdn/i4l/isdn_common.c @@ -981,13 +981,13 @@ isdn_readbchan_tty(int di, int channel, struct tty_struct *tty, int cisco_hack) } -static __inline int +static inline int isdn_minor2drv(int minor) { return (dev->drvmap[minor]); } -static __inline int +static inline int isdn_minor2chan(int minor) { return (dev->chanmap[minor]); diff --git a/drivers/isdn/i4l/isdn_ttyfax.c b/drivers/isdn/i4l/isdn_ttyfax.c index f93de4a303550afa4ea48b3ca6af7f7e4568a446..78f7660c1d0ea9c66153cfc1a1c1af9515d95580 100644 --- a/drivers/isdn/i4l/isdn_ttyfax.c +++ b/drivers/isdn/i4l/isdn_ttyfax.c @@ -906,7 +906,8 @@ isdn_tty_cmd_FCLASS2(char **p, modem_info * info) sprintf(rs, "\r\n0-2"); isdn_tty_at_cout(rs, info); } else { - if ((f->phase != ISDN_FAX_PHASE_D) || (!info->faxonline & 1)) + if ((f->phase != ISDN_FAX_PHASE_D) || + (!(info->faxonline & 1))) PARSE_ERROR1; par = isdn_getnum(p); if ((par < 0) || (par > 2)) diff --git a/drivers/isdn/i4l/isdn_v110.c b/drivers/isdn/i4l/isdn_v110.c index 5484d3c38a5761b76ab888d146cab65719add51b..c5d02b6aafabb614ed731ff9318b9e7281ec93a2 100644 --- a/drivers/isdn/i4l/isdn_v110.c +++ b/drivers/isdn/i4l/isdn_v110.c @@ -62,7 +62,7 @@ static unsigned char V110_OffMatrix_38400[] = * and to 67452301 when keylen = 2. This is necessary because ordering on * the isdn line is the other way. */ -static __inline unsigned char +static inline unsigned char FlipBits(unsigned char c, int keylen) { unsigned char b = c; diff --git a/drivers/isdn/isdnloop/isdnloop.c b/drivers/isdn/isdnloop/isdnloop.c index 655ef9a3f4df2a023d319967e9aa99dda93e4dc8..a335c85a736e25a472c3d66157ef40a0313304da 100644 --- a/drivers/isdn/isdnloop/isdnloop.c +++ b/drivers/isdn/isdnloop/isdnloop.c @@ -1289,7 +1289,7 @@ isdnloop_command(isdn_ctrl * c, isdnloop_card * card) } break; case ISDN_CMD_CLREAZ: - if (!card->flags & ISDNLOOP_FLAGS_RUNNING) + if (!(card->flags & ISDNLOOP_FLAGS_RUNNING)) return -ENODEV; if (card->leased) break; @@ -1333,7 +1333,7 @@ isdnloop_command(isdn_ctrl * c, isdnloop_card * card) } break; case ISDN_CMD_SETL3: - if (!card->flags & ISDNLOOP_FLAGS_RUNNING) + if (!(card->flags & ISDNLOOP_FLAGS_RUNNING)) return -ENODEV; return 0; default: @@ -1380,7 +1380,7 @@ if_writecmd(const u_char __user *buf, int len, int id, int channel) isdnloop_card *card = isdnloop_findcard(id); if (card) { - if (!card->flags & ISDNLOOP_FLAGS_RUNNING) + if (!(card->flags & ISDNLOOP_FLAGS_RUNNING)) return -ENODEV; return (isdnloop_writecmd(buf, len, 1, card)); } diff --git a/drivers/lguest/core.c b/drivers/lguest/core.c index 7743d73768df273c008b700f8165ec5dafd668ec..c632c08cbbdc949793f322b75186aa77beddf1a4 100644 --- a/drivers/lguest/core.c +++ b/drivers/lguest/core.c @@ -69,11 +69,22 @@ static __init int map_switcher(void) switcher_page[i] = virt_to_page(addr); } + /* First we check that the Switcher won't overlap the fixmap area at + * the top of memory. It's currently nowhere near, but it could have + * very strange effects if it ever happened. */ + if (SWITCHER_ADDR + (TOTAL_SWITCHER_PAGES+1)*PAGE_SIZE > FIXADDR_START){ + err = -ENOMEM; + printk("lguest: mapping switcher would thwack fixmap\n"); + goto free_pages; + } + /* Now we reserve the "virtual memory area" we want: 0xFFC00000 * (SWITCHER_ADDR). We might not get it in theory, but in practice - * it's worked so far. */ + * it's worked so far. The end address needs +1 because __get_vm_area + * allocates an extra guard page, so we need space for that. */ switcher_vma = __get_vm_area(TOTAL_SWITCHER_PAGES * PAGE_SIZE, - VM_ALLOC, SWITCHER_ADDR, VMALLOC_END); + VM_ALLOC, SWITCHER_ADDR, SWITCHER_ADDR + + (TOTAL_SWITCHER_PAGES+1) * PAGE_SIZE); if (!switcher_vma) { err = -ENOMEM; printk("lguest: could not map switcher pages high\n"); diff --git a/drivers/lguest/lguest_user.c b/drivers/lguest/lguest_user.c index 85d42d3d01a9a9bbeb739ce422271848cd4be3ff..2221485b07739a48114f44dc38b4f4249a93360c 100644 --- a/drivers/lguest/lguest_user.c +++ b/drivers/lguest/lguest_user.c @@ -241,15 +241,16 @@ static ssize_t write(struct file *file, const char __user *in, cpu = &lg->cpus[cpu_id]; if (!cpu) return -EINVAL; - } - /* Once the Guest is dead, all you can do is read() why it died. */ - if (lg && lg->dead) - return -ENOENT; + /* Once the Guest is dead, you can only read() why it died. */ + if (lg->dead) + return -ENOENT; - /* If you're not the task which owns the Guest, you can only break */ - if (lg && current != cpu->tsk && req != LHREQ_BREAK) - return -EPERM; + /* If you're not the task which owns the Guest, all you can do + * is break the Launcher out of running the Guest. */ + if (current != cpu->tsk && req != LHREQ_BREAK) + return -EPERM; + } switch (req) { case LHREQ_INITIALIZE: diff --git a/drivers/lguest/page_tables.c b/drivers/lguest/page_tables.c index 275f23c2deb49ff302e836abfb4eb14e26395a06..a7f64a9d67e009437b30e5007a208c25863be392 100644 --- a/drivers/lguest/page_tables.c +++ b/drivers/lguest/page_tables.c @@ -391,7 +391,7 @@ static unsigned int find_pgdir(struct lguest *lg, unsigned long pgtable) { unsigned int i; for (i = 0; i < ARRAY_SIZE(lg->pgdirs); i++) - if (lg->pgdirs[i].gpgdir == pgtable) + if (lg->pgdirs[i].pgdir && lg->pgdirs[i].gpgdir == pgtable) break; return i; } diff --git a/drivers/macintosh/via-pmu-backlight.c b/drivers/macintosh/via-pmu-backlight.c index 741a2e3f4fc6e34ce237beed4d1bebea7b0565b0..a348bb0791d37b764a2e61ffe55bacd57a12e182 100644 --- a/drivers/macintosh/via-pmu-backlight.c +++ b/drivers/macintosh/via-pmu-backlight.c @@ -17,7 +17,7 @@ static struct backlight_ops pmu_backlight_data; static DEFINE_SPINLOCK(pmu_backlight_lock); -static int sleeping; +static int sleeping, uses_pmu_bl; static u8 bl_curve[FB_BACKLIGHT_LEVELS]; static void pmu_backlight_init_curve(u8 off, u8 min, u8 max) @@ -128,7 +128,7 @@ void pmu_backlight_set_sleep(int sleep) spin_lock_irqsave(&pmu_backlight_lock, flags); sleeping = sleep; - if (pmac_backlight) { + if (pmac_backlight && uses_pmu_bl) { if (sleep) { struct adb_request req; @@ -166,6 +166,7 @@ void __init pmu_backlight_init() printk(KERN_ERR "PMU Backlight registration failed\n"); return; } + uses_pmu_bl = 1; bd->props.max_brightness = FB_BACKLIGHT_LEVELS - 1; pmu_backlight_init_curve(0x7F, 0x46, 0x0E); diff --git a/drivers/macintosh/via-pmu.c b/drivers/macintosh/via-pmu.c index ebec663d5d3708d74a8197ddfe16e7e761e71c87..d6365a9f0637407f020b901423dd1d06d851edeb 100644 --- a/drivers/macintosh/via-pmu.c +++ b/drivers/macintosh/via-pmu.c @@ -2528,7 +2528,7 @@ EXPORT_SYMBOL(pmu_wait_complete); EXPORT_SYMBOL(pmu_suspend); EXPORT_SYMBOL(pmu_resume); EXPORT_SYMBOL(pmu_unlock); -#if defined(CONFIG_SUSPEND) && defined(CONFIG_PPC32) +#if defined(CONFIG_PPC32) EXPORT_SYMBOL(pmu_enable_irled); EXPORT_SYMBOL(pmu_battery_count); EXPORT_SYMBOL(pmu_batteries); diff --git a/drivers/md/bitmap.c b/drivers/md/bitmap.c index 7aeceedcf7d46de93824a14ce9b93888350930dd..c14dacdacfac530c61370b14de5686d6b51c02a3 100644 --- a/drivers/md/bitmap.c +++ b/drivers/md/bitmap.c @@ -1045,8 +1045,14 @@ void bitmap_daemon_work(struct bitmap *bitmap) if (bitmap == NULL) return; if (time_before(jiffies, bitmap->daemon_lastrun + bitmap->daemon_sleep*HZ)) - return; + goto done; + bitmap->daemon_lastrun = jiffies; + if (bitmap->allclean) { + bitmap->mddev->thread->timeout = MAX_SCHEDULE_TIMEOUT; + return; + } + bitmap->allclean = 1; for (j = 0; j < bitmap->chunks; j++) { bitmap_counter_t *bmc; @@ -1068,8 +1074,10 @@ void bitmap_daemon_work(struct bitmap *bitmap) clear_page_attr(bitmap, page, BITMAP_PAGE_NEEDWRITE); spin_unlock_irqrestore(&bitmap->lock, flags); - if (need_write) + if (need_write) { write_page(bitmap, page, 0); + bitmap->allclean = 0; + } continue; } @@ -1098,6 +1106,9 @@ void bitmap_daemon_work(struct bitmap *bitmap) /* if (j < 100) printk("bitmap: j=%lu, *bmc = 0x%x\n", j, *bmc); */ + if (*bmc) + bitmap->allclean = 0; + if (*bmc == 2) { *bmc=1; /* maybe clear the bit next time */ set_page_attr(bitmap, page, BITMAP_PAGE_CLEAN); @@ -1132,6 +1143,9 @@ void bitmap_daemon_work(struct bitmap *bitmap) } } + done: + if (bitmap->allclean == 0) + bitmap->mddev->thread->timeout = bitmap->daemon_sleep * HZ; } static bitmap_counter_t *bitmap_get_counter(struct bitmap *bitmap, @@ -1226,6 +1240,7 @@ int bitmap_startwrite(struct bitmap *bitmap, sector_t offset, unsigned long sect sectors -= blocks; else sectors = 0; } + bitmap->allclean = 0; return 0; } @@ -1296,6 +1311,7 @@ int bitmap_start_sync(struct bitmap *bitmap, sector_t offset, int *blocks, } } spin_unlock_irq(&bitmap->lock); + bitmap->allclean = 0; return rv; } @@ -1332,6 +1348,7 @@ void bitmap_end_sync(struct bitmap *bitmap, sector_t offset, int *blocks, int ab } unlock: spin_unlock_irqrestore(&bitmap->lock, flags); + bitmap->allclean = 0; } void bitmap_close_sync(struct bitmap *bitmap) @@ -1399,7 +1416,7 @@ static void bitmap_set_memory_bits(struct bitmap *bitmap, sector_t offset, int n set_page_attr(bitmap, page, BITMAP_PAGE_CLEAN); } spin_unlock_irq(&bitmap->lock); - + bitmap->allclean = 0; } /* dirty the memory and file bits for bitmap chunks "s" to "e" */ diff --git a/drivers/md/md.c b/drivers/md/md.c index 7da6ec244e15de75184478818b553a66ec59454f..ccbbf63727cc03fe06fb26bf03debcd9f8e97b6f 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -1105,7 +1105,11 @@ static int super_1_load(mdk_rdev_t *rdev, mdk_rdev_t *refdev, int minor_version) rdev->sb_size = le32_to_cpu(sb->max_dev) * 2 + 256; bmask = queue_hardsect_size(rdev->bdev->bd_disk->queue)-1; if (rdev->sb_size & bmask) - rdev-> sb_size = (rdev->sb_size | bmask)+1; + rdev->sb_size = (rdev->sb_size | bmask) + 1; + + if (minor_version + && rdev->data_offset < sb_offset + (rdev->sb_size/512)) + return -EINVAL; if (sb->level == cpu_to_le32(LEVEL_MULTIPATH)) rdev->desc_nr = -1; @@ -1137,7 +1141,7 @@ static int super_1_load(mdk_rdev_t *rdev, mdk_rdev_t *refdev, int minor_version) else ret = 0; } - if (minor_version) + if (minor_version) rdev->size = ((rdev->bdev->bd_inode->i_size>>9) - le64_to_cpu(sb->data_offset)) / 2; else rdev->size = rdev->sb_offset; @@ -1499,7 +1503,8 @@ static void export_rdev(mdk_rdev_t * rdev) free_disk_sb(rdev); list_del_init(&rdev->same_set); #ifndef MODULE - md_autodetect_dev(rdev->bdev->bd_dev); + if (test_bit(AutoDetected, &rdev->flags)) + md_autodetect_dev(rdev->bdev->bd_dev); #endif unlock_rdev(rdev); kobject_put(&rdev->kobj); @@ -1996,9 +2001,11 @@ rdev_size_store(mdk_rdev_t *rdev, const char *buf, size_t len) char *e; unsigned long long size = simple_strtoull(buf, &e, 10); unsigned long long oldsize = rdev->size; + mddev_t *my_mddev = rdev->mddev; + if (e==buf || (*e && *e != '\n')) return -EINVAL; - if (rdev->mddev->pers) + if (my_mddev->pers) return -EBUSY; rdev->size = size; if (size > oldsize && rdev->mddev->external) { @@ -2011,7 +2018,7 @@ rdev_size_store(mdk_rdev_t *rdev, const char *buf, size_t len) int overlap = 0; struct list_head *tmp, *tmp2; - mddev_unlock(rdev->mddev); + mddev_unlock(my_mddev); for_each_mddev(mddev, tmp) { mdk_rdev_t *rdev2; @@ -2031,7 +2038,7 @@ rdev_size_store(mdk_rdev_t *rdev, const char *buf, size_t len) break; } } - mddev_lock(rdev->mddev); + mddev_lock(my_mddev); if (overlap) { /* Someone else could have slipped in a size * change here, but doing so is just silly. @@ -2043,8 +2050,8 @@ rdev_size_store(mdk_rdev_t *rdev, const char *buf, size_t len) return -EBUSY; } } - if (size < rdev->mddev->size || rdev->mddev->size == 0) - rdev->mddev->size = size; + if (size < my_mddev->size || my_mddev->size == 0) + my_mddev->size = size; return len; } @@ -2065,10 +2072,21 @@ rdev_attr_show(struct kobject *kobj, struct attribute *attr, char *page) { struct rdev_sysfs_entry *entry = container_of(attr, struct rdev_sysfs_entry, attr); mdk_rdev_t *rdev = container_of(kobj, mdk_rdev_t, kobj); + mddev_t *mddev = rdev->mddev; + ssize_t rv; if (!entry->show) return -EIO; - return entry->show(rdev, page); + + rv = mddev ? mddev_lock(mddev) : -EBUSY; + if (!rv) { + if (rdev->mddev == NULL) + rv = -EBUSY; + else + rv = entry->show(rdev, page); + mddev_unlock(mddev); + } + return rv; } static ssize_t @@ -2077,15 +2095,19 @@ rdev_attr_store(struct kobject *kobj, struct attribute *attr, { struct rdev_sysfs_entry *entry = container_of(attr, struct rdev_sysfs_entry, attr); mdk_rdev_t *rdev = container_of(kobj, mdk_rdev_t, kobj); - int rv; + ssize_t rv; + mddev_t *mddev = rdev->mddev; if (!entry->store) return -EIO; if (!capable(CAP_SYS_ADMIN)) return -EACCES; - rv = mddev_lock(rdev->mddev); + rv = mddev ? mddev_lock(mddev): -EBUSY; if (!rv) { - rv = entry->store(rdev, page, length); + if (rdev->mddev == NULL) + rv = -EBUSY; + else + rv = entry->store(rdev, page, length); mddev_unlock(rdev->mddev); } return rv; @@ -5127,7 +5149,7 @@ static int md_seq_show(struct seq_file *seq, void *v) if (mddev->ro==1) seq_printf(seq, " (read-only)"); if (mddev->ro==2) - seq_printf(seq, "(auto-read-only)"); + seq_printf(seq, " (auto-read-only)"); seq_printf(seq, " %s", mddev->pers->name); } @@ -5351,6 +5373,7 @@ void md_write_start(mddev_t *mddev, struct bio *bi) mddev->ro = 0; set_bit(MD_RECOVERY_NEEDED, &mddev->recovery); md_wakeup_thread(mddev->thread); + md_wakeup_thread(mddev->sync_thread); } atomic_inc(&mddev->writes_pending); if (mddev->in_sync) { @@ -6021,6 +6044,7 @@ static void autostart_arrays(int part) MD_BUG(); continue; } + set_bit(AutoDetected, &rdev->flags); list_add(&rdev->same_set, &pending_raid_disks); i_passed++; } diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c index 5c7fef091cec800da3f3cb482f7e97f574cb43c6..ff61b309129aa8ffa9dbd00987a71c1b6eb35bf5 100644 --- a/drivers/md/raid1.c +++ b/drivers/md/raid1.c @@ -592,6 +592,37 @@ static int raid1_congested(void *data, int bits) } +static int flush_pending_writes(conf_t *conf) +{ + /* Any writes that have been queued but are awaiting + * bitmap updates get flushed here. + * We return 1 if any requests were actually submitted. + */ + int rv = 0; + + spin_lock_irq(&conf->device_lock); + + if (conf->pending_bio_list.head) { + struct bio *bio; + bio = bio_list_get(&conf->pending_bio_list); + blk_remove_plug(conf->mddev->queue); + spin_unlock_irq(&conf->device_lock); + /* flush any pending bitmap writes to + * disk before proceeding w/ I/O */ + bitmap_unplug(conf->mddev->bitmap); + + while (bio) { /* submit pending writes */ + struct bio *next = bio->bi_next; + bio->bi_next = NULL; + generic_make_request(bio); + bio = next; + } + rv = 1; + } else + spin_unlock_irq(&conf->device_lock); + return rv; +} + /* Barriers.... * Sometimes we need to suspend IO while we do something else, * either some resync/recovery, or reconfigure the array. @@ -673,15 +704,23 @@ static void freeze_array(conf_t *conf) /* stop syncio and normal IO and wait for everything to * go quite. * We increment barrier and nr_waiting, and then - * wait until barrier+nr_pending match nr_queued+2 + * wait until nr_pending match nr_queued+1 + * This is called in the context of one normal IO request + * that has failed. Thus any sync request that might be pending + * will be blocked by nr_pending, and we need to wait for + * pending IO requests to complete or be queued for re-try. + * Thus the number queued (nr_queued) plus this request (1) + * must match the number of pending IOs (nr_pending) before + * we continue. */ spin_lock_irq(&conf->resync_lock); conf->barrier++; conf->nr_waiting++; wait_event_lock_irq(conf->wait_barrier, - conf->barrier+conf->nr_pending == conf->nr_queued+2, + conf->nr_pending == conf->nr_queued+1, conf->resync_lock, - raid1_unplug(conf->mddev->queue)); + ({ flush_pending_writes(conf); + raid1_unplug(conf->mddev->queue); })); spin_unlock_irq(&conf->resync_lock); } static void unfreeze_array(conf_t *conf) @@ -907,6 +946,9 @@ static int make_request(struct request_queue *q, struct bio * bio) blk_plug_device(mddev->queue); spin_unlock_irqrestore(&conf->device_lock, flags); + /* In case raid1d snuck into freeze_array */ + wake_up(&conf->wait_barrier); + if (do_sync) md_wakeup_thread(mddev->thread); #if 0 @@ -1473,28 +1515,14 @@ static void raid1d(mddev_t *mddev) for (;;) { char b[BDEVNAME_SIZE]; - spin_lock_irqsave(&conf->device_lock, flags); - - if (conf->pending_bio_list.head) { - bio = bio_list_get(&conf->pending_bio_list); - blk_remove_plug(mddev->queue); - spin_unlock_irqrestore(&conf->device_lock, flags); - /* flush any pending bitmap writes to disk before proceeding w/ I/O */ - bitmap_unplug(mddev->bitmap); - while (bio) { /* submit pending writes */ - struct bio *next = bio->bi_next; - bio->bi_next = NULL; - generic_make_request(bio); - bio = next; - } - unplug = 1; + unplug += flush_pending_writes(conf); - continue; - } - - if (list_empty(head)) + spin_lock_irqsave(&conf->device_lock, flags); + if (list_empty(head)) { + spin_unlock_irqrestore(&conf->device_lock, flags); break; + } r1_bio = list_entry(head->prev, r1bio_t, retry_list); list_del(head->prev); conf->nr_queued--; @@ -1590,7 +1618,6 @@ static void raid1d(mddev_t *mddev) } } } - spin_unlock_irqrestore(&conf->device_lock, flags); if (unplug) unplug_slaves(mddev); } diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c index 017f58113c33604e381a5fcc7c75f01344f67841..32389d2f18fcdfcadc87137936441e6d51560c05 100644 --- a/drivers/md/raid10.c +++ b/drivers/md/raid10.c @@ -537,7 +537,8 @@ static int read_balance(conf_t *conf, r10bio_t *r10_bio) current_distance = abs(r10_bio->devs[slot].addr - conf->mirrors[disk].head_position); - /* Find the disk whose head is closest */ + /* Find the disk whose head is closest, + * or - for far > 1 - find the closest to partition beginning */ for (nslot = slot; nslot < conf->copies; nslot++) { int ndisk = r10_bio->devs[nslot].devnum; @@ -557,8 +558,13 @@ static int read_balance(conf_t *conf, r10bio_t *r10_bio) slot = nslot; break; } - new_distance = abs(r10_bio->devs[nslot].addr - - conf->mirrors[ndisk].head_position); + + /* for far > 1 always use the lowest address */ + if (conf->far_copies > 1) + new_distance = r10_bio->devs[nslot].addr; + else + new_distance = abs(r10_bio->devs[nslot].addr - + conf->mirrors[ndisk].head_position); if (new_distance < current_distance) { current_distance = new_distance; disk = ndisk; @@ -629,7 +635,36 @@ static int raid10_congested(void *data, int bits) return ret; } - +static int flush_pending_writes(conf_t *conf) +{ + /* Any writes that have been queued but are awaiting + * bitmap updates get flushed here. + * We return 1 if any requests were actually submitted. + */ + int rv = 0; + + spin_lock_irq(&conf->device_lock); + + if (conf->pending_bio_list.head) { + struct bio *bio; + bio = bio_list_get(&conf->pending_bio_list); + blk_remove_plug(conf->mddev->queue); + spin_unlock_irq(&conf->device_lock); + /* flush any pending bitmap writes to disk + * before proceeding w/ I/O */ + bitmap_unplug(conf->mddev->bitmap); + + while (bio) { /* submit pending writes */ + struct bio *next = bio->bi_next; + bio->bi_next = NULL; + generic_make_request(bio); + bio = next; + } + rv = 1; + } else + spin_unlock_irq(&conf->device_lock); + return rv; +} /* Barriers.... * Sometimes we need to suspend IO while we do something else, * either some resync/recovery, or reconfigure the array. @@ -712,15 +747,23 @@ static void freeze_array(conf_t *conf) /* stop syncio and normal IO and wait for everything to * go quiet. * We increment barrier and nr_waiting, and then - * wait until barrier+nr_pending match nr_queued+2 + * wait until nr_pending match nr_queued+1 + * This is called in the context of one normal IO request + * that has failed. Thus any sync request that might be pending + * will be blocked by nr_pending, and we need to wait for + * pending IO requests to complete or be queued for re-try. + * Thus the number queued (nr_queued) plus this request (1) + * must match the number of pending IOs (nr_pending) before + * we continue. */ spin_lock_irq(&conf->resync_lock); conf->barrier++; conf->nr_waiting++; wait_event_lock_irq(conf->wait_barrier, - conf->barrier+conf->nr_pending == conf->nr_queued+2, + conf->nr_pending == conf->nr_queued+1, conf->resync_lock, - raid10_unplug(conf->mddev->queue)); + ({ flush_pending_writes(conf); + raid10_unplug(conf->mddev->queue); })); spin_unlock_irq(&conf->resync_lock); } @@ -892,6 +935,9 @@ static int make_request(struct request_queue *q, struct bio * bio) blk_plug_device(mddev->queue); spin_unlock_irqrestore(&conf->device_lock, flags); + /* In case raid10d snuck in to freeze_array */ + wake_up(&conf->wait_barrier); + if (do_sync) md_wakeup_thread(mddev->thread); @@ -1464,28 +1510,14 @@ static void raid10d(mddev_t *mddev) for (;;) { char b[BDEVNAME_SIZE]; - spin_lock_irqsave(&conf->device_lock, flags); - if (conf->pending_bio_list.head) { - bio = bio_list_get(&conf->pending_bio_list); - blk_remove_plug(mddev->queue); - spin_unlock_irqrestore(&conf->device_lock, flags); - /* flush any pending bitmap writes to disk before proceeding w/ I/O */ - bitmap_unplug(mddev->bitmap); - - while (bio) { /* submit pending writes */ - struct bio *next = bio->bi_next; - bio->bi_next = NULL; - generic_make_request(bio); - bio = next; - } - unplug = 1; - - continue; - } + unplug += flush_pending_writes(conf); - if (list_empty(head)) + spin_lock_irqsave(&conf->device_lock, flags); + if (list_empty(head)) { + spin_unlock_irqrestore(&conf->device_lock, flags); break; + } r10_bio = list_entry(head->prev, r10bio_t, retry_list); list_del(head->prev); conf->nr_queued--; @@ -1548,7 +1580,6 @@ static void raid10d(mddev_t *mddev) } } } - spin_unlock_irqrestore(&conf->device_lock, flags); if (unplug) unplug_slaves(mddev); } @@ -1787,6 +1818,8 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i if (j == conf->copies) { /* Cannot recover, so abort the recovery */ put_buf(r10_bio); + if (rb2) + atomic_dec(&rb2->remaining); r10_bio = rb2; if (!test_and_set_bit(MD_RECOVERY_ERR, &mddev->recovery)) printk(KERN_INFO "raid10: %s: insufficient working devices for recovery.\n", diff --git a/drivers/memstick/Kconfig b/drivers/memstick/Kconfig index 1093fdb07297fe4c0b8406fb4a2301a314fb9fcd..f0ca41c203239059926739a80e6daeaed22e9008 100644 --- a/drivers/memstick/Kconfig +++ b/drivers/memstick/Kconfig @@ -8,7 +8,7 @@ menuconfig MEMSTICK Sony MemoryStick is a proprietary storage/extension card protocol. If you want MemoryStick support, you should say Y here and also - to the specific driver for your MMC interface. + to the specific driver for your MemoryStick interface. if MEMSTICK diff --git a/drivers/memstick/core/memstick.c b/drivers/memstick/core/memstick.c index bba467fe4bced2a2f9473f6103e015ae1c4ea6cd..de80dba12f9baaddc5aa144434385384958544d2 100644 --- a/drivers/memstick/core/memstick.c +++ b/drivers/memstick/core/memstick.c @@ -18,7 +18,6 @@ #include #define DRIVER_NAME "memstick" -#define DRIVER_VERSION "0.2" static unsigned int cmd_retries = 3; module_param(cmd_retries, uint, 0644); @@ -236,7 +235,7 @@ int memstick_next_req(struct memstick_host *host, struct memstick_request **mrq) rc = host->card->next_request(host->card, mrq); if (!rc) - host->retries = cmd_retries; + host->retries = cmd_retries > 1 ? cmd_retries - 1 : 1; else *mrq = NULL; @@ -271,7 +270,7 @@ void memstick_init_req_sg(struct memstick_request *mrq, unsigned char tpc, mrq->data_dir = READ; mrq->sg = *sg; - mrq->io_type = MEMSTICK_IO_SG; + mrq->long_data = 1; if (tpc == MS_TPC_SET_CMD || tpc == MS_TPC_EX_SET_CMD) mrq->need_card_int = 1; @@ -306,7 +305,7 @@ void memstick_init_req(struct memstick_request *mrq, unsigned char tpc, if (mrq->data_dir == WRITE) memcpy(mrq->data, buf, mrq->data_len); - mrq->io_type = MEMSTICK_IO_VAL; + mrq->long_data = 0; if (tpc == MS_TPC_SET_CMD || tpc == MS_TPC_EX_SET_CMD) mrq->need_card_int = 1; @@ -561,6 +560,31 @@ void memstick_free_host(struct memstick_host *host) } EXPORT_SYMBOL(memstick_free_host); +/** + * memstick_suspend_host - notify bus driver of host suspension + * @host - host to use + */ +void memstick_suspend_host(struct memstick_host *host) +{ + mutex_lock(&host->lock); + host->set_param(host, MEMSTICK_POWER, MEMSTICK_POWER_OFF); + mutex_unlock(&host->lock); +} +EXPORT_SYMBOL(memstick_suspend_host); + +/** + * memstick_resume_host - notify bus driver of host resumption + * @host - host to use + */ +void memstick_resume_host(struct memstick_host *host) +{ + mutex_lock(&host->lock); + host->set_param(host, MEMSTICK_POWER, MEMSTICK_POWER_ON); + mutex_unlock(&host->lock); + memstick_detect_change(host); +} +EXPORT_SYMBOL(memstick_resume_host); + int memstick_register_driver(struct memstick_driver *drv) { drv->driver.bus = &memstick_bus_type; @@ -611,4 +635,3 @@ module_exit(memstick_exit); MODULE_AUTHOR("Alex Dubov"); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("Sony MemoryStick core driver"); -MODULE_VERSION(DRIVER_VERSION); diff --git a/drivers/memstick/core/mspro_block.c b/drivers/memstick/core/mspro_block.c index 423ad8cf4bb9902e605cd000e3506ccf2fbd1a88..1d637e4561d36bea56267d431a2bf9c7db2928ec 100644 --- a/drivers/memstick/core/mspro_block.c +++ b/drivers/memstick/core/mspro_block.c @@ -16,10 +16,10 @@ #include #include #include +#include #include #define DRIVER_NAME "mspro_block" -#define DRIVER_VERSION "0.2" static int major; module_param(major, int, 0644); @@ -110,6 +110,17 @@ struct mspro_mbr { unsigned int sectors_per_partition; } __attribute__((packed)); +struct mspro_specfile { + char name[8]; + char ext[3]; + unsigned char attr; + unsigned char reserved[10]; + unsigned short time; + unsigned short date; + unsigned short cluster; + unsigned int size; +} __attribute__((packed)); + struct mspro_devinfo { unsigned short cylinders; unsigned short heads; @@ -293,6 +304,20 @@ static ssize_t mspro_block_attr_show_sysinfo(struct device *dev, dev_attr); struct mspro_sys_info *x_sys = x_attr->data; ssize_t rc = 0; + int date_tz = 0, date_tz_f = 0; + + if (x_sys->assembly_date[0] > 0x80U) { + date_tz = (~x_sys->assembly_date[0]) + 1; + date_tz_f = date_tz & 3; + date_tz >>= 2; + date_tz = -date_tz; + date_tz_f *= 15; + } else if (x_sys->assembly_date[0] < 0x80U) { + date_tz = x_sys->assembly_date[0]; + date_tz_f = date_tz & 3; + date_tz >>= 2; + date_tz_f *= 15; + } rc += scnprintf(buffer + rc, PAGE_SIZE - rc, "class: %x\n", x_sys->class); @@ -305,8 +330,8 @@ static ssize_t mspro_block_attr_show_sysinfo(struct device *dev, rc += scnprintf(buffer + rc, PAGE_SIZE - rc, "page size: %x\n", be16_to_cpu(x_sys->page_size)); rc += scnprintf(buffer + rc, PAGE_SIZE - rc, "assembly date: " - "%d %04u-%02u-%02u %02u:%02u:%02u\n", - x_sys->assembly_date[0], + "GMT%+d:%d %04u-%02u-%02u %02u:%02u:%02u\n", + date_tz, date_tz_f, be16_to_cpu(*(unsigned short *) &x_sys->assembly_date[1]), x_sys->assembly_date[3], x_sys->assembly_date[4], @@ -398,6 +423,41 @@ static ssize_t mspro_block_attr_show_mbr(struct device *dev, return rc; } +static ssize_t mspro_block_attr_show_specfile(struct device *dev, + struct device_attribute *attr, + char *buffer) +{ + struct mspro_sys_attr *x_attr = container_of(attr, + struct mspro_sys_attr, + dev_attr); + struct mspro_specfile *x_spfile = x_attr->data; + char name[9], ext[4]; + ssize_t rc = 0; + + memcpy(name, x_spfile->name, 8); + name[8] = 0; + memcpy(ext, x_spfile->ext, 3); + ext[3] = 0; + + rc += scnprintf(buffer + rc, PAGE_SIZE - rc, "name: %s\n", name); + rc += scnprintf(buffer + rc, PAGE_SIZE - rc, "ext: %s\n", ext); + rc += scnprintf(buffer + rc, PAGE_SIZE - rc, "attribute: %x\n", + x_spfile->attr); + rc += scnprintf(buffer + rc, PAGE_SIZE - rc, "time: %d:%d:%d\n", + x_spfile->time >> 11, + (x_spfile->time >> 5) & 0x3f, + (x_spfile->time & 0x1f) * 2); + rc += scnprintf(buffer + rc, PAGE_SIZE - rc, "date: %d-%d-%d\n", + (x_spfile->date >> 9) + 1980, + (x_spfile->date >> 5) & 0xf, + x_spfile->date & 0x1f); + rc += scnprintf(buffer + rc, PAGE_SIZE - rc, "start cluster: %x\n", + x_spfile->cluster); + rc += scnprintf(buffer + rc, PAGE_SIZE - rc, "size: %x\n", + x_spfile->size); + return rc; +} + static ssize_t mspro_block_attr_show_devinfo(struct device *dev, struct device_attribute *attr, char *buffer) @@ -430,6 +490,9 @@ static sysfs_show_t mspro_block_attr_show(unsigned char tag) return mspro_block_attr_show_modelname; case MSPRO_BLOCK_ID_MBR: return mspro_block_attr_show_mbr; + case MSPRO_BLOCK_ID_SPECFILEVALUES1: + case MSPRO_BLOCK_ID_SPECFILEVALUES2: + return mspro_block_attr_show_specfile; case MSPRO_BLOCK_ID_DEVINFO: return mspro_block_attr_show_devinfo; default: @@ -629,7 +692,7 @@ static void mspro_block_process_request(struct memstick_dev *card, param.system = msb->system; param.data_count = cpu_to_be16(page_count); param.data_address = cpu_to_be32((uint32_t)t_sec); - param.cmd_param = 0; + param.tpc_param = 0; msb->data_dir = rq_data_dir(req); msb->transfer_cmd = msb->data_dir == READ @@ -758,10 +821,10 @@ static int mspro_block_switch_to_parallel(struct memstick_dev *card) struct memstick_host *host = card->host; struct mspro_block_data *msb = memstick_get_drvdata(card); struct mspro_param_register param = { - .system = 0, + .system = MEMSTICK_SYS_PAR4, .data_count = 0, .data_address = 0, - .cmd_param = 0 + .tpc_param = 0 }; card->next_request = h_mspro_block_req_init; @@ -773,8 +836,8 @@ static int mspro_block_switch_to_parallel(struct memstick_dev *card) if (card->current_mrq.error) return card->current_mrq.error; - msb->system = 0; - host->set_param(host, MEMSTICK_INTERFACE, MEMSTICK_PARALLEL); + msb->system = MEMSTICK_SYS_PAR4; + host->set_param(host, MEMSTICK_INTERFACE, MEMSTICK_PAR4); card->next_request = h_mspro_block_req_init; msb->mrq_handler = h_mspro_block_default; @@ -783,8 +846,24 @@ static int mspro_block_switch_to_parallel(struct memstick_dev *card) wait_for_completion(&card->mrq_complete); if (card->current_mrq.error) { - msb->system = 0x80; + msb->system = MEMSTICK_SYS_SERIAL; + host->set_param(host, MEMSTICK_POWER, MEMSTICK_POWER_OFF); + msleep(1000); + host->set_param(host, MEMSTICK_POWER, MEMSTICK_POWER_ON); host->set_param(host, MEMSTICK_INTERFACE, MEMSTICK_SERIAL); + + if (memstick_set_rw_addr(card)) + return card->current_mrq.error; + + param.system = msb->system; + + card->next_request = h_mspro_block_req_init; + msb->mrq_handler = h_mspro_block_default; + memstick_init_req(&card->current_mrq, MS_TPC_WRITE_REG, ¶m, + sizeof(param)); + memstick_new_req(host); + wait_for_completion(&card->mrq_complete); + return -EFAULT; } @@ -802,7 +881,7 @@ static int mspro_block_read_attributes(struct memstick_dev *card) .system = msb->system, .data_count = cpu_to_be16(1), .data_address = 0, - .cmd_param = 0 + .tpc_param = 0 }; struct mspro_attribute *attr = NULL; struct mspro_sys_attr *s_attr = NULL; @@ -922,7 +1001,7 @@ static int mspro_block_read_attributes(struct memstick_dev *card) param.system = msb->system; param.data_count = cpu_to_be16((rc / msb->page_size) + 1); param.data_address = cpu_to_be32(addr / msb->page_size); - param.cmd_param = 0; + param.tpc_param = 0; sg_init_one(&msb->req_sg[0], buffer, be16_to_cpu(param.data_count) * msb->page_size); @@ -964,7 +1043,7 @@ static int mspro_block_init_card(struct memstick_dev *card) struct memstick_host *host = card->host; int rc = 0; - msb->system = 0x80; + msb->system = MEMSTICK_SYS_SERIAL; card->reg_addr.r_offset = offsetof(struct mspro_register, status); card->reg_addr.r_length = sizeof(struct ms_status_register); card->reg_addr.w_offset = offsetof(struct mspro_register, param); @@ -973,7 +1052,7 @@ static int mspro_block_init_card(struct memstick_dev *card) if (memstick_set_rw_addr(card)) return -EIO; - if (host->caps & MEMSTICK_CAP_PARALLEL) { + if (host->caps & MEMSTICK_CAP_PAR4) { if (mspro_block_switch_to_parallel(card)) printk(KERN_WARNING "%s: could not switch to " "parallel interface\n", card->dev.bus_id); @@ -1348,4 +1427,3 @@ MODULE_LICENSE("GPL"); MODULE_AUTHOR("Alex Dubov"); MODULE_DESCRIPTION("Sony MemoryStickPro block device driver"); MODULE_DEVICE_TABLE(memstick, mspro_block_id_tbl); -MODULE_VERSION(DRIVER_VERSION); diff --git a/drivers/memstick/host/Kconfig b/drivers/memstick/host/Kconfig index c002fcc3c879ca27bd52e568635da51b0b409333..4ce5c8dffb6878e1a073538c3e2eed261c1ab457 100644 --- a/drivers/memstick/host/Kconfig +++ b/drivers/memstick/host/Kconfig @@ -20,3 +20,13 @@ config MEMSTICK_TIFM_MS To compile this driver as a module, choose M here: the module will be called tifm_ms. +config MEMSTICK_JMICRON_38X + tristate "JMicron JMB38X MemoryStick interface support (EXPERIMENTAL)" + depends on EXPERIMENTAL && PCI + + help + Say Y here if you want to be able to access MemoryStick cards with + the JMicron(R) JMB38X MemoryStick card reader. + + To compile this driver as a module, choose M here: the + module will be called jmb38x_ms. diff --git a/drivers/memstick/host/Makefile b/drivers/memstick/host/Makefile index ee666380efa11eb502401f7dbafa6260914ce1e7..12530e4311d31143dcab38c1405d92b02418c8de 100644 --- a/drivers/memstick/host/Makefile +++ b/drivers/memstick/host/Makefile @@ -3,8 +3,8 @@ # ifeq ($(CONFIG_MEMSTICK_DEBUG),y) - EXTRA_CFLAGS += -DDEBUG + EXTRA_CFLAGS += -DDEBUG endif -obj-$(CONFIG_MEMSTICK_TIFM_MS) += tifm_ms.o - +obj-$(CONFIG_MEMSTICK_TIFM_MS) += tifm_ms.o +obj-$(CONFIG_MEMSTICK_JMICRON_38X) += jmb38x_ms.o diff --git a/drivers/memstick/host/jmb38x_ms.c b/drivers/memstick/host/jmb38x_ms.c new file mode 100644 index 0000000000000000000000000000000000000000..03fe8783b1ee0f41dace3f7f4a37a2c597a51050 --- /dev/null +++ b/drivers/memstick/host/jmb38x_ms.c @@ -0,0 +1,945 @@ +/* + * jmb38x_ms.c - JMicron jmb38x MemoryStick card reader + * + * Copyright (C) 2008 Alex Dubov + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + */ + +#include +#include +#include +#include +#include +#include + +#define DRIVER_NAME "jmb38x_ms" + +static int no_dma; +module_param(no_dma, bool, 0644); + +enum { + DMA_ADDRESS = 0x00, + BLOCK = 0x04, + DMA_CONTROL = 0x08, + TPC_P0 = 0x0c, + TPC_P1 = 0x10, + TPC = 0x14, + HOST_CONTROL = 0x18, + DATA = 0x1c, + STATUS = 0x20, + INT_STATUS = 0x24, + INT_STATUS_ENABLE = 0x28, + INT_SIGNAL_ENABLE = 0x2c, + TIMER = 0x30, + TIMER_CONTROL = 0x34, + PAD_OUTPUT_ENABLE = 0x38, + PAD_PU_PD = 0x3c, + CLOCK_DELAY = 0x40, + ADMA_ADDRESS = 0x44, + CLOCK_CONTROL = 0x48, + LED_CONTROL = 0x4c, + VERSION = 0x50 +}; + +struct jmb38x_ms_host { + struct jmb38x_ms *chip; + void __iomem *addr; + spinlock_t lock; + int id; + char host_id[DEVICE_ID_SIZE]; + int irq; + unsigned int block_pos; + unsigned long timeout_jiffies; + struct timer_list timer; + struct memstick_request *req; + unsigned char eject:1, + use_dma:1; + unsigned char cmd_flags; + unsigned char io_pos; + unsigned int io_word[2]; +}; + +struct jmb38x_ms { + struct pci_dev *pdev; + int host_cnt; + struct memstick_host *hosts[]; +}; + +#define BLOCK_COUNT_MASK 0xffff0000 +#define BLOCK_SIZE_MASK 0x00000fff + +#define DMA_CONTROL_ENABLE 0x00000001 + +#define TPC_DATA_SEL 0x00008000 +#define TPC_DIR 0x00004000 +#define TPC_WAIT_INT 0x00002000 +#define TPC_GET_INT 0x00000800 +#define TPC_CODE_SZ_MASK 0x00000700 +#define TPC_DATA_SZ_MASK 0x00000007 + +#define HOST_CONTROL_RESET_REQ 0x00008000 +#define HOST_CONTROL_REI 0x00004000 +#define HOST_CONTROL_LED 0x00000400 +#define HOST_CONTROL_FAST_CLK 0x00000200 +#define HOST_CONTROL_RESET 0x00000100 +#define HOST_CONTROL_POWER_EN 0x00000080 +#define HOST_CONTROL_CLOCK_EN 0x00000040 +#define HOST_CONTROL_IF_SHIFT 4 + +#define HOST_CONTROL_IF_SERIAL 0x0 +#define HOST_CONTROL_IF_PAR4 0x1 +#define HOST_CONTROL_IF_PAR8 0x3 + +#define STATUS_HAS_MEDIA 0x00000400 +#define STATUS_FIFO_EMPTY 0x00000200 +#define STATUS_FIFO_FULL 0x00000100 + +#define INT_STATUS_TPC_ERR 0x00080000 +#define INT_STATUS_CRC_ERR 0x00040000 +#define INT_STATUS_TIMER_TO 0x00020000 +#define INT_STATUS_HSK_TO 0x00010000 +#define INT_STATUS_ANY_ERR 0x00008000 +#define INT_STATUS_FIFO_WRDY 0x00000080 +#define INT_STATUS_FIFO_RRDY 0x00000040 +#define INT_STATUS_MEDIA_OUT 0x00000010 +#define INT_STATUS_MEDIA_IN 0x00000008 +#define INT_STATUS_DMA_BOUNDARY 0x00000004 +#define INT_STATUS_EOTRAN 0x00000002 +#define INT_STATUS_EOTPC 0x00000001 + +#define INT_STATUS_ALL 0x000f801f + +#define PAD_OUTPUT_ENABLE_MS 0x0F3F + +#define PAD_PU_PD_OFF 0x7FFF0000 +#define PAD_PU_PD_ON_MS_SOCK0 0x5f8f0000 +#define PAD_PU_PD_ON_MS_SOCK1 0x0f0f0000 + +enum { + CMD_READY = 0x01, + FIFO_READY = 0x02, + REG_DATA = 0x04, + AUTO_GET_INT = 0x08 +}; + +static unsigned int jmb38x_ms_read_data(struct jmb38x_ms_host *host, + unsigned char *buf, unsigned int length) +{ + unsigned int off = 0; + + while (host->io_pos && length) { + buf[off++] = host->io_word[0] & 0xff; + host->io_word[0] >>= 8; + length--; + host->io_pos--; + } + + if (!length) + return off; + + while (!(STATUS_FIFO_EMPTY & readl(host->addr + STATUS))) { + if (length < 4) + break; + *(unsigned int *)(buf + off) = __raw_readl(host->addr + DATA); + length -= 4; + off += 4; + } + + if (length + && !(STATUS_FIFO_EMPTY & readl(host->addr + STATUS))) { + host->io_word[0] = readl(host->addr + DATA); + for (host->io_pos = 4; host->io_pos; --host->io_pos) { + buf[off++] = host->io_word[0] & 0xff; + host->io_word[0] >>= 8; + length--; + if (!length) + break; + } + } + + return off; +} + +static unsigned int jmb38x_ms_read_reg_data(struct jmb38x_ms_host *host, + unsigned char *buf, + unsigned int length) +{ + unsigned int off = 0; + + while (host->io_pos > 4 && length) { + buf[off++] = host->io_word[0] & 0xff; + host->io_word[0] >>= 8; + length--; + host->io_pos--; + } + + if (!length) + return off; + + while (host->io_pos && length) { + buf[off++] = host->io_word[1] & 0xff; + host->io_word[1] >>= 8; + length--; + host->io_pos--; + } + + return off; +} + +static unsigned int jmb38x_ms_write_data(struct jmb38x_ms_host *host, + unsigned char *buf, + unsigned int length) +{ + unsigned int off = 0; + + if (host->io_pos) { + while (host->io_pos < 4 && length) { + host->io_word[0] |= buf[off++] << (host->io_pos * 8); + host->io_pos++; + length--; + } + } + + if (host->io_pos == 4 + && !(STATUS_FIFO_FULL & readl(host->addr + STATUS))) { + writel(host->io_word[0], host->addr + DATA); + host->io_pos = 0; + host->io_word[0] = 0; + } else if (host->io_pos) { + return off; + } + + if (!length) + return off; + + while (!(STATUS_FIFO_FULL & readl(host->addr + STATUS))) { + if (length < 4) + break; + + __raw_writel(*(unsigned int *)(buf + off), + host->addr + DATA); + length -= 4; + off += 4; + } + + switch (length) { + case 3: + host->io_word[0] |= buf[off + 2] << 16; + host->io_pos++; + case 2: + host->io_word[0] |= buf[off + 1] << 8; + host->io_pos++; + case 1: + host->io_word[0] |= buf[off]; + host->io_pos++; + } + + off += host->io_pos; + + return off; +} + +static unsigned int jmb38x_ms_write_reg_data(struct jmb38x_ms_host *host, + unsigned char *buf, + unsigned int length) +{ + unsigned int off = 0; + + while (host->io_pos < 4 && length) { + host->io_word[0] &= ~(0xff << (host->io_pos * 8)); + host->io_word[0] |= buf[off++] << (host->io_pos * 8); + host->io_pos++; + length--; + } + + if (!length) + return off; + + while (host->io_pos < 8 && length) { + host->io_word[1] &= ~(0xff << (host->io_pos * 8)); + host->io_word[1] |= buf[off++] << (host->io_pos * 8); + host->io_pos++; + length--; + } + + return off; +} + +static int jmb38x_ms_transfer_data(struct jmb38x_ms_host *host) +{ + unsigned int length; + unsigned int off; + unsigned int t_size, p_off, p_cnt; + unsigned char *buf; + struct page *pg; + unsigned long flags = 0; + + if (host->req->long_data) { + length = host->req->sg.length - host->block_pos; + off = host->req->sg.offset + host->block_pos; + } else { + length = host->req->data_len - host->block_pos; + off = 0; + } + + while (length) { + if (host->req->long_data) { + pg = nth_page(sg_page(&host->req->sg), + off >> PAGE_SHIFT); + p_off = offset_in_page(off); + p_cnt = PAGE_SIZE - p_off; + p_cnt = min(p_cnt, length); + + local_irq_save(flags); + buf = kmap_atomic(pg, KM_BIO_SRC_IRQ) + p_off; + } else { + buf = host->req->data + host->block_pos; + p_cnt = host->req->data_len - host->block_pos; + } + + if (host->req->data_dir == WRITE) + t_size = !(host->cmd_flags & REG_DATA) + ? jmb38x_ms_write_data(host, buf, p_cnt) + : jmb38x_ms_write_reg_data(host, buf, p_cnt); + else + t_size = !(host->cmd_flags & REG_DATA) + ? jmb38x_ms_read_data(host, buf, p_cnt) + : jmb38x_ms_read_reg_data(host, buf, p_cnt); + + if (host->req->long_data) { + kunmap_atomic(buf - p_off, KM_BIO_SRC_IRQ); + local_irq_restore(flags); + } + + if (!t_size) + break; + host->block_pos += t_size; + length -= t_size; + off += t_size; + } + + if (!length && host->req->data_dir == WRITE) { + if (host->cmd_flags & REG_DATA) { + writel(host->io_word[0], host->addr + TPC_P0); + writel(host->io_word[1], host->addr + TPC_P1); + } else if (host->io_pos) { + writel(host->io_word[0], host->addr + DATA); + } + } + + return length; +} + +static int jmb38x_ms_issue_cmd(struct memstick_host *msh) +{ + struct jmb38x_ms_host *host = memstick_priv(msh); + unsigned char *data; + unsigned int data_len, cmd, t_val; + + if (!(STATUS_HAS_MEDIA & readl(host->addr + STATUS))) { + dev_dbg(msh->cdev.dev, "no media status\n"); + host->req->error = -ETIME; + return host->req->error; + } + + dev_dbg(msh->cdev.dev, "control %08x\n", + readl(host->addr + HOST_CONTROL)); + dev_dbg(msh->cdev.dev, "status %08x\n", readl(host->addr + INT_STATUS)); + dev_dbg(msh->cdev.dev, "hstatus %08x\n", readl(host->addr + STATUS)); + + host->cmd_flags = 0; + host->block_pos = 0; + host->io_pos = 0; + host->io_word[0] = 0; + host->io_word[1] = 0; + + cmd = host->req->tpc << 16; + cmd |= TPC_DATA_SEL; + + if (host->req->data_dir == READ) + cmd |= TPC_DIR; + if (host->req->need_card_int) + cmd |= TPC_WAIT_INT; + if (host->req->get_int_reg) + cmd |= TPC_GET_INT; + + data = host->req->data; + + host->use_dma = !no_dma; + + if (host->req->long_data) { + data_len = host->req->sg.length; + } else { + data_len = host->req->data_len; + host->use_dma = 0; + } + + if (data_len <= 8) { + cmd &= ~(TPC_DATA_SEL | 0xf); + host->cmd_flags |= REG_DATA; + cmd |= data_len & 0xf; + host->use_dma = 0; + } + + if (host->use_dma) { + if (1 != pci_map_sg(host->chip->pdev, &host->req->sg, 1, + host->req->data_dir == READ + ? PCI_DMA_FROMDEVICE + : PCI_DMA_TODEVICE)) { + host->req->error = -ENOMEM; + return host->req->error; + } + data_len = sg_dma_len(&host->req->sg); + writel(sg_dma_address(&host->req->sg), + host->addr + DMA_ADDRESS); + writel(((1 << 16) & BLOCK_COUNT_MASK) + | (data_len & BLOCK_SIZE_MASK), + host->addr + BLOCK); + writel(DMA_CONTROL_ENABLE, host->addr + DMA_CONTROL); + } else if (!(host->cmd_flags & REG_DATA)) { + writel(((1 << 16) & BLOCK_COUNT_MASK) + | (data_len & BLOCK_SIZE_MASK), + host->addr + BLOCK); + t_val = readl(host->addr + INT_STATUS_ENABLE); + t_val |= host->req->data_dir == READ + ? INT_STATUS_FIFO_RRDY + : INT_STATUS_FIFO_WRDY; + + writel(t_val, host->addr + INT_STATUS_ENABLE); + writel(t_val, host->addr + INT_SIGNAL_ENABLE); + } else { + cmd &= ~(TPC_DATA_SEL | 0xf); + host->cmd_flags |= REG_DATA; + cmd |= data_len & 0xf; + + if (host->req->data_dir == WRITE) { + jmb38x_ms_transfer_data(host); + writel(host->io_word[0], host->addr + TPC_P0); + writel(host->io_word[1], host->addr + TPC_P1); + } + } + + mod_timer(&host->timer, jiffies + host->timeout_jiffies); + writel(HOST_CONTROL_LED | readl(host->addr + HOST_CONTROL), + host->addr + HOST_CONTROL); + host->req->error = 0; + + writel(cmd, host->addr + TPC); + dev_dbg(msh->cdev.dev, "executing TPC %08x, len %x\n", cmd, data_len); + + return 0; +} + +static void jmb38x_ms_complete_cmd(struct memstick_host *msh, int last) +{ + struct jmb38x_ms_host *host = memstick_priv(msh); + unsigned int t_val = 0; + int rc; + + del_timer(&host->timer); + + dev_dbg(msh->cdev.dev, "c control %08x\n", + readl(host->addr + HOST_CONTROL)); + dev_dbg(msh->cdev.dev, "c status %08x\n", + readl(host->addr + INT_STATUS)); + dev_dbg(msh->cdev.dev, "c hstatus %08x\n", readl(host->addr + STATUS)); + + if (host->req->get_int_reg) { + t_val = readl(host->addr + TPC_P0); + host->req->int_reg = (t_val & 0xff); + } + + if (host->use_dma) { + writel(0, host->addr + DMA_CONTROL); + pci_unmap_sg(host->chip->pdev, &host->req->sg, 1, + host->req->data_dir == READ + ? PCI_DMA_FROMDEVICE : PCI_DMA_TODEVICE); + } else { + t_val = readl(host->addr + INT_STATUS_ENABLE); + if (host->req->data_dir == READ) + t_val &= ~INT_STATUS_FIFO_RRDY; + else + t_val &= ~INT_STATUS_FIFO_WRDY; + + writel(t_val, host->addr + INT_STATUS_ENABLE); + writel(t_val, host->addr + INT_SIGNAL_ENABLE); + } + + writel((~HOST_CONTROL_LED) & readl(host->addr + HOST_CONTROL), + host->addr + HOST_CONTROL); + + if (!last) { + do { + rc = memstick_next_req(msh, &host->req); + } while (!rc && jmb38x_ms_issue_cmd(msh)); + } else { + do { + rc = memstick_next_req(msh, &host->req); + if (!rc) + host->req->error = -ETIME; + } while (!rc); + } +} + +static irqreturn_t jmb38x_ms_isr(int irq, void *dev_id) +{ + struct memstick_host *msh = dev_id; + struct jmb38x_ms_host *host = memstick_priv(msh); + unsigned int irq_status; + + spin_lock(&host->lock); + irq_status = readl(host->addr + INT_STATUS); + dev_dbg(&host->chip->pdev->dev, "irq_status = %08x\n", irq_status); + if (irq_status == 0 || irq_status == (~0)) { + spin_unlock(&host->lock); + return IRQ_NONE; + } + + if (host->req) { + if (irq_status & INT_STATUS_ANY_ERR) { + if (irq_status & INT_STATUS_CRC_ERR) + host->req->error = -EILSEQ; + else + host->req->error = -ETIME; + } else { + if (host->use_dma) { + if (irq_status & INT_STATUS_EOTRAN) + host->cmd_flags |= FIFO_READY; + } else { + if (irq_status & (INT_STATUS_FIFO_RRDY + | INT_STATUS_FIFO_WRDY)) + jmb38x_ms_transfer_data(host); + + if (irq_status & INT_STATUS_EOTRAN) { + jmb38x_ms_transfer_data(host); + host->cmd_flags |= FIFO_READY; + } + } + + if (irq_status & INT_STATUS_EOTPC) { + host->cmd_flags |= CMD_READY; + if (host->cmd_flags & REG_DATA) { + if (host->req->data_dir == READ) { + host->io_word[0] + = readl(host->addr + + TPC_P0); + host->io_word[1] + = readl(host->addr + + TPC_P1); + host->io_pos = 8; + + jmb38x_ms_transfer_data(host); + } + host->cmd_flags |= FIFO_READY; + } + } + } + } + + if (irq_status & (INT_STATUS_MEDIA_IN | INT_STATUS_MEDIA_OUT)) { + dev_dbg(&host->chip->pdev->dev, "media changed\n"); + memstick_detect_change(msh); + } + + writel(irq_status, host->addr + INT_STATUS); + + if (host->req + && (((host->cmd_flags & CMD_READY) + && (host->cmd_flags & FIFO_READY)) + || host->req->error)) + jmb38x_ms_complete_cmd(msh, 0); + + spin_unlock(&host->lock); + return IRQ_HANDLED; +} + +static void jmb38x_ms_abort(unsigned long data) +{ + struct memstick_host *msh = (struct memstick_host *)data; + struct jmb38x_ms_host *host = memstick_priv(msh); + unsigned long flags; + + dev_dbg(&host->chip->pdev->dev, "abort\n"); + spin_lock_irqsave(&host->lock, flags); + if (host->req) { + host->req->error = -ETIME; + jmb38x_ms_complete_cmd(msh, 0); + } + spin_unlock_irqrestore(&host->lock, flags); +} + +static void jmb38x_ms_request(struct memstick_host *msh) +{ + struct jmb38x_ms_host *host = memstick_priv(msh); + unsigned long flags; + int rc; + + spin_lock_irqsave(&host->lock, flags); + if (host->req) { + spin_unlock_irqrestore(&host->lock, flags); + BUG(); + return; + } + + do { + rc = memstick_next_req(msh, &host->req); + } while (!rc && jmb38x_ms_issue_cmd(msh)); + spin_unlock_irqrestore(&host->lock, flags); +} + +static void jmb38x_ms_reset(struct jmb38x_ms_host *host) +{ + unsigned int host_ctl = readl(host->addr + HOST_CONTROL); + + writel(host_ctl | HOST_CONTROL_RESET_REQ | HOST_CONTROL_RESET, + host->addr + HOST_CONTROL); + + while (HOST_CONTROL_RESET_REQ + & (host_ctl = readl(host->addr + HOST_CONTROL))) { + ndelay(100); + dev_dbg(&host->chip->pdev->dev, "reset\n"); + } + + writel(INT_STATUS_ALL, host->addr + INT_STATUS_ENABLE); + writel(INT_STATUS_ALL, host->addr + INT_SIGNAL_ENABLE); + + dev_dbg(&host->chip->pdev->dev, "reset\n"); +} + +static void jmb38x_ms_set_param(struct memstick_host *msh, + enum memstick_param param, + int value) +{ + struct jmb38x_ms_host *host = memstick_priv(msh); + unsigned int host_ctl; + unsigned long flags; + + spin_lock_irqsave(&host->lock, flags); + + switch (param) { + case MEMSTICK_POWER: + if (value == MEMSTICK_POWER_ON) { + jmb38x_ms_reset(host); + + writel(host->id ? PAD_PU_PD_ON_MS_SOCK1 + : PAD_PU_PD_ON_MS_SOCK0, + host->addr + PAD_PU_PD); + + writel(PAD_OUTPUT_ENABLE_MS, + host->addr + PAD_OUTPUT_ENABLE); + + host_ctl = readl(host->addr + HOST_CONTROL); + host_ctl |= 7; + writel(host_ctl | (HOST_CONTROL_POWER_EN + | HOST_CONTROL_CLOCK_EN), + host->addr + HOST_CONTROL); + + dev_dbg(&host->chip->pdev->dev, "power on\n"); + } else if (value == MEMSTICK_POWER_OFF) { + writel(readl(host->addr + HOST_CONTROL) + & ~(HOST_CONTROL_POWER_EN + | HOST_CONTROL_CLOCK_EN), + host->addr + HOST_CONTROL); + writel(0, host->addr + PAD_OUTPUT_ENABLE); + writel(PAD_PU_PD_OFF, host->addr + PAD_PU_PD); + dev_dbg(&host->chip->pdev->dev, "power off\n"); + } + break; + case MEMSTICK_INTERFACE: + /* jmb38x_ms_reset(host); */ + + host_ctl = readl(host->addr + HOST_CONTROL); + host_ctl &= ~(3 << HOST_CONTROL_IF_SHIFT); + /* host_ctl |= 7; */ + + if (value == MEMSTICK_SERIAL) { + host_ctl &= ~HOST_CONTROL_FAST_CLK; + host_ctl |= HOST_CONTROL_IF_SERIAL + << HOST_CONTROL_IF_SHIFT; + host_ctl |= HOST_CONTROL_REI; + writel(0, host->addr + CLOCK_DELAY); + } else if (value == MEMSTICK_PAR4) { + host_ctl |= HOST_CONTROL_FAST_CLK; + host_ctl |= HOST_CONTROL_IF_PAR4 + << HOST_CONTROL_IF_SHIFT; + host_ctl &= ~HOST_CONTROL_REI; + writel(4, host->addr + CLOCK_DELAY); + } else if (value == MEMSTICK_PAR8) { + host_ctl |= HOST_CONTROL_FAST_CLK; + host_ctl |= HOST_CONTROL_IF_PAR8 + << HOST_CONTROL_IF_SHIFT; + host_ctl &= ~HOST_CONTROL_REI; + writel(4, host->addr + CLOCK_DELAY); + } + writel(host_ctl, host->addr + HOST_CONTROL); + break; + }; + + spin_unlock_irqrestore(&host->lock, flags); +} + +#ifdef CONFIG_PM + +static int jmb38x_ms_suspend(struct pci_dev *dev, pm_message_t state) +{ + struct jmb38x_ms *jm = pci_get_drvdata(dev); + int cnt; + + for (cnt = 0; cnt < jm->host_cnt; ++cnt) { + if (!jm->hosts[cnt]) + break; + memstick_suspend_host(jm->hosts[cnt]); + } + + pci_save_state(dev); + pci_enable_wake(dev, pci_choose_state(dev, state), 0); + pci_disable_device(dev); + pci_set_power_state(dev, pci_choose_state(dev, state)); + return 0; +} + +static int jmb38x_ms_resume(struct pci_dev *dev) +{ + struct jmb38x_ms *jm = pci_get_drvdata(dev); + int rc; + + pci_set_power_state(dev, PCI_D0); + pci_restore_state(dev); + rc = pci_enable_device(dev); + if (rc) + return rc; + pci_set_master(dev); + + pci_read_config_dword(dev, 0xac, &rc); + pci_write_config_dword(dev, 0xac, rc | 0x00470000); + + for (rc = 0; rc < jm->host_cnt; ++rc) { + if (!jm->hosts[rc]) + break; + memstick_resume_host(jm->hosts[rc]); + memstick_detect_change(jm->hosts[rc]); + } + + return 0; +} + +#else + +#define jmb38x_ms_suspend NULL +#define jmb38x_ms_resume NULL + +#endif /* CONFIG_PM */ + +static int jmb38x_ms_count_slots(struct pci_dev *pdev) +{ + int cnt, rc = 0; + + for (cnt = 0; cnt < PCI_ROM_RESOURCE; ++cnt) { + if (!(IORESOURCE_MEM & pci_resource_flags(pdev, cnt))) + break; + + if (256 != pci_resource_len(pdev, cnt)) + break; + + ++rc; + } + return rc; +} + +static struct memstick_host *jmb38x_ms_alloc_host(struct jmb38x_ms *jm, int cnt) +{ + struct memstick_host *msh; + struct jmb38x_ms_host *host; + + msh = memstick_alloc_host(sizeof(struct jmb38x_ms_host), + &jm->pdev->dev); + if (!msh) + return NULL; + + host = memstick_priv(msh); + host->chip = jm; + host->addr = ioremap(pci_resource_start(jm->pdev, cnt), + pci_resource_len(jm->pdev, cnt)); + if (!host->addr) + goto err_out_free; + + spin_lock_init(&host->lock); + host->id = cnt; + snprintf(host->host_id, DEVICE_ID_SIZE, DRIVER_NAME ":slot%d", + host->id); + host->irq = jm->pdev->irq; + host->timeout_jiffies = msecs_to_jiffies(4000); + msh->request = jmb38x_ms_request; + msh->set_param = jmb38x_ms_set_param; + /* + msh->caps = MEMSTICK_CAP_AUTO_GET_INT | MEMSTICK_CAP_PAR4 + | MEMSTICK_CAP_PAR8; + */ + msh->caps = MEMSTICK_CAP_PAR4 | MEMSTICK_CAP_PAR8; + + setup_timer(&host->timer, jmb38x_ms_abort, (unsigned long)msh); + + if (!request_irq(host->irq, jmb38x_ms_isr, IRQF_SHARED, host->host_id, + msh)) + return msh; + + iounmap(host->addr); +err_out_free: + kfree(msh); + return NULL; +} + +static void jmb38x_ms_free_host(struct memstick_host *msh) +{ + struct jmb38x_ms_host *host = memstick_priv(msh); + + free_irq(host->irq, msh); + iounmap(host->addr); + memstick_free_host(msh); +} + +static int jmb38x_ms_probe(struct pci_dev *pdev, + const struct pci_device_id *dev_id) +{ + struct jmb38x_ms *jm; + int pci_dev_busy = 0; + int rc, cnt; + + rc = pci_set_dma_mask(pdev, DMA_32BIT_MASK); + if (rc) + return rc; + + rc = pci_enable_device(pdev); + if (rc) + return rc; + + pci_set_master(pdev); + + rc = pci_request_regions(pdev, DRIVER_NAME); + if (rc) { + pci_dev_busy = 1; + goto err_out; + } + + pci_read_config_dword(pdev, 0xac, &rc); + pci_write_config_dword(pdev, 0xac, rc | 0x00470000); + + cnt = jmb38x_ms_count_slots(pdev); + if (!cnt) { + rc = -ENODEV; + pci_dev_busy = 1; + goto err_out; + } + + jm = kzalloc(sizeof(struct jmb38x_ms) + + cnt * sizeof(struct memstick_host *), GFP_KERNEL); + if (!jm) { + rc = -ENOMEM; + goto err_out_int; + } + + jm->pdev = pdev; + jm->host_cnt = cnt; + pci_set_drvdata(pdev, jm); + + for (cnt = 0; cnt < jm->host_cnt; ++cnt) { + jm->hosts[cnt] = jmb38x_ms_alloc_host(jm, cnt); + if (!jm->hosts[cnt]) + break; + + rc = memstick_add_host(jm->hosts[cnt]); + + if (rc) { + jmb38x_ms_free_host(jm->hosts[cnt]); + jm->hosts[cnt] = NULL; + break; + } + } + + if (cnt) + return 0; + + rc = -ENODEV; + + pci_set_drvdata(pdev, NULL); + kfree(jm); +err_out_int: + pci_release_regions(pdev); +err_out: + if (!pci_dev_busy) + pci_disable_device(pdev); + return rc; +} + +static void jmb38x_ms_remove(struct pci_dev *dev) +{ + struct jmb38x_ms *jm = pci_get_drvdata(dev); + struct jmb38x_ms_host *host; + int cnt; + unsigned long flags; + + for (cnt = 0; cnt < jm->host_cnt; ++cnt) { + if (!jm->hosts[cnt]) + break; + + host = memstick_priv(jm->hosts[cnt]); + + writel(0, host->addr + INT_SIGNAL_ENABLE); + writel(0, host->addr + INT_STATUS_ENABLE); + mmiowb(); + dev_dbg(&jm->pdev->dev, "interrupts off\n"); + spin_lock_irqsave(&host->lock, flags); + if (host->req) { + host->req->error = -ETIME; + jmb38x_ms_complete_cmd(jm->hosts[cnt], 1); + } + spin_unlock_irqrestore(&host->lock, flags); + + memstick_remove_host(jm->hosts[cnt]); + dev_dbg(&jm->pdev->dev, "host removed\n"); + + jmb38x_ms_free_host(jm->hosts[cnt]); + } + + pci_set_drvdata(dev, NULL); + pci_release_regions(dev); + pci_disable_device(dev); + kfree(jm); +} + +static struct pci_device_id jmb38x_ms_id_tbl [] = { + { PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB38X_MS, PCI_ANY_ID, + PCI_ANY_ID, 0, 0, 0 }, + { } +}; + +static struct pci_driver jmb38x_ms_driver = { + .name = DRIVER_NAME, + .id_table = jmb38x_ms_id_tbl, + .probe = jmb38x_ms_probe, + .remove = jmb38x_ms_remove, + .suspend = jmb38x_ms_suspend, + .resume = jmb38x_ms_resume +}; + +static int __init jmb38x_ms_init(void) +{ + return pci_register_driver(&jmb38x_ms_driver); +} + +static void __exit jmb38x_ms_exit(void) +{ + pci_unregister_driver(&jmb38x_ms_driver); +} + +MODULE_AUTHOR("Alex Dubov"); +MODULE_DESCRIPTION("JMicron jmb38x MemoryStick driver"); +MODULE_LICENSE("GPL"); +MODULE_DEVICE_TABLE(pci, jmb38x_ms_id_tbl); + +module_init(jmb38x_ms_init); +module_exit(jmb38x_ms_exit); diff --git a/drivers/memstick/host/tifm_ms.c b/drivers/memstick/host/tifm_ms.c index 4fb24215bd952aba5a8ab20dc59cd22bee24f87c..2b5bf52a8302b81be8ac1464548d5490eb085a1f 100644 --- a/drivers/memstick/host/tifm_ms.c +++ b/drivers/memstick/host/tifm_ms.c @@ -20,293 +20,315 @@ #include #define DRIVER_NAME "tifm_ms" -#define DRIVER_VERSION "0.1" static int no_dma; module_param(no_dma, bool, 0644); -#define TIFM_MS_TIMEOUT 0x00100 -#define TIFM_MS_BADCRC 0x00200 -#define TIFM_MS_EOTPC 0x01000 -#define TIFM_MS_INT 0x02000 - -/* The meaning of the bit majority in this constant is unknown. */ -#define TIFM_MS_SERIAL 0x04010 +/* + * Some control bits of TIFM appear to conform to Sony's reference design, + * so I'm just assuming they all are. + */ -#define TIFM_MS_SYS_LATCH 0x00100 -#define TIFM_MS_SYS_NOT_RDY 0x00800 -#define TIFM_MS_SYS_DATA 0x10000 +#define TIFM_MS_STAT_DRQ 0x04000 +#define TIFM_MS_STAT_MSINT 0x02000 +#define TIFM_MS_STAT_RDY 0x01000 +#define TIFM_MS_STAT_CRC 0x00200 +#define TIFM_MS_STAT_TOE 0x00100 +#define TIFM_MS_STAT_EMP 0x00020 +#define TIFM_MS_STAT_FUL 0x00010 +#define TIFM_MS_STAT_CED 0x00008 +#define TIFM_MS_STAT_ERR 0x00004 +#define TIFM_MS_STAT_BRQ 0x00002 +#define TIFM_MS_STAT_CNK 0x00001 + +#define TIFM_MS_SYS_DMA 0x10000 +#define TIFM_MS_SYS_RESET 0x08000 +#define TIFM_MS_SYS_SRAC 0x04000 +#define TIFM_MS_SYS_INTEN 0x02000 +#define TIFM_MS_SYS_NOCRC 0x01000 +#define TIFM_MS_SYS_INTCLR 0x00800 +#define TIFM_MS_SYS_MSIEN 0x00400 +#define TIFM_MS_SYS_FCLR 0x00200 +#define TIFM_MS_SYS_FDIR 0x00100 +#define TIFM_MS_SYS_DAM 0x00080 +#define TIFM_MS_SYS_DRM 0x00040 +#define TIFM_MS_SYS_DRQSL 0x00020 +#define TIFM_MS_SYS_REI 0x00010 +#define TIFM_MS_SYS_REO 0x00008 +#define TIFM_MS_SYS_BSY_MASK 0x00007 + +#define TIFM_MS_SYS_FIFO (TIFM_MS_SYS_INTEN | TIFM_MS_SYS_MSIEN \ + | TIFM_MS_SYS_FCLR | TIFM_MS_SYS_BSY_MASK) /* Hardware flags */ enum { - CMD_READY = 0x0001, - FIFO_READY = 0x0002, - CARD_READY = 0x0004, - DATA_CARRY = 0x0008 + CMD_READY = 0x01, + FIFO_READY = 0x02, + CARD_INT = 0x04 }; struct tifm_ms { struct tifm_dev *dev; - unsigned short eject:1, - no_dma:1; - unsigned short cmd_flags; + struct timer_list timer; + struct memstick_request *req; unsigned int mode_mask; unsigned int block_pos; unsigned long timeout_jiffies; - - struct timer_list timer; - struct memstick_request *req; + unsigned char eject:1, + use_dma:1; + unsigned char cmd_flags; + unsigned char io_pos; unsigned int io_word; }; -static void tifm_ms_read_fifo(struct tifm_ms *host, unsigned int fifo_offset, - struct page *pg, unsigned int page_off, - unsigned int length) +static unsigned int tifm_ms_read_data(struct tifm_ms *host, + unsigned char *buf, unsigned int length) { struct tifm_dev *sock = host->dev; - unsigned int cnt = 0, off = 0; - unsigned char *buf = kmap_atomic(pg, KM_BIO_DST_IRQ) + page_off; + unsigned int off = 0; + + while (host->io_pos && length) { + buf[off++] = host->io_word & 0xff; + host->io_word >>= 8; + length--; + host->io_pos--; + } - if (host->cmd_flags & DATA_CARRY) { - while ((fifo_offset & 3) && length) { + if (!length) + return off; + + while (!(TIFM_MS_STAT_EMP & readl(sock->addr + SOCK_MS_STATUS))) { + if (length < 4) + break; + *(unsigned int *)(buf + off) = __raw_readl(sock->addr + + SOCK_MS_DATA); + length -= 4; + off += 4; + } + + if (length + && !(TIFM_MS_STAT_EMP & readl(sock->addr + SOCK_MS_STATUS))) { + host->io_word = readl(sock->addr + SOCK_MS_DATA); + for (host->io_pos = 4; host->io_pos; --host->io_pos) { buf[off++] = host->io_word & 0xff; host->io_word >>= 8; length--; - fifo_offset++; + if (!length) + break; } - if (!(fifo_offset & 3)) - host->cmd_flags &= ~DATA_CARRY; - if (!length) - return; } - do { - host->io_word = readl(sock->addr + SOCK_FIFO_ACCESS - + fifo_offset); - cnt = 4; - while (length && cnt) { - buf[off++] = (host->io_word >> 8) & 0xff; - cnt--; - length--; - } - fifo_offset += 4 - cnt; - } while (length); - - if (cnt) - host->cmd_flags |= DATA_CARRY; - - kunmap_atomic(buf - page_off, KM_BIO_DST_IRQ); + return off; } -static void tifm_ms_write_fifo(struct tifm_ms *host, unsigned int fifo_offset, - struct page *pg, unsigned int page_off, - unsigned int length) +static unsigned int tifm_ms_write_data(struct tifm_ms *host, + unsigned char *buf, unsigned int length) { struct tifm_dev *sock = host->dev; - unsigned int cnt = 0, off = 0; - unsigned char *buf = kmap_atomic(pg, KM_BIO_SRC_IRQ) + page_off; + unsigned int off = 0; - if (host->cmd_flags & DATA_CARRY) { - while (fifo_offset & 3) { - host->io_word |= buf[off++] << (8 * (fifo_offset & 3)); + if (host->io_pos) { + while (host->io_pos < 4 && length) { + host->io_word |= buf[off++] << (host->io_pos * 8); + host->io_pos++; length--; - fifo_offset++; } - if (!(fifo_offset & 3)) { - writel(host->io_word, sock->addr + SOCK_FIFO_ACCESS - + fifo_offset - 4); - - host->cmd_flags &= ~DATA_CARRY; - } - if (!length) - return; } - do { - cnt = 4; + if (host->io_pos == 4 + && !(TIFM_MS_STAT_FUL & readl(sock->addr + SOCK_MS_STATUS))) { + writel(TIFM_MS_SYS_FDIR | readl(sock->addr + SOCK_MS_SYSTEM), + sock->addr + SOCK_MS_SYSTEM); + writel(host->io_word, sock->addr + SOCK_MS_DATA); + host->io_pos = 0; host->io_word = 0; - while (length && cnt) { - host->io_word |= buf[off++] << (4 - cnt); - cnt--; - length--; - } - fifo_offset += 4 - cnt; - if (!cnt) - writel(host->io_word, sock->addr + SOCK_FIFO_ACCESS - + fifo_offset - 4); - - } while (length); - - if (cnt) - host->cmd_flags |= DATA_CARRY; + } else if (host->io_pos) { + return off; + } - kunmap_atomic(buf - page_off, KM_BIO_SRC_IRQ); -} + if (!length) + return off; -static void tifm_ms_move_block(struct tifm_ms *host, unsigned int length) -{ - unsigned int t_size; - unsigned int off = host->req->sg.offset + host->block_pos; - unsigned int p_off, p_cnt; - struct page *pg; - unsigned long flags; + while (!(TIFM_MS_STAT_FUL & readl(sock->addr + SOCK_MS_STATUS))) { + if (length < 4) + break; + writel(TIFM_MS_SYS_FDIR | readl(sock->addr + SOCK_MS_SYSTEM), + sock->addr + SOCK_MS_SYSTEM); + __raw_writel(*(unsigned int *)(buf + off), + sock->addr + SOCK_MS_DATA); + length -= 4; + off += 4; + } - dev_dbg(&host->dev->dev, "moving block\n"); - local_irq_save(flags); - t_size = length; - while (t_size) { - pg = nth_page(sg_page(&host->req->sg), off >> PAGE_SHIFT); - p_off = offset_in_page(off); - p_cnt = PAGE_SIZE - p_off; - p_cnt = min(p_cnt, t_size); + switch (length) { + case 3: + host->io_word |= buf[off + 2] << 16; + host->io_pos++; + case 2: + host->io_word |= buf[off + 1] << 8; + host->io_pos++; + case 1: + host->io_word |= buf[off]; + host->io_pos++; + } - if (host->req->data_dir == WRITE) - tifm_ms_write_fifo(host, length - t_size, - pg, p_off, p_cnt); - else - tifm_ms_read_fifo(host, length - t_size, - pg, p_off, p_cnt); + off += host->io_pos; - t_size -= p_cnt; - } - local_irq_restore(flags); + return off; } -static int tifm_ms_transfer_data(struct tifm_ms *host, int skip) +static unsigned int tifm_ms_transfer_data(struct tifm_ms *host) { struct tifm_dev *sock = host->dev; - unsigned int length = host->req->sg.length - host->block_pos; + unsigned int length; + unsigned int off; + unsigned int t_size, p_off, p_cnt; + unsigned char *buf; + struct page *pg; + unsigned long flags = 0; + + if (host->req->long_data) { + length = host->req->sg.length - host->block_pos; + off = host->req->sg.offset + host->block_pos; + } else { + length = host->req->data_len - host->block_pos; + off = 0; + } + dev_dbg(&sock->dev, "fifo data transfer, %d, %d\n", length, + host->block_pos); + + while (length) { + if (host->req->long_data) { + pg = nth_page(sg_page(&host->req->sg), + off >> PAGE_SHIFT); + p_off = offset_in_page(off); + p_cnt = PAGE_SIZE - p_off; + p_cnt = min(p_cnt, length); + + local_irq_save(flags); + buf = kmap_atomic(pg, KM_BIO_SRC_IRQ) + p_off; + } else { + buf = host->req->data + host->block_pos; + p_cnt = host->req->data_len - host->block_pos; + } - if (!length) - return 1; + t_size = host->req->data_dir == WRITE + ? tifm_ms_write_data(host, buf, p_cnt) + : tifm_ms_read_data(host, buf, p_cnt); - if (length > TIFM_FIFO_SIZE) - length = TIFM_FIFO_SIZE; + if (host->req->long_data) { + kunmap_atomic(buf - p_off, KM_BIO_SRC_IRQ); + local_irq_restore(flags); + } - if (!skip) { - tifm_ms_move_block(host, length); - host->block_pos += length; + if (!t_size) + break; + host->block_pos += t_size; + length -= t_size; + off += t_size; } - if ((host->req->data_dir == READ) - && (host->block_pos == host->req->sg.length)) - return 1; - - writel(ilog2(length) - 2, sock->addr + SOCK_FIFO_PAGE_SIZE); - if (host->req->data_dir == WRITE) - writel((1 << 8) | TIFM_DMA_TX, sock->addr + SOCK_DMA_CONTROL); - else - writel((1 << 8), sock->addr + SOCK_DMA_CONTROL); + dev_dbg(&sock->dev, "fifo data transfer, %d remaining\n", length); + if (!length && (host->req->data_dir == WRITE)) { + if (host->io_pos) { + writel(TIFM_MS_SYS_FDIR + | readl(sock->addr + SOCK_MS_SYSTEM), + sock->addr + SOCK_MS_SYSTEM); + writel(host->io_word, sock->addr + SOCK_MS_DATA); + } + writel(TIFM_MS_SYS_FDIR + | readl(sock->addr + SOCK_MS_SYSTEM), + sock->addr + SOCK_MS_SYSTEM); + writel(0, sock->addr + SOCK_MS_DATA); + } else { + readl(sock->addr + SOCK_MS_DATA); + } - return 0; + return length; } static int tifm_ms_issue_cmd(struct tifm_ms *host) { struct tifm_dev *sock = host->dev; unsigned char *data; - unsigned int data_len = 0, cmd = 0, cmd_mask = 0, cnt, tval = 0; + unsigned int data_len, cmd, sys_param; + host->cmd_flags = 0; + host->block_pos = 0; + host->io_pos = 0; + host->io_word = 0; host->cmd_flags = 0; - if (host->req->io_type == MEMSTICK_IO_SG) { - if (!host->no_dma) { - if (1 != tifm_map_sg(sock, &host->req->sg, 1, - host->req->data_dir == READ - ? PCI_DMA_FROMDEVICE - : PCI_DMA_TODEVICE)) { - host->req->error = -ENOMEM; - return host->req->error; - } - data_len = sg_dma_len(&host->req->sg); - } else - data_len = host->req->sg.length; - - writel(TIFM_FIFO_INT_SETALL, - sock->addr + SOCK_DMA_FIFO_INT_ENABLE_CLEAR); - writel(TIFM_FIFO_ENABLE, - sock->addr + SOCK_FIFO_CONTROL); - writel(TIFM_FIFO_INTMASK, - sock->addr + SOCK_DMA_FIFO_INT_ENABLE_SET); + data = host->req->data; - if (!host->no_dma) { - writel(ilog2(data_len) - 2, - sock->addr + SOCK_FIFO_PAGE_SIZE); - writel(sg_dma_address(&host->req->sg), - sock->addr + SOCK_DMA_ADDRESS); - if (host->req->data_dir == WRITE) - writel((1 << 8) | TIFM_DMA_TX | TIFM_DMA_EN, - sock->addr + SOCK_DMA_CONTROL); - else - writel((1 << 8) | TIFM_DMA_EN, - sock->addr + SOCK_DMA_CONTROL); - } else { - tifm_ms_transfer_data(host, - host->req->data_dir == READ); - } + host->use_dma = !no_dma; - cmd_mask = readl(sock->addr + SOCK_MS_SYSTEM); - cmd_mask |= TIFM_MS_SYS_DATA | TIFM_MS_SYS_NOT_RDY; - writel(cmd_mask, sock->addr + SOCK_MS_SYSTEM); - } else if (host->req->io_type == MEMSTICK_IO_VAL) { - data = host->req->data; + if (host->req->long_data) { + data_len = host->req->sg.length; + if (!is_power_of_2(data_len)) + host->use_dma = 0; + } else { data_len = host->req->data_len; + host->use_dma = 0; + } - cmd_mask = host->mode_mask | 0x2607; /* unknown constant */ - - if (host->req->data_dir == WRITE) { - cmd_mask |= TIFM_MS_SYS_LATCH; - writel(cmd_mask, sock->addr + SOCK_MS_SYSTEM); - for (cnt = 0; (data_len - cnt) >= 4; cnt += 4) { - writel(TIFM_MS_SYS_LATCH - | readl(sock->addr + SOCK_MS_SYSTEM), - sock->addr + SOCK_MS_SYSTEM); - __raw_writel(*(unsigned int *)(data + cnt), - sock->addr + SOCK_MS_DATA); - dev_dbg(&sock->dev, "writing %x\n", - *(int *)(data + cnt)); - } - switch (data_len - cnt) { - case 3: - tval |= data[cnt + 2] << 16; - case 2: - tval |= data[cnt + 1] << 8; - case 1: - tval |= data[cnt]; - writel(TIFM_MS_SYS_LATCH - | readl(sock->addr + SOCK_MS_SYSTEM), - sock->addr + SOCK_MS_SYSTEM); - writel(tval, sock->addr + SOCK_MS_DATA); - dev_dbg(&sock->dev, "writing %x\n", tval); - } + writel(TIFM_FIFO_INT_SETALL, + sock->addr + SOCK_DMA_FIFO_INT_ENABLE_CLEAR); + writel(TIFM_FIFO_ENABLE, + sock->addr + SOCK_FIFO_CONTROL); + + if (host->use_dma) { + if (1 != tifm_map_sg(sock, &host->req->sg, 1, + host->req->data_dir == READ + ? PCI_DMA_FROMDEVICE + : PCI_DMA_TODEVICE)) { + host->req->error = -ENOMEM; + return host->req->error; + } + data_len = sg_dma_len(&host->req->sg); - writel(TIFM_MS_SYS_LATCH - | readl(sock->addr + SOCK_MS_SYSTEM), - sock->addr + SOCK_MS_SYSTEM); - writel(0, sock->addr + SOCK_MS_DATA); - dev_dbg(&sock->dev, "writing %x\n", 0); + writel(ilog2(data_len) - 2, + sock->addr + SOCK_FIFO_PAGE_SIZE); + writel(TIFM_FIFO_INTMASK, + sock->addr + SOCK_DMA_FIFO_INT_ENABLE_SET); + sys_param = TIFM_DMA_EN | (1 << 8); + if (host->req->data_dir == WRITE) + sys_param |= TIFM_DMA_TX; + + writel(TIFM_FIFO_INTMASK, + sock->addr + SOCK_DMA_FIFO_INT_ENABLE_SET); - } else - writel(cmd_mask, sock->addr + SOCK_MS_SYSTEM); + writel(sg_dma_address(&host->req->sg), + sock->addr + SOCK_DMA_ADDRESS); + writel(sys_param, sock->addr + SOCK_DMA_CONTROL); + } else { + writel(host->mode_mask | TIFM_MS_SYS_FIFO, + sock->addr + SOCK_MS_SYSTEM); - cmd_mask = readl(sock->addr + SOCK_MS_SYSTEM); - cmd_mask &= ~TIFM_MS_SYS_DATA; - cmd_mask |= TIFM_MS_SYS_NOT_RDY; - dev_dbg(&sock->dev, "mask %x\n", cmd_mask); - writel(cmd_mask, sock->addr + SOCK_MS_SYSTEM); - } else - BUG(); + writel(TIFM_FIFO_MORE, + sock->addr + SOCK_DMA_FIFO_INT_ENABLE_SET); + } mod_timer(&host->timer, jiffies + host->timeout_jiffies); writel(TIFM_CTRL_LED | readl(sock->addr + SOCK_CONTROL), sock->addr + SOCK_CONTROL); host->req->error = 0; + sys_param = readl(sock->addr + SOCK_MS_SYSTEM); + sys_param |= TIFM_MS_SYS_INTCLR; + + if (host->use_dma) + sys_param |= TIFM_MS_SYS_DMA; + else + sys_param &= ~TIFM_MS_SYS_DMA; + + writel(sys_param, sock->addr + SOCK_MS_SYSTEM); + cmd = (host->req->tpc & 0xf) << 12; cmd |= data_len; writel(cmd, sock->addr + SOCK_MS_COMMAND); - dev_dbg(&sock->dev, "executing TPC %x, %x\n", cmd, cmd_mask); + dev_dbg(&sock->dev, "executing TPC %x, %x\n", cmd, sys_param); return 0; } @@ -314,47 +336,20 @@ static void tifm_ms_complete_cmd(struct tifm_ms *host) { struct tifm_dev *sock = host->dev; struct memstick_host *msh = tifm_get_drvdata(sock); - unsigned int tval = 0, data_len; - unsigned char *data; int rc; del_timer(&host->timer); - if (host->req->io_type == MEMSTICK_IO_SG) { - if (!host->no_dma) - tifm_unmap_sg(sock, &host->req->sg, 1, - host->req->data_dir == READ - ? PCI_DMA_FROMDEVICE - : PCI_DMA_TODEVICE); - } else if (host->req->io_type == MEMSTICK_IO_VAL) { - writel(~TIFM_MS_SYS_DATA & readl(sock->addr + SOCK_MS_SYSTEM), - sock->addr + SOCK_MS_SYSTEM); - - data = host->req->data; - data_len = host->req->data_len; - if (host->req->data_dir == READ) { - for (rc = 0; (data_len - rc) >= 4; rc += 4) - *(int *)(data + rc) - = __raw_readl(sock->addr - + SOCK_MS_DATA); - - if (data_len - rc) - tval = readl(sock->addr + SOCK_MS_DATA); - switch (data_len - rc) { - case 3: - data[rc + 2] = (tval >> 16) & 0xff; - case 2: - data[rc + 1] = (tval >> 8) & 0xff; - case 1: - data[rc] = tval & 0xff; - } - readl(sock->addr + SOCK_MS_DATA); - } - } + if (host->use_dma) + tifm_unmap_sg(sock, &host->req->sg, 1, + host->req->data_dir == READ + ? PCI_DMA_FROMDEVICE + : PCI_DMA_TODEVICE); writel((~TIFM_CTRL_LED) & readl(sock->addr + SOCK_CONTROL), sock->addr + SOCK_CONTROL); + dev_dbg(&sock->dev, "TPC complete\n"); do { rc = memstick_next_req(msh, &host->req); } while (!rc && tifm_ms_issue_cmd(host)); @@ -365,11 +360,10 @@ static int tifm_ms_check_status(struct tifm_ms *host) if (!host->req->error) { if (!(host->cmd_flags & CMD_READY)) return 1; - if ((host->req->io_type == MEMSTICK_IO_SG) - && !(host->cmd_flags & FIFO_READY)) + if (!(host->cmd_flags & FIFO_READY)) return 1; if (host->req->need_card_int - && !(host->cmd_flags & CARD_READY)) + && !(host->cmd_flags & CARD_INT)) return 1; } return 0; @@ -379,18 +373,24 @@ static int tifm_ms_check_status(struct tifm_ms *host) static void tifm_ms_data_event(struct tifm_dev *sock) { struct tifm_ms *host; - unsigned int fifo_status = 0; + unsigned int fifo_status = 0, host_status = 0; int rc = 1; spin_lock(&sock->lock); host = memstick_priv((struct memstick_host *)tifm_get_drvdata(sock)); fifo_status = readl(sock->addr + SOCK_DMA_FIFO_STATUS); - dev_dbg(&sock->dev, "data event: fifo_status %x, flags %x\n", - fifo_status, host->cmd_flags); + host_status = readl(sock->addr + SOCK_MS_STATUS); + dev_dbg(&sock->dev, + "data event: fifo_status %x, host_status %x, flags %x\n", + fifo_status, host_status, host->cmd_flags); if (host->req) { - if (fifo_status & TIFM_FIFO_READY) { - if (!host->no_dma || tifm_ms_transfer_data(host, 0)) { + if (host->use_dma && (fifo_status & 1)) { + host->cmd_flags |= FIFO_READY; + rc = tifm_ms_check_status(host); + } + if (!host->use_dma && (fifo_status & TIFM_FIFO_MORE)) { + if (!tifm_ms_transfer_data(host)) { host->cmd_flags |= FIFO_READY; rc = tifm_ms_check_status(host); } @@ -419,9 +419,9 @@ static void tifm_ms_card_event(struct tifm_dev *sock) host_status, host->cmd_flags); if (host->req) { - if (host_status & TIFM_MS_TIMEOUT) + if (host_status & TIFM_MS_STAT_TOE) host->req->error = -ETIME; - else if (host_status & TIFM_MS_BADCRC) + else if (host_status & TIFM_MS_STAT_CRC) host->req->error = -EILSEQ; if (host->req->error) { @@ -430,18 +430,17 @@ static void tifm_ms_card_event(struct tifm_dev *sock) writel(TIFM_DMA_RESET, sock->addr + SOCK_DMA_CONTROL); } - if (host_status & TIFM_MS_EOTPC) + if (host_status & TIFM_MS_STAT_RDY) host->cmd_flags |= CMD_READY; - if (host_status & TIFM_MS_INT) - host->cmd_flags |= CARD_READY; + + if (host_status & TIFM_MS_STAT_MSINT) + host->cmd_flags |= CARD_INT; rc = tifm_ms_check_status(host); } - writel(TIFM_MS_SYS_NOT_RDY | readl(sock->addr + SOCK_MS_SYSTEM), - sock->addr + SOCK_MS_SYSTEM); - writel((~TIFM_MS_SYS_DATA) & readl(sock->addr + SOCK_MS_SYSTEM), + writel(TIFM_MS_SYS_INTCLR | readl(sock->addr + SOCK_MS_SYSTEM), sock->addr + SOCK_MS_SYSTEM); if (!rc) @@ -497,15 +496,26 @@ static void tifm_ms_set_param(struct memstick_host *msh, switch (param) { case MEMSTICK_POWER: - /* this is set by card detection mechanism */ + /* also affected by media detection mechanism */ + if (value == MEMSTICK_POWER_ON) { + host->mode_mask = TIFM_MS_SYS_SRAC | TIFM_MS_SYS_REI; + writel(TIFM_MS_SYS_RESET, sock->addr + SOCK_MS_SYSTEM); + writel(TIFM_MS_SYS_FCLR | TIFM_MS_SYS_INTCLR, + sock->addr + SOCK_MS_SYSTEM); + writel(0xffffffff, sock->addr + SOCK_MS_STATUS); + } else if (value == MEMSTICK_POWER_OFF) { + writel(TIFM_MS_SYS_FCLR | TIFM_MS_SYS_INTCLR, + sock->addr + SOCK_MS_SYSTEM); + writel(0xffffffff, sock->addr + SOCK_MS_STATUS); + } break; case MEMSTICK_INTERFACE: if (value == MEMSTICK_SERIAL) { - host->mode_mask = TIFM_MS_SERIAL; + host->mode_mask = TIFM_MS_SYS_SRAC | TIFM_MS_SYS_REI; writel((~TIFM_CTRL_FAST_CLK) & readl(sock->addr + SOCK_CONTROL), sock->addr + SOCK_CONTROL); - } else if (value == MEMSTICK_PARALLEL) { + } else if (value == MEMSTICK_PAR4) { host->mode_mask = 0; writel(TIFM_CTRL_FAST_CLK | readl(sock->addr + SOCK_CONTROL), @@ -532,21 +542,6 @@ static void tifm_ms_abort(unsigned long data) tifm_eject(host->dev); } -static int tifm_ms_initialize_host(struct tifm_ms *host) -{ - struct tifm_dev *sock = host->dev; - struct memstick_host *msh = tifm_get_drvdata(sock); - - host->mode_mask = TIFM_MS_SERIAL; - writel(0x8000, sock->addr + SOCK_MS_SYSTEM); - writel(0x0200 | TIFM_MS_SYS_NOT_RDY, sock->addr + SOCK_MS_SYSTEM); - writel(0xffffffff, sock->addr + SOCK_MS_STATUS); - if (tifm_has_ms_pif(sock)) - msh->caps |= MEMSTICK_CAP_PARALLEL; - - return 0; -} - static int tifm_ms_probe(struct tifm_dev *sock) { struct memstick_host *msh; @@ -568,7 +563,6 @@ static int tifm_ms_probe(struct tifm_dev *sock) tifm_set_drvdata(sock, msh); host->dev = sock; host->timeout_jiffies = msecs_to_jiffies(1000); - host->no_dma = no_dma; setup_timer(&host->timer, tifm_ms_abort, (unsigned long)host); @@ -576,10 +570,10 @@ static int tifm_ms_probe(struct tifm_dev *sock) msh->set_param = tifm_ms_set_param; sock->card_event = tifm_ms_card_event; sock->data_event = tifm_ms_data_event; - rc = tifm_ms_initialize_host(host); + if (tifm_has_ms_pif(sock)) + msh->caps |= MEMSTICK_CAP_PAR4; - if (!rc) - rc = memstick_add_host(msh); + rc = memstick_add_host(msh); if (!rc) return 0; @@ -601,7 +595,7 @@ static void tifm_ms_remove(struct tifm_dev *sock) writel(TIFM_FIFO_INT_SETALL, sock->addr + SOCK_DMA_FIFO_INT_ENABLE_CLEAR); writel(TIFM_DMA_RESET, sock->addr + SOCK_DMA_CONTROL); - if ((host->req->io_type == MEMSTICK_IO_SG) && !host->no_dma) + if (host->use_dma) tifm_unmap_sg(sock, &host->req->sg, 1, host->req->data_dir == READ ? PCI_DMA_TODEVICE @@ -617,10 +611,6 @@ static void tifm_ms_remove(struct tifm_dev *sock) spin_unlock_irqrestore(&sock->lock, flags); memstick_remove_host(msh); - - writel(0x0200 | TIFM_MS_SYS_NOT_RDY, sock->addr + SOCK_MS_SYSTEM); - writel(0xffffffff, sock->addr + SOCK_MS_STATUS); - memstick_free_host(msh); } @@ -628,17 +618,17 @@ static void tifm_ms_remove(struct tifm_dev *sock) static int tifm_ms_suspend(struct tifm_dev *sock, pm_message_t state) { + struct memstick_host *msh = tifm_get_drvdata(sock); + + memstick_suspend_host(msh); return 0; } static int tifm_ms_resume(struct tifm_dev *sock) { struct memstick_host *msh = tifm_get_drvdata(sock); - struct tifm_ms *host = memstick_priv(msh); - - tifm_ms_initialize_host(host); - memstick_detect_change(msh); + memstick_resume_host(msh); return 0; } @@ -679,7 +669,6 @@ MODULE_AUTHOR("Alex Dubov"); MODULE_DESCRIPTION("TI FlashMedia MemoryStick driver"); MODULE_LICENSE("GPL"); MODULE_DEVICE_TABLE(tifm, tifm_ms_id_tbl); -MODULE_VERSION(DRIVER_VERSION); module_init(tifm_ms_init); module_exit(tifm_ms_exit); diff --git a/drivers/message/fusion/mptbase.c b/drivers/message/fusion/mptbase.c index 0c303c84b37bbcebf86b8f29f8c4167de6b3db37..6b6df8679585dfae3715f327683a8f677e17eae8 100644 --- a/drivers/message/fusion/mptbase.c +++ b/drivers/message/fusion/mptbase.c @@ -632,8 +632,7 @@ mpt_deregister(u8 cb_idx) /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /** - * mpt_event_register - Register protocol-specific event callback - * handler. + * mpt_event_register - Register protocol-specific event callback handler. * @cb_idx: previously registered (via mpt_register) callback handle * @ev_cbfunc: callback function * @@ -654,8 +653,7 @@ mpt_event_register(u8 cb_idx, MPT_EVHANDLER ev_cbfunc) /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /** - * mpt_event_deregister - Deregister protocol-specific event callback - * handler. + * mpt_event_deregister - Deregister protocol-specific event callback handler * @cb_idx: previously registered callback handle * * Each protocol-specific driver should call this routine @@ -765,11 +763,13 @@ mpt_device_driver_deregister(u8 cb_idx) /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /** - * mpt_get_msg_frame - Obtain a MPT request frame from the pool (of 1024) - * allocated per MPT adapter. + * mpt_get_msg_frame - Obtain an MPT request frame from the pool * @cb_idx: Handle of registered MPT protocol driver * @ioc: Pointer to MPT adapter structure * + * Obtain an MPT request frame from the pool (of 1024) that are + * allocated per MPT adapter. + * * Returns pointer to a MPT request frame or %NULL if none are available * or IOC is not active. */ @@ -834,13 +834,12 @@ mpt_get_msg_frame(u8 cb_idx, MPT_ADAPTER *ioc) /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /** - * mpt_put_msg_frame - Send a protocol specific MPT request frame - * to a IOC. + * mpt_put_msg_frame - Send a protocol-specific MPT request frame to an IOC * @cb_idx: Handle of registered MPT protocol driver * @ioc: Pointer to MPT adapter structure * @mf: Pointer to MPT request frame * - * This routine posts a MPT request frame to the request post FIFO of a + * This routine posts an MPT request frame to the request post FIFO of a * specific MPT adapter. */ void @@ -868,13 +867,15 @@ mpt_put_msg_frame(u8 cb_idx, MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf) } /** - * mpt_put_msg_frame_hi_pri - Send a protocol specific MPT request frame - * to a IOC using hi priority request queue. + * mpt_put_msg_frame_hi_pri - Send a hi-pri protocol-specific MPT request frame * @cb_idx: Handle of registered MPT protocol driver * @ioc: Pointer to MPT adapter structure * @mf: Pointer to MPT request frame * - * This routine posts a MPT request frame to the request post FIFO of a + * Send a protocol-specific MPT request frame to an IOC using + * hi-priority request queue. + * + * This routine posts an MPT request frame to the request post FIFO of a * specific MPT adapter. **/ void diff --git a/drivers/message/fusion/mptsas.c b/drivers/message/fusion/mptsas.c index f77b329f6923baab6e4b23742981b97b58393046..78734e25edd515bcc863fbcae3216c6447e045eb 100644 --- a/drivers/message/fusion/mptsas.c +++ b/drivers/message/fusion/mptsas.c @@ -1701,6 +1701,11 @@ mptsas_sas_expander_pg0(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info, if (error) goto out_free_consistent; + if (!buffer->NumPhys) { + error = -ENODEV; + goto out_free_consistent; + } + /* save config data */ port_info->num_phys = buffer->NumPhys; port_info->phy_info = kcalloc(port_info->num_phys, diff --git a/drivers/message/fusion/mptscsih.c b/drivers/message/fusion/mptscsih.c index af1de0ccee2f54c37c3567585e9e73db6f83bfe4..0c252f60c4c1ba2c5ee4e7012b21dc6dddf36129 100644 --- a/drivers/message/fusion/mptscsih.c +++ b/drivers/message/fusion/mptscsih.c @@ -1533,7 +1533,7 @@ mptscsih_freeChainBuffers(MPT_ADAPTER *ioc, int req_idx) * * Remark: Currently invoked from a non-interrupt thread (_bh). * - * Remark: With old EH code, at most 1 SCSI TaskMgmt function per IOC + * Note: With old EH code, at most 1 SCSI TaskMgmt function per IOC * will be active. * * Returns 0 for SUCCESS, or %FAILED. @@ -2537,14 +2537,12 @@ mptscsih_copy_sense_data(struct scsi_cmnd *sc, MPT_SCSI_HOST *hd, MPT_FRAME_HDR /** * mptscsih_get_scsi_lookup - * - * retrieves scmd entry from ScsiLookup[] array list - * * @ioc: Pointer to MPT_ADAPTER structure * @i: index into the array * - * Returns the scsi_cmd pointer + * retrieves scmd entry from ScsiLookup[] array list * + * Returns the scsi_cmd pointer **/ static struct scsi_cmnd * mptscsih_get_scsi_lookup(MPT_ADAPTER *ioc, int i) @@ -2561,14 +2559,12 @@ mptscsih_get_scsi_lookup(MPT_ADAPTER *ioc, int i) /** * mptscsih_getclear_scsi_lookup - * - * retrieves and clears scmd entry from ScsiLookup[] array list - * * @ioc: Pointer to MPT_ADAPTER structure * @i: index into the array * - * Returns the scsi_cmd pointer + * retrieves and clears scmd entry from ScsiLookup[] array list * + * Returns the scsi_cmd pointer **/ static struct scsi_cmnd * mptscsih_getclear_scsi_lookup(MPT_ADAPTER *ioc, int i) diff --git a/drivers/mfd/sm501.c b/drivers/mfd/sm501.c index afd82966f9a0782ad5624f45fcf4538e3755a73f..13bac53db69a1ffe58726720a461ee0bbac9edd0 100644 --- a/drivers/mfd/sm501.c +++ b/drivers/mfd/sm501.c @@ -48,31 +48,13 @@ struct sm501_devdata { unsigned int pdev_id; unsigned int irq; void __iomem *regs; + unsigned int rev; }; #define MHZ (1000 * 1000) #ifdef DEBUG -static const unsigned int misc_div[] = { - [0] = 1, - [1] = 2, - [2] = 4, - [3] = 8, - [4] = 16, - [5] = 32, - [6] = 64, - [7] = 128, - [8] = 3, - [9] = 6, - [10] = 12, - [11] = 24, - [12] = 48, - [13] = 96, - [14] = 192, - [15] = 384, -}; - -static const unsigned int px_div[] = { +static const unsigned int div_tab[] = { [0] = 1, [1] = 2, [2] = 4, @@ -101,12 +83,12 @@ static const unsigned int px_div[] = { static unsigned long decode_div(unsigned long pll2, unsigned long val, unsigned int lshft, unsigned int selbit, - unsigned long mask, const unsigned int *dtab) + unsigned long mask) { if (val & selbit) pll2 = 288 * MHZ; - return pll2 / dtab[(val >> lshft) & mask]; + return pll2 / div_tab[(val >> lshft) & mask]; } #define fmt_freq(x) ((x) / MHZ), ((x) % MHZ), (x) @@ -141,10 +123,10 @@ static void sm501_dump_clk(struct sm501_devdata *sm) } sdclk0 = (misct & (1<<12)) ? pll2 : 288 * MHZ; - sdclk0 /= misc_div[((misct >> 8) & 0xf)]; + sdclk0 /= div_tab[((misct >> 8) & 0xf)]; sdclk1 = (misct & (1<<20)) ? pll2 : 288 * MHZ; - sdclk1 /= misc_div[((misct >> 16) & 0xf)]; + sdclk1 /= div_tab[((misct >> 16) & 0xf)]; dev_dbg(sm->dev, "MISCT=%08lx, PM0=%08lx, PM1=%08lx\n", misct, pm0, pm1); @@ -158,19 +140,19 @@ static void sm501_dump_clk(struct sm501_devdata *sm) "P2 %ld.%ld MHz (%ld), V2 %ld.%ld (%ld), " "M %ld.%ld (%ld), MX1 %ld.%ld (%ld)\n", (pmc & 3 ) == 0 ? '*' : '-', - fmt_freq(decode_div(pll2, pm0, 24, 1<<29, 31, px_div)), - fmt_freq(decode_div(pll2, pm0, 16, 1<<20, 15, misc_div)), - fmt_freq(decode_div(pll2, pm0, 8, 1<<12, 15, misc_div)), - fmt_freq(decode_div(pll2, pm0, 0, 1<<4, 15, misc_div))); + fmt_freq(decode_div(pll2, pm0, 24, 1<<29, 31)), + fmt_freq(decode_div(pll2, pm0, 16, 1<<20, 15)), + fmt_freq(decode_div(pll2, pm0, 8, 1<<12, 15)), + fmt_freq(decode_div(pll2, pm0, 0, 1<<4, 15))); dev_dbg(sm->dev, "PM1[%c]: " "P2 %ld.%ld MHz (%ld), V2 %ld.%ld (%ld), " "M %ld.%ld (%ld), MX1 %ld.%ld (%ld)\n", (pmc & 3 ) == 1 ? '*' : '-', - fmt_freq(decode_div(pll2, pm1, 24, 1<<29, 31, px_div)), - fmt_freq(decode_div(pll2, pm1, 16, 1<<20, 15, misc_div)), - fmt_freq(decode_div(pll2, pm1, 8, 1<<12, 15, misc_div)), - fmt_freq(decode_div(pll2, pm1, 0, 1<<4, 15, misc_div))); + fmt_freq(decode_div(pll2, pm1, 24, 1<<29, 31)), + fmt_freq(decode_div(pll2, pm1, 16, 1<<20, 15)), + fmt_freq(decode_div(pll2, pm1, 8, 1<<12, 15)), + fmt_freq(decode_div(pll2, pm1, 0, 1<<4, 15))); } static void sm501_dump_regs(struct sm501_devdata *sm) @@ -436,46 +418,108 @@ struct sm501_clock { unsigned long mclk; int divider; int shift; + unsigned int m, n, k; }; +/* sm501_calc_clock + * + * Calculates the nearest discrete clock frequency that + * can be achieved with the specified input clock. + * the maximum divisor is 3 or 5 + */ + +static int sm501_calc_clock(unsigned long freq, + struct sm501_clock *clock, + int max_div, + unsigned long mclk, + long *best_diff) +{ + int ret = 0; + int divider; + int shift; + long diff; + + /* try dividers 1 and 3 for CRT and for panel, + try divider 5 for panel only.*/ + + for (divider = 1; divider <= max_div; divider += 2) { + /* try all 8 shift values.*/ + for (shift = 0; shift < 8; shift++) { + /* Calculate difference to requested clock */ + diff = sm501fb_round_div(mclk, divider << shift) - freq; + if (diff < 0) + diff = -diff; + + /* If it is less than the current, use it */ + if (diff < *best_diff) { + *best_diff = diff; + + clock->mclk = mclk; + clock->divider = divider; + clock->shift = shift; + ret = 1; + } + } + } + + return ret; +} + +/* sm501_calc_pll + * + * Calculates the nearest discrete clock frequency that can be + * achieved using the programmable PLL. + * the maximum divisor is 3 or 5 + */ + +static unsigned long sm501_calc_pll(unsigned long freq, + struct sm501_clock *clock, + int max_div) +{ + unsigned long mclk; + unsigned int m, n, k; + long best_diff = 999999999; + + /* + * The SM502 datasheet doesn't specify the min/max values for M and N. + * N = 1 at least doesn't work in practice. + */ + for (m = 2; m <= 255; m++) { + for (n = 2; n <= 127; n++) { + for (k = 0; k <= 1; k++) { + mclk = (24000000UL * m / n) >> k; + + if (sm501_calc_clock(freq, clock, max_div, + mclk, &best_diff)) { + clock->m = m; + clock->n = n; + clock->k = k; + } + } + } + } + + /* Return best clock. */ + return clock->mclk / (clock->divider << clock->shift); +} + /* sm501_select_clock * - * selects nearest discrete clock frequency the SM501 can achive + * Calculates the nearest discrete clock frequency that can be + * achieved using the 288MHz and 336MHz PLLs. * the maximum divisor is 3 or 5 */ + static unsigned long sm501_select_clock(unsigned long freq, struct sm501_clock *clock, int max_div) { unsigned long mclk; - int divider; - int shift; - long diff; long best_diff = 999999999; /* Try 288MHz and 336MHz clocks. */ for (mclk = 288000000; mclk <= 336000000; mclk += 48000000) { - /* try dividers 1 and 3 for CRT and for panel, - try divider 5 for panel only.*/ - - for (divider = 1; divider <= max_div; divider += 2) { - /* try all 8 shift values.*/ - for (shift = 0; shift < 8; shift++) { - /* Calculate difference to requested clock */ - diff = sm501fb_round_div(mclk, divider << shift) - freq; - if (diff < 0) - diff = -diff; - - /* If it is less than the current, use it */ - if (diff < best_diff) { - best_diff = diff; - - clock->mclk = mclk; - clock->divider = divider; - clock->shift = shift; - } - } - } + sm501_calc_clock(freq, clock, max_div, mclk, &best_diff); } /* Return best clock. */ @@ -497,6 +541,7 @@ unsigned long sm501_set_clock(struct device *dev, unsigned long gate = readl(sm->regs + SM501_CURRENT_GATE); unsigned long clock = readl(sm->regs + SM501_CURRENT_CLOCK); unsigned char reg; + unsigned int pll_reg = 0; unsigned long sm501_freq; /* the actual frequency acheived */ struct sm501_clock to; @@ -511,14 +556,28 @@ unsigned long sm501_set_clock(struct device *dev, * requested frequency the value must be multiplied by * 2. This clock also has an additional pre divisor */ - sm501_freq = (sm501_select_clock(2 * req_freq, &to, 5) / 2); - reg=to.shift & 0x07;/* bottom 3 bits are shift */ - if (to.divider == 3) - reg |= 0x08; /* /3 divider required */ - else if (to.divider == 5) - reg |= 0x10; /* /5 divider required */ - if (to.mclk != 288000000) - reg |= 0x20; /* which mclk pll is source */ + if (sm->rev >= 0xC0) { + /* SM502 -> use the programmable PLL */ + sm501_freq = (sm501_calc_pll(2 * req_freq, + &to, 5) / 2); + reg = to.shift & 0x07;/* bottom 3 bits are shift */ + if (to.divider == 3) + reg |= 0x08; /* /3 divider required */ + else if (to.divider == 5) + reg |= 0x10; /* /5 divider required */ + reg |= 0x40; /* select the programmable PLL */ + pll_reg = 0x20000 | (to.k << 15) | (to.n << 8) | to.m; + } else { + sm501_freq = (sm501_select_clock(2 * req_freq, + &to, 5) / 2); + reg = to.shift & 0x07;/* bottom 3 bits are shift */ + if (to.divider == 3) + reg |= 0x08; /* /3 divider required */ + else if (to.divider == 5) + reg |= 0x10; /* /5 divider required */ + if (to.mclk != 288000000) + reg |= 0x20; /* which mclk pll is source */ + } break; case SM501_CLOCK_V2XCLK: @@ -579,6 +638,10 @@ unsigned long sm501_set_clock(struct device *dev, } writel(mode, sm->regs + SM501_POWER_MODE_CONTROL); + + if (pll_reg) + writel(pll_reg, sm->regs + SM501_PROGRAMMABLE_PLL_CONTROL); + sm501_sync_regs(sm); dev_info(sm->dev, "gate %08lx, clock %08lx, mode %08lx\n", @@ -599,15 +662,24 @@ EXPORT_SYMBOL_GPL(sm501_set_clock); * finds the closest available frequency for a given clock */ -unsigned long sm501_find_clock(int clksrc, +unsigned long sm501_find_clock(struct device *dev, + int clksrc, unsigned long req_freq) { + struct sm501_devdata *sm = dev_get_drvdata(dev); unsigned long sm501_freq; /* the frequency achiveable by the 501 */ struct sm501_clock to; switch (clksrc) { case SM501_CLOCK_P2XCLK: - sm501_freq = (sm501_select_clock(2 * req_freq, &to, 5) / 2); + if (sm->rev >= 0xC0) { + /* SM502 -> use the programmable PLL */ + sm501_freq = (sm501_calc_pll(2 * req_freq, + &to, 5) / 2); + } else { + sm501_freq = (sm501_select_clock(2 * req_freq, + &to, 5) / 2); + } break; case SM501_CLOCK_V2XCLK: @@ -914,6 +986,8 @@ static int sm501_init_dev(struct sm501_devdata *sm) dev_info(sm->dev, "SM501 At %p: Version %08lx, %ld Mb, IRQ %d\n", sm->regs, devid, (unsigned long)mem_avail >> 20, sm->irq); + sm->rev = devid & SM501_DEVICEID_REVMASK; + sm501_dump_gate(sm); ret = device_create_file(sm->dev, &dev_attr_dbg_regs); diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig index 982e27b86d101a15ebb2f579652a67d4ae08f806..962817e49fba02e063dc164a3d0971e221eaa3a7 100644 --- a/drivers/misc/Kconfig +++ b/drivers/misc/Kconfig @@ -108,6 +108,7 @@ config ACER_WMI depends on ACPI depends on LEDS_CLASS depends on BACKLIGHT_CLASS_DEVICE + depends on SERIO_I8042 select ACPI_WMI ---help--- This is a driver for newer Acer (and Wistron) laptops. It adds diff --git a/drivers/misc/acer-wmi.c b/drivers/misc/acer-wmi.c index 74d12b4a3abdae48be072857ec75a34c90496dcb..dd13a3749927494804aa4566c59df652d963f40b 100644 --- a/drivers/misc/acer-wmi.c +++ b/drivers/misc/acer-wmi.c @@ -217,6 +217,15 @@ static struct dmi_system_id acer_quirks[] = { }, .driver_data = &quirk_acer_travelmate_2490, }, + { + .callback = dmi_matched, + .ident = "Acer Aspire 3610", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Acer"), + DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 3610"), + }, + .driver_data = &quirk_acer_travelmate_2490, + }, { .callback = dmi_matched, .ident = "Acer Aspire 5100", @@ -226,6 +235,15 @@ static struct dmi_system_id acer_quirks[] = { }, .driver_data = &quirk_acer_travelmate_2490, }, + { + .callback = dmi_matched, + .ident = "Acer Aspire 5610", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Acer"), + DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5610"), + }, + .driver_data = &quirk_acer_travelmate_2490, + }, { .callback = dmi_matched, .ident = "Acer Aspire 5630", @@ -761,11 +779,11 @@ enum led_brightness value) } static struct led_classdev mail_led = { - .name = "acer-mail:green", + .name = "acer-wmi::mail", .brightness_set = mail_led_set, }; -static int __init acer_led_init(struct device *dev) +static int __devinit acer_led_init(struct device *dev) { return led_classdev_register(dev, &mail_led); } @@ -798,7 +816,7 @@ static struct backlight_ops acer_bl_ops = { .update_status = update_bl_status, }; -static int __init acer_backlight_init(struct device *dev) +static int __devinit acer_backlight_init(struct device *dev) { struct backlight_device *bd; @@ -817,7 +835,7 @@ static int __init acer_backlight_init(struct device *dev) return 0; } -static void __exit acer_backlight_exit(void) +static void acer_backlight_exit(void) { backlight_device_unregister(acer_backlight_device); } @@ -1052,11 +1070,12 @@ static int __init acer_wmi_init(void) if (wmi_has_guid(WMID_GUID2) && interface) { if (ACPI_FAILURE(WMID_set_capabilities())) { - printk(ACER_ERR "Unable to detect available devices\n"); + printk(ACER_ERR "Unable to detect available WMID " + "devices\n"); return -ENODEV; } } else if (!wmi_has_guid(WMID_GUID2) && interface) { - printk(ACER_ERR "Unable to detect available devices\n"); + printk(ACER_ERR "No WMID device detection method found\n"); return -ENODEV; } @@ -1064,21 +1083,20 @@ static int __init acer_wmi_init(void) interface = &AMW0_interface; if (ACPI_FAILURE(AMW0_set_capabilities())) { - printk(ACER_ERR "Unable to detect available devices\n"); + printk(ACER_ERR "Unable to detect available AMW0 " + "devices\n"); return -ENODEV; } } - if (wmi_has_guid(AMW0_GUID1)) { - if (ACPI_FAILURE(AMW0_find_mailled())) - printk(ACER_ERR "Unable to detect mail LED\n"); - } + if (wmi_has_guid(AMW0_GUID1)) + AMW0_find_mailled(); find_quirks(); if (!interface) { - printk(ACER_ERR "No or unsupported WMI interface, unable to "); - printk(KERN_CONT "load.\n"); + printk(ACER_ERR "No or unsupported WMI interface, unable to " + "load\n"); return -ENODEV; } diff --git a/drivers/misc/sony-laptop.c b/drivers/misc/sony-laptop.c index 899e3f75f288dd853a50f61e9c15772ea3d60b01..02ff3d19b1ccaf40981c861e9977c43eea634f3f 100644 --- a/drivers/misc/sony-laptop.c +++ b/drivers/misc/sony-laptop.c @@ -315,7 +315,7 @@ static void sony_laptop_report_input_event(u8 event) break; default: - if (event > ARRAY_SIZE(sony_laptop_input_index)) { + if (event >= ARRAY_SIZE(sony_laptop_input_index)) { dprintk("sony_laptop_report_input_event, event not known: %d\n", event); break; } diff --git a/drivers/misc/thinkpad_acpi.c b/drivers/misc/thinkpad_acpi.c index bb269d0c677edbc4cadd268dc634e90b6120a80e..6cb781262f947611a20916bf6b996c9ff3e713cb 100644 --- a/drivers/misc/thinkpad_acpi.c +++ b/drivers/misc/thinkpad_acpi.c @@ -1078,7 +1078,8 @@ static int hotkey_get_tablet_mode(int *status) if (!acpi_evalf(hkey_handle, &s, "MHKG", "d")) return -EIO; - return ((s & TP_HOTKEY_TABLET_MASK) != 0); + *status = ((s & TP_HOTKEY_TABLET_MASK) != 0); + return 0; } /* diff --git a/drivers/misc/tifm_7xx1.c b/drivers/misc/tifm_7xx1.c index 63a089b29545a3bd34eb1e64327c6b693ce04e85..67503ea71d218bc4c5ff67cdbd8afbb6e2c94a7d 100644 --- a/drivers/misc/tifm_7xx1.c +++ b/drivers/misc/tifm_7xx1.c @@ -367,6 +367,8 @@ static int tifm_7xx1_probe(struct pci_dev *dev, if (rc) goto err_out_irq; + writel(TIFM_IRQ_ENABLE | TIFM_IRQ_SOCKMASK((1 << fm->num_sockets) - 1), + fm->addr + FM_CLEAR_INTERRUPT_ENABLE); writel(TIFM_IRQ_ENABLE | TIFM_IRQ_SOCKMASK((1 << fm->num_sockets) - 1), fm->addr + FM_SET_INTERRUPT_ENABLE); return 0; diff --git a/drivers/mmc/host/tifm_sd.c b/drivers/mmc/host/tifm_sd.c index 20d5c7bd940a7c48eaa42b8af06484d918e6e6b8..1c14a186f000acc10b23b59b5bc554533bf6a4ec 100644 --- a/drivers/mmc/host/tifm_sd.c +++ b/drivers/mmc/host/tifm_sd.c @@ -180,7 +180,7 @@ static void tifm_sd_transfer_data(struct tifm_sd *host) host->sg_pos++; if (host->sg_pos == host->sg_len) { if ((r_data->flags & MMC_DATA_WRITE) - && DATA_CARRY) + && (host->cmd_flags & DATA_CARRY)) writel(host->bounce_buf_data[0], host->dev->addr + SOCK_MMCSD_DATA); diff --git a/drivers/mtd/ubi/build.c b/drivers/mtd/ubi/build.c index 6ac81e35355cd39fc8232698b790de75f077e59b..2759604629703e6ea9d9c2e6735478a9cd5a9e1c 100644 --- a/drivers/mtd/ubi/build.c +++ b/drivers/mtd/ubi/build.c @@ -1000,8 +1000,8 @@ static int __init ubi_init(void) mutex_unlock(&ubi_devices_mutex); if (err < 0) { put_mtd_device(mtd); - printk(KERN_ERR "UBI error: cannot attach %s\n", - p->name); + printk(KERN_ERR "UBI error: cannot attach mtd%d\n", + mtd->index); goto out_detach; } } diff --git a/drivers/mtd/ubi/ubi.h b/drivers/mtd/ubi/ubi.h index 457710615261126e2fef2d2ad6463c991d83a895..a548c1d28fa818a5485aa5524a2527eff269edf0 100644 --- a/drivers/mtd/ubi/ubi.h +++ b/drivers/mtd/ubi/ubi.h @@ -217,11 +217,11 @@ struct ubi_volume { void *upd_buf; int *eba_tbl; - int checked:1; - int corrupted:1; - int upd_marker:1; - int updating:1; - int changing_leb:1; + unsigned int checked:1; + unsigned int corrupted:1; + unsigned int upd_marker:1; + unsigned int updating:1; + unsigned int changing_leb:1; #ifdef CONFIG_MTD_UBI_GLUEBI /* diff --git a/drivers/mtd/ubi/vmt.c b/drivers/mtd/ubi/vmt.c index a3ca2257e6015e586ddcbfa513acb760b01afb08..5be58d85c6393c53c2be0f4693ff8a9bd13e40b3 100644 --- a/drivers/mtd/ubi/vmt.c +++ b/drivers/mtd/ubi/vmt.c @@ -376,7 +376,9 @@ out_sysfs: get_device(&vol->dev); volume_sysfs_close(vol); out_gluebi: - ubi_destroy_gluebi(vol); + if (ubi_destroy_gluebi(vol)) + dbg_err("cannot destroy gluebi for volume %d:%d", + ubi->ubi_num, vol_id); out_cdev: cdev_del(&vol->cdev); out_mapping: diff --git a/drivers/mtd/ubi/vtbl.c b/drivers/mtd/ubi/vtbl.c index 56fc3fbce838179b7d34276ccbb51e1ee2ff2018..af36b12be27871ddefd1c34a0d17f95483042343 100644 --- a/drivers/mtd/ubi/vtbl.c +++ b/drivers/mtd/ubi/vtbl.c @@ -519,6 +519,7 @@ static int init_volumes(struct ubi_device *ubi, const struct ubi_scan_info *si, if (ubi->autoresize_vol_id != -1) { ubi_err("more then one auto-resize volume (%d " "and %d)", ubi->autoresize_vol_id, i); + kfree(vol); return -EINVAL; } diff --git a/drivers/net/3c501.c b/drivers/net/3c501.c index 7d253686ed0d978b175131d8f11cdcabf816746d..5ba4bab6d43e75342e9932cd93b6207e6d0dd517 100644 --- a/drivers/net/3c501.c +++ b/drivers/net/3c501.c @@ -485,9 +485,7 @@ static int el_start_xmit(struct sk_buff *skb, struct net_device *dev) printk(KERN_DEBUG "%s: burped during tx load.\n", dev->name); spin_lock_irqsave(&lp->lock, flags); - } - while (1); - + } while (1); } /** @@ -612,7 +610,8 @@ static irqreturn_t el_interrupt(int irq, void *dev_id) dev->stats.tx_packets++; if (el_debug > 6) printk(KERN_DEBUG " Tx succeeded %s\n", - (txsr & TX_RDY) ? "." : "but tx is busy!"); + (txsr & TX_RDY) ? "." : + "but tx is busy!"); /* * This is safe the interrupt is atomic WRT itself. */ @@ -693,7 +692,8 @@ static void el_receive(struct net_device *dev) if (pkt_len < 60 || pkt_len > 1536) { if (el_debug) - printk(KERN_DEBUG "%s: bogus packet, length=%d\n", dev->name, pkt_len); + printk(KERN_DEBUG "%s: bogus packet, length=%d\n", + dev->name, pkt_len); dev->stats.rx_over_errors++; return; } @@ -711,7 +711,8 @@ static void el_receive(struct net_device *dev) outw(0x00, GP_LOW); if (skb == NULL) { - printk(KERN_INFO "%s: Memory squeeze, dropping packet.\n", dev->name); + printk(KERN_INFO "%s: Memory squeeze, dropping packet.\n", + dev->name); dev->stats.rx_dropped++; return; } else { @@ -748,7 +749,8 @@ static void el_reset(struct net_device *dev) if (el_debug > 2) printk(KERN_INFO "3c501 reset..."); outb(AX_RESET, AX_CMD); /* Reset the chip */ - outb(AX_LOOP, AX_CMD); /* Aux control, irq and loopback enabled */ + /* Aux control, irq and loopback enabled */ + outb(AX_LOOP, AX_CMD); { int i; for (i = 0; i < 6; i++) /* Set the station address. */ diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index a64bb415f10cfc93547ae7b367e6beb7c7973c2a..fe7b5ec09708adac2efa77442066a095608a802a 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -2366,15 +2366,15 @@ config GELIC_NET module will be called ps3_gelic. config GELIC_WIRELESS - bool "PS3 Wireless support" - depends on GELIC_NET - select WIRELESS_EXT - help - This option adds the support for the wireless feature of PS3. - If you have the wireless-less model of PS3 or have no plan to - use wireless feature, disabling this option saves memory. As - the driver automatically distinguishes the models, you can - safely enable this option even if you have a wireless-less model. + bool "PS3 Wireless support" + depends on GELIC_NET + select WIRELESS_EXT + help + This option adds the support for the wireless feature of PS3. + If you have the wireless-less model of PS3 or have no plan to + use wireless feature, disabling this option saves memory. As + the driver automatically distinguishes the models, you can + safely enable this option even if you have a wireless-less model. config GIANFAR tristate "Gianfar Ethernet" diff --git a/drivers/net/ac3200.c b/drivers/net/ac3200.c index 5136d94923aa3910e0007982dd7893c493e2fd62..b1448637107f3fada6f1a97536dfd6492a9d9117 100644 --- a/drivers/net/ac3200.c +++ b/drivers/net/ac3200.c @@ -369,7 +369,7 @@ MODULE_PARM_DESC(mem, "Memory base address(es)"); MODULE_DESCRIPTION("Ansel AC3200 EISA ethernet driver"); MODULE_LICENSE("GPL"); -int __init init_module(void) +static int __init ac3200_module_init(void) { struct net_device *dev; int this_dev, found = 0; @@ -404,8 +404,7 @@ static void cleanup_card(struct net_device *dev) iounmap(ei_status.mem); } -void __exit -cleanup_module(void) +static void __exit ac3200_module_exit(void) { int this_dev; @@ -418,4 +417,6 @@ cleanup_module(void) } } } +module_init(ac3200_module_init); +module_exit(ac3200_module_exit); #endif /* MODULE */ diff --git a/drivers/net/apne.c b/drivers/net/apne.c index c12cbdf368b1edbe37b3077e9debdcf4f93cc847..47a8275d396281bd79f6a2631dbfd1da93273529 100644 --- a/drivers/net/apne.c +++ b/drivers/net/apne.c @@ -569,7 +569,7 @@ static irqreturn_t apne_interrupt(int irq, void *dev_id) #ifdef MODULE static struct net_device *apne_dev; -int __init init_module(void) +static int __init apne_module_init(void) { apne_dev = apne_probe(-1); if (IS_ERR(apne_dev)) @@ -577,7 +577,7 @@ int __init init_module(void) return 0; } -void __exit cleanup_module(void) +static void __exit apne_module_exit(void) { unregister_netdev(apne_dev); @@ -591,7 +591,8 @@ void __exit cleanup_module(void) free_netdev(apne_dev); } - +module_init(apne_module_init); +module_exit(apne_module_exit); #endif static int init_pcmcia(void) diff --git a/drivers/net/appletalk/ltpc.c b/drivers/net/appletalk/ltpc.c index 6ab2c2d4d673de32baf44307a32a0d5baf00183b..fef5560bc7a2ee2d8c6aee66f6e413022fdfdca1 100644 --- a/drivers/net/appletalk/ltpc.c +++ b/drivers/net/appletalk/ltpc.c @@ -1252,7 +1252,7 @@ module_param(irq, int, 0); module_param(dma, int, 0); -int __init init_module(void) +static int __init ltpc_module_init(void) { if(io == 0) printk(KERN_NOTICE @@ -1263,6 +1263,7 @@ int __init init_module(void) return PTR_ERR(dev_ltpc); return 0; } +module_init(ltpc_module_init); #endif static void __exit ltpc_cleanup(void) diff --git a/drivers/net/arcnet/capmode.c b/drivers/net/arcnet/capmode.c index cc4610db6395f9e743e16ff374fd88f860d5dbe2..02cb8f1c11484b23460100c85f60faec62bd3ea5 100644 --- a/drivers/net/arcnet/capmode.c +++ b/drivers/net/arcnet/capmode.c @@ -80,17 +80,19 @@ void arcnet_cap_init(void) #ifdef MODULE -int __init init_module(void) +static int __init capmode_module_init(void) { printk(VERSION); arcnet_cap_init(); return 0; } -void cleanup_module(void) +static void __exit capmode_module_exit(void) { arcnet_unregister_proto(&capmode_proto); } +module_init(capmode_module_init); +module_exit(capmode_module_exit); MODULE_LICENSE("GPL"); #endif /* MODULE */ diff --git a/drivers/net/atl1/atl1_main.c b/drivers/net/atl1/atl1_main.c index 9200ee59d854aba57ab2e845c2d31bb44f07c5d1..129b8b3aa7731632853e331ee422435ef419efd3 100644 --- a/drivers/net/atl1/atl1_main.c +++ b/drivers/net/atl1/atl1_main.c @@ -1765,15 +1765,12 @@ static irqreturn_t atl1_intr(int irq, void *data) { struct atl1_adapter *adapter = netdev_priv(data); u32 status; - u8 update_rx; int max_ints = 10; status = adapter->cmb.cmb->int_stats; if (!status) return IRQ_NONE; - update_rx = 0; - do { /* clear CMB interrupt status at once */ adapter->cmb.cmb->int_stats = 0; diff --git a/drivers/net/cxgb3/sge.c b/drivers/net/cxgb3/sge.c index 979f3fc5e76567f1f20d2f03c77816a6469ab144..db586870c5f43843cacba508cfc60673f6a2864e 100644 --- a/drivers/net/cxgb3/sge.c +++ b/drivers/net/cxgb3/sge.c @@ -1107,9 +1107,15 @@ int t3_eth_xmit(struct sk_buff *skb, struct net_device *dev) } q->in_use += ndesc; - if (unlikely(credits - ndesc < q->stop_thres)) - if (USE_GTS || !should_restart_tx(q)) - t3_stop_queue(dev, qs, q); + if (unlikely(credits - ndesc < q->stop_thres)) { + t3_stop_queue(dev, qs, q); + + if (should_restart_tx(q) && + test_and_clear_bit(TXQ_ETH, &qs->txq_stopped)) { + q->restarts++; + netif_wake_queue(dev); + } + } gen = q->gen; q->unacked += ndesc; diff --git a/drivers/net/enc28j60.c b/drivers/net/enc28j60.c index 0809a6a5a286ec8325a562a4acc510a2b60ae765..46a90e9ec56320e4eaca6d48ba21c6d463981ddc 100644 --- a/drivers/net/enc28j60.c +++ b/drivers/net/enc28j60.c @@ -900,7 +900,7 @@ static void enc28j60_hw_rx(struct net_device *ndev) if (RSV_GETBIT(rxstat, RSV_LENCHECKERR)) ndev->stats.rx_frame_errors++; } else { - skb = dev_alloc_skb(len); + skb = dev_alloc_skb(len + NET_IP_ALIGN); if (!skb) { if (netif_msg_rx_err(priv)) dev_err(&ndev->dev, @@ -908,6 +908,7 @@ static void enc28j60_hw_rx(struct net_device *ndev) ndev->stats.rx_dropped++; } else { skb->dev = ndev; + skb_reserve(skb, NET_IP_ALIGN); /* copy the packet from the receive buffer */ enc28j60_mem_read(priv, priv->next_pk_ptr + sizeof(rsv), len, skb_put(skb, len)); diff --git a/drivers/net/epic100.c b/drivers/net/epic100.c index 0b365b8d947ba8dabd1dd28e94f1710d823cca77..76118ddd104272f82f194746739ceacbb102c017 100644 --- a/drivers/net/epic100.c +++ b/drivers/net/epic100.c @@ -131,8 +131,8 @@ IIIa. Ring buffers IVb. References -http://www.smsc.com/main/datasheets/83c171.pdf -http://www.smsc.com/main/datasheets/83c175.pdf +http://www.smsc.com/main/tools/discontinued/83c171.pdf +http://www.smsc.com/main/tools/discontinued/83c175.pdf http://scyld.com/expert/NWay.html http://www.national.com/pf/DP/DP83840A.html @@ -227,7 +227,12 @@ static const u16 media2miictl[16] = { 0, 0x0C00, 0x0C00, 0x2000, 0x0100, 0x2100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; -/* The EPIC100 Rx and Tx buffer descriptors. */ +/* + * The EPIC100 Rx and Tx buffer descriptors. Note that these + * really ARE host-endian; it's not a misannotation. We tell + * the card to byteswap them internally on big-endian hosts - + * look for #ifdef CONFIG_BIG_ENDIAN in epic_open(). + */ struct epic_tx_desc { u32 txstatus; @@ -418,7 +423,7 @@ static int __devinit epic_init_one (struct pci_dev *pdev, /* Note: the '175 does not have a serial EEPROM. */ for (i = 0; i < 3; i++) - ((u16 *)dev->dev_addr)[i] = le16_to_cpu(inw(ioaddr + LAN0 + i*4)); + ((__le16 *)dev->dev_addr)[i] = cpu_to_le16(inw(ioaddr + LAN0 + i*4)); if (debug > 2) { dev_printk(KERN_DEBUG, &pdev->dev, "EEPROM contents:\n"); @@ -682,7 +687,8 @@ static int epic_open(struct net_device *dev) if (ep->chip_flags & MII_PWRDWN) outl((inl(ioaddr + NVCTL) & ~0x003C) | 0x4800, ioaddr + NVCTL); -#if defined(__powerpc__) || defined(__sparc__) /* Big endian */ + /* Tell the chip to byteswap descriptors on big-endian hosts */ +#ifdef CONFIG_BIG_ENDIAN outl(0x4432 | (RX_FIFO_THRESH<<8), ioaddr + GENCTL); inl(ioaddr + GENCTL); outl(0x0432 | (RX_FIFO_THRESH<<8), ioaddr + GENCTL); @@ -695,7 +701,7 @@ static int epic_open(struct net_device *dev) udelay(20); /* Looks like EPII needs that if you want reliable RX init. FIXME: pci posting bug? */ for (i = 0; i < 3; i++) - outl(cpu_to_le16(((u16*)dev->dev_addr)[i]), ioaddr + LAN0 + i*4); + outl(le16_to_cpu(((__le16*)dev->dev_addr)[i]), ioaddr + LAN0 + i*4); ep->tx_threshold = TX_FIFO_THRESH; outl(ep->tx_threshold, ioaddr + TxThresh); @@ -798,7 +804,7 @@ static void epic_restart(struct net_device *dev) for (i = 16; i > 0; i--) outl(0x0008, ioaddr + TEST1); -#if defined(__powerpc__) || defined(__sparc__) /* Big endian */ +#ifdef CONFIG_BIG_ENDIAN outl(0x0432 | (RX_FIFO_THRESH<<8), ioaddr + GENCTL); #else outl(0x0412 | (RX_FIFO_THRESH<<8), ioaddr + GENCTL); @@ -808,7 +814,7 @@ static void epic_restart(struct net_device *dev) outl((inl(ioaddr + NVCTL) & ~0x003C) | 0x4800, ioaddr + NVCTL); for (i = 0; i < 3; i++) - outl(cpu_to_le16(((u16*)dev->dev_addr)[i]), ioaddr + LAN0 + i*4); + outl(le16_to_cpu(((__le16*)dev->dev_addr)[i]), ioaddr + LAN0 + i*4); ep->tx_threshold = TX_FIFO_THRESH; outl(ep->tx_threshold, ioaddr + TxThresh); @@ -919,7 +925,7 @@ static void epic_init_ring(struct net_device *dev) /* Initialize all Rx descriptors. */ for (i = 0; i < RX_RING_SIZE; i++) { ep->rx_ring[i].rxstatus = 0; - ep->rx_ring[i].buflength = cpu_to_le32(ep->rx_buf_sz); + ep->rx_ring[i].buflength = ep->rx_buf_sz; ep->rx_ring[i].next = ep->rx_ring_dma + (i+1)*sizeof(struct epic_rx_desc); ep->rx_skbuff[i] = NULL; @@ -936,7 +942,7 @@ static void epic_init_ring(struct net_device *dev) skb_reserve(skb, 2); /* 16 byte align the IP header. */ ep->rx_ring[i].bufaddr = pci_map_single(ep->pci_dev, skb->data, ep->rx_buf_sz, PCI_DMA_FROMDEVICE); - ep->rx_ring[i].rxstatus = cpu_to_le32(DescOwn); + ep->rx_ring[i].rxstatus = DescOwn; } ep->dirty_rx = (unsigned int)(i - RX_RING_SIZE); @@ -974,20 +980,20 @@ static int epic_start_xmit(struct sk_buff *skb, struct net_device *dev) ep->tx_ring[entry].bufaddr = pci_map_single(ep->pci_dev, skb->data, skb->len, PCI_DMA_TODEVICE); if (free_count < TX_QUEUE_LEN/2) {/* Typical path */ - ctrl_word = cpu_to_le32(0x100000); /* No interrupt */ + ctrl_word = 0x100000; /* No interrupt */ } else if (free_count == TX_QUEUE_LEN/2) { - ctrl_word = cpu_to_le32(0x140000); /* Tx-done intr. */ + ctrl_word = 0x140000; /* Tx-done intr. */ } else if (free_count < TX_QUEUE_LEN - 1) { - ctrl_word = cpu_to_le32(0x100000); /* No Tx-done intr. */ + ctrl_word = 0x100000; /* No Tx-done intr. */ } else { /* Leave room for an additional entry. */ - ctrl_word = cpu_to_le32(0x140000); /* Tx-done intr. */ + ctrl_word = 0x140000; /* Tx-done intr. */ ep->tx_full = 1; } - ep->tx_ring[entry].buflength = ctrl_word | cpu_to_le32(skb->len); + ep->tx_ring[entry].buflength = ctrl_word | skb->len; ep->tx_ring[entry].txstatus = ((skb->len >= ETH_ZLEN ? skb->len : ETH_ZLEN) << 16) - | cpu_to_le32(DescOwn); + | DescOwn; ep->cur_tx++; if (ep->tx_full) @@ -1041,7 +1047,7 @@ static void epic_tx(struct net_device *dev, struct epic_private *ep) for (dirty_tx = ep->dirty_tx; cur_tx - dirty_tx > 0; dirty_tx++) { struct sk_buff *skb; int entry = dirty_tx % TX_RING_SIZE; - int txstatus = le32_to_cpu(ep->tx_ring[entry].txstatus); + int txstatus = ep->tx_ring[entry].txstatus; if (txstatus & DescOwn) break; /* It still hasn't been Txed */ @@ -1163,8 +1169,8 @@ static int epic_rx(struct net_device *dev, int budget) rx_work_limit = budget; /* If we own the next entry, it's a new packet. Send it up. */ - while ((ep->rx_ring[entry].rxstatus & cpu_to_le32(DescOwn)) == 0) { - int status = le32_to_cpu(ep->rx_ring[entry].rxstatus); + while ((ep->rx_ring[entry].rxstatus & DescOwn) == 0) { + int status = ep->rx_ring[entry].rxstatus; if (debug > 4) printk(KERN_DEBUG " epic_rx() status was %8.8x.\n", status); @@ -1238,7 +1244,8 @@ static int epic_rx(struct net_device *dev, int budget) skb->data, ep->rx_buf_sz, PCI_DMA_FROMDEVICE); work_done++; } - ep->rx_ring[entry].rxstatus = cpu_to_le32(DescOwn); + /* AV: shouldn't we add a barrier here? */ + ep->rx_ring[entry].rxstatus = DescOwn; } return work_done; } diff --git a/drivers/net/fec.c b/drivers/net/fec.c index 0fbf1bbbaee9972a56ab6f4d13eb31f00ed40c2c..d7a3ea88eddb562be4f632387d30776da84f4ef7 100644 --- a/drivers/net/fec.c +++ b/drivers/net/fec.c @@ -1253,7 +1253,7 @@ static void __inline__ fec_request_intrs(struct net_device *dev) /* Setup interrupt handlers. */ for (idp = id; idp->name; idp++) { - if (request_irq(idp->irq, idp->handler, 0, idp->name, dev) != 0) + if (request_irq(idp->irq, idp->handler, IRQF_DISABLED, idp->name, dev) != 0) printk("FEC: Could not allocate %s IRQ(%d)!\n", idp->name, idp->irq); } @@ -1382,7 +1382,7 @@ static void __inline__ fec_request_intrs(struct net_device *dev) /* Setup interrupt handlers. */ for (idp = id; idp->name; idp++) { - if (request_irq(b+idp->irq, fec_enet_interrupt, 0, idp->name, dev) != 0) + if (request_irq(b+idp->irq, fec_enet_interrupt, IRQF_DISABLED, idp->name, dev) != 0) printk("FEC: Could not allocate %s IRQ(%d)!\n", idp->name, b+idp->irq); } @@ -1553,7 +1553,7 @@ static void __inline__ fec_request_intrs(struct net_device *dev) /* Setup interrupt handlers. */ for (idp = id; idp->name; idp++) { - if (request_irq(b+idp->irq,fec_enet_interrupt,0,idp->name,dev)!=0) + if (request_irq(b+idp->irq, fec_enet_interrupt, IRQF_DISABLED, idp->name,dev) != 0) printk("FEC: Could not allocate %s IRQ(%d)!\n", idp->name, b+idp->irq); } @@ -1680,7 +1680,7 @@ static void __inline__ fec_request_intrs(struct net_device *dev) /* Setup interrupt handlers. */ for (idp = id; idp->name; idp++) { - if (request_irq(b+idp->irq,fec_enet_interrupt,0,idp->name,dev)!=0) + if (request_irq(b+idp->irq, fec_enet_interrupt, IRQF_DISABLED, idp->name,dev) != 0) printk("FEC: Could not allocate %s IRQ(%d)!\n", idp->name, b+idp->irq); } diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c index 801b4d9cd97254593ce2af8c4c3b8aa750c60585..6f7e3fde9e7cdcbe9fa12c23eb88cad8a3dbee0e 100644 --- a/drivers/net/forcedeth.c +++ b/drivers/net/forcedeth.c @@ -184,6 +184,7 @@ #define DEV_HAS_PAUSEFRAME_TX_V1 0x08000 /* device supports tx pause frames version 1 */ #define DEV_HAS_PAUSEFRAME_TX_V2 0x10000 /* device supports tx pause frames version 2 */ #define DEV_HAS_PAUSEFRAME_TX_V3 0x20000 /* device supports tx pause frames version 3 */ +#define DEV_NEED_TX_LIMIT 0x40000 /* device needs to limit tx */ enum { NvRegIrqStatus = 0x000, @@ -635,6 +636,8 @@ union ring_type { #define NV_RESTART_TX 0x1 #define NV_RESTART_RX 0x2 +#define NV_TX_LIMIT_COUNT 16 + /* statistics */ struct nv_ethtool_str { char name[ETH_GSTRING_LEN]; @@ -743,6 +746,8 @@ struct nv_skb_map { struct sk_buff *skb; dma_addr_t dma; unsigned int dma_len; + struct ring_desc_ex *first_tx_desc; + struct nv_skb_map *next_tx_ctx; }; /* @@ -827,6 +832,10 @@ struct fe_priv { union ring_type tx_ring; u32 tx_flags; int tx_ring_size; + int tx_limit; + u32 tx_pkts_in_progress; + struct nv_skb_map *tx_change_owner; + struct nv_skb_map *tx_end_flip; int tx_stop; /* vlan fields */ @@ -1707,6 +1716,9 @@ static void nv_init_tx(struct net_device *dev) np->last_tx.ex = &np->tx_ring.ex[np->tx_ring_size-1]; np->get_tx_ctx = np->put_tx_ctx = np->first_tx_ctx = np->tx_skb; np->last_tx_ctx = &np->tx_skb[np->tx_ring_size-1]; + np->tx_pkts_in_progress = 0; + np->tx_change_owner = NULL; + np->tx_end_flip = NULL; for (i = 0; i < np->tx_ring_size; i++) { if (np->desc_ver == DESC_VER_1 || np->desc_ver == DESC_VER_2) { @@ -1720,6 +1732,9 @@ static void nv_init_tx(struct net_device *dev) } np->tx_skb[i].skb = NULL; np->tx_skb[i].dma = 0; + np->tx_skb[i].dma_len = 0; + np->tx_skb[i].first_tx_desc = NULL; + np->tx_skb[i].next_tx_ctx = NULL; } } @@ -1771,7 +1786,14 @@ static void nv_drain_tx(struct net_device *dev) } if (nv_release_txskb(dev, &np->tx_skb[i])) dev->stats.tx_dropped++; + np->tx_skb[i].dma = 0; + np->tx_skb[i].dma_len = 0; + np->tx_skb[i].first_tx_desc = NULL; + np->tx_skb[i].next_tx_ctx = NULL; } + np->tx_pkts_in_progress = 0; + np->tx_change_owner = NULL; + np->tx_end_flip = NULL; } static void nv_drain_rx(struct net_device *dev) @@ -1948,6 +1970,7 @@ static int nv_start_xmit_optimized(struct sk_buff *skb, struct net_device *dev) struct ring_desc_ex* start_tx; struct ring_desc_ex* prev_tx; struct nv_skb_map* prev_tx_ctx; + struct nv_skb_map* start_tx_ctx; /* add fragments to entries count */ for (i = 0; i < fragments; i++) { @@ -1965,6 +1988,7 @@ static int nv_start_xmit_optimized(struct sk_buff *skb, struct net_device *dev) } start_tx = put_tx = np->put_tx.ex; + start_tx_ctx = np->put_tx_ctx; /* setup the header buffer */ do { @@ -2037,6 +2061,26 @@ static int nv_start_xmit_optimized(struct sk_buff *skb, struct net_device *dev) spin_lock_irq(&np->lock); + if (np->tx_limit) { + /* Limit the number of outstanding tx. Setup all fragments, but + * do not set the VALID bit on the first descriptor. Save a pointer + * to that descriptor and also for next skb_map element. + */ + + if (np->tx_pkts_in_progress == NV_TX_LIMIT_COUNT) { + if (!np->tx_change_owner) + np->tx_change_owner = start_tx_ctx; + + /* remove VALID bit */ + tx_flags &= ~NV_TX2_VALID; + start_tx_ctx->first_tx_desc = start_tx; + start_tx_ctx->next_tx_ctx = np->put_tx_ctx; + np->tx_end_flip = np->put_tx_ctx; + } else { + np->tx_pkts_in_progress++; + } + } + /* set tx flags */ start_tx->flaglen |= cpu_to_le32(tx_flags | tx_flags_extra); np->put_tx.ex = put_tx; @@ -2060,6 +2104,25 @@ static int nv_start_xmit_optimized(struct sk_buff *skb, struct net_device *dev) return NETDEV_TX_OK; } +static inline void nv_tx_flip_ownership(struct net_device *dev) +{ + struct fe_priv *np = netdev_priv(dev); + + np->tx_pkts_in_progress--; + if (np->tx_change_owner) { + __le32 flaglen = le32_to_cpu(np->tx_change_owner->first_tx_desc->flaglen); + flaglen |= NV_TX2_VALID; + np->tx_change_owner->first_tx_desc->flaglen = cpu_to_le32(flaglen); + np->tx_pkts_in_progress++; + + np->tx_change_owner = np->tx_change_owner->next_tx_ctx; + if (np->tx_change_owner == np->tx_end_flip) + np->tx_change_owner = NULL; + + writel(NVREG_TXRXCTL_KICK|np->txrxctl_bits, get_hwbase(dev) + NvRegTxRxControl); + } +} + /* * nv_tx_done: check for completed packets, release the skbs. * @@ -2147,6 +2210,10 @@ static void nv_tx_done_optimized(struct net_device *dev, int limit) dev->stats.tx_packets++; dev_kfree_skb_any(np->get_tx_ctx->skb); np->get_tx_ctx->skb = NULL; + + if (np->tx_limit) { + nv_tx_flip_ownership(dev); + } } if (unlikely(np->get_tx.ex++ == np->last_tx.ex)) np->get_tx.ex = np->first_tx.ex; @@ -5333,6 +5400,21 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i np->need_linktimer = 0; } + /* Limit the number of tx's outstanding for hw bug */ + if (id->driver_data & DEV_NEED_TX_LIMIT) { + np->tx_limit = 1; + if ((id->device == PCI_DEVICE_ID_NVIDIA_NVENET_32 || + id->device == PCI_DEVICE_ID_NVIDIA_NVENET_33 || + id->device == PCI_DEVICE_ID_NVIDIA_NVENET_34 || + id->device == PCI_DEVICE_ID_NVIDIA_NVENET_35 || + id->device == PCI_DEVICE_ID_NVIDIA_NVENET_36 || + id->device == PCI_DEVICE_ID_NVIDIA_NVENET_37 || + id->device == PCI_DEVICE_ID_NVIDIA_NVENET_38 || + id->device == PCI_DEVICE_ID_NVIDIA_NVENET_39) && + pci_dev->revision >= 0xA2) + np->tx_limit = 0; + } + /* clear phy state and temporarily halt phy interrupts */ writel(0, base + NvRegMIIMask); phystate = readl(base + NvRegAdapterControl); @@ -5563,19 +5645,19 @@ static struct pci_device_id pci_tbl[] = { }, { /* CK804 Ethernet Controller */ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_8), - .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_STATISTICS_V1, + .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_STATISTICS_V1|DEV_NEED_TX_LIMIT, }, { /* CK804 Ethernet Controller */ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_9), - .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_STATISTICS_V1, + .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_STATISTICS_V1|DEV_NEED_TX_LIMIT, }, { /* MCP04 Ethernet Controller */ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_10), - .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_STATISTICS_V1, + .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_STATISTICS_V1|DEV_NEED_TX_LIMIT, }, { /* MCP04 Ethernet Controller */ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_11), - .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_STATISTICS_V1, + .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_STATISTICS_V1|DEV_NEED_TX_LIMIT, }, { /* MCP51 Ethernet Controller */ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_12), @@ -5587,11 +5669,11 @@ static struct pci_device_id pci_tbl[] = { }, { /* MCP55 Ethernet Controller */ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_14), - .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_VLAN|DEV_HAS_MSI|DEV_HAS_MSI_X|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT, + .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_VLAN|DEV_HAS_MSI|DEV_HAS_MSI_X|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_NEED_TX_LIMIT, }, { /* MCP55 Ethernet Controller */ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_15), - .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_VLAN|DEV_HAS_MSI|DEV_HAS_MSI_X|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT, + .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_VLAN|DEV_HAS_MSI|DEV_HAS_MSI_X|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_NEED_TX_LIMIT, }, { /* MCP61 Ethernet Controller */ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_16), @@ -5611,19 +5693,19 @@ static struct pci_device_id pci_tbl[] = { }, { /* MCP65 Ethernet Controller */ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_20), - .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR, + .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_NEED_TX_LIMIT|DEV_NEED_TX_LIMIT, }, { /* MCP65 Ethernet Controller */ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_21), - .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR, + .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_NEED_TX_LIMIT, }, { /* MCP65 Ethernet Controller */ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_22), - .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR, + .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_NEED_TX_LIMIT, }, { /* MCP65 Ethernet Controller */ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_23), - .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR, + .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_NEED_TX_LIMIT, }, { /* MCP67 Ethernet Controller */ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_24), @@ -5659,35 +5741,35 @@ static struct pci_device_id pci_tbl[] = { }, { /* MCP77 Ethernet Controller */ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_32), - .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V2|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX, + .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V2|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_NEED_TX_LIMIT, }, { /* MCP77 Ethernet Controller */ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_33), - .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V2|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX, + .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V2|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_NEED_TX_LIMIT, }, { /* MCP77 Ethernet Controller */ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_34), - .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V2|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX, + .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V2|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_NEED_TX_LIMIT, }, { /* MCP77 Ethernet Controller */ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_35), - .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V2|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX, + .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V2|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_NEED_TX_LIMIT, }, { /* MCP79 Ethernet Controller */ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_36), - .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V3|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX, + .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V3|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_NEED_TX_LIMIT, }, { /* MCP79 Ethernet Controller */ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_37), - .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V3|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX, + .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V3|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_NEED_TX_LIMIT, }, { /* MCP79 Ethernet Controller */ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_38), - .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V3|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX, + .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V3|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_NEED_TX_LIMIT, }, { /* MCP79 Ethernet Controller */ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_39), - .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V3|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX, + .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V3|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_NEED_TX_LIMIT, }, {0,}, }; diff --git a/drivers/net/ibm_newemac/core.c b/drivers/net/ibm_newemac/core.c index e6c69f77259b1d3aa173715237b117f7e3ceae62..0789802d59ed3314dd304feb8bfa6ba637790b9b 100644 --- a/drivers/net/ibm_newemac/core.c +++ b/drivers/net/ibm_newemac/core.c @@ -143,6 +143,10 @@ static inline void emac_report_timeout_error(struct emac_instance *dev, #define STOP_TIMEOUT_1000 13 #define STOP_TIMEOUT_1000_JUMBO 73 +static unsigned char default_mcast_addr[] = { + 0x01, 0x80, 0xC2, 0x00, 0x00, 0x01 +}; + /* Please, keep in sync with struct ibm_emac_stats/ibm_emac_error_stats */ static const char emac_stats_keys[EMAC_ETHTOOL_STATS_COUNT][ETH_GSTRING_LEN] = { "rx_packets", "rx_bytes", "tx_packets", "tx_bytes", "rx_packets_csum", @@ -618,6 +622,9 @@ static int emac_configure(struct emac_instance *dev) if (emac_phy_gpcs(dev->phy.mode)) emac_mii_reset_phy(&dev->phy); + /* Required for Pause packet support in EMAC */ + dev_mc_add(ndev, default_mcast_addr, sizeof(default_mcast_addr), 1); + return 0; } diff --git a/drivers/net/ibm_newemac/tah.c b/drivers/net/ibm_newemac/tah.c index 96417adec32625b9389b1825e35a3c44d7aa8411..b023d10d7e1c2d14ecac3f61e3af4d6501392ff1 100644 --- a/drivers/net/ibm_newemac/tah.c +++ b/drivers/net/ibm_newemac/tah.c @@ -154,6 +154,10 @@ static int __devexit tah_remove(struct of_device *ofdev) static struct of_device_id tah_match[] = { + { + .compatible = "ibm,tah", + }, + /* For backward compat with old DT */ { .type = "tah", }, diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c index 6a1f23092099b5d3f0d974b7ea370a9a73c63b31..928ce8287e6932027fdffdc316962a64f6be73e1 100644 --- a/drivers/net/igb/igb_main.c +++ b/drivers/net/igb/igb_main.c @@ -31,7 +31,6 @@ #include #include #include -#include #include #include #include @@ -2484,10 +2483,24 @@ static inline bool igb_tx_csum_adv(struct igb_adapter *adapter, tu_cmd |= (E1000_TXD_CMD_DEXT | E1000_ADVTXD_DTYP_CTXT); if (skb->ip_summed == CHECKSUM_PARTIAL) { - if (skb->protocol == htons(ETH_P_IP)) + switch (skb->protocol) { + case __constant_htons(ETH_P_IP): tu_cmd |= E1000_ADVTXD_TUCMD_IPV4; - if (skb->sk && (skb->sk->sk_protocol == IPPROTO_TCP)) - tu_cmd |= E1000_ADVTXD_TUCMD_L4T_TCP; + if (ip_hdr(skb)->protocol == IPPROTO_TCP) + tu_cmd |= E1000_ADVTXD_TUCMD_L4T_TCP; + break; + case __constant_htons(ETH_P_IPV6): + /* XXX what about other V6 headers?? */ + if (ipv6_hdr(skb)->nexthdr == IPPROTO_TCP) + tu_cmd |= E1000_ADVTXD_TUCMD_L4T_TCP; + break; + default: + if (unlikely(net_ratelimit())) + dev_warn(&adapter->pdev->dev, + "partial checksum but proto=%x!\n", + skb->protocol); + break; + } } context_desc->type_tucmd_mlhl = cpu_to_le32(tu_cmd); diff --git a/drivers/net/ioc3-eth.c b/drivers/net/ioc3-eth.c index 373f72cdbe8e4d12922d3e41984d876e8006942c..1f25263dc7ebb8f90066d7388bbd297bd8d82b26 100644 --- a/drivers/net/ioc3-eth.c +++ b/drivers/net/ioc3-eth.c @@ -1221,7 +1221,8 @@ static void __devinit ioc3_serial_probe(struct pci_dev *pdev, struct ioc3 *ioc3) } #endif -static int ioc3_probe(struct pci_dev *pdev, const struct pci_device_id *ent) +static int __devinit ioc3_probe(struct pci_dev *pdev, + const struct pci_device_id *ent) { unsigned int sw_physid1, sw_physid2; struct net_device *dev = NULL; diff --git a/drivers/net/ipg.c b/drivers/net/ipg.c index 5e5d9b527ed10b6a98aec3b58bd04968e8ee3efb..9b358f61ed7fb4c7ba612b644665b3d221c9a785 100644 --- a/drivers/net/ipg.c +++ b/drivers/net/ipg.c @@ -472,7 +472,6 @@ static int ipg_config_autoneg(struct net_device *dev) unsigned int txflowcontrol; unsigned int rxflowcontrol; unsigned int fullduplex; - unsigned int gig; u32 mac_ctrl_val; u32 asicctrl; u8 phyctrl; @@ -489,7 +488,6 @@ static int ipg_config_autoneg(struct net_device *dev) fullduplex = 0; txflowcontrol = 0; rxflowcontrol = 0; - gig = 0; /* To accomodate a problem in 10Mbps operation, * set a global flag if PHY running in 10Mbps mode. @@ -511,7 +509,6 @@ static int ipg_config_autoneg(struct net_device *dev) break; case IPG_PC_LINK_SPEED_1000MBPS: printk("1000Mbps.\n"); - gig = 1; break; default: printk("undefined!\n"); @@ -1900,8 +1897,13 @@ static int ipg_nic_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) /* Specify the TFC field within the TFD. */ txfd->tfc |= cpu_to_le64(IPG_TFC_WORDALIGNDISABLED | - (IPG_TFC_FRAMEID & cpu_to_le64(sp->tx_current)) | + (IPG_TFC_FRAMEID & sp->tx_current) | (IPG_TFC_FRAGCOUNT & (1 << 24))); + /* + * 16--17 (WordAlign) <- 3 (disable), + * 0--15 (FrameId) <- sp->tx_current, + * 24--27 (FragCount) <- 1 + */ /* Request TxComplete interrupts at an interval defined * by the constant IPG_FRAMESBETWEENTXCOMPLETES. diff --git a/drivers/net/ne2k-pci.c b/drivers/net/ne2k-pci.c index b569c90da4ba547ff69ff08f0860bb75736c0f8b..de0de744a8fa4e1fe961cc89e301046b862a8e51 100644 --- a/drivers/net/ne2k-pci.c +++ b/drivers/net/ne2k-pci.c @@ -535,9 +535,9 @@ static void ne2k_pci_block_input(struct net_device *dev, int count, if (count & 3) { buf += count & ~3; if (count & 2) { - u16 *b = (u16 *)buf; + __le16 *b = (__le16 *)buf; - *b++ = le16_to_cpu(inw(NE_BASE + NE_DATAPORT)); + *b++ = cpu_to_le16(inw(NE_BASE + NE_DATAPORT)); buf = (char *)b; } if (count & 1) @@ -600,9 +600,9 @@ static void ne2k_pci_block_output(struct net_device *dev, int count, if (count & 3) { buf += count & ~3; if (count & 2) { - u16 *b = (u16 *)buf; + __le16 *b = (__le16 *)buf; - outw(cpu_to_le16(*b++), NE_BASE + NE_DATAPORT); + outw(le16_to_cpu(*b++), NE_BASE + NE_DATAPORT); buf = (char *)b; } } diff --git a/drivers/net/pppol2tp.c b/drivers/net/pppol2tp.c index 86e5dba079fed6d9a62bcd6d9e9e31fb40888999..3d10ca050b7991b9f53cf4a6cc3d5adb873137aa 100644 --- a/drivers/net/pppol2tp.c +++ b/drivers/net/pppol2tp.c @@ -302,14 +302,14 @@ pppol2tp_session_find(struct pppol2tp_tunnel *tunnel, u16 session_id) struct pppol2tp_session *session; struct hlist_node *walk; - read_lock(&tunnel->hlist_lock); + read_lock_bh(&tunnel->hlist_lock); hlist_for_each_entry(session, walk, session_list, hlist) { if (session->tunnel_addr.s_session == session_id) { - read_unlock(&tunnel->hlist_lock); + read_unlock_bh(&tunnel->hlist_lock); return session; } } - read_unlock(&tunnel->hlist_lock); + read_unlock_bh(&tunnel->hlist_lock); return NULL; } @@ -320,14 +320,14 @@ static struct pppol2tp_tunnel *pppol2tp_tunnel_find(u16 tunnel_id) { struct pppol2tp_tunnel *tunnel = NULL; - read_lock(&pppol2tp_tunnel_list_lock); + read_lock_bh(&pppol2tp_tunnel_list_lock); list_for_each_entry(tunnel, &pppol2tp_tunnel_list, list) { if (tunnel->stats.tunnel_id == tunnel_id) { - read_unlock(&pppol2tp_tunnel_list_lock); + read_unlock_bh(&pppol2tp_tunnel_list_lock); return tunnel; } } - read_unlock(&pppol2tp_tunnel_list_lock); + read_unlock_bh(&pppol2tp_tunnel_list_lock); return NULL; } @@ -342,10 +342,11 @@ static struct pppol2tp_tunnel *pppol2tp_tunnel_find(u16 tunnel_id) static void pppol2tp_recv_queue_skb(struct pppol2tp_session *session, struct sk_buff *skb) { struct sk_buff *skbp; + struct sk_buff *tmp; u16 ns = PPPOL2TP_SKB_CB(skb)->ns; - spin_lock(&session->reorder_q.lock); - skb_queue_walk(&session->reorder_q, skbp) { + spin_lock_bh(&session->reorder_q.lock); + skb_queue_walk_safe(&session->reorder_q, skbp, tmp) { if (PPPOL2TP_SKB_CB(skbp)->ns > ns) { __skb_insert(skb, skbp->prev, skbp, &session->reorder_q); PRINTK(session->debug, PPPOL2TP_MSG_SEQ, KERN_DEBUG, @@ -360,7 +361,7 @@ static void pppol2tp_recv_queue_skb(struct pppol2tp_session *session, struct sk_ __skb_queue_tail(&session->reorder_q, skb); out: - spin_unlock(&session->reorder_q.lock); + spin_unlock_bh(&session->reorder_q.lock); } /* Dequeue a single skb. @@ -371,10 +372,9 @@ static void pppol2tp_recv_dequeue_skb(struct pppol2tp_session *session, struct s int length = PPPOL2TP_SKB_CB(skb)->length; struct sock *session_sock = NULL; - /* We're about to requeue the skb, so unlink it and return resources + /* We're about to requeue the skb, so return resources * to its current owner (a socket receive buffer). */ - skb_unlink(skb, &session->reorder_q); skb_orphan(skb); tunnel->stats.rx_packets++; @@ -442,7 +442,7 @@ static void pppol2tp_recv_dequeue(struct pppol2tp_session *session) * expect to send up next, dequeue it and any other * in-sequence packets behind it. */ - spin_lock(&session->reorder_q.lock); + spin_lock_bh(&session->reorder_q.lock); skb_queue_walk_safe(&session->reorder_q, skb, tmp) { if (time_after(jiffies, PPPOL2TP_SKB_CB(skb)->expires)) { session->stats.rx_seq_discards++; @@ -470,13 +470,18 @@ static void pppol2tp_recv_dequeue(struct pppol2tp_session *session) goto out; } } - spin_unlock(&session->reorder_q.lock); + __skb_unlink(skb, &session->reorder_q); + + /* Process the skb. We release the queue lock while we + * do so to let other contexts process the queue. + */ + spin_unlock_bh(&session->reorder_q.lock); pppol2tp_recv_dequeue_skb(session, skb); - spin_lock(&session->reorder_q.lock); + spin_lock_bh(&session->reorder_q.lock); } out: - spin_unlock(&session->reorder_q.lock); + spin_unlock_bh(&session->reorder_q.lock); } /* Internal receive frame. Do the real work of receiving an L2TP data frame @@ -1059,7 +1064,7 @@ static int pppol2tp_xmit(struct ppp_channel *chan, struct sk_buff *skb) /* Get routing info from the tunnel socket */ dst_release(skb->dst); - skb->dst = sk_dst_get(sk_tun); + skb->dst = dst_clone(__sk_dst_get(sk_tun)); skb_orphan(skb); skb->sk = sk_tun; @@ -1107,7 +1112,7 @@ static void pppol2tp_tunnel_closeall(struct pppol2tp_tunnel *tunnel) PRINTK(tunnel->debug, PPPOL2TP_MSG_CONTROL, KERN_INFO, "%s: closing all sessions...\n", tunnel->name); - write_lock(&tunnel->hlist_lock); + write_lock_bh(&tunnel->hlist_lock); for (hash = 0; hash < PPPOL2TP_HASH_SIZE; hash++) { again: hlist_for_each_safe(walk, tmp, &tunnel->session_hlist[hash]) { @@ -1129,7 +1134,7 @@ again: * disappear as we're jumping between locks. */ sock_hold(sk); - write_unlock(&tunnel->hlist_lock); + write_unlock_bh(&tunnel->hlist_lock); lock_sock(sk); if (sk->sk_state & (PPPOX_CONNECTED | PPPOX_BOUND)) { @@ -1154,11 +1159,11 @@ again: * list so we are guaranteed to make forward * progress. */ - write_lock(&tunnel->hlist_lock); + write_lock_bh(&tunnel->hlist_lock); goto again; } } - write_unlock(&tunnel->hlist_lock); + write_unlock_bh(&tunnel->hlist_lock); } /* Really kill the tunnel. @@ -1167,9 +1172,9 @@ again: static void pppol2tp_tunnel_free(struct pppol2tp_tunnel *tunnel) { /* Remove from socket list */ - write_lock(&pppol2tp_tunnel_list_lock); + write_lock_bh(&pppol2tp_tunnel_list_lock); list_del_init(&tunnel->list); - write_unlock(&pppol2tp_tunnel_list_lock); + write_unlock_bh(&pppol2tp_tunnel_list_lock); atomic_dec(&pppol2tp_tunnel_count); kfree(tunnel); @@ -1245,9 +1250,9 @@ static void pppol2tp_session_destruct(struct sock *sk) /* Delete the session socket from the * hash */ - write_lock(&tunnel->hlist_lock); + write_lock_bh(&tunnel->hlist_lock); hlist_del_init(&session->hlist); - write_unlock(&tunnel->hlist_lock); + write_unlock_bh(&tunnel->hlist_lock); atomic_dec(&pppol2tp_session_count); } @@ -1392,9 +1397,9 @@ static struct sock *pppol2tp_prepare_tunnel_socket(int fd, u16 tunnel_id, /* Add tunnel to our list */ INIT_LIST_HEAD(&tunnel->list); - write_lock(&pppol2tp_tunnel_list_lock); + write_lock_bh(&pppol2tp_tunnel_list_lock); list_add(&tunnel->list, &pppol2tp_tunnel_list); - write_unlock(&pppol2tp_tunnel_list_lock); + write_unlock_bh(&pppol2tp_tunnel_list_lock); atomic_inc(&pppol2tp_tunnel_count); /* Bump the reference count. The tunnel context is deleted @@ -1599,11 +1604,11 @@ static int pppol2tp_connect(struct socket *sock, struct sockaddr *uservaddr, sk->sk_user_data = session; /* Add session to the tunnel's hash list */ - write_lock(&tunnel->hlist_lock); + write_lock_bh(&tunnel->hlist_lock); hlist_add_head(&session->hlist, pppol2tp_session_id_hash(tunnel, session->tunnel_addr.s_session)); - write_unlock(&tunnel->hlist_lock); + write_unlock_bh(&tunnel->hlist_lock); atomic_inc(&pppol2tp_session_count); @@ -2205,7 +2210,7 @@ static struct pppol2tp_session *next_session(struct pppol2tp_tunnel *tunnel, str int next = 0; int i; - read_lock(&tunnel->hlist_lock); + read_lock_bh(&tunnel->hlist_lock); for (i = 0; i < PPPOL2TP_HASH_SIZE; i++) { hlist_for_each_entry(session, walk, &tunnel->session_hlist[i], hlist) { if (curr == NULL) { @@ -2223,7 +2228,7 @@ static struct pppol2tp_session *next_session(struct pppol2tp_tunnel *tunnel, str } } out: - read_unlock(&tunnel->hlist_lock); + read_unlock_bh(&tunnel->hlist_lock); if (!found) session = NULL; @@ -2234,13 +2239,13 @@ static struct pppol2tp_tunnel *next_tunnel(struct pppol2tp_tunnel *curr) { struct pppol2tp_tunnel *tunnel = NULL; - read_lock(&pppol2tp_tunnel_list_lock); + read_lock_bh(&pppol2tp_tunnel_list_lock); if (list_is_last(&curr->list, &pppol2tp_tunnel_list)) { goto out; } tunnel = list_entry(curr->list.next, struct pppol2tp_tunnel, list); out: - read_unlock(&pppol2tp_tunnel_list_lock); + read_unlock_bh(&pppol2tp_tunnel_list_lock); return tunnel; } diff --git a/drivers/net/ps3_gelic_wireless.c b/drivers/net/ps3_gelic_wireless.c index daf5abab9534a7e371a872252a0cdfa86c1b1b68..ddbc6e475e285fdde2cc2d84c16fdb8023c431be 100644 --- a/drivers/net/ps3_gelic_wireless.c +++ b/drivers/net/ps3_gelic_wireless.c @@ -1644,13 +1644,24 @@ static void gelic_wl_scan_complete_event(struct gelic_wl_info *wl) } /* put them in the newtork_list */ - scan_info = wl->buf; - scan_info_size = 0; - i = 0; - while (scan_info_size < data_len) { + for (i = 0, scan_info_size = 0, scan_info = wl->buf; + scan_info_size < data_len; + i++, scan_info_size += be16_to_cpu(scan_info->size), + scan_info = (void *)scan_info + be16_to_cpu(scan_info->size)) { pr_debug("%s:size=%d bssid=%s scan_info=%p\n", __func__, be16_to_cpu(scan_info->size), print_mac(mac, &scan_info->bssid[2]), scan_info); + + /* + * The wireless firmware may return invalid channel 0 and/or + * invalid rate if the AP emits zero length SSID ie. As this + * scan information is useless, ignore it + */ + if (!be16_to_cpu(scan_info->channel) || !scan_info->rate[0]) { + pr_debug("%s: invalid scan info\n", __func__); + continue; + } + found = 0; oldest = NULL; list_for_each_entry(target, &wl->network_list, list) { @@ -1687,10 +1698,6 @@ static void gelic_wl_scan_complete_event(struct gelic_wl_info *wl) GFP_KERNEL); if (!target->hwinfo) { pr_info("%s: kzalloc failed\n", __func__); - i++; - scan_info_size += be16_to_cpu(scan_info->size); - scan_info = (void *)scan_info + - be16_to_cpu(scan_info->size); continue; } /* copy hw scan info */ @@ -1709,10 +1716,6 @@ static void gelic_wl_scan_complete_event(struct gelic_wl_info *wl) if (scan_info->ext_rate[r]) target->rate_ext_len++; list_move_tail(&target->list, &wl->network_list); - /* bump pointer */ - i++; - scan_info_size += be16_to_cpu(scan_info->size); - scan_info = (void *)scan_info + be16_to_cpu(scan_info->size); } memset(&data, 0, sizeof(data)); wireless_send_event(port_to_netdev(wl_port(wl)), SIOCGIWSCAN, &data, @@ -2389,6 +2392,8 @@ static struct net_device *gelic_wl_alloc(struct gelic_card *card) if (!netdev) return NULL; + strcpy(netdev->name, "wlan%d"); + port = netdev_priv(netdev); port->netdev = netdev; port->card = card; diff --git a/drivers/net/r6040.c b/drivers/net/r6040.c index 19184e486ae97bf418f2521b174d769d6d8c9241..169edc154928305e154ccba45796b0cd52ec3c92 100644 --- a/drivers/net/r6040.c +++ b/drivers/net/r6040.c @@ -239,7 +239,8 @@ static void r6040_free_txbufs(struct net_device *dev) for (i = 0; i < TX_DCNT; i++) { if (lp->tx_insert_ptr->skb_ptr) { - pci_unmap_single(lp->pdev, lp->tx_insert_ptr->buf, + pci_unmap_single(lp->pdev, + le32_to_cpu(lp->tx_insert_ptr->buf), MAX_BUF_SIZE, PCI_DMA_TODEVICE); dev_kfree_skb(lp->tx_insert_ptr->skb_ptr); lp->rx_insert_ptr->skb_ptr = NULL; @@ -255,7 +256,8 @@ static void r6040_free_rxbufs(struct net_device *dev) for (i = 0; i < RX_DCNT; i++) { if (lp->rx_insert_ptr->skb_ptr) { - pci_unmap_single(lp->pdev, lp->rx_insert_ptr->buf, + pci_unmap_single(lp->pdev, + le32_to_cpu(lp->rx_insert_ptr->buf), MAX_BUF_SIZE, PCI_DMA_FROMDEVICE); dev_kfree_skb(lp->rx_insert_ptr->skb_ptr); lp->rx_insert_ptr->skb_ptr = NULL; @@ -542,7 +544,7 @@ static int r6040_rx(struct net_device *dev, int limit) skb_ptr->dev = priv->dev; /* Do not count the CRC */ skb_put(skb_ptr, descptr->len - 4); - pci_unmap_single(priv->pdev, descptr->buf, + pci_unmap_single(priv->pdev, le32_to_cpu(descptr->buf), MAX_BUF_SIZE, PCI_DMA_FROMDEVICE); skb_ptr->protocol = eth_type_trans(skb_ptr, priv->dev); /* Send to upper layer */ @@ -585,7 +587,7 @@ static void r6040_tx(struct net_device *dev) if (descptr->status & 0x8000) break; /* Not complete */ skb_ptr = descptr->skb_ptr; - pci_unmap_single(priv->pdev, descptr->buf, + pci_unmap_single(priv->pdev, le32_to_cpu(descptr->buf), skb_ptr->len, PCI_DMA_TODEVICE); /* Free buffer */ dev_kfree_skb_irq(skb_ptr); diff --git a/drivers/net/tulip/de2104x.c b/drivers/net/tulip/de2104x.c index 567c62757e9d154ec39b5083d1f0f4b28bcf18ad..1b5edd646a8c924c835129280d9ad964186676f6 100644 --- a/drivers/net/tulip/de2104x.c +++ b/drivers/net/tulip/de2104x.c @@ -842,7 +842,7 @@ static inline int de_is_running (struct de_private *de) static void de_stop_rxtx (struct de_private *de) { u32 macmode; - unsigned int work = 1000; + unsigned int i = 1300/100; macmode = dr32(MacMode); if (macmode & RxTx) { @@ -850,10 +850,14 @@ static void de_stop_rxtx (struct de_private *de) dr32(MacMode); } - while (--work > 0) { + /* wait until in-flight frame completes. + * Max time @ 10BT: 1500*8b/10Mbps == 1200us (+ 100us margin) + * Typically expect this loop to end in < 50 us on 100BT. + */ + while (--i) { if (!de_is_running(de)) return; - cpu_relax(); + udelay(100); } printk(KERN_WARNING "%s: timeout expired stopping DMA\n", de->dev->name); diff --git a/drivers/net/ucc_geth.c b/drivers/net/ucc_geth.c index fba0811d2608824bfebd0535b37cc21d14dd9859..8cc316653a397cff04cae39951cf8183333260e8 100644 --- a/drivers/net/ucc_geth.c +++ b/drivers/net/ucc_geth.c @@ -154,8 +154,8 @@ static struct ucc_geth_info ugeth_primary_info = { .rxQoSMode = UCC_GETH_QOS_MODE_DEFAULT, .aufc = UPSMR_AUTOMATIC_FLOW_CONTROL_MODE_NONE, .padAndCrc = MACCFG2_PAD_AND_CRC_MODE_PAD_AND_CRC, - .numThreadsTx = UCC_GETH_NUM_OF_THREADS_4, - .numThreadsRx = UCC_GETH_NUM_OF_THREADS_4, + .numThreadsTx = UCC_GETH_NUM_OF_THREADS_1, + .numThreadsRx = UCC_GETH_NUM_OF_THREADS_1, .riscTx = QE_RISC_ALLOCATION_RISC1_AND_RISC2, .riscRx = QE_RISC_ALLOCATION_RISC1_AND_RISC2, }; @@ -3975,6 +3975,8 @@ static int ucc_geth_probe(struct of_device* ofdev, const struct of_device_id *ma ug_info->uf_info.utfs = UCC_GETH_UTFS_GIGA_INIT; ug_info->uf_info.utfet = UCC_GETH_UTFET_GIGA_INIT; ug_info->uf_info.utftt = UCC_GETH_UTFTT_GIGA_INIT; + ug_info->numThreadsTx = UCC_GETH_NUM_OF_THREADS_4; + ug_info->numThreadsRx = UCC_GETH_NUM_OF_THREADS_4; } /* Set the bus id */ diff --git a/drivers/net/usb/rndis_host.c b/drivers/net/usb/rndis_host.c index a61324757b179b04d67673d26c2484580d5a8676..727547a289920dd59b7ca2ec3045c031cd75c856 100644 --- a/drivers/net/usb/rndis_host.c +++ b/drivers/net/usb/rndis_host.c @@ -16,10 +16,6 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - -// #define DEBUG // error path messages, extra info -// #define VERBOSE // more; success messages - #include #include #include @@ -318,6 +314,14 @@ generic_rndis_bind(struct usbnet *dev, struct usb_interface *intf, int flags) net->hard_header_len += sizeof (struct rndis_data_hdr); dev->hard_mtu = net->mtu + net->hard_header_len; + dev->maxpacket = usb_maxpacket(dev->udev, dev->out, 1); + if (dev->maxpacket == 0) { + if (netif_msg_probe(dev)) + dev_dbg(&intf->dev, "dev->maxpacket can't be 0\n"); + retval = -EINVAL; + goto fail_and_release; + } + dev->rx_urb_size = dev->hard_mtu + (dev->maxpacket + 1); dev->rx_urb_size &= ~(dev->maxpacket - 1); u.init->max_transfer_size = cpu_to_le32(dev->rx_urb_size); diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c index 19fd4cb0ddf8583cbd9235b6085a7ad1100dfa19..b58472cf76f862c16fa861b02bcb494008c00f90 100644 --- a/drivers/net/virtio_net.c +++ b/drivers/net/virtio_net.c @@ -203,8 +203,11 @@ again: if (received < budget) { netif_rx_complete(vi->dev, napi); if (unlikely(!vi->rvq->vq_ops->enable_cb(vi->rvq)) - && netif_rx_reschedule(vi->dev, napi)) + && napi_schedule_prep(napi)) { + vi->rvq->vq_ops->disable_cb(vi->rvq); + __netif_rx_schedule(vi->dev, napi); goto again; + } } return received; @@ -278,10 +281,11 @@ again: pr_debug("%s: virtio not prepared to send\n", dev->name); netif_stop_queue(dev); - /* Activate callback for using skbs: if this fails it + /* Activate callback for using skbs: if this returns false it * means some were used in the meantime. */ if (unlikely(!vi->svq->vq_ops->enable_cb(vi->svq))) { - printk("Unlikely: restart svq failed\n"); + printk("Unlikely: restart svq race\n"); + vi->svq->vq_ops->disable_cb(vi->svq); netif_start_queue(dev); goto again; } @@ -294,6 +298,15 @@ again: return 0; } +#ifdef CONFIG_NET_POLL_CONTROLLER +static void virtnet_netpoll(struct net_device *dev) +{ + struct virtnet_info *vi = netdev_priv(dev); + + napi_schedule(&vi->napi); +} +#endif + static int virtnet_open(struct net_device *dev) { struct virtnet_info *vi = netdev_priv(dev); @@ -336,6 +349,9 @@ static int virtnet_probe(struct virtio_device *vdev) dev->stop = virtnet_close; dev->hard_start_xmit = start_xmit; dev->features = NETIF_F_HIGHDMA; +#ifdef CONFIG_NET_POLL_CONTROLLER + dev->poll_controller = virtnet_netpoll; +#endif SET_NETDEV_DEV(dev, &vdev->dev); /* Do we support "hardware" checksums? */ diff --git a/drivers/net/wan/farsync.c b/drivers/net/wan/farsync.c index cf27bf40d36eefe7285b67e9884bc87bbdee9af2..547368e9633d7bd511ceb3a4820146bd87e12486 100644 --- a/drivers/net/wan/farsync.c +++ b/drivers/net/wan/farsync.c @@ -2024,6 +2024,7 @@ fst_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) struct fstioc_write wrthdr; struct fstioc_info info; unsigned long flags; + void *buf; dbg(DBG_IOCTL, "ioctl: %x, %p\n", cmd, ifr->ifr_data); @@ -2065,16 +2066,22 @@ fst_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) return -ENXIO; } - /* Now copy the data to the card. - * This will probably break on some architectures. - * I'll fix it when I have something to test on. - */ - if (copy_from_user(card->mem + wrthdr.offset, + /* Now copy the data to the card. */ + + buf = kmalloc(wrthdr.size, GFP_KERNEL); + if (!buf) + return -ENOMEM; + + if (copy_from_user(buf, ifr->ifr_data + sizeof (struct fstioc_write), wrthdr.size)) { + kfree(buf); return -EFAULT; } + memcpy_toio(card->mem + wrthdr.offset, buf, wrthdr.size); + kfree(buf); + /* Writes to the memory of a card in the reset state constitute * a download */ diff --git a/drivers/net/wan/sbni.c b/drivers/net/wan/sbni.c index 15d5c58e57bcf5a170958afd69e9e57b960cc453..e59255a155a91e34719b11e70c9a471d4fd36e6d 100644 --- a/drivers/net/wan/sbni.c +++ b/drivers/net/wan/sbni.c @@ -751,7 +751,7 @@ upload_data( struct net_device *dev, unsigned framelen, unsigned frameno, } -static __inline void +static inline void send_complete( struct net_local *nl ) { #ifdef CONFIG_SBNI_MULTILINE diff --git a/drivers/net/wireless/ath5k/hw.c b/drivers/net/wireless/ath5k/hw.c index 677600b302d95fc33fa836e3e12501cdadc77957..ff579a22362129287c57ee145a9dc5c3c4313b7e 100644 --- a/drivers/net/wireless/ath5k/hw.c +++ b/drivers/net/wireless/ath5k/hw.c @@ -458,6 +458,8 @@ void ath5k_hw_detach(struct ath5k_hw *ah) { ATH5K_TRACE(ah->ah_sc); + __set_bit(ATH_STAT_INVALID, ah->ah_sc->status); + if (ah->ah_rf_banks != NULL) kfree(ah->ah_rf_banks); diff --git a/drivers/net/wireless/b43/phy.c b/drivers/net/wireless/b43/phy.c index 71507b260b6d2fd5e1befb0eddee486db109034e..575c5436ebdfdcdcfcd8ab56a8671c1da3dd0a9a 100644 --- a/drivers/net/wireless/b43/phy.c +++ b/drivers/net/wireless/b43/phy.c @@ -860,7 +860,7 @@ static void b43_phy_ww(struct b43_wldev *dev) b43_phy_write(dev, B43_PHY_OFDM(0xBB), (b43_phy_read(dev, B43_PHY_OFDM(0xBB)) & 0xF000) | 0x0053); b43_phy_write(dev, B43_PHY_OFDM61, - (b43_phy_read(dev, B43_PHY_OFDM61 & 0xFE1F)) | 0x0120); + (b43_phy_read(dev, B43_PHY_OFDM61) & 0xFE1F) | 0x0120); b43_phy_write(dev, B43_PHY_OFDM(0x13), (b43_phy_read(dev, B43_PHY_OFDM(0x13)) & 0x0FFF) | 0x3000); b43_phy_write(dev, B43_PHY_OFDM(0x14), diff --git a/drivers/net/wireless/libertas/cmdresp.c b/drivers/net/wireless/libertas/cmdresp.c index 15e4ebdcd47769a2290fda4ec36f1a04f1661284..63aa884b18f28546cc894b36925497aba1fd481b 100644 --- a/drivers/net/wireless/libertas/cmdresp.c +++ b/drivers/net/wireless/libertas/cmdresp.c @@ -515,7 +515,7 @@ int lbs_process_rx_command(struct lbs_private *priv) goto done; } if (respcmd != CMD_RET(curcmd) && - respcmd != CMD_802_11_ASSOCIATE && curcmd != CMD_RET_802_11_ASSOCIATE) { + respcmd != CMD_RET_802_11_ASSOCIATE && curcmd != CMD_802_11_ASSOCIATE) { lbs_pr_info("Invalid CMD_RESP %x to command %x!\n", respcmd, curcmd); spin_unlock_irqrestore(&priv->driver_lock, flags); ret = -1; diff --git a/drivers/net/wireless/p54usb.c b/drivers/net/wireless/p54usb.c index e7d4aee8799e7863ea9b08aa4c65d8818050b28c..98ddbb3b3273483964552f106cab47044defcfee 100644 --- a/drivers/net/wireless/p54usb.c +++ b/drivers/net/wireless/p54usb.c @@ -63,6 +63,7 @@ static struct usb_device_id p54u_table[] __devinitdata = { {USB_DEVICE(0x0cde, 0x0008)}, /* Sagem XG703A */ {USB_DEVICE(0x0d8e, 0x3762)}, /* DLink DWL-G120 Cohiba */ {USB_DEVICE(0x09aa, 0x1000)}, /* Spinnaker Proto board */ + {USB_DEVICE(0x124a, 0x4025)}, /* IOGear GWU513 (GW3887IK chip) */ {USB_DEVICE(0x13b1, 0x000a)}, /* Linksys WUSB54G ver 2 */ {USB_DEVICE(0x13B1, 0x000C)}, /* Linksys WUSB54AG */ {USB_DEVICE(0x1435, 0x0427)}, /* Inventel UR054G */ diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h index dfd0af0e0a165fa70ca9e8815a19ffcc128ac0ab..c016bfe1defdd1808cc62ab91f18abbdd47757e9 100644 --- a/drivers/net/wireless/rt2x00/rt2x00.h +++ b/drivers/net/wireless/rt2x00/rt2x00.h @@ -671,6 +671,9 @@ struct rt2x00_dev { * This will only be compiled in when required. */ #ifdef CONFIG_RT2X00_LIB_RFKILL +unsigned long rfkill_state; +#define RFKILL_STATE_ALLOCATED 1 +#define RFKILL_STATE_REGISTERED 2 struct rfkill *rfkill; struct input_polled_dev *poll_dev; #endif /* CONFIG_RT2X00_LIB_RFKILL */ diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c index b81efc9b058d7af5ae6bbe1d8569ec39f16a1bfd..acf4d67ba43d7fc481d5b430a716c14b7bf73f40 100644 --- a/drivers/net/wireless/rt2x00/rt2x00dev.c +++ b/drivers/net/wireless/rt2x00/rt2x00dev.c @@ -994,7 +994,7 @@ static void rt2x00lib_uninitialize(struct rt2x00_dev *rt2x00dev) return; /* - * Unregister rfkill. + * Unregister extra components. */ rt2x00rfkill_unregister(rt2x00dev); @@ -1033,11 +1033,9 @@ static int rt2x00lib_initialize(struct rt2x00_dev *rt2x00dev) __set_bit(DEVICE_INITIALIZED, &rt2x00dev->flags); /* - * Register the rfkill handler. + * Register the extra components. */ - status = rt2x00rfkill_register(rt2x00dev); - if (status) - goto exit; + rt2x00rfkill_register(rt2x00dev); return 0; @@ -1151,20 +1149,10 @@ int rt2x00lib_probe_dev(struct rt2x00_dev *rt2x00dev) } /* - * Register LED. + * Register extra components. */ rt2x00leds_register(rt2x00dev); - - /* - * Allocatie rfkill. - */ - retval = rt2x00rfkill_allocate(rt2x00dev); - if (retval) - goto exit; - - /* - * Open the debugfs entry. - */ + rt2x00rfkill_allocate(rt2x00dev); rt2x00debug_register(rt2x00dev); __set_bit(DEVICE_PRESENT, &rt2x00dev->flags); @@ -1193,13 +1181,9 @@ void rt2x00lib_remove_dev(struct rt2x00_dev *rt2x00dev) rt2x00lib_uninitialize(rt2x00dev); /* - * Close debugfs entry. + * Free extra components */ rt2x00debug_deregister(rt2x00dev); - - /* - * Free rfkill - */ rt2x00rfkill_free(rt2x00dev); /* @@ -1243,12 +1227,16 @@ int rt2x00lib_suspend(struct rt2x00_dev *rt2x00dev, pm_message_t state) __set_bit(DEVICE_STARTED_SUSPEND, &rt2x00dev->flags); /* - * Disable radio and unitialize all items - * that must be recreated on resume. + * Disable radio. */ rt2x00lib_stop(rt2x00dev); rt2x00lib_uninitialize(rt2x00dev); + + /* + * Suspend/disable extra components. + */ rt2x00leds_suspend(rt2x00dev); + rt2x00rfkill_suspend(rt2x00dev); rt2x00debug_deregister(rt2x00dev); exit: @@ -1292,9 +1280,10 @@ int rt2x00lib_resume(struct rt2x00_dev *rt2x00dev) NOTICE(rt2x00dev, "Waking up.\n"); /* - * Open the debugfs entry and restore led handling. + * Restore/enable extra components. */ rt2x00debug_register(rt2x00dev); + rt2x00rfkill_resume(rt2x00dev); rt2x00leds_resume(rt2x00dev); /* diff --git a/drivers/net/wireless/rt2x00/rt2x00lib.h b/drivers/net/wireless/rt2x00/rt2x00lib.h index e4b4dd23d61111d1e66951ccf65b1ec18ab501f8..64fae7e3f73b92d0a6be3fe909e79998e7ae1a80 100644 --- a/drivers/net/wireless/rt2x00/rt2x00lib.h +++ b/drivers/net/wireless/rt2x00/rt2x00lib.h @@ -148,28 +148,36 @@ static inline void rt2x00debug_dump_frame(struct rt2x00_dev *rt2x00dev, * RFkill handlers. */ #ifdef CONFIG_RT2X00_LIB_RFKILL -int rt2x00rfkill_register(struct rt2x00_dev *rt2x00dev); +void rt2x00rfkill_register(struct rt2x00_dev *rt2x00dev); void rt2x00rfkill_unregister(struct rt2x00_dev *rt2x00dev); -int rt2x00rfkill_allocate(struct rt2x00_dev *rt2x00dev); +void rt2x00rfkill_allocate(struct rt2x00_dev *rt2x00dev); void rt2x00rfkill_free(struct rt2x00_dev *rt2x00dev); +void rt2x00rfkill_suspend(struct rt2x00_dev *rt2x00dev); +void rt2x00rfkill_resume(struct rt2x00_dev *rt2x00dev); #else -static inline int rt2x00rfkill_register(struct rt2x00_dev *rt2x00dev) +static inline void rt2x00rfkill_register(struct rt2x00_dev *rt2x00dev) { - return 0; } static inline void rt2x00rfkill_unregister(struct rt2x00_dev *rt2x00dev) { } -static inline int rt2x00rfkill_allocate(struct rt2x00_dev *rt2x00dev) +static inline void rt2x00rfkill_allocate(struct rt2x00_dev *rt2x00dev) { - return 0; } static inline void rt2x00rfkill_free(struct rt2x00_dev *rt2x00dev) { } + +static inline void rt2x00rfkill_suspend(struct rt2x00_dev *rt2x00dev) +{ +} + +static inline void rt2x00rfkill_resume(struct rt2x00_dev *rt2x00dev) +{ +} #endif /* CONFIG_RT2X00_LIB_RFKILL */ /* diff --git a/drivers/net/wireless/rt2x00/rt2x00rfkill.c b/drivers/net/wireless/rt2x00/rt2x00rfkill.c index 67121427a5bd73ff00c3836071317eea1f49c85d..fcef9885ab5eaf1c4c841184517dbf0b45b0f158 100644 --- a/drivers/net/wireless/rt2x00/rt2x00rfkill.c +++ b/drivers/net/wireless/rt2x00/rt2x00rfkill.c @@ -69,56 +69,81 @@ static void rt2x00rfkill_poll(struct input_polled_dev *poll_dev) } } -int rt2x00rfkill_register(struct rt2x00_dev *rt2x00dev) +void rt2x00rfkill_register(struct rt2x00_dev *rt2x00dev) { - int retval; - - if (!test_bit(CONFIG_SUPPORT_HW_BUTTON, &rt2x00dev->flags)) - return 0; + if (!test_bit(CONFIG_SUPPORT_HW_BUTTON, &rt2x00dev->flags) || + !test_bit(RFKILL_STATE_ALLOCATED, &rt2x00dev->rfkill_state)) + return; - retval = rfkill_register(rt2x00dev->rfkill); - if (retval) { + if (rfkill_register(rt2x00dev->rfkill)) { ERROR(rt2x00dev, "Failed to register rfkill handler.\n"); - return retval; + return; } - retval = input_register_polled_device(rt2x00dev->poll_dev); - if (retval) { + if (input_register_polled_device(rt2x00dev->poll_dev)) { ERROR(rt2x00dev, "Failed to register polled device.\n"); rfkill_unregister(rt2x00dev->rfkill); - return retval; + return; } + __set_bit(RFKILL_STATE_REGISTERED, &rt2x00dev->rfkill_state); + /* * Force initial poll which will detect the initial device state, * and correctly sends the signal to the rfkill layer about this * state. */ rt2x00rfkill_poll(rt2x00dev->poll_dev); - - return 0; } void rt2x00rfkill_unregister(struct rt2x00_dev *rt2x00dev) { - if (!test_bit(CONFIG_SUPPORT_HW_BUTTON, &rt2x00dev->flags)) + if (!test_bit(CONFIG_SUPPORT_HW_BUTTON, &rt2x00dev->flags) || + !test_bit(RFKILL_STATE_REGISTERED, &rt2x00dev->rfkill_state)) return; input_unregister_polled_device(rt2x00dev->poll_dev); rfkill_unregister(rt2x00dev->rfkill); + + __clear_bit(RFKILL_STATE_REGISTERED, &rt2x00dev->rfkill_state); } -int rt2x00rfkill_allocate(struct rt2x00_dev *rt2x00dev) +static struct input_polled_dev * +rt2x00rfkill_allocate_polldev(struct rt2x00_dev *rt2x00dev) { - struct device *device = wiphy_dev(rt2x00dev->hw->wiphy); + struct input_polled_dev *poll_dev; + + poll_dev = input_allocate_polled_device(); + if (!poll_dev) + return NULL; + + poll_dev->private = rt2x00dev; + poll_dev->poll = rt2x00rfkill_poll; + poll_dev->poll_interval = RFKILL_POLL_INTERVAL; + + poll_dev->input->name = rt2x00dev->ops->name; + poll_dev->input->phys = wiphy_name(rt2x00dev->hw->wiphy); + poll_dev->input->id.bustype = BUS_HOST; + poll_dev->input->id.vendor = 0x1814; + poll_dev->input->id.product = rt2x00dev->chip.rt; + poll_dev->input->id.version = rt2x00dev->chip.rev; + poll_dev->input->dev.parent = wiphy_dev(rt2x00dev->hw->wiphy); + poll_dev->input->evbit[0] = BIT(EV_KEY); + set_bit(KEY_WLAN, poll_dev->input->keybit); + + return poll_dev; +} +void rt2x00rfkill_allocate(struct rt2x00_dev *rt2x00dev) +{ if (!test_bit(CONFIG_SUPPORT_HW_BUTTON, &rt2x00dev->flags)) - return 0; + return; - rt2x00dev->rfkill = rfkill_allocate(device, RFKILL_TYPE_WLAN); + rt2x00dev->rfkill = + rfkill_allocate(wiphy_dev(rt2x00dev->hw->wiphy), RFKILL_TYPE_WLAN); if (!rt2x00dev->rfkill) { ERROR(rt2x00dev, "Failed to allocate rfkill handler.\n"); - goto exit; + return; } rt2x00dev->rfkill->name = rt2x00dev->ops->name; @@ -126,40 +151,49 @@ int rt2x00rfkill_allocate(struct rt2x00_dev *rt2x00dev) rt2x00dev->rfkill->state = -1; rt2x00dev->rfkill->toggle_radio = rt2x00rfkill_toggle_radio; - rt2x00dev->poll_dev = input_allocate_polled_device(); + rt2x00dev->poll_dev = rt2x00rfkill_allocate_polldev(rt2x00dev); if (!rt2x00dev->poll_dev) { ERROR(rt2x00dev, "Failed to allocate polled device.\n"); - goto exit_free_rfkill; + rfkill_free(rt2x00dev->rfkill); + rt2x00dev->rfkill = NULL; + return; } - rt2x00dev->poll_dev->private = rt2x00dev; - rt2x00dev->poll_dev->poll = rt2x00rfkill_poll; - rt2x00dev->poll_dev->poll_interval = RFKILL_POLL_INTERVAL; + return; +} - rt2x00dev->poll_dev->input->name = rt2x00dev->ops->name; - rt2x00dev->poll_dev->input->phys = wiphy_name(rt2x00dev->hw->wiphy); - rt2x00dev->poll_dev->input->id.bustype = BUS_HOST; - rt2x00dev->poll_dev->input->id.vendor = 0x1814; - rt2x00dev->poll_dev->input->id.product = rt2x00dev->chip.rt; - rt2x00dev->poll_dev->input->id.version = rt2x00dev->chip.rev; - rt2x00dev->poll_dev->input->dev.parent = device; - rt2x00dev->poll_dev->input->evbit[0] = BIT(EV_KEY); - set_bit(KEY_WLAN, rt2x00dev->poll_dev->input->keybit); +void rt2x00rfkill_free(struct rt2x00_dev *rt2x00dev) +{ + if (!test_bit(CONFIG_SUPPORT_HW_BUTTON, &rt2x00dev->flags) || + !test_bit(RFKILL_STATE_ALLOCATED, &rt2x00dev->rfkill_state)) + return; - return 0; + input_free_polled_device(rt2x00dev->poll_dev); + rt2x00dev->poll_dev = NULL; -exit_free_rfkill: rfkill_free(rt2x00dev->rfkill); - -exit: - return -ENOMEM; + rt2x00dev->rfkill = NULL; } -void rt2x00rfkill_free(struct rt2x00_dev *rt2x00dev) +void rt2x00rfkill_suspend(struct rt2x00_dev *rt2x00dev) { - if (!test_bit(CONFIG_SUPPORT_HW_BUTTON, &rt2x00dev->flags)) + if (!test_bit(CONFIG_SUPPORT_HW_BUTTON, &rt2x00dev->flags) || + !test_bit(RFKILL_STATE_ALLOCATED, &rt2x00dev->rfkill_state)) return; input_free_polled_device(rt2x00dev->poll_dev); - rfkill_free(rt2x00dev->rfkill); + rt2x00dev->poll_dev = NULL; +} + +void rt2x00rfkill_resume(struct rt2x00_dev *rt2x00dev) +{ + if (!test_bit(CONFIG_SUPPORT_HW_BUTTON, &rt2x00dev->flags) || + !test_bit(RFKILL_STATE_ALLOCATED, &rt2x00dev->rfkill_state)) + return; + + rt2x00dev->poll_dev = rt2x00rfkill_allocate_polldev(rt2x00dev); + if (!rt2x00dev->poll_dev) { + ERROR(rt2x00dev, "Failed to allocate polled device.\n"); + return; + } } diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c index 4baa916b80cf215f68aa9166b7a49d166a92e5a9..babb240cef3def52c107223217ce4844889c877d 100644 --- a/drivers/net/wireless/rt2x00/rt61pci.c +++ b/drivers/net/wireless/rt2x00/rt61pci.c @@ -2306,9 +2306,9 @@ static void rt61pci_configure_filter(struct ieee80211_hw *hw, * Apply some rules to the filters: * - Some filters imply different filters to be set. * - Some things we can't filter out at all. + * - Multicast filter seems to kill broadcast traffic so never use it. */ - if (mc_count) - *total_flags |= FIF_ALLMULTI; + *total_flags |= FIF_ALLMULTI; if (*total_flags & FIF_OTHER_BSS || *total_flags & FIF_PROMISC_IN_BSS) *total_flags |= FIF_PROMISC_IN_BSS | FIF_OTHER_BSS; diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c index 48938819ee2f41777dd14240df87b037f0988d83..46b040bf62decdbc93abf6db706273aefa0adbcf 100644 --- a/drivers/net/wireless/rt2x00/rt73usb.c +++ b/drivers/net/wireless/rt2x00/rt73usb.c @@ -1906,9 +1906,9 @@ static void rt73usb_configure_filter(struct ieee80211_hw *hw, * Apply some rules to the filters: * - Some filters imply different filters to be set. * - Some things we can't filter out at all. + * - Multicast filter seems to kill broadcast traffic so never use it. */ - if (mc_count) - *total_flags |= FIF_ALLMULTI; + *total_flags |= FIF_ALLMULTI; if (*total_flags & FIF_OTHER_BSS || *total_flags & FIF_PROMISC_IN_BSS) *total_flags |= FIF_PROMISC_IN_BSS | FIF_OTHER_BSS; @@ -2163,6 +2163,7 @@ static struct usb_device_id rt73usb_device_table[] = { /* D-Link */ { USB_DEVICE(0x07d1, 0x3c03), USB_DEVICE_DATA(&rt73usb_ops) }, { USB_DEVICE(0x07d1, 0x3c04), USB_DEVICE_DATA(&rt73usb_ops) }, + { USB_DEVICE(0x07d1, 0x3c07), USB_DEVICE_DATA(&rt73usb_ops) }, /* Gemtek */ { USB_DEVICE(0x15a9, 0x0004), USB_DEVICE_DATA(&rt73usb_ops) }, /* Gigabyte */ diff --git a/drivers/parisc/Kconfig b/drivers/parisc/Kconfig index 1d3b84b4af3fc5fb0937763098f7f65e57fb80fd..553a9905299a9cb80f1171ca24d3f449532ca719 100644 --- a/drivers/parisc/Kconfig +++ b/drivers/parisc/Kconfig @@ -103,6 +103,11 @@ config IOMMU_SBA depends on PCI_LBA default PCI_LBA +config IOMMU_HELPER + bool + depends on IOMMU_SBA || IOMMU_CCIO + default y + #config PCI_EPIC # bool "EPIC/SAGA PCI support" # depends on PCI diff --git a/drivers/parisc/ccio-dma.c b/drivers/parisc/ccio-dma.c index d08b284de196b2e807518ac656d678e585f9560c..62db3c3fe4dcbd35dcd6181c4061954e4b0b0d87 100644 --- a/drivers/parisc/ccio-dma.c +++ b/drivers/parisc/ccio-dma.c @@ -43,6 +43,7 @@ #include #include #include +#include #include #include /* for L1_CACHE_BYTES */ @@ -302,13 +303,17 @@ static int ioc_count; */ #define CCIO_SEARCH_LOOP(ioc, res_idx, mask, size) \ for(; res_ptr < res_end; ++res_ptr) { \ - if(0 == (*res_ptr & mask)) { \ - *res_ptr |= mask; \ - res_idx = (unsigned int)((unsigned long)res_ptr - (unsigned long)ioc->res_map); \ - ioc->res_hint = res_idx + (size >> 3); \ - goto resource_found; \ - } \ - } + int ret;\ + unsigned int idx;\ + idx = (unsigned int)((unsigned long)res_ptr - (unsigned long)ioc->res_map); \ + ret = iommu_is_span_boundary(idx << 3, pages_needed, 0, boundary_size);\ + if ((0 == (*res_ptr & mask)) && !ret) { \ + *res_ptr |= mask; \ + res_idx = idx;\ + ioc->res_hint = res_idx + (size >> 3); \ + goto resource_found; \ + } \ + } #define CCIO_FIND_FREE_MAPPING(ioa, res_idx, mask, size) \ u##size *res_ptr = (u##size *)&((ioc)->res_map[ioa->res_hint & ~((size >> 3) - 1)]); \ @@ -341,10 +346,11 @@ static int ioc_count; * of available pages for the requested size. */ static int -ccio_alloc_range(struct ioc *ioc, size_t size) +ccio_alloc_range(struct ioc *ioc, struct device *dev, size_t size) { unsigned int pages_needed = size >> IOVP_SHIFT; unsigned int res_idx; + unsigned long boundary_size; #ifdef CCIO_SEARCH_TIME unsigned long cr_start = mfctl(16); #endif @@ -360,6 +366,9 @@ ccio_alloc_range(struct ioc *ioc, size_t size) ** ggg sacrifices another 710 to the computer gods. */ + boundary_size = ALIGN((unsigned long long)dma_get_seg_boundary(dev) + 1, + 1ULL << IOVP_SHIFT) >> IOVP_SHIFT; + if (pages_needed <= 8) { /* * LAN traffic will not thrash the TLB IFF the same NIC @@ -760,7 +769,7 @@ ccio_map_single(struct device *dev, void *addr, size_t size, ioc->msingle_pages += size >> IOVP_SHIFT; #endif - idx = ccio_alloc_range(ioc, size); + idx = ccio_alloc_range(ioc, dev, size); iovp = (dma_addr_t)MKIOVP(idx); pdir_start = &(ioc->pdir_base[idx]); diff --git a/drivers/parisc/iommu-helpers.h b/drivers/parisc/iommu-helpers.h index 97ba8286c5969285294c2dd886a0e375071f4878..a9c46cc2db3701157485b8194af83a6c03c7b189 100644 --- a/drivers/parisc/iommu-helpers.h +++ b/drivers/parisc/iommu-helpers.h @@ -96,8 +96,8 @@ iommu_fill_pdir(struct ioc *ioc, struct scatterlist *startsg, int nents, static inline unsigned int iommu_coalesce_chunks(struct ioc *ioc, struct device *dev, - struct scatterlist *startsg, int nents, - int (*iommu_alloc_range)(struct ioc *, size_t)) + struct scatterlist *startsg, int nents, + int (*iommu_alloc_range)(struct ioc *, struct device *, size_t)) { struct scatterlist *contig_sg; /* contig chunk head */ unsigned long dma_offset, dma_len; /* start/len of DMA stream */ @@ -166,7 +166,7 @@ iommu_coalesce_chunks(struct ioc *ioc, struct device *dev, dma_len = ALIGN(dma_len + dma_offset, IOVP_SIZE); sg_dma_address(contig_sg) = PIDE_FLAG - | (iommu_alloc_range(ioc, dma_len) << IOVP_SHIFT) + | (iommu_alloc_range(ioc, dev, dma_len) << IOVP_SHIFT) | dma_offset; n_mappings++; } diff --git a/drivers/parisc/pdc_stable.c b/drivers/parisc/pdc_stable.c index de34aa9d3136055566204767cd2f5b9cbb28bfb6..f9f9a5f1bbd0f9d74c5f505c4dea7f7a1ac6c129 100644 --- a/drivers/parisc/pdc_stable.c +++ b/drivers/parisc/pdc_stable.c @@ -829,7 +829,7 @@ static ssize_t pdcs_autoboot_write(struct kobject *kobj, struct kobj_attribute *attr, const char *buf, size_t count) { - return pdcs_auto_write(kset, attr, buf, count, PF_AUTOBOOT); + return pdcs_auto_write(kobj, attr, buf, count, PF_AUTOBOOT); } /** @@ -845,7 +845,7 @@ static ssize_t pdcs_autosearch_write(struct kobject *kobj, struct kobj_attribute *attr, const char *buf, size_t count) { - return pdcs_auto_write(kset, attr, buf, count, PF_AUTOSEARCH); + return pdcs_auto_write(kobj, attr, buf, count, PF_AUTOSEARCH); } /** @@ -1066,7 +1066,7 @@ pdc_stable_init(void) } /* Don't forget the root entries */ - error = sysfs_create_group(stable_kobj, pdcs_attr_group); + error = sysfs_create_group(stable_kobj, &pdcs_attr_group); /* register the paths kset as a child of the stable kset */ paths_kset = kset_create_and_add("paths", NULL, stable_kobj); diff --git a/drivers/parisc/sba_iommu.c b/drivers/parisc/sba_iommu.c index d06627c3f353a607f7730b300af68a3d607b83b6..8c4d2c13d5f246057a42d73ac518637973fca79e 100644 --- a/drivers/parisc/sba_iommu.c +++ b/drivers/parisc/sba_iommu.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #include @@ -313,6 +314,12 @@ sba_dump_sg( struct ioc *ioc, struct scatterlist *startsg, int nents) #define RESMAP_MASK(n) (~0UL << (BITS_PER_LONG - (n))) #define RESMAP_IDX_MASK (sizeof(unsigned long) - 1) +static unsigned long ptr_to_pide(struct ioc *ioc, unsigned long *res_ptr, + unsigned int bitshiftcnt) +{ + return (((unsigned long)res_ptr - (unsigned long)ioc->res_map) << 3) + + bitshiftcnt; +} /** * sba_search_bitmap - find free space in IO PDIR resource bitmap @@ -324,19 +331,36 @@ sba_dump_sg( struct ioc *ioc, struct scatterlist *startsg, int nents) * Cool perf optimization: search for log2(size) bits at a time. */ static SBA_INLINE unsigned long -sba_search_bitmap(struct ioc *ioc, unsigned long bits_wanted) +sba_search_bitmap(struct ioc *ioc, struct device *dev, + unsigned long bits_wanted) { unsigned long *res_ptr = ioc->res_hint; unsigned long *res_end = (unsigned long *) &(ioc->res_map[ioc->res_size]); - unsigned long pide = ~0UL; + unsigned long pide = ~0UL, tpide; + unsigned long boundary_size; + unsigned long shift; + int ret; + + boundary_size = ALIGN((unsigned long long)dma_get_seg_boundary(dev) + 1, + 1ULL << IOVP_SHIFT) >> IOVP_SHIFT; + +#if defined(ZX1_SUPPORT) + BUG_ON(ioc->ibase & ~IOVP_MASK); + shift = ioc->ibase >> IOVP_SHIFT; +#else + shift = 0; +#endif if (bits_wanted > (BITS_PER_LONG/2)) { /* Search word at a time - no mask needed */ for(; res_ptr < res_end; ++res_ptr) { - if (*res_ptr == 0) { + tpide = ptr_to_pide(ioc, res_ptr, 0); + ret = iommu_is_span_boundary(tpide, bits_wanted, + shift, + boundary_size); + if ((*res_ptr == 0) && !ret) { *res_ptr = RESMAP_MASK(bits_wanted); - pide = ((unsigned long)res_ptr - (unsigned long)ioc->res_map); - pide <<= 3; /* convert to bit address */ + pide = tpide; break; } } @@ -365,11 +389,13 @@ sba_search_bitmap(struct ioc *ioc, unsigned long bits_wanted) { DBG_RES(" %p %lx %lx\n", res_ptr, mask, *res_ptr); WARN_ON(mask == 0); - if(((*res_ptr) & mask) == 0) { + tpide = ptr_to_pide(ioc, res_ptr, bitshiftcnt); + ret = iommu_is_span_boundary(tpide, bits_wanted, + shift, + boundary_size); + if ((((*res_ptr) & mask) == 0) && !ret) { *res_ptr |= mask; /* mark resources busy! */ - pide = ((unsigned long)res_ptr - (unsigned long)ioc->res_map); - pide <<= 3; /* convert to bit address */ - pide += bitshiftcnt; + pide = tpide; break; } mask >>= o; @@ -404,7 +430,7 @@ sba_search_bitmap(struct ioc *ioc, unsigned long bits_wanted) * resource bit map. */ static int -sba_alloc_range(struct ioc *ioc, size_t size) +sba_alloc_range(struct ioc *ioc, struct device *dev, size_t size) { unsigned int pages_needed = size >> IOVP_SHIFT; #ifdef SBA_COLLECT_STATS @@ -412,9 +438,9 @@ sba_alloc_range(struct ioc *ioc, size_t size) #endif unsigned long pide; - pide = sba_search_bitmap(ioc, pages_needed); + pide = sba_search_bitmap(ioc, dev, pages_needed); if (pide >= (ioc->res_size << 3)) { - pide = sba_search_bitmap(ioc, pages_needed); + pide = sba_search_bitmap(ioc, dev, pages_needed); if (pide >= (ioc->res_size << 3)) panic("%s: I/O MMU @ %p is out of mapping resources\n", __FILE__, ioc->ioc_hpa); @@ -710,7 +736,7 @@ sba_map_single(struct device *dev, void *addr, size_t size, ioc->msingle_calls++; ioc->msingle_pages += size >> IOVP_SHIFT; #endif - pide = sba_alloc_range(ioc, size); + pide = sba_alloc_range(ioc, dev, size); iovp = (dma_addr_t) pide << IOVP_SHIFT; DBG_RUN("%s() 0x%p -> 0x%lx\n", diff --git a/drivers/pci/bus.c b/drivers/pci/bus.c index ef5a6a245f5fa36363d513e5aa35fef248a499a4..d708358326e556ae03e00b213e89dd1baf0dceff 100644 --- a/drivers/pci/bus.c +++ b/drivers/pci/bus.c @@ -143,15 +143,21 @@ void pci_bus_add_devices(struct pci_bus *bus) /* register the bus with sysfs as the parent is now * properly registered. */ child_bus = dev->subordinate; + if (child_bus->is_added) + continue; child_bus->dev.parent = child_bus->bridge; retval = device_register(&child_bus->dev); - if (!retval) + if (retval) + dev_err(&dev->dev, "Error registering pci_bus," + " continuing...\n"); + else { + child_bus->is_added = 1; retval = device_create_file(&child_bus->dev, &dev_attr_cpuaffinity); + } if (retval) - dev_err(&dev->dev, "Error registering pci_bus" - " device bridge symlink," - " continuing...\n"); + dev_err(&dev->dev, "Error creating cpuaffinity" + " file, continuing...\n"); } } } diff --git a/drivers/pci/hotplug-pci.c b/drivers/pci/hotplug-pci.c index a590ef682153ee5d765af348640ce79d39a9d4e8..4d4a64478404650a9640c852b3cf708937fc5ff0 100644 --- a/drivers/pci/hotplug-pci.c +++ b/drivers/pci/hotplug-pci.c @@ -4,7 +4,7 @@ #include "pci.h" -unsigned int pci_do_scan_bus(struct pci_bus *bus) +unsigned int __devinit pci_do_scan_bus(struct pci_bus *bus) { unsigned int max; diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c index cf22f9e01e005721257bd61c7a2894008f65b497..5e50008d1181046ea2b77378f68c4fd7596c1914 100644 --- a/drivers/pci/hotplug/acpiphp_glue.c +++ b/drivers/pci/hotplug/acpiphp_glue.c @@ -1085,7 +1085,7 @@ static int acpiphp_bus_trim(acpi_handle handle) * This function should be called per *physical slot*, * not per each slot object in ACPI namespace. */ -static int enable_device(struct acpiphp_slot *slot) +static int __ref enable_device(struct acpiphp_slot *slot) { struct pci_dev *dev; struct pci_bus *bus = slot->bridge->pci_bus; diff --git a/drivers/pci/hotplug/cpci_hotplug_pci.c b/drivers/pci/hotplug/cpci_hotplug_pci.c index 5e9be44817cb5ff4daa3f8bc5b04f6f45f10e6d3..b3515fc4cd38383fd2a25860b346b514006c3c52 100644 --- a/drivers/pci/hotplug/cpci_hotplug_pci.c +++ b/drivers/pci/hotplug/cpci_hotplug_pci.c @@ -250,7 +250,7 @@ int cpci_led_off(struct slot* slot) * Device configuration functions */ -int cpci_configure_slot(struct slot* slot) +int __ref cpci_configure_slot(struct slot *slot) { struct pci_bus *parent; int fn; diff --git a/drivers/pci/hotplug/ibmphp_ebda.c b/drivers/pci/hotplug/ibmphp_ebda.c index 600ed7b67ae7fab1f748d2d99cfee8a3dc516de4..bbccde9f228f1c25dd183dd7899e3bda3524006f 100644 --- a/drivers/pci/hotplug/ibmphp_ebda.c +++ b/drivers/pci/hotplug/ibmphp_ebda.c @@ -963,6 +963,7 @@ static int __init ebda_rsrc_controller (void) bus_info_ptr1 = ibmphp_find_same_bus_num (hpc_ptr->slots[index].slot_bus_num); if (!bus_info_ptr1) { + kfree(tmp_slot); rc = -ENODEV; goto error; } diff --git a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c index 6eba9b2cfb90b359fc1fb92b45408846b4694f6f..698975a6a21c712b46654cba06b71b641612a143 100644 --- a/drivers/pci/hotplug/pciehp_hpc.c +++ b/drivers/pci/hotplug/pciehp_hpc.c @@ -711,7 +711,8 @@ static int hpc_power_off_slot(struct slot * slot) retval = pcie_write_cmd(slot, slot_cmd, cmd_mask); if (retval) { err("%s: Write command failed!\n", __FUNCTION__); - return -1; + retval = -1; + goto out; } dbg("%s: SLOTCTRL %x write cmd %x\n", __FUNCTION__, ctrl->cap_base + SLOTCTRL, slot_cmd); @@ -722,7 +723,7 @@ static int hpc_power_off_slot(struct slot * slot) * removed from the slot/adapter. */ msleep(1000); - + out: if (changed) pcie_unmask_bad_dllp(ctrl); diff --git a/drivers/pci/hotplug/pciehp_pci.c b/drivers/pci/hotplug/pciehp_pci.c index dd50713966d1b011bc480aa9d2cab642c63bb7c9..9372a840b63dbd3d43147dca446c3f078455a2e5 100644 --- a/drivers/pci/hotplug/pciehp_pci.c +++ b/drivers/pci/hotplug/pciehp_pci.c @@ -167,7 +167,7 @@ static void program_fw_provided_values(struct pci_dev *dev) } } -static int pciehp_add_bridge(struct pci_dev *dev) +static int __ref pciehp_add_bridge(struct pci_dev *dev) { struct pci_bus *parent = dev->bus; int pass, busnr, start = parent->secondary; diff --git a/drivers/pci/hotplug/shpchp_pci.c b/drivers/pci/hotplug/shpchp_pci.c index 0a6b25ef194c2991e36d3be4e2bb605b61a4bed4..a69a21520895814caf732ab93735b9a950688c60 100644 --- a/drivers/pci/hotplug/shpchp_pci.c +++ b/drivers/pci/hotplug/shpchp_pci.c @@ -96,7 +96,7 @@ static void program_fw_provided_values(struct pci_dev *dev) } } -int shpchp_configure_device(struct slot *p_slot) +int __ref shpchp_configure_device(struct slot *p_slot) { struct pci_dev *dev; struct pci_bus *parent = p_slot->ctrl->pci_dev->subordinate; diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c index 4a23654184fc04da02eb1a73468818709fbe6371..72f7476930c857ffa20a4c323dff3af6bf7c9baa 100644 --- a/drivers/pci/pci-acpi.c +++ b/drivers/pci/pci-acpi.c @@ -272,21 +272,29 @@ static int acpi_pci_set_power_state(struct pci_dev *dev, pci_power_t state) { acpi_handle handle = DEVICE_ACPI_HANDLE(&dev->dev); acpi_handle tmp; - static int state_conv[] = { - [0] = 0, - [1] = 1, - [2] = 2, - [3] = 3, - [4] = 3 + static const u8 state_conv[] = { + [PCI_D0] = ACPI_STATE_D0, + [PCI_D1] = ACPI_STATE_D1, + [PCI_D2] = ACPI_STATE_D2, + [PCI_D3hot] = ACPI_STATE_D3, + [PCI_D3cold] = ACPI_STATE_D3 }; - int acpi_state = state_conv[(int __force) state]; if (!handle) return -ENODEV; /* If the ACPI device has _EJ0, ignore the device */ if (ACPI_SUCCESS(acpi_get_handle(handle, "_EJ0", &tmp))) return 0; - return acpi_bus_set_power(handle, acpi_state); + + switch (state) { + case PCI_D0: + case PCI_D1: + case PCI_D2: + case PCI_D3hot: + case PCI_D3cold: + return acpi_bus_set_power(handle, state_conv[state]); + } + return -EINVAL; } diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index 4d23b9fb551bc129239f07404e04f6a4102ae092..2db2e4bb0d1ed6073b6ec9d3e0dec604868974ab 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c @@ -286,7 +286,7 @@ static void pci_read_bases(struct pci_dev *dev, unsigned int howmany, int rom) } } -void pci_read_bridge_bases(struct pci_bus *child) +void __devinit pci_read_bridge_bases(struct pci_bus *child) { struct pci_dev *dev = child->self; u8 io_base_lo, io_limit_lo; @@ -472,7 +472,7 @@ static void pci_fixup_parent_subordinate_busnr(struct pci_bus *child, int max) * them, we proceed to assigning numbers to the remaining buses in * order to avoid overlaps between old and new bus numbers. */ -int pci_scan_bridge(struct pci_bus *bus, struct pci_dev * dev, int max, int pass) +int __devinit pci_scan_bridge(struct pci_bus *bus, struct pci_dev *dev, int max, int pass) { struct pci_bus *child; int is_cardbus = (dev->hdr_type == PCI_HEADER_TYPE_CARDBUS); @@ -1008,7 +1008,7 @@ int pci_scan_slot(struct pci_bus *bus, int devfn) return nr; } -unsigned int pci_scan_child_bus(struct pci_bus *bus) +unsigned int __devinit pci_scan_child_bus(struct pci_bus *bus) { unsigned int devfn, pass, max = bus->secondary; struct pci_dev *dev; @@ -1116,7 +1116,7 @@ err_out: return NULL; } -struct pci_bus *pci_scan_bus_parented(struct device *parent, +struct pci_bus * __devinit pci_scan_bus_parented(struct device *parent, int bus, struct pci_ops *ops, void *sysdata) { struct pci_bus *b; diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index bbad4a9f264f0045dfc091cb1f96cb5877eb11ce..e9a333d985526c5a5af22c1e6cc79c3e2dccad10 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c @@ -1652,9 +1652,8 @@ static void __devinit quirk_via_cx700_pci_parking_caching(struct pci_dev *dev) pci_write_config_byte(dev, 0x75, 0x1); pci_write_config_byte(dev, 0x77, 0x0); - printk(KERN_INFO - "PCI: VIA CX700 PCI parking/caching fixup on %s\n", - pci_name(dev)); + dev_info(&dev->dev, + "Disabling VIA CX700 PCI parking/caching\n"); } } } @@ -1726,32 +1725,6 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_HT2 quirk_msi_ht_cap); -/* - * Force enable MSI mapping capability on HT bridges - */ -static void __devinit quirk_msi_ht_cap_enable(struct pci_dev *dev) -{ - int pos, ttl = 48; - - pos = pci_find_ht_capability(dev, HT_CAPTYPE_MSI_MAPPING); - while (pos && ttl--) { - u8 flags; - - if (pci_read_config_byte(dev, pos + HT_MSI_FLAGS, &flags) == 0) { - printk(KERN_INFO "PCI: Enabling HT MSI Mapping on %s\n", - pci_name(dev)); - - pci_write_config_byte(dev, pos + HT_MSI_FLAGS, - flags | HT_MSI_FLAGS_ENABLE); - } - pos = pci_find_next_ht_capability(dev, pos, - HT_CAPTYPE_MSI_MAPPING); - } -} -DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SERVERWORKS, - PCI_DEVICE_ID_SERVERWORKS_HT1000_PXB, - quirk_msi_ht_cap_enable); - /* The nVidia CK804 chipset may have 2 HT MSI mappings. * MSI are supported if the MSI capability set in any of these mappings. */ @@ -1778,9 +1751,8 @@ static void __devinit quirk_nvidia_ck804_msi_ht_cap(struct pci_dev *dev) DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_CK804_PCIE, quirk_nvidia_ck804_msi_ht_cap); -/* - * Force enable MSI mapping capability on HT bridges */ -static inline void ht_enable_msi_mapping(struct pci_dev *dev) +/* Force enable MSI mapping capability on HT bridges */ +static void __devinit ht_enable_msi_mapping(struct pci_dev *dev) { int pos, ttl = 48; @@ -1799,6 +1771,9 @@ static inline void ht_enable_msi_mapping(struct pci_dev *dev) HT_CAPTYPE_MSI_MAPPING); } } +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SERVERWORKS, + PCI_DEVICE_ID_SERVERWORKS_HT1000_PXB, + ht_enable_msi_mapping); static void __devinit nv_msi_ht_cap_quirk(struct pci_dev *dev) { @@ -1830,7 +1805,7 @@ static void __devinit nv_msi_ht_cap_quirk(struct pci_dev *dev) if (pci_read_config_byte(dev, pos + HT_MSI_FLAGS, &flags) == 0) { - dev_info(&dev->dev, "Quirk disabling HT MSI mapping"); + dev_info(&dev->dev, "Disabling HT MSI mapping"); pci_write_config_byte(dev, pos + HT_MSI_FLAGS, flags & ~HT_MSI_FLAGS_ENABLE); } diff --git a/drivers/pci/rom.c b/drivers/pci/rom.c index a98b2470b9ea5f85b95a3ae3c9da79aeafb29363..bd5c0e031398e9b50404380076b69c0c25889c71 100644 --- a/drivers/pci/rom.c +++ b/drivers/pci/rom.c @@ -242,8 +242,7 @@ void pci_remove_rom(struct pci_dev *pdev) #endif /* 0 */ /** - * pci_cleanup_rom - internal routine for freeing the ROM copy created - * by pci_map_rom_copy called from remove.c + * pci_cleanup_rom - free the ROM copy created by pci_map_rom_copy * @pdev: pointer to pci device struct * * Free the copied ROM if we allocated one. diff --git a/drivers/pnp/quirks.c b/drivers/pnp/quirks.c index 4065139753b6c4b6e9e1becf06df11234bde8b5f..37993206ae5dd149d98672345ef5d16c6c21743c 100644 --- a/drivers/pnp/quirks.c +++ b/drivers/pnp/quirks.c @@ -17,7 +17,6 @@ #include #include #include -#include #include #include "base.h" @@ -109,42 +108,73 @@ static void quirk_sb16audio_resources(struct pnp_dev *dev) "pnp: SB audio device quirk - increasing port range\n"); } -static void quirk_supermicro_h8dce_system(struct pnp_dev *dev) + +#include + +static void quirk_system_pci_resources(struct pnp_dev *dev) { - int i; - static struct dmi_system_id supermicro_h8dce[] = { - { - .ident = "Supermicro H8DCE", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Supermicro"), - DMI_MATCH(DMI_PRODUCT_NAME, "H8DCE"), - }, - }, - { } - }; - - if (!dmi_check_system(supermicro_h8dce)) - return; + struct pci_dev *pdev = NULL; + resource_size_t pnp_start, pnp_end, pci_start, pci_end; + int i, j; /* - * On the Supermicro H8DCE, there's a system device with resources - * that overlap BAR 6 of the built-in SATA PCI adapter. If the PNP - * system device claims them, the sata_nv driver won't be able to. - * More details at: - * https://bugzilla.redhat.com/show_bug.cgi?id=280641 - * https://bugzilla.redhat.com/show_bug.cgi?id=313491 - * http://lkml.org/lkml/2008/1/9/449 - * http://thread.gmane.org/gmane.linux.acpi.devel/27312 + * Some BIOSes have PNP motherboard devices with resources that + * partially overlap PCI BARs. The PNP system driver claims these + * motherboard resources, which prevents the normal PCI driver from + * requesting them later. + * + * This patch disables the PNP resources that conflict with PCI BARs + * so they won't be claimed by the PNP system driver. */ - for (i = 0; i < PNP_MAX_MEM; i++) { - if (pnp_mem_valid(dev, i) && pnp_mem_len(dev, i) && - (pnp_mem_start(dev, i) & 0xdfef0000) == 0xdfef0000) { - dev_warn(&dev->dev, "disabling 0x%llx-0x%llx to prevent" - " conflict with sata_nv PCI device\n", - (unsigned long long) pnp_mem_start(dev, i), - (unsigned long long) (pnp_mem_start(dev, i) + - pnp_mem_len(dev, i) - 1)); - pnp_mem_flags(dev, i) = 0; + for_each_pci_dev(pdev) { + for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) { + if (!(pci_resource_flags(pdev, i) & IORESOURCE_MEM) || + pci_resource_len(pdev, i) == 0) + continue; + + pci_start = pci_resource_start(pdev, i); + pci_end = pci_resource_end(pdev, i); + for (j = 0; j < PNP_MAX_MEM; j++) { + if (!pnp_mem_valid(dev, j) || + pnp_mem_len(dev, j) == 0) + continue; + + pnp_start = pnp_mem_start(dev, j); + pnp_end = pnp_mem_end(dev, j); + + /* + * If the PNP region doesn't overlap the PCI + * region at all, there's no problem. + */ + if (pnp_end < pci_start || pnp_start > pci_end) + continue; + + /* + * If the PNP region completely encloses (or is + * at least as large as) the PCI region, that's + * also OK. For example, this happens when the + * PNP device describes a bridge with PCI + * behind it. + */ + if (pnp_start <= pci_start && + pnp_end >= pci_end) + continue; + + /* + * Otherwise, the PNP region overlaps *part* of + * the PCI region, and that might prevent a PCI + * driver from requesting its resources. + */ + dev_warn(&dev->dev, "mem resource " + "(0x%llx-0x%llx) overlaps %s BAR %d " + "(0x%llx-0x%llx), disabling\n", + (unsigned long long) pnp_start, + (unsigned long long) pnp_end, + pci_name(pdev), i, + (unsigned long long) pci_start, + (unsigned long long) pci_end); + pnp_mem_flags(dev, j) = 0; + } } } } @@ -169,8 +199,8 @@ static struct pnp_fixup pnp_fixups[] = { {"CTL0043", quirk_sb16audio_resources}, {"CTL0044", quirk_sb16audio_resources}, {"CTL0045", quirk_sb16audio_resources}, - {"PNP0c01", quirk_supermicro_h8dce_system}, - {"PNP0c02", quirk_supermicro_h8dce_system}, + {"PNP0c01", quirk_system_pci_resources}, + {"PNP0c02", quirk_system_pci_resources}, {""} }; diff --git a/drivers/rapidio/rio-driver.c b/drivers/rapidio/rio-driver.c index 5480119ff9d36d94af3dce527dbaacac4d5811d7..3ce9f3defc1287f688f6484f2f265b7cdb620125 100644 --- a/drivers/rapidio/rio-driver.c +++ b/drivers/rapidio/rio-driver.c @@ -78,8 +78,7 @@ void rio_dev_put(struct rio_dev *rdev) } /** - * rio_device_probe - Tell if a RIO device structure has a matching RIO - * device id structure + * rio_device_probe - Tell if a RIO device structure has a matching RIO device id structure * @id: the RIO device id structure to match against * @dev: the RIO device structure to match against * @@ -137,7 +136,7 @@ static int rio_device_remove(struct device *dev) * rio_register_driver - register a new RIO driver * @rdrv: the RIO driver structure to register * - * Adds a &struct rio_driver to the list of registered drivers + * Adds a &struct rio_driver to the list of registered drivers. * Returns a negative value on error, otherwise 0. If no error * occurred, the driver remains registered even if no device * was claimed during registration. @@ -167,8 +166,7 @@ void rio_unregister_driver(struct rio_driver *rdrv) } /** - * rio_match_bus - Tell if a RIO device structure has a matching RIO - * driver device id structure + * rio_match_bus - Tell if a RIO device structure has a matching RIO driver device id structure * @dev: the standard device structure to match against * @drv: the standard driver structure containing the ids to match against * diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig index 6402d699072b5a28a11069a5188dd2e34245a079..82f5ad9c3af479a86e711819b8cea6ddfc42f947 100644 --- a/drivers/rtc/Kconfig +++ b/drivers/rtc/Kconfig @@ -250,6 +250,15 @@ config RTC_DRV_TWL92330 platforms. The support is integrated with the rest of the Menelaus driver; it's not separate module. +config RTC_DRV_S35390A + tristate "Seiko Instruments S-35390A" + help + If you say yes here you will get support for the Seiko + Instruments S-35390A. + + This driver can also be built as a module. If so the module + will be called rtc-s35390a. + endif # I2C comment "SPI RTC drivers" diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile index ec703f34ab864da930d3eadbe594d0ca67fb5bfa..872f1218ff9f5d7e2480a8128b481a33e4a4d096 100644 --- a/drivers/rtc/Makefile +++ b/drivers/rtc/Makefile @@ -45,6 +45,7 @@ obj-$(CONFIG_RTC_DRV_R9701) += rtc-r9701.o obj-$(CONFIG_RTC_DRV_RS5C313) += rtc-rs5c313.o obj-$(CONFIG_RTC_DRV_RS5C348) += rtc-rs5c348.o obj-$(CONFIG_RTC_DRV_RS5C372) += rtc-rs5c372.o +obj-$(CONFIG_RTC_DRV_S35390A) += rtc-s35390a.o obj-$(CONFIG_RTC_DRV_S3C) += rtc-s3c.o obj-$(CONFIG_RTC_DRV_SA1100) += rtc-sa1100.o obj-$(CONFIG_RTC_DRV_SH) += rtc-sh.o diff --git a/drivers/rtc/rtc-s35390a.c b/drivers/rtc/rtc-s35390a.c new file mode 100644 index 0000000000000000000000000000000000000000..e8abc90c32c5fe0e82938ad7d4b711807a8c7779 --- /dev/null +++ b/drivers/rtc/rtc-s35390a.c @@ -0,0 +1,316 @@ +/* + * Seiko Instruments S-35390A RTC Driver + * + * Copyright (c) 2007 Byron Bradley + * + * 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 +#include +#include +#include +#include +#include + +#define S35390A_CMD_STATUS1 0 +#define S35390A_CMD_STATUS2 1 +#define S35390A_CMD_TIME1 2 + +#define S35390A_BYTE_YEAR 0 +#define S35390A_BYTE_MONTH 1 +#define S35390A_BYTE_DAY 2 +#define S35390A_BYTE_WDAY 3 +#define S35390A_BYTE_HOURS 4 +#define S35390A_BYTE_MINS 5 +#define S35390A_BYTE_SECS 6 + +#define S35390A_FLAG_POC 0x01 +#define S35390A_FLAG_BLD 0x02 +#define S35390A_FLAG_24H 0x40 +#define S35390A_FLAG_RESET 0x80 +#define S35390A_FLAG_TEST 0x01 + +struct s35390a { + struct i2c_client *client[8]; + struct rtc_device *rtc; + int twentyfourhour; +}; + +static int s35390a_set_reg(struct s35390a *s35390a, int reg, char *buf, int len) +{ + struct i2c_client *client = s35390a->client[reg]; + struct i2c_msg msg[] = { + { client->addr, 0, len, buf }, + }; + + if ((i2c_transfer(client->adapter, msg, 1)) != 1) + return -EIO; + + return 0; +} + +static int s35390a_get_reg(struct s35390a *s35390a, int reg, char *buf, int len) +{ + struct i2c_client *client = s35390a->client[reg]; + struct i2c_msg msg[] = { + { client->addr, I2C_M_RD, len, buf }, + }; + + if ((i2c_transfer(client->adapter, msg, 1)) != 1) + return -EIO; + + return 0; +} + +static int s35390a_reset(struct s35390a *s35390a) +{ + char buf[1]; + + if (s35390a_get_reg(s35390a, S35390A_CMD_STATUS1, buf, sizeof(buf)) < 0) + return -EIO; + + if (!(buf[0] & (S35390A_FLAG_POC | S35390A_FLAG_BLD))) + return 0; + + buf[0] |= (S35390A_FLAG_RESET | S35390A_FLAG_24H); + buf[0] &= 0xf0; + return s35390a_set_reg(s35390a, S35390A_CMD_STATUS1, buf, sizeof(buf)); +} + +static int s35390a_disable_test_mode(struct s35390a *s35390a) +{ + char buf[1]; + + if (s35390a_get_reg(s35390a, S35390A_CMD_STATUS2, buf, sizeof(buf)) < 0) + return -EIO; + + if (!(buf[0] & S35390A_FLAG_TEST)) + return 0; + + buf[0] &= ~S35390A_FLAG_TEST; + return s35390a_set_reg(s35390a, S35390A_CMD_STATUS2, buf, sizeof(buf)); +} + +static char s35390a_hr2reg(struct s35390a *s35390a, int hour) +{ + if (s35390a->twentyfourhour) + return BIN2BCD(hour); + + if (hour < 12) + return BIN2BCD(hour); + + return 0x40 | BIN2BCD(hour - 12); +} + +static int s35390a_reg2hr(struct s35390a *s35390a, char reg) +{ + unsigned hour; + + if (s35390a->twentyfourhour) + return BCD2BIN(reg & 0x3f); + + hour = BCD2BIN(reg & 0x3f); + if (reg & 0x40) + hour += 12; + + return hour; +} + +static int s35390a_set_datetime(struct i2c_client *client, struct rtc_time *tm) +{ + struct s35390a *s35390a = i2c_get_clientdata(client); + int i, err; + char buf[7]; + + dev_dbg(&client->dev, "%s: tm is secs=%d, mins=%d, hours=%d mday=%d, " + "mon=%d, year=%d, wday=%d\n", __func__, tm->tm_sec, + tm->tm_min, tm->tm_hour, tm->tm_mday, tm->tm_mon, tm->tm_year, + tm->tm_wday); + + buf[S35390A_BYTE_YEAR] = BIN2BCD(tm->tm_year - 100); + buf[S35390A_BYTE_MONTH] = BIN2BCD(tm->tm_mon + 1); + buf[S35390A_BYTE_DAY] = BIN2BCD(tm->tm_mday); + buf[S35390A_BYTE_WDAY] = BIN2BCD(tm->tm_wday); + buf[S35390A_BYTE_HOURS] = s35390a_hr2reg(s35390a, tm->tm_hour); + buf[S35390A_BYTE_MINS] = BIN2BCD(tm->tm_min); + buf[S35390A_BYTE_SECS] = BIN2BCD(tm->tm_sec); + + /* This chip expects the bits of each byte to be in reverse order */ + for (i = 0; i < 7; ++i) + buf[i] = bitrev8(buf[i]); + + err = s35390a_set_reg(s35390a, S35390A_CMD_TIME1, buf, sizeof(buf)); + + return err; +} + +static int s35390a_get_datetime(struct i2c_client *client, struct rtc_time *tm) +{ + struct s35390a *s35390a = i2c_get_clientdata(client); + char buf[7]; + int i, err; + + err = s35390a_get_reg(s35390a, S35390A_CMD_TIME1, buf, sizeof(buf)); + if (err < 0) + return err; + + /* This chip returns the bits of each byte in reverse order */ + for (i = 0; i < 7; ++i) + buf[i] = bitrev8(buf[i]); + + tm->tm_sec = BCD2BIN(buf[S35390A_BYTE_SECS]); + tm->tm_min = BCD2BIN(buf[S35390A_BYTE_MINS]); + tm->tm_hour = s35390a_reg2hr(s35390a, buf[S35390A_BYTE_HOURS]); + tm->tm_wday = BCD2BIN(buf[S35390A_BYTE_WDAY]); + tm->tm_mday = BCD2BIN(buf[S35390A_BYTE_DAY]); + tm->tm_mon = BCD2BIN(buf[S35390A_BYTE_MONTH]) - 1; + tm->tm_year = BCD2BIN(buf[S35390A_BYTE_YEAR]) + 100; + + dev_dbg(&client->dev, "%s: tm is secs=%d, mins=%d, hours=%d, mday=%d, " + "mon=%d, year=%d, wday=%d\n", __func__, tm->tm_sec, + tm->tm_min, tm->tm_hour, tm->tm_mday, tm->tm_mon, tm->tm_year, + tm->tm_wday); + + return rtc_valid_tm(tm); +} + +static int s35390a_rtc_read_time(struct device *dev, struct rtc_time *tm) +{ + return s35390a_get_datetime(to_i2c_client(dev), tm); +} + +static int s35390a_rtc_set_time(struct device *dev, struct rtc_time *tm) +{ + return s35390a_set_datetime(to_i2c_client(dev), tm); +} + +static const struct rtc_class_ops s35390a_rtc_ops = { + .read_time = s35390a_rtc_read_time, + .set_time = s35390a_rtc_set_time, +}; + +static struct i2c_driver s35390a_driver; + +static int s35390a_probe(struct i2c_client *client) +{ + int err; + unsigned int i; + struct s35390a *s35390a; + struct rtc_time tm; + char buf[1]; + + if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { + err = -ENODEV; + goto exit; + } + + s35390a = kzalloc(sizeof(struct s35390a), GFP_KERNEL); + if (!s35390a) { + err = -ENOMEM; + goto exit; + } + + s35390a->client[0] = client; + i2c_set_clientdata(client, s35390a); + + /* This chip uses multiple addresses, use dummy devices for them */ + for (i = 1; i < 8; ++i) { + s35390a->client[i] = i2c_new_dummy(client->adapter, + client->addr + i, "rtc-s35390a"); + if (!s35390a->client[i]) { + dev_err(&client->dev, "Address %02x unavailable\n", + client->addr + i); + err = -EBUSY; + goto exit_dummy; + } + } + + err = s35390a_reset(s35390a); + if (err < 0) { + dev_err(&client->dev, "error resetting chip\n"); + goto exit_dummy; + } + + err = s35390a_disable_test_mode(s35390a); + if (err < 0) { + dev_err(&client->dev, "error disabling test mode\n"); + goto exit_dummy; + } + + err = s35390a_get_reg(s35390a, S35390A_CMD_STATUS1, buf, sizeof(buf)); + if (err < 0) { + dev_err(&client->dev, "error checking 12/24 hour mode\n"); + goto exit_dummy; + } + if (buf[0] & S35390A_FLAG_24H) + s35390a->twentyfourhour = 1; + else + s35390a->twentyfourhour = 0; + + if (s35390a_get_datetime(client, &tm) < 0) + dev_warn(&client->dev, "clock needs to be set\n"); + + s35390a->rtc = rtc_device_register(s35390a_driver.driver.name, + &client->dev, &s35390a_rtc_ops, THIS_MODULE); + + if (IS_ERR(s35390a->rtc)) { + err = PTR_ERR(s35390a->rtc); + goto exit_dummy; + } + return 0; + +exit_dummy: + for (i = 1; i < 8; ++i) + if (s35390a->client[i]) + i2c_unregister_device(s35390a->client[i]); + kfree(s35390a); + i2c_set_clientdata(client, NULL); + +exit: + return err; +} + +static int s35390a_remove(struct i2c_client *client) +{ + unsigned int i; + + struct s35390a *s35390a = i2c_get_clientdata(client); + for (i = 1; i < 8; ++i) + if (s35390a->client[i]) + i2c_unregister_device(s35390a->client[i]); + + rtc_device_unregister(s35390a->rtc); + kfree(s35390a); + i2c_set_clientdata(client, NULL); + + return 0; +} + +static struct i2c_driver s35390a_driver = { + .driver = { + .name = "rtc-s35390a", + }, + .probe = s35390a_probe, + .remove = s35390a_remove, +}; + +static int __init s35390a_rtc_init(void) +{ + return i2c_add_driver(&s35390a_driver); +} + +static void __exit s35390a_rtc_exit(void) +{ + i2c_del_driver(&s35390a_driver); +} + +MODULE_AUTHOR("Byron Bradley "); +MODULE_DESCRIPTION("S35390A RTC driver"); +MODULE_LICENSE("GPL"); + +module_init(s35390a_rtc_init); +module_exit(s35390a_rtc_exit); diff --git a/drivers/s390/block/dasd_3990_erp.c b/drivers/s390/block/dasd_3990_erp.c index f69714a0e9e7bf3ed750e3b497ce429d2f459ffb..b19db20a0befdc1c31ea98bdf691daaec6807f6f 100644 --- a/drivers/s390/block/dasd_3990_erp.c +++ b/drivers/s390/block/dasd_3990_erp.c @@ -2310,10 +2310,8 @@ static int dasd_3990_erp_error_match(struct dasd_ccw_req *cqr1, struct dasd_ccw_req *cqr2) { - /* check failed CCW */ - if (cqr1->irb.scsw.cpa != cqr2->irb.scsw.cpa) { - // return 0; /* CCW doesn't match */ - } + if (cqr1->startdev != cqr2->startdev) + return 0; if (cqr1->irb.esw.esw0.erw.cons != cqr2->irb.esw.esw0.erw.cons) return 0; diff --git a/drivers/s390/block/dasd_proc.c b/drivers/s390/block/dasd_proc.c index 28a86f070048b4a3a25719fb100546df9cd8ebd8..556063e8f7a91d1163450cc63d1cd9128e6a77b4 100644 --- a/drivers/s390/block/dasd_proc.c +++ b/drivers/s390/block/dasd_proc.c @@ -62,8 +62,10 @@ dasd_devices_show(struct seq_file *m, void *v) return 0; if (device->block) block = device->block; - else + else { + dasd_put_device(device); return 0; + } /* Print device number. */ seq_printf(m, "%s", device->cdev->dev.bus_id); /* Print discipline string. */ diff --git a/drivers/s390/char/defkeymap.c b/drivers/s390/char/defkeymap.c index 389346cda6c826fdecfb7d8663a7950ddd2fab43..07c7f31081bccbe629c7bcbd789bb7665e57edb3 100644 --- a/drivers/s390/char/defkeymap.c +++ b/drivers/s390/char/defkeymap.c @@ -151,8 +151,8 @@ char *func_table[MAX_NR_FUNC] = { }; struct kbdiacruc accent_table[MAX_DIACR] = { - {'^', 'c', '\003'}, {'^', 'd', '\004'}, - {'^', 'z', '\032'}, {'^', '\012', '\000'}, + {'^', 'c', 0003}, {'^', 'd', 0004}, + {'^', 'z', 0032}, {'^', 0012, 0000}, }; unsigned int accent_table_size = 4; diff --git a/drivers/s390/char/sclp_vt220.c b/drivers/s390/char/sclp_vt220.c index 92f527201792971095eea15a1503c0938d1eaeb0..f7b258dfd52cf5a40c14470654a240c0f29b0a93 100644 --- a/drivers/s390/char/sclp_vt220.c +++ b/drivers/s390/char/sclp_vt220.c @@ -367,7 +367,7 @@ sclp_vt220_timeout(unsigned long data) sclp_vt220_emit_current(); } -#define BUFFER_MAX_DELAY HZ/2 +#define BUFFER_MAX_DELAY HZ/20 /* * Internal implementation of the write function. Write COUNT bytes of data diff --git a/drivers/s390/crypto/ap_bus.c b/drivers/s390/crypto/ap_bus.c index d0c6fd3b1c19a02af51665e657fc102829d4d488..7b0b81901297e9b0d28d967dee4694fb2cd9fadc 100644 --- a/drivers/s390/crypto/ap_bus.c +++ b/drivers/s390/crypto/ap_bus.c @@ -490,10 +490,12 @@ static int ap_device_probe(struct device *dev) int rc; ap_dev->drv = ap_drv; - spin_lock_bh(&ap_device_lock); - list_add(&ap_dev->list, &ap_device_list); - spin_unlock_bh(&ap_device_lock); rc = ap_drv->probe ? ap_drv->probe(ap_dev) : -ENODEV; + if (!rc) { + spin_lock_bh(&ap_device_lock); + list_add(&ap_dev->list, &ap_device_list); + spin_unlock_bh(&ap_device_lock); + } return rc; } @@ -532,11 +534,11 @@ static int ap_device_remove(struct device *dev) ap_flush_queue(ap_dev); del_timer_sync(&ap_dev->timeout); - if (ap_drv->remove) - ap_drv->remove(ap_dev); spin_lock_bh(&ap_device_lock); list_del_init(&ap_dev->list); spin_unlock_bh(&ap_device_lock); + if (ap_drv->remove) + ap_drv->remove(ap_dev); spin_lock_bh(&ap_dev->lock); atomic_sub(ap_dev->queue_count, &ap_poll_requests); spin_unlock_bh(&ap_dev->lock); diff --git a/drivers/scsi/aic94xx/aic94xx.h b/drivers/scsi/aic94xx/aic94xx.h index 32f513b1b78ab314253e7ddceb4117aa5e40fcad..eb8efdcefe482e0bf8997b566a72db30d76027ba 100644 --- a/drivers/scsi/aic94xx/aic94xx.h +++ b/drivers/scsi/aic94xx/aic94xx.h @@ -102,6 +102,7 @@ int asd_abort_task_set(struct domain_device *, u8 *lun); int asd_clear_aca(struct domain_device *, u8 *lun); int asd_clear_task_set(struct domain_device *, u8 *lun); int asd_lu_reset(struct domain_device *, u8 *lun); +int asd_I_T_nexus_reset(struct domain_device *dev); int asd_query_task(struct sas_task *); /* ---------- Adapter and Port management ---------- */ diff --git a/drivers/scsi/aic94xx/aic94xx_hwi.h b/drivers/scsi/aic94xx/aic94xx_hwi.h index 150f6706d23f8d95a024fbd5836da76bcd8ac91c..abc757559c1af2911584f3e14be97c69159d923c 100644 --- a/drivers/scsi/aic94xx/aic94xx_hwi.h +++ b/drivers/scsi/aic94xx/aic94xx_hwi.h @@ -140,7 +140,7 @@ struct asd_ascb { /* internally generated command */ struct timer_list timer; - struct completion completion; + struct completion *completion; u8 tag_valid:1; __be16 tag; /* error recovery only */ @@ -294,7 +294,6 @@ static inline void asd_init_ascb(struct asd_ha_struct *asd_ha, ascb->timer.function = NULL; init_timer(&ascb->timer); ascb->tc_index = -1; - init_completion(&ascb->completion); } /* Must be called with the tc_index_lock held! diff --git a/drivers/scsi/aic94xx/aic94xx_init.c b/drivers/scsi/aic94xx/aic94xx_init.c index 5d761eb67442356fa50e360e4cde33af360c8612..88d1e731b65e15b04e5e1a71f281ba1d2035a8d7 100644 --- a/drivers/scsi/aic94xx/aic94xx_init.c +++ b/drivers/scsi/aic94xx/aic94xx_init.c @@ -1003,7 +1003,7 @@ static struct sas_domain_function_template aic94xx_transport_functions = { .lldd_abort_task_set = asd_abort_task_set, .lldd_clear_aca = asd_clear_aca, .lldd_clear_task_set = asd_clear_task_set, - .lldd_I_T_nexus_reset = NULL, + .lldd_I_T_nexus_reset = asd_I_T_nexus_reset, .lldd_lu_reset = asd_lu_reset, .lldd_query_task = asd_query_task, diff --git a/drivers/scsi/aic94xx/aic94xx_task.c b/drivers/scsi/aic94xx/aic94xx_task.c index 965d4bb999d919f314ec83e810c8ad85b0f17075..008df9ab92a5f89b57c8f8cf36fa8ede7abc36d8 100644 --- a/drivers/scsi/aic94xx/aic94xx_task.c +++ b/drivers/scsi/aic94xx/aic94xx_task.c @@ -343,11 +343,13 @@ Again: task->task_state_flags &= ~SAS_TASK_AT_INITIATOR; task->task_state_flags |= SAS_TASK_STATE_DONE; if (unlikely((task->task_state_flags & SAS_TASK_STATE_ABORTED))) { + struct completion *completion = ascb->completion; spin_unlock_irqrestore(&task->task_state_lock, flags); ASD_DPRINTK("task 0x%p done with opcode 0x%x resp 0x%x " "stat 0x%x but aborted by upper layer!\n", task, opcode, ts->resp, ts->stat); - complete(&ascb->completion); + if (completion) + complete(completion); } else { spin_unlock_irqrestore(&task->task_state_lock, flags); task->lldd_task = NULL; diff --git a/drivers/scsi/aic94xx/aic94xx_tmf.c b/drivers/scsi/aic94xx/aic94xx_tmf.c index 144f5ad20453bbc56ec010d8e870c881c0ef0fd2..b9ac8f703a1d7914d3f269a4e6bddee9a90cda4c 100644 --- a/drivers/scsi/aic94xx/aic94xx_tmf.c +++ b/drivers/scsi/aic94xx/aic94xx_tmf.c @@ -53,50 +53,64 @@ static int asd_enqueue_internal(struct asd_ascb *ascb, return res; } -static inline void asd_timedout_common(unsigned long data) -{ - struct asd_ascb *ascb = (void *) data; - struct asd_seq_data *seq = &ascb->ha->seq; - unsigned long flags; +/* ---------- CLEAR NEXUS ---------- */ - spin_lock_irqsave(&seq->pend_q_lock, flags); - seq->pending--; - list_del_init(&ascb->list); - spin_unlock_irqrestore(&seq->pend_q_lock, flags); -} +struct tasklet_completion_status { + int dl_opcode; + int tmf_state; + u8 tag_valid:1; + __be16 tag; +}; + +#define DECLARE_TCS(tcs) \ + struct tasklet_completion_status tcs = { \ + .dl_opcode = 0, \ + .tmf_state = 0, \ + .tag_valid = 0, \ + .tag = 0, \ + } -/* ---------- CLEAR NEXUS ---------- */ static void asd_clear_nexus_tasklet_complete(struct asd_ascb *ascb, struct done_list_struct *dl) { + struct tasklet_completion_status *tcs = ascb->uldd_task; ASD_DPRINTK("%s: here\n", __FUNCTION__); if (!del_timer(&ascb->timer)) { ASD_DPRINTK("%s: couldn't delete timer\n", __FUNCTION__); return; } ASD_DPRINTK("%s: opcode: 0x%x\n", __FUNCTION__, dl->opcode); - ascb->uldd_task = (void *) (unsigned long) dl->opcode; - complete(&ascb->completion); + tcs->dl_opcode = dl->opcode; + complete(ascb->completion); + asd_ascb_free(ascb); } static void asd_clear_nexus_timedout(unsigned long data) { - struct asd_ascb *ascb = (void *) data; + struct asd_ascb *ascb = (void *)data; + struct tasklet_completion_status *tcs = ascb->uldd_task; ASD_DPRINTK("%s: here\n", __FUNCTION__); - asd_timedout_common(data); - ascb->uldd_task = (void *) TMF_RESP_FUNC_FAILED; - complete(&ascb->completion); + tcs->dl_opcode = TMF_RESP_FUNC_FAILED; + complete(ascb->completion); } #define CLEAR_NEXUS_PRE \ + struct asd_ascb *ascb; \ + struct scb *scb; \ + int res; \ + DECLARE_COMPLETION_ONSTACK(completion); \ + DECLARE_TCS(tcs); \ + \ ASD_DPRINTK("%s: PRE\n", __FUNCTION__); \ res = 1; \ ascb = asd_ascb_alloc_list(asd_ha, &res, GFP_KERNEL); \ if (!ascb) \ return -ENOMEM; \ \ + ascb->completion = &completion; \ + ascb->uldd_task = &tcs; \ scb = ascb->scb; \ scb->header.opcode = CLEAR_NEXUS @@ -107,10 +121,11 @@ static void asd_clear_nexus_timedout(unsigned long data) if (res) \ goto out_err; \ ASD_DPRINTK("%s: clear nexus posted, waiting...\n", __FUNCTION__); \ - wait_for_completion(&ascb->completion); \ - res = (int) (unsigned long) ascb->uldd_task; \ + wait_for_completion(&completion); \ + res = tcs.dl_opcode; \ if (res == TC_NO_ERROR) \ res = TMF_RESP_FUNC_COMPLETE; \ + return res; \ out_err: \ asd_ascb_free(ascb); \ return res @@ -118,9 +133,6 @@ out_err: \ int asd_clear_nexus_ha(struct sas_ha_struct *sas_ha) { struct asd_ha_struct *asd_ha = sas_ha->lldd_ha; - struct asd_ascb *ascb; - struct scb *scb; - int res; CLEAR_NEXUS_PRE; scb->clear_nexus.nexus = NEXUS_ADAPTER; @@ -130,9 +142,6 @@ int asd_clear_nexus_ha(struct sas_ha_struct *sas_ha) int asd_clear_nexus_port(struct asd_sas_port *port) { struct asd_ha_struct *asd_ha = port->ha->lldd_ha; - struct asd_ascb *ascb; - struct scb *scb; - int res; CLEAR_NEXUS_PRE; scb->clear_nexus.nexus = NEXUS_PORT; @@ -140,29 +149,73 @@ int asd_clear_nexus_port(struct asd_sas_port *port) CLEAR_NEXUS_POST; } -#if 0 -static int asd_clear_nexus_I_T(struct domain_device *dev) +enum clear_nexus_phase { + NEXUS_PHASE_PRE, + NEXUS_PHASE_POST, + NEXUS_PHASE_RESUME, +}; + +static int asd_clear_nexus_I_T(struct domain_device *dev, + enum clear_nexus_phase phase) { struct asd_ha_struct *asd_ha = dev->port->ha->lldd_ha; - struct asd_ascb *ascb; - struct scb *scb; - int res; CLEAR_NEXUS_PRE; scb->clear_nexus.nexus = NEXUS_I_T; - scb->clear_nexus.flags = SEND_Q | EXEC_Q | NOTINQ; + switch (phase) { + case NEXUS_PHASE_PRE: + scb->clear_nexus.flags = EXEC_Q | SUSPEND_TX; + break; + case NEXUS_PHASE_POST: + scb->clear_nexus.flags = SEND_Q | NOTINQ; + break; + case NEXUS_PHASE_RESUME: + scb->clear_nexus.flags = RESUME_TX; + } scb->clear_nexus.conn_handle = cpu_to_le16((u16)(unsigned long) dev->lldd_dev); CLEAR_NEXUS_POST; } -#endif + +int asd_I_T_nexus_reset(struct domain_device *dev) +{ + int res, tmp_res, i; + struct sas_phy *phy = sas_find_local_phy(dev); + /* Standard mandates link reset for ATA (type 0) and + * hard reset for SSP (type 1) */ + int reset_type = (dev->dev_type == SATA_DEV || + (dev->tproto & SAS_PROTOCOL_STP)) ? 0 : 1; + + asd_clear_nexus_I_T(dev, NEXUS_PHASE_PRE); + /* send a hard reset */ + ASD_DPRINTK("sending %s reset to %s\n", + reset_type ? "hard" : "soft", phy->dev.bus_id); + res = sas_phy_reset(phy, reset_type); + if (res == TMF_RESP_FUNC_COMPLETE) { + /* wait for the maximum settle time */ + msleep(500); + /* clear all outstanding commands (keep nexus suspended) */ + asd_clear_nexus_I_T(dev, NEXUS_PHASE_POST); + } + for (i = 0 ; i < 3; i++) { + tmp_res = asd_clear_nexus_I_T(dev, NEXUS_PHASE_RESUME); + if (tmp_res == TC_RESUME) + return res; + msleep(500); + } + + /* This is a bit of a problem: the sequencer is still suspended + * and is refusing to resume. Hope it will resume on a bigger hammer + * or the disk is lost */ + dev_printk(KERN_ERR, &phy->dev, + "Failed to resume nexus after reset 0x%x\n", tmp_res); + + return TMF_RESP_FUNC_FAILED; +} static int asd_clear_nexus_I_T_L(struct domain_device *dev, u8 *lun) { struct asd_ha_struct *asd_ha = dev->port->ha->lldd_ha; - struct asd_ascb *ascb; - struct scb *scb; - int res; CLEAR_NEXUS_PRE; scb->clear_nexus.nexus = NEXUS_I_T_L; @@ -177,9 +230,6 @@ static int asd_clear_nexus_tag(struct sas_task *task) { struct asd_ha_struct *asd_ha = task->dev->port->ha->lldd_ha; struct asd_ascb *tascb = task->lldd_task; - struct asd_ascb *ascb; - struct scb *scb; - int res; CLEAR_NEXUS_PRE; scb->clear_nexus.nexus = NEXUS_TAG; @@ -195,9 +245,6 @@ static int asd_clear_nexus_index(struct sas_task *task) { struct asd_ha_struct *asd_ha = task->dev->port->ha->lldd_ha; struct asd_ascb *tascb = task->lldd_task; - struct asd_ascb *ascb; - struct scb *scb; - int res; CLEAR_NEXUS_PRE; scb->clear_nexus.nexus = NEXUS_TRANS_CX; @@ -213,11 +260,11 @@ static int asd_clear_nexus_index(struct sas_task *task) static void asd_tmf_timedout(unsigned long data) { struct asd_ascb *ascb = (void *) data; + struct tasklet_completion_status *tcs = ascb->uldd_task; ASD_DPRINTK("tmf timed out\n"); - asd_timedout_common(data); - ascb->uldd_task = (void *) TMF_RESP_FUNC_FAILED; - complete(&ascb->completion); + tcs->tmf_state = TMF_RESP_FUNC_FAILED; + complete(ascb->completion); } static int asd_get_tmf_resp_tasklet(struct asd_ascb *ascb, @@ -269,18 +316,24 @@ static int asd_get_tmf_resp_tasklet(struct asd_ascb *ascb, static void asd_tmf_tasklet_complete(struct asd_ascb *ascb, struct done_list_struct *dl) { + struct tasklet_completion_status *tcs; + if (!del_timer(&ascb->timer)) return; + tcs = ascb->uldd_task; ASD_DPRINTK("tmf tasklet complete\n"); - if (dl->opcode == TC_SSP_RESP) - ascb->uldd_task = (void *) (unsigned long) - asd_get_tmf_resp_tasklet(ascb, dl); - else - ascb->uldd_task = (void *) 0xFF00 + (unsigned long) dl->opcode; + tcs->dl_opcode = dl->opcode; + + if (dl->opcode == TC_SSP_RESP) { + tcs->tmf_state = asd_get_tmf_resp_tasklet(ascb, dl); + tcs->tag_valid = ascb->tag_valid; + tcs->tag = ascb->tag; + } - complete(&ascb->completion); + complete(ascb->completion); + asd_ascb_free(ascb); } static inline int asd_clear_nexus(struct sas_task *task) @@ -288,15 +341,19 @@ static inline int asd_clear_nexus(struct sas_task *task) int res = TMF_RESP_FUNC_FAILED; int leftover; struct asd_ascb *tascb = task->lldd_task; + DECLARE_COMPLETION_ONSTACK(completion); unsigned long flags; + tascb->completion = &completion; + ASD_DPRINTK("task not done, clearing nexus\n"); if (tascb->tag_valid) res = asd_clear_nexus_tag(task); else res = asd_clear_nexus_index(task); - leftover = wait_for_completion_timeout(&tascb->completion, + leftover = wait_for_completion_timeout(&completion, AIC94XX_SCB_TIMEOUT); + tascb->completion = NULL; ASD_DPRINTK("came back from clear nexus\n"); spin_lock_irqsave(&task->task_state_lock, flags); if (leftover < 1) @@ -350,6 +407,11 @@ int asd_abort_task(struct sas_task *task) struct asd_ascb *ascb = NULL; struct scb *scb; int leftover; + DECLARE_TCS(tcs); + DECLARE_COMPLETION_ONSTACK(completion); + DECLARE_COMPLETION_ONSTACK(tascb_completion); + + tascb->completion = &tascb_completion; spin_lock_irqsave(&task->task_state_lock, flags); if (task->task_state_flags & SAS_TASK_STATE_DONE) { @@ -363,8 +425,10 @@ int asd_abort_task(struct sas_task *task) ascb = asd_ascb_alloc_list(asd_ha, &res, GFP_KERNEL); if (!ascb) return -ENOMEM; - scb = ascb->scb; + ascb->uldd_task = &tcs; + ascb->completion = &completion; + scb = ascb->scb; scb->header.opcode = SCB_ABORT_TASK; switch (task->task_proto) { @@ -406,13 +470,12 @@ int asd_abort_task(struct sas_task *task) res = asd_enqueue_internal(ascb, asd_tmf_tasklet_complete, asd_tmf_timedout); if (res) - goto out; - wait_for_completion(&ascb->completion); + goto out_free; + wait_for_completion(&completion); ASD_DPRINTK("tmf came back\n"); - res = (int) (unsigned long) ascb->uldd_task; - tascb->tag = ascb->tag; - tascb->tag_valid = ascb->tag_valid; + tascb->tag = tcs.tag; + tascb->tag_valid = tcs.tag_valid; spin_lock_irqsave(&task->task_state_lock, flags); if (task->task_state_flags & SAS_TASK_STATE_DONE) { @@ -423,63 +486,68 @@ int asd_abort_task(struct sas_task *task) } spin_unlock_irqrestore(&task->task_state_lock, flags); - switch (res) { - /* The task to be aborted has been sent to the device. - * We got a Response IU for the ABORT TASK TMF. */ - case TC_NO_ERROR + 0xFF00: - case TMF_RESP_FUNC_COMPLETE: - case TMF_RESP_FUNC_FAILED: - res = asd_clear_nexus(task); - break; - case TMF_RESP_INVALID_FRAME: - case TMF_RESP_OVERLAPPED_TAG: - case TMF_RESP_FUNC_ESUPP: - case TMF_RESP_NO_LUN: - goto out_done; break; - } - /* In the following we assume that the managing layer - * will _never_ make a mistake, when issuing ABORT TASK. - */ - switch (res) { - default: - res = asd_clear_nexus(task); - /* fallthrough */ - case TC_NO_ERROR + 0xFF00: - case TMF_RESP_FUNC_COMPLETE: - break; - /* The task hasn't been sent to the device xor we never got - * a (sane) Response IU for the ABORT TASK TMF. - */ - case TF_NAK_RECV + 0xFF00: - res = TMF_RESP_INVALID_FRAME; - break; - case TF_TMF_TASK_DONE + 0xFF00: /* done but not reported yet */ + if (tcs.dl_opcode == TC_SSP_RESP) { + /* The task to be aborted has been sent to the device. + * We got a Response IU for the ABORT TASK TMF. */ + if (tcs.tmf_state == TMF_RESP_FUNC_COMPLETE) + res = asd_clear_nexus(task); + else + res = tcs.tmf_state; + } else if (tcs.dl_opcode == TC_NO_ERROR && + tcs.tmf_state == TMF_RESP_FUNC_FAILED) { + /* timeout */ res = TMF_RESP_FUNC_FAILED; - leftover = wait_for_completion_timeout(&tascb->completion, - AIC94XX_SCB_TIMEOUT); - spin_lock_irqsave(&task->task_state_lock, flags); - if (leftover < 1) + } else { + /* In the following we assume that the managing layer + * will _never_ make a mistake, when issuing ABORT + * TASK. + */ + switch (tcs.dl_opcode) { + default: + res = asd_clear_nexus(task); + /* fallthrough */ + case TC_NO_ERROR: + break; + /* The task hasn't been sent to the device xor + * we never got a (sane) Response IU for the + * ABORT TASK TMF. + */ + case TF_NAK_RECV: + res = TMF_RESP_INVALID_FRAME; + break; + case TF_TMF_TASK_DONE: /* done but not reported yet */ res = TMF_RESP_FUNC_FAILED; - if (task->task_state_flags & SAS_TASK_STATE_DONE) + leftover = + wait_for_completion_timeout(&tascb_completion, + AIC94XX_SCB_TIMEOUT); + spin_lock_irqsave(&task->task_state_lock, flags); + if (leftover < 1) + res = TMF_RESP_FUNC_FAILED; + if (task->task_state_flags & SAS_TASK_STATE_DONE) + res = TMF_RESP_FUNC_COMPLETE; + spin_unlock_irqrestore(&task->task_state_lock, flags); + break; + case TF_TMF_NO_TAG: + case TF_TMF_TAG_FREE: /* the tag is in the free list */ + case TF_TMF_NO_CONN_HANDLE: /* no such device */ res = TMF_RESP_FUNC_COMPLETE; - spin_unlock_irqrestore(&task->task_state_lock, flags); - goto out_done; - case TF_TMF_NO_TAG + 0xFF00: - case TF_TMF_TAG_FREE + 0xFF00: /* the tag is in the free list */ - case TF_TMF_NO_CONN_HANDLE + 0xFF00: /* no such device */ - res = TMF_RESP_FUNC_COMPLETE; - goto out_done; - case TF_TMF_NO_CTX + 0xFF00: /* not in seq, or proto != SSP */ - res = TMF_RESP_FUNC_ESUPP; - goto out; + break; + case TF_TMF_NO_CTX: /* not in seq, or proto != SSP */ + res = TMF_RESP_FUNC_ESUPP; + break; + } } -out_done: + out_done: + tascb->completion = NULL; if (res == TMF_RESP_FUNC_COMPLETE) { task->lldd_task = NULL; mb(); asd_ascb_free(tascb); } -out: + ASD_DPRINTK("task 0x%p aborted, res: 0x%x\n", task, res); + return res; + + out_free: asd_ascb_free(ascb); ASD_DPRINTK("task 0x%p aborted, res: 0x%x\n", task, res); return res; @@ -507,6 +575,8 @@ static int asd_initiate_ssp_tmf(struct domain_device *dev, u8 *lun, struct asd_ascb *ascb; int res = 1; struct scb *scb; + DECLARE_COMPLETION_ONSTACK(completion); + DECLARE_TCS(tcs); if (!(dev->tproto & SAS_PROTOCOL_SSP)) return TMF_RESP_FUNC_ESUPP; @@ -514,6 +584,9 @@ static int asd_initiate_ssp_tmf(struct domain_device *dev, u8 *lun, ascb = asd_ascb_alloc_list(asd_ha, &res, GFP_KERNEL); if (!ascb) return -ENOMEM; + + ascb->completion = &completion; + ascb->uldd_task = &tcs; scb = ascb->scb; if (tmf == TMF_QUERY_TASK) @@ -546,31 +619,32 @@ static int asd_initiate_ssp_tmf(struct domain_device *dev, u8 *lun, asd_tmf_timedout); if (res) goto out_err; - wait_for_completion(&ascb->completion); - res = (int) (unsigned long) ascb->uldd_task; + wait_for_completion(&completion); - switch (res) { - case TC_NO_ERROR + 0xFF00: + switch (tcs.dl_opcode) { + case TC_NO_ERROR: res = TMF_RESP_FUNC_COMPLETE; break; - case TF_NAK_RECV + 0xFF00: + case TF_NAK_RECV: res = TMF_RESP_INVALID_FRAME; break; - case TF_TMF_TASK_DONE + 0xFF00: + case TF_TMF_TASK_DONE: res = TMF_RESP_FUNC_FAILED; break; - case TF_TMF_NO_TAG + 0xFF00: - case TF_TMF_TAG_FREE + 0xFF00: /* the tag is in the free list */ - case TF_TMF_NO_CONN_HANDLE + 0xFF00: /* no such device */ + case TF_TMF_NO_TAG: + case TF_TMF_TAG_FREE: /* the tag is in the free list */ + case TF_TMF_NO_CONN_HANDLE: /* no such device */ res = TMF_RESP_FUNC_COMPLETE; break; - case TF_TMF_NO_CTX + 0xFF00: /* not in seq, or proto != SSP */ + case TF_TMF_NO_CTX: /* not in seq, or proto != SSP */ res = TMF_RESP_FUNC_ESUPP; break; default: /* Allow TMF response codes to propagate upwards */ + res = tcs.dl_opcode; break; } + return res; out_err: asd_ascb_free(ascb); return res; diff --git a/drivers/scsi/arcmsr/arcmsr.h b/drivers/scsi/arcmsr/arcmsr.h index 57786502e3ec18df7f47815b549a2e0152791110..0393707bdfce2a56ade99f0e5e2938a15ae84d78 100644 --- a/drivers/scsi/arcmsr/arcmsr.h +++ b/drivers/scsi/arcmsr/arcmsr.h @@ -48,7 +48,7 @@ struct class_device_attribute; /*The limit of outstanding scsi command that firmware can handle*/ #define ARCMSR_MAX_OUTSTANDING_CMD 256 #define ARCMSR_MAX_FREECCB_NUM 320 -#define ARCMSR_DRIVER_VERSION "Driver Version 1.20.00.15 2007/12/24" +#define ARCMSR_DRIVER_VERSION "Driver Version 1.20.00.15 2008/02/27" #define ARCMSR_SCSI_INITIATOR_ID 255 #define ARCMSR_MAX_XFER_SECTORS 512 #define ARCMSR_MAX_XFER_SECTORS_B 4096 diff --git a/drivers/scsi/gdth.c b/drivers/scsi/gdth.c index 6d67f5c0eb8e4133621898d7f5f07f18920592a5..27ebd336409b6fbd922c17360438a7c0ec79babe 100644 --- a/drivers/scsi/gdth.c +++ b/drivers/scsi/gdth.c @@ -160,7 +160,7 @@ static void gdth_readapp_event(gdth_ha_str *ha, unchar application, static void gdth_clear_events(void); static void gdth_copy_internal_data(gdth_ha_str *ha, Scsi_Cmnd *scp, - char *buffer, ushort count, int to_buffer); + char *buffer, ushort count); static int gdth_internal_cache_cmd(gdth_ha_str *ha, Scsi_Cmnd *scp); static int gdth_fill_cache_cmd(gdth_ha_str *ha, Scsi_Cmnd *scp, ushort hdrive); @@ -182,7 +182,6 @@ static int gdth_ioctl(struct inode *inode, struct file *filep, unsigned int cmd, unsigned long arg); static void gdth_flush(gdth_ha_str *ha); -static int gdth_halt(struct notifier_block *nb, ulong event, void *buf); static int gdth_queuecommand(Scsi_Cmnd *scp,void (*done)(Scsi_Cmnd *)); static int __gdth_queuecommand(gdth_ha_str *ha, struct scsi_cmnd *scp, struct gdth_cmndinfo *cmndinfo); @@ -417,12 +416,6 @@ static inline void gdth_set_sglist(struct scsi_cmnd *cmd, #include "gdth_proc.h" #include "gdth_proc.c" -/* notifier block to get a notify on system shutdown/halt/reboot */ -static struct notifier_block gdth_notifier = { - gdth_halt, NULL, 0 -}; -static int notifier_disabled = 0; - static gdth_ha_str *gdth_find_ha(int hanum) { gdth_ha_str *ha; @@ -445,8 +438,8 @@ static struct gdth_cmndinfo *gdth_get_cmndinfo(gdth_ha_str *ha) for (i=0; icmndinfo[i].index == 0) { priv = &ha->cmndinfo[i]; - priv->index = i+1; memset(priv, 0, sizeof(*priv)); + priv->index = i+1; break; } } @@ -493,7 +486,6 @@ int __gdth_execute(struct scsi_device *sdev, gdth_cmd_str *gdtcmd, char *cmnd, gdth_ha_str *ha = shost_priv(sdev->host); Scsi_Cmnd *scp; struct gdth_cmndinfo cmndinfo; - struct scatterlist one_sg; DECLARE_COMPLETION_ONSTACK(wait); int rval; @@ -507,13 +499,10 @@ int __gdth_execute(struct scsi_device *sdev, gdth_cmd_str *gdtcmd, char *cmnd, /* use request field to save the ptr. to completion struct. */ scp->request = (struct request *)&wait; scp->timeout_per_command = timeout*HZ; - sg_init_one(&one_sg, gdtcmd, sizeof(*gdtcmd)); - gdth_set_sglist(scp, &one_sg); - gdth_set_sg_count(scp, 1); - gdth_set_bufflen(scp, sizeof(*gdtcmd)); scp->cmd_len = 12; memcpy(scp->cmnd, cmnd, 12); cmndinfo.priority = IOCTL_PRI; + cmndinfo.internal_cmd_str = gdtcmd; cmndinfo.internal_command = 1; TRACE(("__gdth_execute() cmd 0x%x\n", scp->cmnd[0])); @@ -2355,7 +2344,7 @@ static void gdth_next(gdth_ha_str *ha) * buffers, kmap_atomic() as needed. */ static void gdth_copy_internal_data(gdth_ha_str *ha, Scsi_Cmnd *scp, - char *buffer, ushort count, int to_buffer) + char *buffer, ushort count) { ushort cpcount,i, max_sg = gdth_sg_count(scp); ushort cpsum,cpnow; @@ -2381,10 +2370,7 @@ static void gdth_copy_internal_data(gdth_ha_str *ha, Scsi_Cmnd *scp, } local_irq_save(flags); address = kmap_atomic(sg_page(sl), KM_BIO_SRC_IRQ) + sl->offset; - if (to_buffer) - memcpy(buffer, address, cpnow); - else - memcpy(address, buffer, cpnow); + memcpy(address, buffer, cpnow); flush_dcache_page(sg_page(sl)); kunmap_atomic(address, KM_BIO_SRC_IRQ); local_irq_restore(flags); @@ -2438,7 +2424,7 @@ static int gdth_internal_cache_cmd(gdth_ha_str *ha, Scsi_Cmnd *scp) strcpy(inq.vendor,ha->oem_name); sprintf(inq.product,"Host Drive #%02d",t); strcpy(inq.revision," "); - gdth_copy_internal_data(ha, scp, (char*)&inq, sizeof(gdth_inq_data), 0); + gdth_copy_internal_data(ha, scp, (char*)&inq, sizeof(gdth_inq_data)); break; case REQUEST_SENSE: @@ -2448,7 +2434,7 @@ static int gdth_internal_cache_cmd(gdth_ha_str *ha, Scsi_Cmnd *scp) sd.key = NO_SENSE; sd.info = 0; sd.add_length= 0; - gdth_copy_internal_data(ha, scp, (char*)&sd, sizeof(gdth_sense_data), 0); + gdth_copy_internal_data(ha, scp, (char*)&sd, sizeof(gdth_sense_data)); break; case MODE_SENSE: @@ -2460,7 +2446,7 @@ static int gdth_internal_cache_cmd(gdth_ha_str *ha, Scsi_Cmnd *scp) mpd.bd.block_length[0] = (SECTOR_SIZE & 0x00ff0000) >> 16; mpd.bd.block_length[1] = (SECTOR_SIZE & 0x0000ff00) >> 8; mpd.bd.block_length[2] = (SECTOR_SIZE & 0x000000ff); - gdth_copy_internal_data(ha, scp, (char*)&mpd, sizeof(gdth_modep_data), 0); + gdth_copy_internal_data(ha, scp, (char*)&mpd, sizeof(gdth_modep_data)); break; case READ_CAPACITY: @@ -2470,7 +2456,7 @@ static int gdth_internal_cache_cmd(gdth_ha_str *ha, Scsi_Cmnd *scp) else rdc.last_block_no = cpu_to_be32(ha->hdr[t].size-1); rdc.block_length = cpu_to_be32(SECTOR_SIZE); - gdth_copy_internal_data(ha, scp, (char*)&rdc, sizeof(gdth_rdcap_data), 0); + gdth_copy_internal_data(ha, scp, (char*)&rdc, sizeof(gdth_rdcap_data)); break; case SERVICE_ACTION_IN: @@ -2482,7 +2468,7 @@ static int gdth_internal_cache_cmd(gdth_ha_str *ha, Scsi_Cmnd *scp) rdc16.last_block_no = cpu_to_be64(ha->hdr[t].size-1); rdc16.block_length = cpu_to_be32(SECTOR_SIZE); gdth_copy_internal_data(ha, scp, (char*)&rdc16, - sizeof(gdth_rdcap16_data), 0); + sizeof(gdth_rdcap16_data)); } else { scp->result = DID_ABORT << 16; } @@ -2852,6 +2838,7 @@ static int gdth_fill_raw_cmd(gdth_ha_str *ha, Scsi_Cmnd *scp, unchar b) static int gdth_special_cmd(gdth_ha_str *ha, Scsi_Cmnd *scp) { register gdth_cmd_str *cmdp; + struct gdth_cmndinfo *cmndinfo = gdth_cmnd_priv(scp); int cmd_index; cmdp= ha->pccb; @@ -2860,7 +2847,7 @@ static int gdth_special_cmd(gdth_ha_str *ha, Scsi_Cmnd *scp) if (ha->type==GDT_EISA && ha->cmd_cnt>0) return 0; - gdth_copy_internal_data(ha, scp, (char *)cmdp, sizeof(gdth_cmd_str), 1); + *cmdp = *cmndinfo->internal_cmd_str; cmdp->RequestBuffer = scp; /* search free command index */ @@ -3794,6 +3781,8 @@ static void gdth_timeout(ulong data) gdth_ha_str *ha; ulong flags; + BUG_ON(list_empty(&gdth_instances)); + ha = list_first_entry(&gdth_instances, gdth_ha_str, list); spin_lock_irqsave(&ha->smp_lock, flags); @@ -4669,45 +4658,6 @@ static void gdth_flush(gdth_ha_str *ha) } } -/* shutdown routine */ -static int gdth_halt(struct notifier_block *nb, ulong event, void *buf) -{ - gdth_ha_str *ha; -#ifndef __alpha__ - gdth_cmd_str gdtcmd; - char cmnd[MAX_COMMAND_SIZE]; -#endif - - if (notifier_disabled) - return NOTIFY_OK; - - TRACE2(("gdth_halt() event %d\n",(int)event)); - if (event != SYS_RESTART && event != SYS_HALT && event != SYS_POWER_OFF) - return NOTIFY_DONE; - - notifier_disabled = 1; - printk("GDT-HA: Flushing all host drives .. "); - list_for_each_entry(ha, &gdth_instances, list) { - gdth_flush(ha); - -#ifndef __alpha__ - /* controller reset */ - memset(cmnd, 0xff, MAX_COMMAND_SIZE); - gdtcmd.BoardNode = LOCALBOARD; - gdtcmd.Service = CACHESERVICE; - gdtcmd.OpCode = GDT_RESET; - TRACE2(("gdth_halt(): reset controller %d\n", ha->hanum)); - gdth_execute(ha->shost, &gdtcmd, cmnd, 10, NULL); -#endif - } - printk("Done.\n"); - -#ifdef GDTH_STATISTICS - del_timer(&gdth_timer); -#endif - return NOTIFY_OK; -} - /* configure lun */ static int gdth_slave_configure(struct scsi_device *sdev) { @@ -5142,13 +5092,13 @@ static void gdth_remove_one(gdth_ha_str *ha) scsi_remove_host(shp); + gdth_flush(ha); + if (ha->sdev) { scsi_free_host_dev(ha->sdev); ha->sdev = NULL; } - gdth_flush(ha); - if (shp->irq) free_irq(shp->irq,ha); @@ -5174,6 +5124,24 @@ static void gdth_remove_one(gdth_ha_str *ha) scsi_host_put(shp); } +static int gdth_halt(struct notifier_block *nb, ulong event, void *buf) +{ + gdth_ha_str *ha; + + TRACE2(("gdth_halt() event %d\n", (int)event)); + if (event != SYS_RESTART && event != SYS_HALT && event != SYS_POWER_OFF) + return NOTIFY_DONE; + + list_for_each_entry(ha, &gdth_instances, list) + gdth_flush(ha); + + return NOTIFY_OK; +} + +static struct notifier_block gdth_notifier = { + gdth_halt, NULL, 0 +}; + static int __init gdth_init(void) { if (disable) { @@ -5236,7 +5204,6 @@ static int __init gdth_init(void) add_timer(&gdth_timer); #endif major = register_chrdev(0,"gdth", &gdth_fops); - notifier_disabled = 0; register_reboot_notifier(&gdth_notifier); gdth_polling = FALSE; return 0; @@ -5246,14 +5213,15 @@ static void __exit gdth_exit(void) { gdth_ha_str *ha; - list_for_each_entry(ha, &gdth_instances, list) - gdth_remove_one(ha); + unregister_chrdev(major, "gdth"); + unregister_reboot_notifier(&gdth_notifier); #ifdef GDTH_STATISTICS - del_timer(&gdth_timer); + del_timer_sync(&gdth_timer); #endif - unregister_chrdev(major,"gdth"); - unregister_reboot_notifier(&gdth_notifier); + + list_for_each_entry(ha, &gdth_instances, list) + gdth_remove_one(ha); } module_init(gdth_init); diff --git a/drivers/scsi/gdth.h b/drivers/scsi/gdth.h index 1434c6b0297c6977f17c73166ddcd6b9c48bb7ed..26e4e92515e0cfcc0793f9b01b15e1e669acbfe2 100644 --- a/drivers/scsi/gdth.h +++ b/drivers/scsi/gdth.h @@ -915,6 +915,7 @@ typedef struct { struct gdth_cmndinfo { /* per-command private info */ int index; int internal_command; /* don't call scsi_done */ + gdth_cmd_str *internal_cmd_str; /* crier for internal messages*/ dma_addr_t sense_paddr; /* sense dma-addr */ unchar priority; int timeout; diff --git a/drivers/scsi/ibmvscsi/ibmvstgt.c b/drivers/scsi/ibmvscsi/ibmvstgt.c index bd62131b97a1d431eef230ab0efd9ed487a7234f..e5881e92d0fb29f730d93f79b8c554e629a72dfa 100644 --- a/drivers/scsi/ibmvscsi/ibmvstgt.c +++ b/drivers/scsi/ibmvscsi/ibmvstgt.c @@ -290,7 +290,7 @@ static int ibmvstgt_cmd_done(struct scsi_cmnd *sc, int err = 0; dprintk("%p %p %x %u\n", iue, target, vio_iu(iue)->srp.cmd.cdb[0], - cmd->usg_sg); + scsi_sg_count(sc)); if (scsi_sg_count(sc)) err = srp_transfer_data(sc, &vio_iu(iue)->srp.cmd, ibmvstgt_rdma, 1, 1); @@ -838,9 +838,6 @@ static int ibmvstgt_probe(struct vio_dev *dev, const struct vio_device_id *id) if (!shost) goto free_vport; shost->transportt = ibmvstgt_transport_template; - err = scsi_tgt_alloc_queue(shost); - if (err) - goto put_host; target = host_to_srp_target(shost); target->shost = shost; @@ -872,6 +869,10 @@ static int ibmvstgt_probe(struct vio_dev *dev, const struct vio_device_id *id) if (err) goto destroy_queue; + err = scsi_tgt_alloc_queue(shost); + if (err) + goto destroy_queue; + return 0; destroy_queue: crq_queue_destroy(target); diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c index 59f8445eab0daa7a5b138c278897da53aa4ca351..bdd7de7da39a5819cea137dcb5b083f6f69a8d3c 100644 --- a/drivers/scsi/libiscsi.c +++ b/drivers/scsi/libiscsi.c @@ -1708,8 +1708,8 @@ iscsi_session_setup(struct iscsi_transport *iscsit, qdepth = ISCSI_DEF_CMD_PER_LUN; } - if (!is_power_of_2(cmds_max) || - cmds_max >= ISCSI_MGMT_ITT_OFFSET) { + if (!is_power_of_2(cmds_max) || cmds_max >= ISCSI_MGMT_ITT_OFFSET || + cmds_max < 2) { if (cmds_max != 0) printk(KERN_ERR "iscsi: invalid can_queue of %d. " "can_queue must be a power of 2 and between " diff --git a/drivers/scsi/libsas/sas_ata.c b/drivers/scsi/libsas/sas_ata.c index 7cd05b599a12ca68348ccd721963e4afb7becede..b0e5ac372a3223453b3e4fbfecc737d21fad2977 100644 --- a/drivers/scsi/libsas/sas_ata.c +++ b/drivers/scsi/libsas/sas_ata.c @@ -236,12 +236,12 @@ static void sas_ata_phy_reset(struct ata_port *ap) struct domain_device *dev = ap->private_data; struct sas_internal *i = to_sas_internal(dev->port->ha->core.shost->transportt); - int res = 0; + int res = TMF_RESP_FUNC_FAILED; if (i->dft->lldd_I_T_nexus_reset) res = i->dft->lldd_I_T_nexus_reset(dev); - if (res) + if (res != TMF_RESP_FUNC_COMPLETE) SAS_DPRINTK("%s: Unable to reset I T nexus?\n", __FUNCTION__); switch (dev->sata_dev.command_set) { @@ -656,21 +656,6 @@ out: return res; } -static void sas_sata_propagate_sas_addr(struct domain_device *dev) -{ - unsigned long flags; - struct asd_sas_port *port = dev->port; - struct asd_sas_phy *phy; - - BUG_ON(dev->parent); - - memcpy(port->attached_sas_addr, dev->sas_addr, SAS_ADDR_SIZE); - spin_lock_irqsave(&port->phy_list_lock, flags); - list_for_each_entry(phy, &port->phy_list, port_phy_el) - memcpy(phy->attached_sas_addr, dev->sas_addr, SAS_ADDR_SIZE); - spin_unlock_irqrestore(&port->phy_list_lock, flags); -} - #define ATA_IDENTIFY_DEV 0xEC #define ATA_IDENTIFY_PACKET_DEV 0xA1 #define ATA_SET_FEATURES 0xEF @@ -728,26 +713,6 @@ static int sas_discover_sata_dev(struct domain_device *dev) goto out_err; } cont1: - /* Get WWN */ - if (dev->port->oob_mode != SATA_OOB_MODE) { - memcpy(dev->sas_addr, dev->sata_dev.rps_resp.rps.stp_sas_addr, - SAS_ADDR_SIZE); - } else if (dev->sata_dev.command_set == ATA_COMMAND_SET && - (le16_to_cpu(dev->sata_dev.identify_device[108]) & 0xF000) - == 0x5000) { - int i; - - for (i = 0; i < 4; i++) { - dev->sas_addr[2*i] = - (le16_to_cpu(dev->sata_dev.identify_device[108+i]) & 0xFF00) >> 8; - dev->sas_addr[2*i+1] = - le16_to_cpu(dev->sata_dev.identify_device[108+i]) & 0x00FF; - } - } - sas_hash_addr(dev->hashed_sas_addr, dev->sas_addr); - if (!dev->parent) - sas_sata_propagate_sas_addr(dev); - /* XXX Hint: register this SATA device with SATL. When this returns, dev->sata_dev->lu is alive and present. diff --git a/drivers/scsi/libsas/sas_port.c b/drivers/scsi/libsas/sas_port.c index e1e2d085c920918dc508d4ec8d67dfad98095450..39ae68a3b0ef57a14eefcff9112e9668deb6fe1f 100644 --- a/drivers/scsi/libsas/sas_port.c +++ b/drivers/scsi/libsas/sas_port.c @@ -92,9 +92,6 @@ static void sas_form_port(struct asd_sas_phy *phy) if (!port->phy) port->phy = phy->phy; - SAS_DPRINTK("phy%d added to port%d, phy_mask:0x%x\n", phy->id, - port->id, port->phy_mask); - if (*(u64 *)port->attached_sas_addr == 0) { port->class = phy->class; memcpy(port->attached_sas_addr, phy->attached_sas_addr, @@ -115,6 +112,11 @@ static void sas_form_port(struct asd_sas_phy *phy) } sas_port_add_phy(port->port, phy->phy); + SAS_DPRINTK("%s added to %s, phy_mask:0x%x (%16llx)\n", + phy->phy->dev.bus_id,port->port->dev.bus_id, + port->phy_mask, + SAS_ADDR(port->attached_sas_addr)); + if (port->port_dev) port->port_dev->pathways = port->num_phys; @@ -255,12 +257,11 @@ void sas_porte_hard_reset(struct work_struct *work) static void sas_init_port(struct asd_sas_port *port, struct sas_ha_struct *sas_ha, int i) { + memset(port, 0, sizeof(*port)); port->id = i; INIT_LIST_HEAD(&port->dev_list); spin_lock_init(&port->phy_list_lock); INIT_LIST_HEAD(&port->phy_list); - port->num_phys = 0; - port->phy_mask = 0; port->ha = sas_ha; spin_lock_init(&port->dev_list_lock); diff --git a/drivers/scsi/libsas/sas_scsi_host.c b/drivers/scsi/libsas/sas_scsi_host.c index 704ea06a6e500a8d3bfd25179dc9efa73791c655..1f8241563c6ccea625640eb69c22554d931f3d87 100644 --- a/drivers/scsi/libsas/sas_scsi_host.c +++ b/drivers/scsi/libsas/sas_scsi_host.c @@ -434,7 +434,7 @@ static int sas_recover_I_T(struct domain_device *dev) } /* Find the sas_phy that's attached to this device */ -static struct sas_phy *find_local_sas_phy(struct domain_device *dev) +struct sas_phy *sas_find_local_phy(struct domain_device *dev) { struct domain_device *pdev = dev->parent; struct ex_phy *exphy = NULL; @@ -456,6 +456,7 @@ static struct sas_phy *find_local_sas_phy(struct domain_device *dev) BUG_ON(!exphy); return exphy->phy; } +EXPORT_SYMBOL_GPL(sas_find_local_phy); /* Attempt to send a LUN reset message to a device */ int sas_eh_device_reset_handler(struct scsi_cmnd *cmd) @@ -482,7 +483,7 @@ int sas_eh_device_reset_handler(struct scsi_cmnd *cmd) int sas_eh_bus_reset_handler(struct scsi_cmnd *cmd) { struct domain_device *dev = cmd_to_domain_dev(cmd); - struct sas_phy *phy = find_local_sas_phy(dev); + struct sas_phy *phy = sas_find_local_phy(dev); int res; res = sas_phy_reset(phy, 1); @@ -497,10 +498,10 @@ int sas_eh_bus_reset_handler(struct scsi_cmnd *cmd) } /* Try to reset a device */ -static int try_to_reset_cmd_device(struct Scsi_Host *shost, - struct scsi_cmnd *cmd) +static int try_to_reset_cmd_device(struct scsi_cmnd *cmd) { int res; + struct Scsi_Host *shost = cmd->device->host; if (!shost->hostt->eh_device_reset_handler) goto try_bus_reset; @@ -540,6 +541,12 @@ Again: need_reset = task->task_state_flags & SAS_TASK_NEED_DEV_RESET; spin_unlock_irqrestore(&task->task_state_lock, flags); + if (need_reset) { + SAS_DPRINTK("%s: task 0x%p requests reset\n", + __FUNCTION__, task); + goto reset; + } + SAS_DPRINTK("trying to find task 0x%p\n", task); res = sas_scsi_find_task(task); @@ -550,18 +557,15 @@ Again: SAS_DPRINTK("%s: task 0x%p is done\n", __FUNCTION__, task); sas_eh_finish_cmd(cmd); - if (need_reset) - try_to_reset_cmd_device(shost, cmd); continue; case TASK_IS_ABORTED: SAS_DPRINTK("%s: task 0x%p is aborted\n", __FUNCTION__, task); sas_eh_finish_cmd(cmd); - if (need_reset) - try_to_reset_cmd_device(shost, cmd); continue; case TASK_IS_AT_LU: SAS_DPRINTK("task 0x%p is at LU: lu recover\n", task); + reset: tmf_resp = sas_recover_lu(task->dev, cmd); if (tmf_resp == TMF_RESP_FUNC_COMPLETE) { SAS_DPRINTK("dev %016llx LU %x is " @@ -569,8 +573,6 @@ Again: SAS_ADDR(task->dev), cmd->device->lun); sas_eh_finish_cmd(cmd); - if (need_reset) - try_to_reset_cmd_device(shost, cmd); sas_scsi_clear_queue_lu(work_q, cmd); goto Again; } @@ -581,15 +583,15 @@ Again: task); tmf_resp = sas_recover_I_T(task->dev); if (tmf_resp == TMF_RESP_FUNC_COMPLETE) { + struct domain_device *dev = task->dev; SAS_DPRINTK("I_T %016llx recovered\n", SAS_ADDR(task->dev->sas_addr)); sas_eh_finish_cmd(cmd); - if (need_reset) - try_to_reset_cmd_device(shost, cmd); - sas_scsi_clear_queue_I_T(work_q, task->dev); + sas_scsi_clear_queue_I_T(work_q, dev); goto Again; } /* Hammer time :-) */ + try_to_reset_cmd_device(cmd); if (i->dft->lldd_clear_nexus_port) { struct asd_sas_port *port = task->dev->port; SAS_DPRINTK("clearing nexus for port:%d\n", @@ -599,8 +601,6 @@ Again: SAS_DPRINTK("clear nexus port:%d " "succeeded\n", port->id); sas_eh_finish_cmd(cmd); - if (need_reset) - try_to_reset_cmd_device(shost, cmd); sas_scsi_clear_queue_port(work_q, port); goto Again; @@ -613,8 +613,6 @@ Again: SAS_DPRINTK("clear nexus ha " "succeeded\n"); sas_eh_finish_cmd(cmd); - if (need_reset) - try_to_reset_cmd_device(shost, cmd); goto clear_q; } } @@ -628,8 +626,6 @@ Again: cmd->device->lun); sas_eh_finish_cmd(cmd); - if (need_reset) - try_to_reset_cmd_device(shost, cmd); goto clear_q; } } diff --git a/drivers/scsi/mvsas.c b/drivers/scsi/mvsas.c index d4a6ac3c9c4746155eca706225995344ff265e52..5ec0665b3a3dd875e9e555def0bd4d2977f4a782 100644 --- a/drivers/scsi/mvsas.c +++ b/drivers/scsi/mvsas.c @@ -40,7 +40,7 @@ #include #define DRV_NAME "mvsas" -#define DRV_VERSION "0.5" +#define DRV_VERSION "0.5.1" #define _MV_DUMP 0 #define MVS_DISABLE_NVRAM #define MVS_DISABLE_MSI @@ -1005,7 +1005,7 @@ err_out: return rc; #else /* FIXME , For SAS target mode */ - memcpy(buf, "\x00\x00\xab\x11\x30\x04\x05\x50", 8); + memcpy(buf, "\x50\x05\x04\x30\x11\xab\x00\x00", 8); return 0; #endif } @@ -1330,7 +1330,7 @@ static int mvs_int_rx(struct mvs_info *mvi, bool self_clear) mvs_hba_cq_dump(mvi); - if (unlikely(rx_desc & RXQ_DONE)) + if (likely(rx_desc & RXQ_DONE)) mvs_slot_complete(mvi, rx_desc); if (rx_desc & RXQ_ATTN) { attn = true; @@ -2720,9 +2720,8 @@ static int __devinit mvs_hw_init(struct mvs_info *mvi) msleep(100); /* init and reset phys */ for (i = 0; i < mvi->chip->n_phy; i++) { - /* FIXME: is this the correct dword order? */ - u32 lo = *((u32 *)&mvi->sas_addr[0]); - u32 hi = *((u32 *)&mvi->sas_addr[4]); + u32 lo = be32_to_cpu(*(u32 *)&mvi->sas_addr[4]); + u32 hi = be32_to_cpu(*(u32 *)&mvi->sas_addr[0]); mvs_detect_porttype(mvi, i); diff --git a/drivers/scsi/ps3rom.c b/drivers/scsi/ps3rom.c index 0cd614a0fa73d98eb354aee000c1c4f1909de050..fad6cb5cba283acc8410e9d8bed1e996062d03b8 100644 --- a/drivers/scsi/ps3rom.c +++ b/drivers/scsi/ps3rom.c @@ -124,7 +124,7 @@ static int fill_from_dev_buffer(struct scsi_cmnd *cmd, const void *buf) } req_len += sgpnt->length; } - scsi_set_resid(cmd, req_len - act_len); + scsi_set_resid(cmd, buflen - act_len); return 0; } @@ -427,7 +427,7 @@ static struct scsi_host_template ps3rom_host_template = { .cmd_per_lun = 1, .emulated = 1, /* only sg driver uses this */ .max_sectors = PS3ROM_MAX_SECTORS, - .use_clustering = ENABLE_CLUSTERING, + .use_clustering = DISABLE_CLUSTERING, .module = THIS_MODULE, }; diff --git a/drivers/scsi/qla2xxx/qla_gs.c b/drivers/scsi/qla2xxx/qla_gs.c index 6226d88479f59fa2a1ded8423180281a98393ab0..c1808763d40ef21608e6dab7fab271712098f975 100644 --- a/drivers/scsi/qla2xxx/qla_gs.c +++ b/drivers/scsi/qla2xxx/qla_gs.c @@ -39,7 +39,7 @@ qla2x00_prep_ms_iocb(scsi_qla_host_t *ha, uint32_t req_size, uint32_t rsp_size) ms_pkt->entry_count = 1; SET_TARGET_ID(ha, ms_pkt->loop_id, SIMPLE_NAME_SERVER); ms_pkt->control_flags = __constant_cpu_to_le16(CF_READ | CF_HEAD_TAG); - ms_pkt->timeout = __constant_cpu_to_le16(25); + ms_pkt->timeout = cpu_to_le16(ha->r_a_tov / 10 * 2); ms_pkt->cmd_dsd_count = __constant_cpu_to_le16(1); ms_pkt->total_dsd_count = __constant_cpu_to_le16(2); ms_pkt->rsp_bytecount = cpu_to_le32(rsp_size); @@ -75,7 +75,7 @@ qla24xx_prep_ms_iocb(scsi_qla_host_t *ha, uint32_t req_size, uint32_t rsp_size) ct_pkt->entry_type = CT_IOCB_TYPE; ct_pkt->entry_count = 1; ct_pkt->nport_handle = __constant_cpu_to_le16(NPH_SNS); - ct_pkt->timeout = __constant_cpu_to_le16(25); + ct_pkt->timeout = cpu_to_le16(ha->r_a_tov / 10 * 2); ct_pkt->cmd_dsd_count = __constant_cpu_to_le16(1); ct_pkt->rsp_dsd_count = __constant_cpu_to_le16(1); ct_pkt->rsp_byte_count = cpu_to_le32(rsp_size); @@ -1144,7 +1144,7 @@ qla2x00_prep_ms_fdmi_iocb(scsi_qla_host_t *ha, uint32_t req_size, ms_pkt->entry_count = 1; SET_TARGET_ID(ha, ms_pkt->loop_id, ha->mgmt_svr_loop_id); ms_pkt->control_flags = __constant_cpu_to_le16(CF_READ | CF_HEAD_TAG); - ms_pkt->timeout = __constant_cpu_to_le16(59); + ms_pkt->timeout = cpu_to_le16(ha->r_a_tov / 10 * 2); ms_pkt->cmd_dsd_count = __constant_cpu_to_le16(1); ms_pkt->total_dsd_count = __constant_cpu_to_le16(2); ms_pkt->rsp_bytecount = cpu_to_le32(rsp_size); @@ -1181,7 +1181,7 @@ qla24xx_prep_ms_fdmi_iocb(scsi_qla_host_t *ha, uint32_t req_size, ct_pkt->entry_type = CT_IOCB_TYPE; ct_pkt->entry_count = 1; ct_pkt->nport_handle = cpu_to_le16(ha->mgmt_svr_loop_id); - ct_pkt->timeout = __constant_cpu_to_le16(59); + ct_pkt->timeout = cpu_to_le16(ha->r_a_tov / 10 * 2); ct_pkt->cmd_dsd_count = __constant_cpu_to_le16(1); ct_pkt->rsp_dsd_count = __constant_cpu_to_le16(1); ct_pkt->rsp_byte_count = cpu_to_le32(rsp_size); @@ -1761,7 +1761,7 @@ qla24xx_prep_ms_fm_iocb(scsi_qla_host_t *ha, uint32_t req_size, ct_pkt->entry_type = CT_IOCB_TYPE; ct_pkt->entry_count = 1; ct_pkt->nport_handle = cpu_to_le16(ha->mgmt_svr_loop_id); - ct_pkt->timeout = __constant_cpu_to_le16(59); + ct_pkt->timeout = cpu_to_le16(ha->r_a_tov / 10 * 2); ct_pkt->cmd_dsd_count = __constant_cpu_to_le16(1); ct_pkt->rsp_dsd_count = __constant_cpu_to_le16(1); ct_pkt->rsp_byte_count = cpu_to_le32(rsp_size); diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index d5c7853e7ebab34e0b621d98dbb6f36de823ca06..364be7d068759c4972cc7fd414cc26c63c396323 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c @@ -1733,8 +1733,8 @@ qla2x00_nvram_config(scsi_qla_host_t *ha) ha->login_timeout = nv->login_timeout; icb->login_timeout = nv->login_timeout; - /* Set minimum RATOV to 200 tenths of a second. */ - ha->r_a_tov = 200; + /* Set minimum RATOV to 100 tenths of a second. */ + ha->r_a_tov = 100; ha->loop_reset_delay = nv->reset_delay; @@ -3645,8 +3645,8 @@ qla24xx_nvram_config(scsi_qla_host_t *ha) ha->login_timeout = le16_to_cpu(nv->login_timeout); icb->login_timeout = cpu_to_le16(nv->login_timeout); - /* Set minimum RATOV to 200 tenths of a second. */ - ha->r_a_tov = 200; + /* Set minimum RATOV to 100 tenths of a second. */ + ha->r_a_tov = 100; ha->loop_reset_delay = nv->reset_delay; @@ -4022,7 +4022,8 @@ qla2x00_try_to_stop_firmware(scsi_qla_host_t *ha) return; ret = qla2x00_stop_firmware(ha); - for (retries = 5; ret != QLA_SUCCESS && retries ; retries--) { + for (retries = 5; ret != QLA_SUCCESS && ret != QLA_FUNCTION_TIMEOUT && + retries ; retries--) { qla2x00_reset_chip(ha); if (qla2x00_chip_diag(ha) != QLA_SUCCESS) continue; diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c index 14e6f22944b71886be2ba17094a406e2f49b2f7c..f0337036c7bb144242567963591c368999deecbd 100644 --- a/drivers/scsi/qla2xxx/qla_isr.c +++ b/drivers/scsi/qla2xxx/qla_isr.c @@ -958,6 +958,11 @@ qla2x00_status_entry(scsi_qla_host_t *ha, void *pkt) } } + /* Check for overrun. */ + if (IS_FWI2_CAPABLE(ha) && comp_status == CS_COMPLETE && + scsi_status & SS_RESIDUAL_OVER) + comp_status = CS_DATA_OVERRUN; + /* * Based on Host and scsi status generate status code for Linux */ diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c index 99d29fff836d631bc37686b6c45bee7972dcb4e4..bb103580e1ba8b874e59bb8987c2b5addad940cb 100644 --- a/drivers/scsi/qla2xxx/qla_mbx.c +++ b/drivers/scsi/qla2xxx/qla_mbx.c @@ -2206,7 +2206,7 @@ qla24xx_abort_target(fc_port_t *fcport) tsk->p.tsk.entry_type = TSK_MGMT_IOCB_TYPE; tsk->p.tsk.entry_count = 1; tsk->p.tsk.nport_handle = cpu_to_le16(fcport->loop_id); - tsk->p.tsk.timeout = __constant_cpu_to_le16(25); + tsk->p.tsk.timeout = cpu_to_le16(ha->r_a_tov / 10 * 2); tsk->p.tsk.control_flags = __constant_cpu_to_le32(TCF_TARGET_RESET); tsk->p.tsk.port_id[0] = fcport->d_id.b.al_pa; tsk->p.tsk.port_id[1] = fcport->d_id.b.area; diff --git a/drivers/scsi/qla2xxx/qla_version.h b/drivers/scsi/qla2xxx/qla_version.h index c5742cc15abbbc56b1134619d09714e400d1a33d..ea08a129fee91827b4c3b285f78c8ae171782cdf 100644 --- a/drivers/scsi/qla2xxx/qla_version.h +++ b/drivers/scsi/qla2xxx/qla_version.h @@ -7,7 +7,7 @@ /* * Driver version */ -#define QLA2XXX_VERSION "8.02.00-k8" +#define QLA2XXX_VERSION "8.02.00-k9" #define QLA_DRIVER_MAJOR_VER 8 #define QLA_DRIVER_MINOR_VER 2 diff --git a/drivers/scsi/qla4xxx/ql4_init.c b/drivers/scsi/qla4xxx/ql4_init.c index 10b3b9a620f357f0bcf91a39546a9b594451f149..109c5f5985ecfb1772956296a27ea219ee7a01ff 100644 --- a/drivers/scsi/qla4xxx/ql4_init.c +++ b/drivers/scsi/qla4xxx/ql4_init.c @@ -1299,9 +1299,9 @@ int qla4xxx_process_ddb_changed(struct scsi_qla_host *ha, ddb_entry->fw_ddb_device_state = state; /* Device is back online. */ if (ddb_entry->fw_ddb_device_state == DDB_DS_SESSION_ACTIVE) { + atomic_set(&ddb_entry->state, DDB_STATE_ONLINE); atomic_set(&ddb_entry->port_down_timer, ha->port_down_retry_count); - atomic_set(&ddb_entry->state, DDB_STATE_ONLINE); atomic_set(&ddb_entry->relogin_retry_count, 0); atomic_set(&ddb_entry->relogin_timer, 0); clear_bit(DF_RELOGIN, &ddb_entry->flags); diff --git a/drivers/scsi/qla4xxx/ql4_os.c b/drivers/scsi/qla4xxx/ql4_os.c index c3c59d7630371781b25a7bf46fed47d02f37edb6..8b92f348f02c73ad8e139be5ede91843d31afc47 100644 --- a/drivers/scsi/qla4xxx/ql4_os.c +++ b/drivers/scsi/qla4xxx/ql4_os.c @@ -75,6 +75,7 @@ static int qla4xxx_eh_host_reset(struct scsi_cmnd *cmd); static int qla4xxx_slave_alloc(struct scsi_device *device); static int qla4xxx_slave_configure(struct scsi_device *device); static void qla4xxx_slave_destroy(struct scsi_device *sdev); +static void qla4xxx_scan_start(struct Scsi_Host *shost); static struct scsi_host_template qla4xxx_driver_template = { .module = THIS_MODULE, @@ -90,6 +91,7 @@ static struct scsi_host_template qla4xxx_driver_template = { .slave_destroy = qla4xxx_slave_destroy, .scan_finished = iscsi_scan_finished, + .scan_start = qla4xxx_scan_start, .this_id = -1, .cmd_per_lun = 3, @@ -299,6 +301,18 @@ struct ddb_entry *qla4xxx_alloc_sess(struct scsi_qla_host *ha) return ddb_entry; } +static void qla4xxx_scan_start(struct Scsi_Host *shost) +{ + struct scsi_qla_host *ha = shost_priv(shost); + struct ddb_entry *ddb_entry, *ddbtemp; + + /* finish setup of sessions that were already setup in firmware */ + list_for_each_entry_safe(ddb_entry, ddbtemp, &ha->ddb_list, list) { + if (ddb_entry->fw_ddb_device_state == DDB_DS_SESSION_ACTIVE) + qla4xxx_add_sess(ddb_entry); + } +} + /* * Timer routines */ @@ -864,8 +878,9 @@ static void qla4xxx_flush_active_srbs(struct scsi_qla_host *ha) * qla4xxx_recover_adapter - recovers adapter after a fatal error * @ha: Pointer to host adapter structure. * @renew_ddb_list: Indicates what to do with the adapter's ddb list - * after adapter recovery has completed. - * 0=preserve ddb list, 1=destroy and rebuild ddb list + * + * renew_ddb_list value can be 0=preserve ddb list, 1=destroy and rebuild + * ddb list. **/ static int qla4xxx_recover_adapter(struct scsi_qla_host *ha, uint8_t renew_ddb_list) @@ -874,6 +889,7 @@ static int qla4xxx_recover_adapter(struct scsi_qla_host *ha, /* Stall incoming I/O until we are done */ clear_bit(AF_ONLINE, &ha->flags); + DEBUG2(printk("scsi%ld: %s calling qla4xxx_cmd_wait\n", ha->host_no, __func__)); @@ -1176,7 +1192,6 @@ static int __devinit qla4xxx_probe_adapter(struct pci_dev *pdev, int ret = -ENODEV, status; struct Scsi_Host *host; struct scsi_qla_host *ha; - struct ddb_entry *ddb_entry, *ddbtemp; uint8_t init_retry_count = 0; char buf[34]; @@ -1295,13 +1310,6 @@ static int __devinit qla4xxx_probe_adapter(struct pci_dev *pdev, if (ret) goto probe_failed; - /* Update transport device information for all devices. */ - list_for_each_entry_safe(ddb_entry, ddbtemp, &ha->ddb_list, list) { - if (ddb_entry->fw_ddb_device_state == DDB_DS_SESSION_ACTIVE) - if (qla4xxx_add_sess(ddb_entry)) - goto remove_host; - } - printk(KERN_INFO " QLogic iSCSI HBA Driver version: %s\n" " QLogic ISP%04x @ %s, host#=%ld, fw=%02d.%02d.%02d.%02d\n", @@ -1311,10 +1319,6 @@ static int __devinit qla4xxx_probe_adapter(struct pci_dev *pdev, scsi_scan_host(host); return 0; -remove_host: - qla4xxx_free_ddb_list(ha); - scsi_remove_host(host); - probe_failed: qla4xxx_free_adapter(ha); scsi_host_put(ha->host); @@ -1600,9 +1604,12 @@ static int qla4xxx_eh_host_reset(struct scsi_cmnd *cmd) return FAILED; } - if (qla4xxx_recover_adapter(ha, PRESERVE_DDB_LIST) == QLA_SUCCESS) { + /* make sure the dpc thread is stopped while we reset the hba */ + clear_bit(AF_ONLINE, &ha->flags); + flush_workqueue(ha->dpc_thread); + + if (qla4xxx_recover_adapter(ha, PRESERVE_DDB_LIST) == QLA_SUCCESS) return_status = SUCCESS; - } dev_info(&ha->pdev->dev, "HOST RESET %s.\n", return_status == FAILED ? "FAILED" : "SUCCEDED"); diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c index fecba05b4e7783da1c22402080c7ab0c6338504b..e5c6f6af876558c0b92dea602c6d2f6eed1a23a5 100644 --- a/drivers/scsi/scsi.c +++ b/drivers/scsi/scsi.c @@ -757,7 +757,7 @@ void scsi_finish_command(struct scsi_cmnd *cmd) "Notifying upper driver of completion " "(result %x)\n", cmd->result)); - good_bytes = scsi_bufflen(cmd); + good_bytes = scsi_bufflen(cmd) + cmd->request->extra_len; if (cmd->request->cmd_type != REQ_TYPE_BLOCK_PC) { drv = scsi_cmd_to_driver(cmd); if (drv->done) diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c index 1dc165ad17fb20edae98e80b408fbd8cfd0c4543..e67c14e31babba5913f0ab1852f7952e191502bb 100644 --- a/drivers/scsi/scsi_scan.c +++ b/drivers/scsi/scsi_scan.c @@ -1577,8 +1577,7 @@ static void __scsi_scan_target(struct device *parent, unsigned int channel, } /** - * scsi_scan_target - scan a target id, possibly including all LUNs on the - * target. + * scsi_scan_target - scan a target id, possibly including all LUNs on the target. * @parent: host to scan * @channel: channel to scan * @id: target id to scan diff --git a/drivers/scsi/scsi_tgt_lib.c b/drivers/scsi/scsi_tgt_lib.c index 3677fbb30b720d50b6777a395125ba03ae1c492b..a0f308bd145b062e2403af9b57a2c32d92108ca0 100644 --- a/drivers/scsi/scsi_tgt_lib.c +++ b/drivers/scsi/scsi_tgt_lib.c @@ -103,7 +103,6 @@ struct scsi_cmnd *scsi_host_get_command(struct Scsi_Host *shost, if (!cmd) goto release_rq; - memset(cmd, 0, sizeof(*cmd)); cmd->sc_data_direction = data_dir; cmd->jiffies_at_alloc = jiffies; cmd->request = rq; @@ -382,6 +381,11 @@ static int scsi_map_user_pages(struct scsi_tgt_cmd *tcmd, struct scsi_cmnd *cmd, scsi_release_buffers(cmd); goto unmap_rq; } + /* + * we use REQ_TYPE_BLOCK_PC so scsi_init_io doesn't set the + * length for us. + */ + cmd->sdb.length = rq->data_len; return 0; diff --git a/drivers/scsi/scsi_transport_iscsi.c b/drivers/scsi/scsi_transport_iscsi.c index 9981682d5302d5ea0bbbea58f181fb75458345f2..ca7bb6f63bdeb6bcee801e8588b5d339c47a6f57 100644 --- a/drivers/scsi/scsi_transport_iscsi.c +++ b/drivers/scsi/scsi_transport_iscsi.c @@ -33,7 +33,7 @@ #define ISCSI_SESSION_ATTRS 19 #define ISCSI_CONN_ATTRS 13 #define ISCSI_HOST_ATTRS 4 -#define ISCSI_TRANSPORT_VERSION "2.0-868" +#define ISCSI_TRANSPORT_VERSION "2.0-869" struct iscsi_internal { int daemon_pid; @@ -373,24 +373,25 @@ static void session_recovery_timedout(struct work_struct *work) scsi_target_unblock(&session->dev); } -static void __iscsi_unblock_session(struct iscsi_cls_session *session) -{ - if (!cancel_delayed_work(&session->recovery_work)) - flush_workqueue(iscsi_eh_timer_workq); - scsi_target_unblock(&session->dev); -} - -void iscsi_unblock_session(struct iscsi_cls_session *session) +static void __iscsi_unblock_session(struct work_struct *work) { + struct iscsi_cls_session *session = + container_of(work, struct iscsi_cls_session, + unblock_work); struct Scsi_Host *shost = iscsi_session_to_shost(session); struct iscsi_host *ihost = shost->shost_data; unsigned long flags; + /* + * The recovery and unblock work get run from the same workqueue, + * so try to cancel it if it was going to run after this unblock. + */ + cancel_delayed_work(&session->recovery_work); spin_lock_irqsave(&session->lock, flags); session->state = ISCSI_SESSION_LOGGED_IN; spin_unlock_irqrestore(&session->lock, flags); - - __iscsi_unblock_session(session); + /* start IO */ + scsi_target_unblock(&session->dev); /* * Only do kernel scanning if the driver is properly hooked into * the async scanning code (drivers like iscsi_tcp do login and @@ -401,20 +402,43 @@ void iscsi_unblock_session(struct iscsi_cls_session *session) atomic_inc(&ihost->nr_scans); } } + +/** + * iscsi_unblock_session - set a session as logged in and start IO. + * @session: iscsi session + * + * Mark a session as ready to accept IO. + */ +void iscsi_unblock_session(struct iscsi_cls_session *session) +{ + queue_work(iscsi_eh_timer_workq, &session->unblock_work); + /* + * make sure all the events have completed before tell the driver + * it is safe + */ + flush_workqueue(iscsi_eh_timer_workq); +} EXPORT_SYMBOL_GPL(iscsi_unblock_session); -void iscsi_block_session(struct iscsi_cls_session *session) +static void __iscsi_block_session(struct work_struct *work) { + struct iscsi_cls_session *session = + container_of(work, struct iscsi_cls_session, + block_work); unsigned long flags; spin_lock_irqsave(&session->lock, flags); session->state = ISCSI_SESSION_FAILED; spin_unlock_irqrestore(&session->lock, flags); - scsi_target_block(&session->dev); queue_delayed_work(iscsi_eh_timer_workq, &session->recovery_work, session->recovery_tmo * HZ); } + +void iscsi_block_session(struct iscsi_cls_session *session) +{ + queue_work(iscsi_eh_timer_workq, &session->block_work); +} EXPORT_SYMBOL_GPL(iscsi_block_session); static void __iscsi_unbind_session(struct work_struct *work) @@ -463,6 +487,8 @@ iscsi_alloc_session(struct Scsi_Host *shost, INIT_DELAYED_WORK(&session->recovery_work, session_recovery_timedout); INIT_LIST_HEAD(&session->host_list); INIT_LIST_HEAD(&session->sess_list); + INIT_WORK(&session->unblock_work, __iscsi_unblock_session); + INIT_WORK(&session->block_work, __iscsi_block_session); INIT_WORK(&session->unbind_work, __iscsi_unbind_session); INIT_WORK(&session->scan_work, iscsi_scan_session); spin_lock_init(&session->lock); @@ -575,24 +601,25 @@ void iscsi_remove_session(struct iscsi_cls_session *session) list_del(&session->sess_list); spin_unlock_irqrestore(&sesslock, flags); + /* make sure there are no blocks/unblocks queued */ + flush_workqueue(iscsi_eh_timer_workq); + /* make sure the timedout callout is not running */ + if (!cancel_delayed_work(&session->recovery_work)) + flush_workqueue(iscsi_eh_timer_workq); /* * If we are blocked let commands flow again. The lld or iscsi * layer should set up the queuecommand to fail commands. + * We assume that LLD will not be calling block/unblock while + * removing the session. */ spin_lock_irqsave(&session->lock, flags); session->state = ISCSI_SESSION_FREE; spin_unlock_irqrestore(&session->lock, flags); - __iscsi_unblock_session(session); - __iscsi_unbind_session(&session->unbind_work); - /* flush running scans */ + scsi_target_unblock(&session->dev); + /* flush running scans then delete devices */ flush_workqueue(ihost->scan_workq); - /* - * If the session dropped while removing devices then we need to make - * sure it is not blocked - */ - if (!cancel_delayed_work(&session->recovery_work)) - flush_workqueue(iscsi_eh_timer_workq); + __iscsi_unbind_session(&session->unbind_work); /* hw iscsi may not have removed all connections from session */ err = device_for_each_child(&session->dev, NULL, @@ -802,23 +829,16 @@ EXPORT_SYMBOL_GPL(iscsi_recv_pdu); void iscsi_conn_error(struct iscsi_cls_conn *conn, enum iscsi_err error) { - struct iscsi_cls_session *session = iscsi_conn_to_session(conn); struct nlmsghdr *nlh; struct sk_buff *skb; struct iscsi_uevent *ev; struct iscsi_internal *priv; int len = NLMSG_SPACE(sizeof(*ev)); - unsigned long flags; priv = iscsi_if_transport_lookup(conn->transport); if (!priv) return; - spin_lock_irqsave(&session->lock, flags); - if (session->state == ISCSI_SESSION_LOGGED_IN) - session->state = ISCSI_SESSION_FAILED; - spin_unlock_irqrestore(&session->lock, flags); - skb = alloc_skb(len, GFP_ATOMIC); if (!skb) { iscsi_cls_conn_printk(KERN_ERR, conn, "gracefully ignored " diff --git a/drivers/serial/8250_pnp.c b/drivers/serial/8250_pnp.c index 6f09cbd7fc488ac53286c92ba1ce0698f11ba0bd..97c68d021d28bcb3ecd1cae57846cdac3fdaed7e 100644 --- a/drivers/serial/8250_pnp.c +++ b/drivers/serial/8250_pnp.c @@ -91,6 +91,8 @@ static const struct pnp_device_id pnp_dev_table[] = { /* Archtek America Corp. */ /* Archtek SmartLink Modem 3334BT Plug & Play */ { "GVC000F", 0 }, + /* Archtek SmartLink Modem 3334BRV 33.6K Data Fax Voice */ + { "GVC0303", 0 }, /* Hayes */ /* Hayes Optima 288 V.34-V.FC + FAX + Voice Plug & Play */ { "HAY0001", 0 }, diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig index b82595cf13e86ff759c92109fb096f706e68e7e5..cf627cd1b4c8f27e028649e97091a5b06e375e5c 100644 --- a/drivers/serial/Kconfig +++ b/drivers/serial/Kconfig @@ -686,7 +686,7 @@ config UART0_RTS_PIN config SERIAL_BFIN_UART1 bool "Enable UART1" - depends on SERIAL_BFIN && (BF534 || BF536 || BF537 || BF54x) + depends on SERIAL_BFIN && (!BF531 && !BF532 && !BF533 && !BF561) help Enable UART1 @@ -699,14 +699,14 @@ config BFIN_UART1_CTSRTS config UART1_CTS_PIN int "UART1 CTS pin" - depends on BFIN_UART1_CTSRTS && (BF53x || BF561) + depends on BFIN_UART1_CTSRTS && !BF54x default -1 help Refer to ./include/asm-blackfin/gpio.h to see the GPIO map. config UART1_RTS_PIN int "UART1 RTS pin" - depends on BFIN_UART1_CTSRTS && (BF53x || BF561) + depends on BFIN_UART1_CTSRTS && !BF54x default -1 help Refer to ./include/asm-blackfin/gpio.h to see the GPIO map. diff --git a/drivers/serial/bfin_5xx.c b/drivers/serial/bfin_5xx.c index ac2a3ef28d55435d3673a8909e01ee27c77ebd82..0aa345b9a38bd8d605cb2112153fc49f388f8ec8 100644 --- a/drivers/serial/bfin_5xx.c +++ b/drivers/serial/bfin_5xx.c @@ -1,30 +1,11 @@ /* - * File: drivers/serial/bfin_5xx.c - * Based on: Based on drivers/serial/sa1100.c - * Author: Aubrey Li + * Blackfin On-Chip Serial Driver * - * Created: - * Description: Driver for blackfin 5xx serial ports + * Copyright 2006-2007 Analog Devices Inc. * - * Modified: - * Copyright 2006 Analog Devices Inc. + * Enter bugs at http://blackfin.uclinux.org/ * - * Bugs: Enter bugs at http://blackfin.uclinux.org/ - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see the file COPYING, or write - * to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * Licensed under the GPL-2 or later. */ #if defined(CONFIG_SERIAL_BFIN_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) @@ -67,14 +48,12 @@ #define DMA_RX_XCOUNT 512 #define DMA_RX_YCOUNT (PAGE_SIZE / DMA_RX_XCOUNT) -#define DMA_RX_FLUSH_JIFFIES 5 +#define DMA_RX_FLUSH_JIFFIES (HZ / 50) #ifdef CONFIG_SERIAL_BFIN_DMA static void bfin_serial_dma_tx_chars(struct bfin_serial_port *uart); #else -static void bfin_serial_do_work(struct work_struct *work); static void bfin_serial_tx_chars(struct bfin_serial_port *uart); -static void local_put_char(struct bfin_serial_port *uart, char ch); #endif static void bfin_serial_mctrl_check(struct bfin_serial_port *uart); @@ -85,23 +64,26 @@ static void bfin_serial_mctrl_check(struct bfin_serial_port *uart); static void bfin_serial_stop_tx(struct uart_port *port) { struct bfin_serial_port *uart = (struct bfin_serial_port *)port; + struct circ_buf *xmit = &uart->port.info->xmit; +#if !defined(CONFIG_BF54x) && !defined(CONFIG_SERIAL_BFIN_DMA) + unsigned short ier; +#endif while (!(UART_GET_LSR(uart) & TEMT)) - continue; + cpu_relax(); #ifdef CONFIG_SERIAL_BFIN_DMA disable_dma(uart->tx_dma_channel); + xmit->tail = (xmit->tail + uart->tx_count) & (UART_XMIT_SIZE - 1); + uart->port.icount.tx += uart->tx_count; + uart->tx_count = 0; + uart->tx_done = 1; #else #ifdef CONFIG_BF54x - /* Waiting for Transmission Finished */ - while (!(UART_GET_LSR(uart) & TFI)) - continue; /* Clear TFI bit */ UART_PUT_LSR(uart, TFI); UART_CLEAR_IER(uart, ETBEI); #else - unsigned short ier; - ier = UART_GET_IER(uart); ier &= ~ETBEI; UART_PUT_IER(uart, ier); @@ -117,7 +99,8 @@ static void bfin_serial_start_tx(struct uart_port *port) struct bfin_serial_port *uart = (struct bfin_serial_port *)port; #ifdef CONFIG_SERIAL_BFIN_DMA - bfin_serial_dma_tx_chars(uart); + if (uart->tx_done) + bfin_serial_dma_tx_chars(uart); #else #ifdef CONFIG_BF54x UART_SET_IER(uart, ETBEI); @@ -209,34 +192,27 @@ int kgdb_get_debug_char(void) } #endif -#ifdef CONFIG_SERIAL_BFIN_PIO -static void local_put_char(struct bfin_serial_port *uart, char ch) -{ - unsigned short status; - int flags = 0; - - spin_lock_irqsave(&uart->port.lock, flags); - - do { - status = UART_GET_LSR(uart); - } while (!(status & THRE)); - - UART_PUT_CHAR(uart, ch); - SSYNC(); - - spin_unlock_irqrestore(&uart->port.lock, flags); -} +#if ANOMALY_05000230 && defined(CONFIG_SERIAL_BFIN_PIO) +# define UART_GET_ANOMALY_THRESHOLD(uart) ((uart)->anomaly_threshold) +# define UART_SET_ANOMALY_THRESHOLD(uart, v) ((uart)->anomaly_threshold = (v)) +#else +# define UART_GET_ANOMALY_THRESHOLD(uart) 0 +# define UART_SET_ANOMALY_THRESHOLD(uart, v) +#endif +#ifdef CONFIG_SERIAL_BFIN_PIO static void bfin_serial_rx_chars(struct bfin_serial_port *uart) { struct tty_struct *tty = uart->port.info->tty; unsigned int status, ch, flg; - static int in_break = 0; + static struct timeval anomaly_start = { .tv_sec = 0 }; #ifdef CONFIG_KGDB_UART struct pt_regs *regs = get_irq_regs(); #endif status = UART_GET_LSR(uart); + UART_CLEAR_LSR(uart); + ch = UART_GET_CHAR(uart); uart->port.icount.rx++; @@ -262,28 +238,56 @@ static void bfin_serial_rx_chars(struct bfin_serial_port *uart) #endif if (ANOMALY_05000230) { - /* The BF533 family of processors have a nice misbehavior where - * they continuously generate characters for a "single" break. + /* The BF533 (and BF561) family of processors have a nice anomaly + * where they continuously generate characters for a "single" break. * We have to basically ignore this flood until the "next" valid - * character comes across. All other Blackfin families operate - * properly though. + * character comes across. Due to the nature of the flood, it is + * not possible to reliably catch bytes that are sent too quickly + * after this break. So application code talking to the Blackfin + * which sends a break signal must allow at least 1.5 character + * times after the end of the break for things to stabilize. This + * timeout was picked as it must absolutely be larger than 1 + * character time +/- some percent. So 1.5 sounds good. All other + * Blackfin families operate properly. Woo. * Note: While Anomaly 05000230 does not directly address this, * the changes that went in for it also fixed this issue. + * That anomaly was fixed in 0.5+ silicon. I like bunnies. */ - if (in_break) { - if (ch != 0) { - in_break = 0; - ch = UART_GET_CHAR(uart); - if (bfin_revid() < 5) - return; - } else - return; + if (anomaly_start.tv_sec) { + struct timeval curr; + suseconds_t usecs; + + if ((~ch & (~ch + 1)) & 0xff) + goto known_good_char; + + do_gettimeofday(&curr); + if (curr.tv_sec - anomaly_start.tv_sec > 1) + goto known_good_char; + + usecs = 0; + if (curr.tv_sec != anomaly_start.tv_sec) + usecs += USEC_PER_SEC; + usecs += curr.tv_usec - anomaly_start.tv_usec; + + if (usecs > UART_GET_ANOMALY_THRESHOLD(uart)) + goto known_good_char; + + if (ch) + anomaly_start.tv_sec = 0; + else + anomaly_start = curr; + + return; + + known_good_char: + anomaly_start.tv_sec = 0; } } if (status & BI) { if (ANOMALY_05000230) - in_break = 1; + if (bfin_revid() < 5) + do_gettimeofday(&anomaly_start); uart->port.icount.brk++; if (uart_handle_break(&uart->port)) goto ignore_char; @@ -324,7 +328,6 @@ static void bfin_serial_tx_chars(struct bfin_serial_port *uart) UART_PUT_CHAR(uart, uart->port.x_char); uart->port.icount.tx++; uart->port.x_char = 0; - return; } /* * Check the modem control lines before @@ -337,9 +340,12 @@ static void bfin_serial_tx_chars(struct bfin_serial_port *uart) return; } - local_put_char(uart, xmit->buf[xmit->tail]); - xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); - uart->port.icount.tx++; + while ((UART_GET_LSR(uart) & THRE) && xmit->tail != xmit->head) { + UART_PUT_CHAR(uart, xmit->buf[xmit->tail]); + xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); + uart->port.icount.tx++; + SSYNC(); + } if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) uart_write_wakeup(&uart->port); @@ -352,21 +358,11 @@ static irqreturn_t bfin_serial_rx_int(int irq, void *dev_id) { struct bfin_serial_port *uart = dev_id; -#ifdef CONFIG_BF54x - unsigned short status; - spin_lock(&uart->port.lock); - status = UART_GET_LSR(uart); - while ((UART_GET_IER(uart) & ERBFI) && (status & DR)) { - bfin_serial_rx_chars(uart); - status = UART_GET_LSR(uart); - } - spin_unlock(&uart->port.lock); -#else spin_lock(&uart->port.lock); - while ((UART_GET_IIR(uart) & IIR_STATUS) == IIR_RX_READY) + while (UART_GET_LSR(uart) & DR) bfin_serial_rx_chars(uart); spin_unlock(&uart->port.lock); -#endif + return IRQ_HANDLED; } @@ -374,25 +370,16 @@ static irqreturn_t bfin_serial_tx_int(int irq, void *dev_id) { struct bfin_serial_port *uart = dev_id; -#ifdef CONFIG_BF54x - unsigned short status; spin_lock(&uart->port.lock); - status = UART_GET_LSR(uart); - while ((UART_GET_IER(uart) & ETBEI) && (status & THRE)) { + if (UART_GET_LSR(uart) & THRE) bfin_serial_tx_chars(uart); - status = UART_GET_LSR(uart); - } spin_unlock(&uart->port.lock); -#else - spin_lock(&uart->port.lock); - while ((UART_GET_IIR(uart) & IIR_STATUS) == IIR_TX_READY) - bfin_serial_tx_chars(uart); - spin_unlock(&uart->port.lock); -#endif + return IRQ_HANDLED; } +#endif - +#ifdef CONFIG_SERIAL_BFIN_CTSRTS static void bfin_serial_do_work(struct work_struct *work) { struct bfin_serial_port *uart = container_of(work, struct bfin_serial_port, cts_workqueue); @@ -406,33 +393,27 @@ static void bfin_serial_dma_tx_chars(struct bfin_serial_port *uart) { struct circ_buf *xmit = &uart->port.info->xmit; unsigned short ier; - int flags = 0; - - if (!uart->tx_done) - return; uart->tx_done = 0; + if (uart_circ_empty(xmit) || uart_tx_stopped(&uart->port)) { + uart->tx_count = 0; + uart->tx_done = 1; + return; + } + if (uart->port.x_char) { UART_PUT_CHAR(uart, uart->port.x_char); uart->port.icount.tx++; uart->port.x_char = 0; - uart->tx_done = 1; - return; } + /* * Check the modem control lines before * transmitting anything. */ bfin_serial_mctrl_check(uart); - if (uart_circ_empty(xmit) || uart_tx_stopped(&uart->port)) { - bfin_serial_stop_tx(&uart->port); - uart->tx_done = 1; - return; - } - - spin_lock_irqsave(&uart->port.lock, flags); uart->tx_count = CIRC_CNT(xmit->head, xmit->tail, UART_XMIT_SIZE); if (uart->tx_count > (UART_XMIT_SIZE - xmit->tail)) uart->tx_count = UART_XMIT_SIZE - xmit->tail; @@ -448,6 +429,7 @@ static void bfin_serial_dma_tx_chars(struct bfin_serial_port *uart) set_dma_x_count(uart->tx_dma_channel, uart->tx_count); set_dma_x_modify(uart->tx_dma_channel, 1); enable_dma(uart->tx_dma_channel); + #ifdef CONFIG_BF54x UART_SET_IER(uart, ETBEI); #else @@ -455,7 +437,6 @@ static void bfin_serial_dma_tx_chars(struct bfin_serial_port *uart) ier |= ETBEI; UART_PUT_IER(uart, ier); #endif - spin_unlock_irqrestore(&uart->port.lock, flags); } static void bfin_serial_dma_rx_chars(struct bfin_serial_port *uart) @@ -464,7 +445,11 @@ static void bfin_serial_dma_rx_chars(struct bfin_serial_port *uart) int i, flg, status; status = UART_GET_LSR(uart); - uart->port.icount.rx += CIRC_CNT(uart->rx_dma_buf.head, uart->rx_dma_buf.tail, UART_XMIT_SIZE);; + UART_CLEAR_LSR(uart); + + uart->port.icount.rx += + CIRC_CNT(uart->rx_dma_buf.head, uart->rx_dma_buf.tail, + UART_XMIT_SIZE); if (status & BI) { uart->port.icount.brk++; @@ -490,10 +475,12 @@ static void bfin_serial_dma_rx_chars(struct bfin_serial_port *uart) else flg = TTY_NORMAL; - for (i = uart->rx_dma_buf.head; i < uart->rx_dma_buf.tail; i++) { - if (uart_handle_sysrq_char(&uart->port, uart->rx_dma_buf.buf[i])) - goto dma_ignore_char; - uart_insert_char(&uart->port, status, OE, uart->rx_dma_buf.buf[i], flg); + for (i = uart->rx_dma_buf.tail; i != uart->rx_dma_buf.head; i++) { + if (i >= UART_XMIT_SIZE) + i = 0; + if (!uart_handle_sysrq_char(&uart->port, uart->rx_dma_buf.buf[i])) + uart_insert_char(&uart->port, status, OE, + uart->rx_dma_buf.buf[i], flg); } dma_ignore_char: @@ -503,23 +490,23 @@ static void bfin_serial_dma_rx_chars(struct bfin_serial_port *uart) void bfin_serial_rx_dma_timeout(struct bfin_serial_port *uart) { int x_pos, pos; - int flags = 0; - - bfin_serial_dma_tx_chars(uart); - spin_lock_irqsave(&uart->port.lock, flags); - x_pos = DMA_RX_XCOUNT - get_dma_curr_xcount(uart->rx_dma_channel); + uart->rx_dma_nrows = get_dma_curr_ycount(uart->rx_dma_channel); + x_pos = get_dma_curr_xcount(uart->rx_dma_channel); + uart->rx_dma_nrows = DMA_RX_YCOUNT - uart->rx_dma_nrows; + if (uart->rx_dma_nrows == DMA_RX_YCOUNT) + uart->rx_dma_nrows = 0; + x_pos = DMA_RX_XCOUNT - x_pos; if (x_pos == DMA_RX_XCOUNT) x_pos = 0; pos = uart->rx_dma_nrows * DMA_RX_XCOUNT + x_pos; - - if (pos>uart->rx_dma_buf.tail) { - uart->rx_dma_buf.tail = pos; + if (pos != uart->rx_dma_buf.tail) { + uart->rx_dma_buf.head = pos; bfin_serial_dma_rx_chars(uart); - uart->rx_dma_buf.head = uart->rx_dma_buf.tail; + uart->rx_dma_buf.tail = uart->rx_dma_buf.head; } - spin_unlock_irqrestore(&uart->port.lock, flags); + uart->rx_dma_timer.expires = jiffies + DMA_RX_FLUSH_JIFFIES; add_timer(&(uart->rx_dma_timer)); } @@ -532,8 +519,8 @@ static irqreturn_t bfin_serial_dma_tx_int(int irq, void *dev_id) spin_lock(&uart->port.lock); if (!(get_dma_curr_irqstat(uart->tx_dma_channel)&DMA_RUN)) { - clear_dma_irqstat(uart->tx_dma_channel); disable_dma(uart->tx_dma_channel); + clear_dma_irqstat(uart->tx_dma_channel); #ifdef CONFIG_BF54x UART_CLEAR_IER(uart, ETBEI); #else @@ -541,15 +528,13 @@ static irqreturn_t bfin_serial_dma_tx_int(int irq, void *dev_id) ier &= ~ETBEI; UART_PUT_IER(uart, ier); #endif - xmit->tail = (xmit->tail+uart->tx_count) &(UART_XMIT_SIZE -1); - uart->port.icount.tx+=uart->tx_count; + xmit->tail = (xmit->tail + uart->tx_count) & (UART_XMIT_SIZE - 1); + uart->port.icount.tx += uart->tx_count; if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) uart_write_wakeup(&uart->port); - if (uart_circ_empty(xmit)) - bfin_serial_stop_tx(&uart->port); - uart->tx_done = 1; + bfin_serial_dma_tx_chars(uart); } spin_unlock(&uart->port.lock); @@ -561,18 +546,15 @@ static irqreturn_t bfin_serial_dma_rx_int(int irq, void *dev_id) struct bfin_serial_port *uart = dev_id; unsigned short irqstat; - uart->rx_dma_nrows++; - if (uart->rx_dma_nrows == DMA_RX_YCOUNT) { - uart->rx_dma_nrows = 0; - uart->rx_dma_buf.tail = DMA_RX_XCOUNT*DMA_RX_YCOUNT; - bfin_serial_dma_rx_chars(uart); - uart->rx_dma_buf.head = uart->rx_dma_buf.tail = 0; - } spin_lock(&uart->port.lock); irqstat = get_dma_curr_irqstat(uart->rx_dma_channel); clear_dma_irqstat(uart->rx_dma_channel); - spin_unlock(&uart->port.lock); + + del_timer(&(uart->rx_dma_timer)); + uart->rx_dma_timer.expires = jiffies; + add_timer(&(uart->rx_dma_timer)); + return IRQ_HANDLED; } #endif @@ -599,7 +581,11 @@ static unsigned int bfin_serial_get_mctrl(struct uart_port *port) if (uart->cts_pin < 0) return TIOCM_CTS | TIOCM_DSR | TIOCM_CAR; +# ifdef BF54x + if (UART_GET_MSR(uart) & CTS) +# else if (gpio_get_value(uart->cts_pin)) +# endif return TIOCM_DSR | TIOCM_CAR; else #endif @@ -614,9 +600,17 @@ static void bfin_serial_set_mctrl(struct uart_port *port, unsigned int mctrl) return; if (mctrl & TIOCM_RTS) +# ifdef BF54x + UART_PUT_MCR(uart, UART_GET_MCR(uart) & ~MRTS); +# else gpio_set_value(uart->rts_pin, 0); +# endif else +# ifdef BF54x + UART_PUT_MCR(uart, UART_GET_MCR(uart) | MRTS); +# else gpio_set_value(uart->rts_pin, 1); +# endif #endif } @@ -627,22 +621,17 @@ static void bfin_serial_mctrl_check(struct bfin_serial_port *uart) { #ifdef CONFIG_SERIAL_BFIN_CTSRTS unsigned int status; -# ifdef CONFIG_SERIAL_BFIN_DMA struct uart_info *info = uart->port.info; struct tty_struct *tty = info->tty; status = bfin_serial_get_mctrl(&uart->port); + uart_handle_cts_change(&uart->port, status & TIOCM_CTS); if (!(status & TIOCM_CTS)) { tty->hw_stopped = 1; + schedule_work(&uart->cts_workqueue); } else { tty->hw_stopped = 0; } -# else - status = bfin_serial_get_mctrl(&uart->port); - uart_handle_cts_change(&uart->port, status & TIOCM_CTS); - if (!(status & TIOCM_CTS)) - schedule_work(&uart->cts_workqueue); -# endif #endif } @@ -743,6 +732,7 @@ static void bfin_serial_shutdown(struct uart_port *port) disable_dma(uart->rx_dma_channel); free_dma(uart->rx_dma_channel); del_timer(&(uart->rx_dma_timer)); + dma_free_coherent(NULL, PAGE_SIZE, uart->rx_dma_buf.buf, 0); #else #ifdef CONFIG_KGDB_UART if (uart->port.line != CONFIG_KGDB_UART_PORT) @@ -814,6 +804,8 @@ bfin_serial_set_termios(struct uart_port *port, struct ktermios *termios, quot = uart_get_divisor(port, baud); spin_lock_irqsave(&uart->port.lock, flags); + UART_SET_ANOMALY_THRESHOLD(uart, USEC_PER_SEC / baud * 15); + do { lsr = UART_GET_LSR(uart); } while (!(lsr & TEMT)); @@ -956,10 +948,9 @@ static void __init bfin_serial_init_ports(void) bfin_serial_ports[i].rx_dma_channel = bfin_serial_resource[i].uart_rx_dma_channel; init_timer(&(bfin_serial_ports[i].rx_dma_timer)); -#else - INIT_WORK(&bfin_serial_ports[i].cts_workqueue, bfin_serial_do_work); #endif #ifdef CONFIG_SERIAL_BFIN_CTSRTS + INIT_WORK(&bfin_serial_ports[i].cts_workqueue, bfin_serial_do_work); bfin_serial_ports[i].cts_pin = bfin_serial_resource[i].uart_cts_pin; bfin_serial_ports[i].rts_pin = diff --git a/drivers/serial/m32r_sio.c b/drivers/serial/m32r_sio.c index 348ee2c19b5830a32b92b2d93b5a6167f199a51b..c2bb11c02bdedebd73d6934f4f67702199e81a0d 100644 --- a/drivers/serial/m32r_sio.c +++ b/drivers/serial/m32r_sio.c @@ -421,7 +421,7 @@ static void transmit_chars(struct uart_sio_port *up) up->port.icount.tx++; if (uart_circ_empty(xmit)) break; - while (!serial_in(up, UART_LSR) & UART_LSR_THRE); + while (!(serial_in(up, UART_LSR) & UART_LSR_THRE)); } while (--count > 0); diff --git a/drivers/serial/of_serial.c b/drivers/serial/of_serial.c index a64d858219969d218c9a973d5b04224a838ea433..c0e50a461055b85a5b4dd8e6996692679e62c1c1 100644 --- a/drivers/serial/of_serial.c +++ b/drivers/serial/of_serial.c @@ -138,7 +138,7 @@ static struct of_device_id __devinitdata of_platform_serial_table[] = { { /* end of list */ }, }; -static struct of_platform_driver __devinitdata of_platform_serial_driver = { +static struct of_platform_driver of_platform_serial_driver = { .owner = THIS_MODULE, .name = "of_serial", .probe = of_platform_serial_probe, diff --git a/drivers/serial/sh-sci.c b/drivers/serial/sh-sci.c index 9ce12cb2cebc0d6dfa74dc5bc8fdf77bbf1df6b8..a8c116b80bffc18d8fd0e5c8cf43813076581e67 100644 --- a/drivers/serial/sh-sci.c +++ b/drivers/serial/sh-sci.c @@ -41,6 +41,7 @@ #include #include #include +#include #ifdef CONFIG_CPU_FREQ #include @@ -54,7 +55,6 @@ #include #endif -#include #include "sh-sci.h" struct sci_port { diff --git a/drivers/sh/maple/maple.c b/drivers/sh/maple/maple.c index 9cfcfd8dad5e5fb5dfd36bd651a70efc99c43c31..617efb1640b10375c9dc2362cff085beef85f596 100644 --- a/drivers/sh/maple/maple.c +++ b/drivers/sh/maple/maple.c @@ -1,7 +1,7 @@ /* * Core maple bus functionality * - * Copyright (C) 2007 Adrian McMenamin + * Copyright (C) 2007, 2008 Adrian McMenamin * * Based on 2.4 code by: * @@ -18,7 +18,6 @@ #include #include #include -#include #include #include #include @@ -54,7 +53,7 @@ static struct device maple_bus; static int subdevice_map[MAPLE_PORTS]; static unsigned long *maple_sendbuf, *maple_sendptr, *maple_lastptr; static unsigned long maple_pnp_time; -static int started, scanning, liststatus, realscan; +static int started, scanning, liststatus, fullscan; static struct kmem_cache *maple_queue_cache; struct maple_device_specify { @@ -62,6 +61,9 @@ struct maple_device_specify { int unit; }; +static bool checked[4]; +static struct maple_device *baseunits[4]; + /** * maple_driver_register - register a device driver * automatically makes the driver bus a maple bus @@ -309,11 +311,9 @@ static void maple_attach_driver(struct maple_device *mdev) else break; - if (realscan) { - printk(KERN_INFO "Maple device detected: %s\n", - mdev->product_name); - printk(KERN_INFO "Maple device: %s\n", mdev->product_licence); - } + printk(KERN_INFO "Maple device detected: %s\n", + mdev->product_name); + printk(KERN_INFO "Maple device: %s\n", mdev->product_licence); function = be32_to_cpu(mdev->devinfo.function); @@ -323,10 +323,9 @@ static void maple_attach_driver(struct maple_device *mdev) mdev->driver = &maple_dummy_driver; sprintf(mdev->dev.bus_id, "%d:0.port", mdev->port); } else { - if (realscan) - printk(KERN_INFO - "Maple bus at (%d, %d): Function 0x%lX\n", - mdev->port, mdev->unit, function); + printk(KERN_INFO + "Maple bus at (%d, %d): Function 0x%lX\n", + mdev->port, mdev->unit, function); matched = bus_for_each_drv(&maple_bus_type, NULL, mdev, @@ -334,9 +333,8 @@ static void maple_attach_driver(struct maple_device *mdev) if (matched == 0) { /* Driver does not exist yet */ - if (realscan) - printk(KERN_INFO - "No maple driver found.\n"); + printk(KERN_INFO + "No maple driver found.\n"); mdev->driver = &maple_dummy_driver; } sprintf(mdev->dev.bus_id, "%d:0%d.%lX", mdev->port, @@ -472,9 +470,12 @@ static void maple_response_none(struct maple_device *mdev, maple_detach_driver(mdev); return; } - if (!started) { - printk(KERN_INFO "No maple devices attached to port %d\n", - mdev->port); + if (!started || !fullscan) { + if (checked[mdev->port] == false) { + checked[mdev->port] = true; + printk(KERN_INFO "No maple devices attached" + " to port %d\n", mdev->port); + } return; } maple_clean_submap(mdev); @@ -485,8 +486,14 @@ static void maple_response_devinfo(struct maple_device *mdev, char *recvbuf) { char submask; - if ((!started) || (scanning == 2)) { - maple_attach_driver(mdev); + if (!started || (scanning == 2) || !fullscan) { + if ((mdev->unit == 0) && (checked[mdev->port] == false)) { + checked[mdev->port] = true; + maple_attach_driver(mdev); + } else { + if (mdev->unit != 0) + maple_attach_driver(mdev); + } return; } if (mdev->unit == 0) { @@ -505,6 +512,7 @@ static void maple_dma_handler(struct work_struct *work) struct maple_device *dev; char *recvbuf; enum maple_code code; + int i; if (!maple_dma_done()) return; @@ -557,6 +565,19 @@ static void maple_dma_handler(struct work_struct *work) } else scanning = 0; + if (!fullscan) { + fullscan = 1; + for (i = 0; i < MAPLE_PORTS; i++) { + if (checked[i] == false) { + fullscan = 0; + dev = baseunits[i]; + dev->mq->command = + MAPLE_COMMAND_DEVINFO; + dev->mq->length = 0; + maple_add_packet(dev->mq); + } + } + } if (started == 0) started = 1; } @@ -694,7 +715,9 @@ static int __init maple_bus_init(void) /* setup maple ports */ for (i = 0; i < MAPLE_PORTS; i++) { + checked[i] = false; mdev[i] = maple_alloc_dev(i, 0); + baseunits[i] = mdev[i]; if (!mdev[i]) { while (i-- > 0) maple_free_dev(mdev[i]); @@ -703,12 +726,9 @@ static int __init maple_bus_init(void) mdev[i]->mq->command = MAPLE_COMMAND_DEVINFO; mdev[i]->mq->length = 0; maple_add_packet(mdev[i]->mq); - /* delay aids hardware detection */ - mdelay(5); subdevice_map[i] = 0; } - realscan = 1; /* setup maplebus hardware */ maplebus_dma_reset(); /* initial detection */ diff --git a/drivers/sn/ioc3.c b/drivers/sn/ioc3.c index 29fcd6d0301d7244eeab44f2e7f8d0b395f73a19..a0aa33dde0a43dc36b1acbae9f9f22da5c39c065 100644 --- a/drivers/sn/ioc3.c +++ b/drivers/sn/ioc3.c @@ -561,7 +561,7 @@ void ioc3_unregister_submodule(struct ioc3_submodule *is) printk(KERN_WARNING "%s: IOC3 submodule %s remove failed " "for pci_dev %s.\n", - __FUNCTION__, module_name(is->owner), + __func__, module_name(is->owner), pci_name(idd->pdev)); idd->active[is->id] = 0; if(is->irq_mask) @@ -611,7 +611,7 @@ static int ioc3_probe(struct pci_dev *pdev, const struct pci_device_id *pci_id) if ((ret = pci_enable_device(pdev))) { printk(KERN_WARNING "%s: Failed to enable IOC3 device for pci_dev %s.\n", - __FUNCTION__, pci_name(pdev)); + __func__, pci_name(pdev)); goto out; } pci_set_master(pdev); @@ -623,7 +623,7 @@ static int ioc3_probe(struct pci_dev *pdev, const struct pci_device_id *pci_id) if (ret < 0) { printk(KERN_WARNING "%s: Unable to obtain 64 bit DMA " "for consistent allocations\n", - __FUNCTION__); + __func__); } } #endif @@ -633,7 +633,7 @@ static int ioc3_probe(struct pci_dev *pdev, const struct pci_device_id *pci_id) if (!idd) { printk(KERN_WARNING "%s: Failed to allocate IOC3 data for pci_dev %s.\n", - __FUNCTION__, pci_name(pdev)); + __func__, pci_name(pdev)); ret = -ENODEV; goto out_idd; } @@ -649,7 +649,7 @@ static int ioc3_probe(struct pci_dev *pdev, const struct pci_device_id *pci_id) printk(KERN_WARNING "%s: Unable to find IOC3 resource " "for pci_dev %s.\n", - __FUNCTION__, pci_name(pdev)); + __func__, pci_name(pdev)); ret = -ENODEV; goto out_pci; } @@ -657,7 +657,7 @@ static int ioc3_probe(struct pci_dev *pdev, const struct pci_device_id *pci_id) printk(KERN_WARNING "%s: Unable to request IOC3 region " "for pci_dev %s.\n", - __FUNCTION__, pci_name(pdev)); + __func__, pci_name(pdev)); ret = -ENODEV; goto out_pci; } @@ -666,7 +666,7 @@ static int ioc3_probe(struct pci_dev *pdev, const struct pci_device_id *pci_id) printk(KERN_WARNING "%s: Unable to remap IOC3 region " "for pci_dev %s.\n", - __FUNCTION__, pci_name(pdev)); + __func__, pci_name(pdev)); ret = -ENODEV; goto out_misc_region; } @@ -709,7 +709,7 @@ static int ioc3_probe(struct pci_dev *pdev, const struct pci_device_id *pci_id) } else { printk(KERN_WARNING "%s : request_irq fails for IRQ 0x%x\n ", - __FUNCTION__, pdev->irq); + __func__, pdev->irq); } if (!request_irq(pdev->irq+2, ioc3_intr_io, IRQF_SHARED, "ioc3-io", (void *)idd)) { @@ -717,7 +717,7 @@ static int ioc3_probe(struct pci_dev *pdev, const struct pci_device_id *pci_id) } else { printk(KERN_WARNING "%s : request_irq fails for IRQ 0x%x\n ", - __FUNCTION__, pdev->irq+2); + __func__, pdev->irq+2); } } else { if (!request_irq(pdev->irq, ioc3_intr_io, IRQF_SHARED, @@ -726,7 +726,7 @@ static int ioc3_probe(struct pci_dev *pdev, const struct pci_device_id *pci_id) } else { printk(KERN_WARNING "%s : request_irq fails for IRQ 0x%x\n ", - __FUNCTION__, pdev->irq); + __func__, pdev->irq); } } @@ -769,7 +769,7 @@ static void ioc3_remove(struct pci_dev *pdev) printk(KERN_WARNING "%s: IOC3 submodule 0x%s remove failed " "for pci_dev %s.\n", - __FUNCTION__, + __func__, module_name(ioc3_submodules[id]->owner), pci_name(pdev)); idd->active[id] = 0; diff --git a/drivers/spi/au1550_spi.c b/drivers/spi/au1550_spi.c index c47a650183a14beeec627db2f439d47b7a08c401..41a3d00c45156f27d9c59c1663f02c95f4993265 100644 --- a/drivers/spi/au1550_spi.c +++ b/drivers/spi/au1550_spi.c @@ -99,7 +99,7 @@ static dbdev_tab_t au1550_spi_mem_dbdev = static void au1550_spi_bits_handlers_set(struct au1550_spi *hw, int bpw); -/** +/* * compute BRG and DIV bits to setup spi clock based on main input clock rate * that was specified in platform data structure * according to au1550 datasheet: @@ -650,7 +650,7 @@ static int au1550_spi_txrx_bufs(struct spi_device *spi, struct spi_transfer *t) return hw->txrx_bufs(spi, t); } -static irqreturn_t au1550_spi_irq(int irq, void *dev, struct pt_regs *regs) +static irqreturn_t au1550_spi_irq(int irq, void *dev) { struct au1550_spi *hw = dev; return hw->irq_callback(hw); diff --git a/drivers/spi/mpc52xx_psc_spi.c b/drivers/spi/mpc52xx_psc_spi.c index 253ed5682a6d6c354a761791b4103d2ec4f04a20..a86315a0c5b8e93c90c70edac02fd6734cf62bbb 100644 --- a/drivers/spi/mpc52xx_psc_spi.c +++ b/drivers/spi/mpc52xx_psc_spi.c @@ -42,6 +42,7 @@ struct mpc52xx_psc_spi { /* driver internal data */ struct mpc52xx_psc __iomem *psc; + struct mpc52xx_psc_fifo __iomem *fifo; unsigned int irq; u8 bits_per_word; u8 busy; @@ -139,6 +140,7 @@ static int mpc52xx_psc_spi_transfer_rxtx(struct spi_device *spi, { struct mpc52xx_psc_spi *mps = spi_master_get_devdata(spi->master); struct mpc52xx_psc __iomem *psc = mps->psc; + struct mpc52xx_psc_fifo __iomem *fifo = mps->fifo; unsigned rb = 0; /* number of bytes receieved */ unsigned sb = 0; /* number of bytes sent */ unsigned char *rx_buf = (unsigned char *)t->rx_buf; @@ -190,11 +192,11 @@ static int mpc52xx_psc_spi_transfer_rxtx(struct spi_device *spi, out_8(&psc->mode, 0); } else { out_8(&psc->mode, MPC52xx_PSC_MODE_FFULL); - out_be16(&psc->rfalarm, rfalarm); + out_be16(&fifo->rfalarm, rfalarm); } out_be16(&psc->mpc52xx_psc_imr, MPC52xx_PSC_IMR_RXRDY); wait_for_completion(&mps->done); - recv_at_once = in_be16(&psc->rfnum); + recv_at_once = in_be16(&fifo->rfnum); dev_dbg(&spi->dev, "%d bytes received\n", recv_at_once); send_at_once = recv_at_once; @@ -331,6 +333,7 @@ static void mpc52xx_psc_spi_cleanup(struct spi_device *spi) static int mpc52xx_psc_spi_port_config(int psc_id, struct mpc52xx_psc_spi *mps) { struct mpc52xx_psc __iomem *psc = mps->psc; + struct mpc52xx_psc_fifo __iomem *fifo = mps->fifo; u32 mclken_div; int ret = 0; @@ -346,7 +349,7 @@ static int mpc52xx_psc_spi_port_config(int psc_id, struct mpc52xx_psc_spi *mps) /* Disable interrupts, interrupts are based on alarm level */ out_be16(&psc->mpc52xx_psc_imr, 0); out_8(&psc->command, MPC52xx_PSC_SEL_MODE_REG_1); - out_8(&psc->rfcntl, 0); + out_8(&fifo->rfcntl, 0); out_8(&psc->mode, MPC52xx_PSC_MODE_FFULL); /* Configure 8bit codec mode as a SPI master and use EOF flags */ @@ -419,6 +422,8 @@ static int __init mpc52xx_psc_spi_do_probe(struct device *dev, u32 regaddr, ret = -EFAULT; goto free_master; } + /* On the 5200, fifo regs are immediately ajacent to the psc regs */ + mps->fifo = ((void __iomem *)mps->psc) + sizeof(struct mpc52xx_psc); ret = request_irq(mps->irq, mpc52xx_psc_spi_isr, 0, "mpc52xx-psc-spi", mps); diff --git a/drivers/spi/spi_bitbang.c b/drivers/spi/spi_bitbang.c index f7f8580edad86c9be126ce1b6abd97d7629ee261..71e881419cddaa6ba9c77f588ae6723ff633249a 100644 --- a/drivers/spi/spi_bitbang.c +++ b/drivers/spi/spi_bitbang.c @@ -344,12 +344,14 @@ static void bitbang_work(struct work_struct *work) t->rx_dma = t->tx_dma = 0; status = bitbang->txrx_bufs(spi, t); } + if (status > 0) + m->actual_length += status; if (status != t->len) { - if (status > 0) - status = -EMSGSIZE; + /* always report some kind of error */ + if (status >= 0) + status = -EREMOTEIO; break; } - m->actual_length += status; status = 0; /* protocol tweaks before next transfer */ diff --git a/drivers/thermal/Kconfig b/drivers/thermal/Kconfig index 69f19f22487566e2e12110236c550265da7b7ff5..3ab313ed441cc07a4c9ef17ee62c3e325493a32c 100644 --- a/drivers/thermal/Kconfig +++ b/drivers/thermal/Kconfig @@ -4,6 +4,7 @@ menuconfig THERMAL bool "Generic Thermal sysfs driver" + select HWMON default y help Generic Thermal Sysfs driver offers a generic mechanism for diff --git a/drivers/thermal/thermal.c b/drivers/thermal/thermal.c index 8b86e53ccf7a081586d32d09350dce072f2ef75e..41bd4c805ace249c6c43f44066df7c049d0cdac4 100644 --- a/drivers/thermal/thermal.c +++ b/drivers/thermal/thermal.c @@ -30,8 +30,10 @@ #include #include #include +#include +#include -MODULE_AUTHOR("Zhang Rui") +MODULE_AUTHOR("Zhang Rui"); MODULE_DESCRIPTION("Generic thermal management sysfs support"); MODULE_LICENSE("GPL"); @@ -56,6 +58,9 @@ static LIST_HEAD(thermal_tz_list); static LIST_HEAD(thermal_cdev_list); static DEFINE_MUTEX(thermal_list_lock); +static struct device *thermal_hwmon; +#define MAX_THERMAL_ZONES 10 + static int get_idr(struct idr *idr, struct mutex *lock, int *id) { int err; @@ -87,7 +92,67 @@ static void release_idr(struct idr *idr, struct mutex *lock, int id) mutex_unlock(lock); } -/* sys I/F for thermal zone */ +/* hwmon sys I/F*/ +static ssize_t +name_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "thermal_sys_class\n"); +} + +static ssize_t +temp_input_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + struct thermal_zone_device *tz; + struct sensor_device_attribute *sensor_attr + = to_sensor_dev_attr(attr); + + list_for_each_entry(tz, &thermal_tz_list, node) + if (tz->id == sensor_attr->index) + return tz->ops->get_temp(tz, buf); + + return -ENODEV; +} + +static ssize_t +temp_crit_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct thermal_zone_device *tz; + struct sensor_device_attribute *sensor_attr + = to_sensor_dev_attr(attr); + + list_for_each_entry(tz, &thermal_tz_list, node) + if (tz->id == sensor_attr->index) + return tz->ops->get_trip_temp(tz, 0, buf); + + return -ENODEV; +} + +static DEVICE_ATTR(name, 0444, name_show, NULL); +static struct sensor_device_attribute sensor_attrs[] = { + SENSOR_ATTR(temp1_input, 0444, temp_input_show, NULL, 0), + SENSOR_ATTR(temp1_crit, 0444, temp_crit_show, NULL, 0), + SENSOR_ATTR(temp2_input, 0444, temp_input_show, NULL, 1), + SENSOR_ATTR(temp2_crit, 0444, temp_crit_show, NULL, 1), + SENSOR_ATTR(temp3_input, 0444, temp_input_show, NULL, 2), + SENSOR_ATTR(temp3_crit, 0444, temp_crit_show, NULL, 2), + SENSOR_ATTR(temp4_input, 0444, temp_input_show, NULL, 3), + SENSOR_ATTR(temp4_crit, 0444, temp_crit_show, NULL, 3), + SENSOR_ATTR(temp5_input, 0444, temp_input_show, NULL, 4), + SENSOR_ATTR(temp5_crit, 0444, temp_crit_show, NULL, 4), + SENSOR_ATTR(temp6_input, 0444, temp_input_show, NULL, 5), + SENSOR_ATTR(temp6_crit, 0444, temp_crit_show, NULL, 5), + SENSOR_ATTR(temp7_input, 0444, temp_input_show, NULL, 6), + SENSOR_ATTR(temp7_crit, 0444, temp_crit_show, NULL, 6), + SENSOR_ATTR(temp8_input, 0444, temp_input_show, NULL, 7), + SENSOR_ATTR(temp8_crit, 0444, temp_crit_show, NULL, 7), + SENSOR_ATTR(temp9_input, 0444, temp_input_show, NULL, 8), + SENSOR_ATTR(temp9_crit, 0444, temp_crit_show, NULL, 8), + SENSOR_ATTR(temp10_input, 0444, temp_input_show, NULL, 9), + SENSOR_ATTR(temp10_crit, 0444, temp_crit_show, NULL, 9), +}; + +/* thermal zone sys I/F */ #define to_thermal_zone(_dev) \ container_of(_dev, struct thermal_zone_device, device) @@ -214,7 +279,7 @@ do { \ device_remove_file(_dev, &trip_point_attrs[_index * 2 + 1]); \ } while (0) -/* sys I/F for cooling device */ +/* cooling device sys I/F */ #define to_cooling_device(_dev) \ container_of(_dev, struct thermal_cooling_device, device) @@ -447,6 +512,9 @@ struct thermal_cooling_device *thermal_cooling_device_register(char *type, struct thermal_zone_device *pos; int result; + if (!type) + return ERR_PTR(-EINVAL); + if (strlen(type) >= THERMAL_NAME_LENGTH) return ERR_PTR(-EINVAL); @@ -477,11 +545,9 @@ struct thermal_cooling_device *thermal_cooling_device_register(char *type, } /* sys I/F */ - if (type) { - result = device_create_file(&cdev->device, &dev_attr_cdev_type); - if (result) - goto unregister; - } + result = device_create_file(&cdev->device, &dev_attr_cdev_type); + if (result) + goto unregister; result = device_create_file(&cdev->device, &dev_attr_max_state); if (result) @@ -547,8 +613,8 @@ void thermal_cooling_device_unregister(struct tz->ops->unbind(tz, cdev); } mutex_unlock(&thermal_list_lock); - if (cdev->type[0]) - device_remove_file(&cdev->device, &dev_attr_cdev_type); + + device_remove_file(&cdev->device, &dev_attr_cdev_type); device_remove_file(&cdev->device, &dev_attr_max_state); device_remove_file(&cdev->device, &dev_attr_cur_state); @@ -580,6 +646,9 @@ struct thermal_zone_device *thermal_zone_device_register(char *type, int result; int count; + if (!type) + return ERR_PTR(-EINVAL); + if (strlen(type) >= THERMAL_NAME_LENGTH) return ERR_PTR(-EINVAL); @@ -601,6 +670,13 @@ struct thermal_zone_device *thermal_zone_device_register(char *type, kfree(tz); return ERR_PTR(result); } + if (tz->id >= MAX_THERMAL_ZONES) { + printk(KERN_ERR PREFIX + "Too many thermal zones\n"); + release_idr(&thermal_tz_idr, &thermal_idr_lock, tz->id); + kfree(tz); + return ERR_PTR(-EINVAL); + } strcpy(tz->type, type); tz->ops = ops; @@ -615,13 +691,28 @@ struct thermal_zone_device *thermal_zone_device_register(char *type, return ERR_PTR(result); } - /* sys I/F */ - if (type) { - result = device_create_file(&tz->device, &dev_attr_type); - if (result) - goto unregister; + /* hwmon sys I/F */ + result = device_create_file(thermal_hwmon, + &sensor_attrs[tz->id * 2].dev_attr); + if (result) + goto unregister; + + if (trips > 0) { + char buf[40]; + result = tz->ops->get_trip_type(tz, 0, buf); + if (result > 0 && !strcmp(buf, "critical\n")) { + result = device_create_file(thermal_hwmon, + &sensor_attrs[tz->id * 2 + 1].dev_attr); + if (result) + goto unregister; + } } + /* sys I/F */ + result = device_create_file(&tz->device, &dev_attr_type); + if (result) + goto unregister; + result = device_create_file(&tz->device, &dev_attr_temp); if (result) goto unregister; @@ -687,8 +778,17 @@ void thermal_zone_device_unregister(struct thermal_zone_device *tz) tz->ops->unbind(tz, cdev); mutex_unlock(&thermal_list_lock); - if (tz->type[0]) - device_remove_file(&tz->device, &dev_attr_type); + device_remove_file(thermal_hwmon, + &sensor_attrs[tz->id * 2].dev_attr); + if (tz->trips > 0) { + char buf[40]; + if (tz->ops->get_trip_type(tz, 0, buf) > 0) + if (!strcmp(buf, "critical\n")) + device_remove_file(thermal_hwmon, + &sensor_attrs[tz->id * 2 + 1].dev_attr); + } + + device_remove_file(&tz->device, &dev_attr_type); device_remove_file(&tz->device, &dev_attr_temp); if (tz->ops->get_mode) device_remove_file(&tz->device, &dev_attr_mode); @@ -705,6 +805,19 @@ void thermal_zone_device_unregister(struct thermal_zone_device *tz) EXPORT_SYMBOL(thermal_zone_device_unregister); +static void thermal_exit(void) +{ + if (thermal_hwmon) { + device_remove_file(thermal_hwmon, &dev_attr_name); + hwmon_device_unregister(thermal_hwmon); + } + class_unregister(&thermal_class); + idr_destroy(&thermal_tz_idr); + idr_destroy(&thermal_cdev_idr); + mutex_destroy(&thermal_idr_lock); + mutex_destroy(&thermal_list_lock); +} + static int __init thermal_init(void) { int result = 0; @@ -716,16 +829,20 @@ static int __init thermal_init(void) mutex_destroy(&thermal_idr_lock); mutex_destroy(&thermal_list_lock); } - return result; -} -static void __exit thermal_exit(void) -{ - class_unregister(&thermal_class); - idr_destroy(&thermal_tz_idr); - idr_destroy(&thermal_cdev_idr); - mutex_destroy(&thermal_idr_lock); - mutex_destroy(&thermal_list_lock); + thermal_hwmon = hwmon_device_register(NULL); + if (IS_ERR(thermal_hwmon)) { + result = PTR_ERR(thermal_hwmon); + thermal_hwmon = NULL; + printk(KERN_ERR PREFIX + "unable to register hwmon device\n"); + thermal_exit(); + return result; + } + + result = device_create_file(thermal_hwmon, &dev_attr_name); + + return result; } subsys_initcall(thermal_init); diff --git a/drivers/usb/core/Kconfig b/drivers/usb/core/Kconfig index 5c33cdb9cac7131a0e4d2715ecbcec538903406f..a2b0aa48b8eaba4d5be56c5d2bcbe3a4ed9fc2cd 100644 --- a/drivers/usb/core/Kconfig +++ b/drivers/usb/core/Kconfig @@ -87,12 +87,13 @@ config USB_DYNAMIC_MINORS If you are unsure about this, say N here. config USB_SUSPEND - bool "USB selective suspend/resume and wakeup (EXPERIMENTAL)" - depends on USB && PM && EXPERIMENTAL + bool "USB selective suspend/resume and wakeup" + depends on USB && PM help If you say Y here, you can use driver calls or the sysfs - "power/state" file to suspend or resume individual USB - peripherals. + "power/level" file to suspend or resume individual USB + peripherals and to enable or disable autosuspend (see + Documentation/usb/power-management.txt for more details). Also, USB "remote wakeup" signaling is supported, whereby some USB devices (like keyboards and network adapters) can wake up diff --git a/drivers/usb/core/quirks.c b/drivers/usb/core/quirks.c index f90ab5e94c5842d5b5c61f55e5fd33fdf4b5ecb1..d9d1eb19f2a134ecde7a5f5bad21cb195da0bdb1 100644 --- a/drivers/usb/core/quirks.c +++ b/drivers/usb/core/quirks.c @@ -28,35 +28,38 @@ * devices is broken... */ static const struct usb_device_id usb_quirk_list[] = { - /* Action Semiconductor flash disk */ - { USB_DEVICE(0x10d6, 0x2200), .driver_info = USB_QUIRK_STRING_FETCH_255}, - /* CBM - Flash disk */ { USB_DEVICE(0x0204, 0x6025), .driver_info = USB_QUIRK_RESET_RESUME }, + /* HP 5300/5370C scanner */ - { USB_DEVICE(0x03f0, 0x0701), .driver_info = USB_QUIRK_STRING_FETCH_255 }, + { USB_DEVICE(0x03f0, 0x0701), .driver_info = + USB_QUIRK_STRING_FETCH_255 }, /* Creative SB Audigy 2 NX */ { USB_DEVICE(0x041e, 0x3020), .driver_info = USB_QUIRK_RESET_RESUME }, + /* Philips PSC805 audio device */ + { USB_DEVICE(0x0471, 0x0155), .driver_info = USB_QUIRK_RESET_RESUME }, + /* Roland SC-8820 */ { USB_DEVICE(0x0582, 0x0007), .driver_info = USB_QUIRK_RESET_RESUME }, /* Edirol SD-20 */ { USB_DEVICE(0x0582, 0x0027), .driver_info = USB_QUIRK_RESET_RESUME }, - /* INTEL VALUE SSD */ - { USB_DEVICE(0x8086, 0xf1a5), .driver_info = USB_QUIRK_RESET_RESUME }, - /* M-Systems Flash Disk Pioneers */ { USB_DEVICE(0x08ec, 0x1000), .driver_info = USB_QUIRK_RESET_RESUME }, - /* Philips PSC805 audio device */ - { USB_DEVICE(0x0471, 0x0155), .driver_info = USB_QUIRK_RESET_RESUME }, + /* Action Semiconductor flash disk */ + { USB_DEVICE(0x10d6, 0x2200), .driver_info = + USB_QUIRK_STRING_FETCH_255 }, /* SKYMEDI USB_DRIVE */ { USB_DEVICE(0x1516, 0x8628), .driver_info = USB_QUIRK_RESET_RESUME }, + /* INTEL VALUE SSD */ + { USB_DEVICE(0x8086, 0xf1a5), .driver_info = USB_QUIRK_RESET_RESUME }, + { } /* terminating entry must be last */ }; diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c index 4e984060c984b4cbb715607f26ab13dfb05d357e..1f0db51190ccc79c121364de04a39a93c7e54aae 100644 --- a/drivers/usb/core/usb.c +++ b/drivers/usb/core/usb.c @@ -99,8 +99,7 @@ struct usb_interface *usb_ifnum_to_if(const struct usb_device *dev, EXPORT_SYMBOL_GPL(usb_ifnum_to_if); /** - * usb_altnum_to_altsetting - get the altsetting structure with a given - * alternate setting number. + * usb_altnum_to_altsetting - get the altsetting structure with a given alternate setting number. * @intf: the interface containing the altsetting in question * @altnum: the desired alternate setting number * @@ -234,7 +233,7 @@ static int ksuspend_usb_init(void) * singlethreaded. Its job doesn't justify running on more * than one CPU. */ - ksuspend_usb_wq = create_singlethread_workqueue("ksuspend_usbd"); + ksuspend_usb_wq = create_freezeable_workqueue("ksuspend_usbd"); if (!ksuspend_usb_wq) return -ENOMEM; return 0; @@ -442,8 +441,7 @@ EXPORT_SYMBOL_GPL(usb_put_intf); */ /** - * usb_lock_device_for_reset - cautiously acquire the lock for a - * usb device structure + * usb_lock_device_for_reset - cautiously acquire the lock for a usb device structure * @udev: device that's being locked * @iface: interface bound to the driver making the request (optional) * diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig index c1395516468618c3683fccac3d27bc22bc5a0759..6f45dd669b3378a3f4bd0c9970fe65fdcdae6cbb 100644 --- a/drivers/usb/gadget/Kconfig +++ b/drivers/usb/gadget/Kconfig @@ -131,7 +131,7 @@ config USB_ATMEL_USBA config USB_GADGET_FSL_USB2 boolean "Freescale Highspeed USB DR Peripheral Controller" - depends on MPC834x || PPC_MPC831x + depends on FSL_SOC select USB_GADGET_DUALSPEED help Some of Freescale PowerPC processors have a High Speed diff --git a/drivers/usb/gadget/printer.c b/drivers/usb/gadget/printer.c index 4f6bfa100f2ad009381190605cdb75c1ee4271ae..2c32bd08ee7db2c6051df00de37f709de9041a10 100644 --- a/drivers/usb/gadget/printer.c +++ b/drivers/usb/gadget/printer.c @@ -92,7 +92,6 @@ struct printer_dev { u8 *current_rx_buf; u8 printer_status; u8 reset_printer; - struct class_device *printer_class_dev; struct cdev printer_cdev; struct device *pdev; u8 printer_cdev_open; diff --git a/drivers/usb/gadget/pxa2xx_udc.c b/drivers/usb/gadget/pxa2xx_udc.c index 4402d6f042d971bd42d6a1453bb3c0bef85172ee..096c41cc40d1bc8acd262fb75f5cf310d8189e6c 100644 --- a/drivers/usb/gadget/pxa2xx_udc.c +++ b/drivers/usb/gadget/pxa2xx_udc.c @@ -103,6 +103,12 @@ static const char ep0name [] = "ep0"; #error "Can't configure both IXP and PXA" #endif +/* IXP doesn't yet support */ +#define clk_get(dev,name) NULL +#define clk_enable(clk) do { } while (0) +#define clk_disable(clk) do { } while (0) +#define clk_put(clk) do { } while (0) + #endif #include "pxa2xx_udc.h" @@ -934,20 +940,31 @@ static void udc_disable(struct pxa2xx_udc *); /* We disable the UDC -- and its 48 MHz clock -- whenever it's not * in active use. */ -static int pullup(struct pxa2xx_udc *udc, int is_active) +static int pullup(struct pxa2xx_udc *udc) { - is_active = is_active && udc->vbus && udc->pullup; + int is_active = udc->vbus && udc->pullup && !udc->suspended; DMSG("%s\n", is_active ? "active" : "inactive"); - if (is_active) - udc_enable(udc); - else { - if (udc->gadget.speed != USB_SPEED_UNKNOWN) { - DMSG("disconnect %s\n", udc->driver - ? udc->driver->driver.name - : "(no driver)"); - stop_activity(udc, udc->driver); + if (is_active) { + if (!udc->active) { + udc->active = 1; + /* Enable clock for USB device */ + clk_enable(udc->clk); + udc_enable(udc); } - udc_disable(udc); + } else { + if (udc->active) { + if (udc->gadget.speed != USB_SPEED_UNKNOWN) { + DMSG("disconnect %s\n", udc->driver + ? udc->driver->driver.name + : "(no driver)"); + stop_activity(udc, udc->driver); + } + udc_disable(udc); + /* Disable clock for USB device */ + clk_disable(udc->clk); + udc->active = 0; + } + } return 0; } @@ -958,9 +975,9 @@ static int pxa2xx_udc_vbus_session(struct usb_gadget *_gadget, int is_active) struct pxa2xx_udc *udc; udc = container_of(_gadget, struct pxa2xx_udc, gadget); - udc->vbus = is_active = (is_active != 0); + udc->vbus = (is_active != 0); DMSG("vbus %s\n", is_active ? "supplied" : "inactive"); - pullup(udc, is_active); + pullup(udc); return 0; } @@ -975,9 +992,8 @@ static int pxa2xx_udc_pullup(struct usb_gadget *_gadget, int is_active) if (!udc->mach->gpio_pullup && !udc->mach->udc_command) return -EOPNOTSUPP; - is_active = (is_active != 0); - udc->pullup = is_active; - pullup(udc, is_active); + udc->pullup = (is_active != 0); + pullup(udc); return 0; } @@ -997,7 +1013,7 @@ static const struct usb_gadget_ops pxa2xx_udc_ops = { #ifdef CONFIG_USB_GADGET_DEBUG_FS static int -udc_seq_show(struct seq_file *m, void *d) +udc_seq_show(struct seq_file *m, void *_d) { struct pxa2xx_udc *dev = m->private; unsigned long flags; @@ -1146,11 +1162,6 @@ static void udc_disable(struct pxa2xx_udc *dev) udc_clear_mask_UDCCR(UDCCR_UDE); -#ifdef CONFIG_ARCH_PXA - /* Disable clock for USB device */ - clk_disable(dev->clk); -#endif - ep0_idle (dev); dev->gadget.speed = USB_SPEED_UNKNOWN; } @@ -1191,11 +1202,6 @@ static void udc_enable (struct pxa2xx_udc *dev) { udc_clear_mask_UDCCR(UDCCR_UDE); -#ifdef CONFIG_ARCH_PXA - /* Enable clock for USB device */ - clk_enable(dev->clk); -#endif - /* try to clear these bits before we enable the udc */ udc_ack_int_UDCCR(UDCCR_SUSIR|/*UDCCR_RSTIR|*/UDCCR_RESIR); @@ -1286,7 +1292,7 @@ fail: * for set_configuration as well as eventual disconnect. */ DMSG("registered gadget driver '%s'\n", driver->driver.name); - pullup(dev, 1); + pullup(dev); dump_state(dev); return 0; } @@ -1329,7 +1335,8 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver) return -EINVAL; local_irq_disable(); - pullup(dev, 0); + dev->pullup = 0; + pullup(dev); stop_activity(dev, driver); local_irq_enable(); @@ -2131,13 +2138,11 @@ static int __init pxa2xx_udc_probe(struct platform_device *pdev) if (irq < 0) return -ENODEV; -#ifdef CONFIG_ARCH_PXA dev->clk = clk_get(&pdev->dev, "UDCCLK"); if (IS_ERR(dev->clk)) { retval = PTR_ERR(dev->clk); goto err_clk; } -#endif pr_debug("%s: IRQ %d%s%s\n", driver_name, irq, dev->has_cfr ? "" : " (!cfr)", @@ -2250,10 +2255,8 @@ lubbock_fail0: if (dev->mach->gpio_vbus) gpio_free(dev->mach->gpio_vbus); err_gpio_vbus: -#ifdef CONFIG_ARCH_PXA clk_put(dev->clk); err_clk: -#endif return retval; } @@ -2269,7 +2272,9 @@ static int __exit pxa2xx_udc_remove(struct platform_device *pdev) if (dev->driver) return -EBUSY; - udc_disable(dev); + dev->pullup = 0; + pullup(dev); + remove_debug_files(dev); if (dev->got_irq) { @@ -2289,9 +2294,7 @@ static int __exit pxa2xx_udc_remove(struct platform_device *pdev) if (dev->mach->gpio_pullup) gpio_free(dev->mach->gpio_pullup); -#ifdef CONFIG_ARCH_PXA clk_put(dev->clk); -#endif platform_set_drvdata(pdev, NULL); the_controller = NULL; @@ -2317,10 +2320,15 @@ static int __exit pxa2xx_udc_remove(struct platform_device *pdev) static int pxa2xx_udc_suspend(struct platform_device *dev, pm_message_t state) { struct pxa2xx_udc *udc = platform_get_drvdata(dev); + unsigned long flags; if (!udc->mach->gpio_pullup && !udc->mach->udc_command) WARN("USB host won't detect disconnect!\n"); - pullup(udc, 0); + udc->suspended = 1; + + local_irq_save(flags); + pullup(udc); + local_irq_restore(flags); return 0; } @@ -2328,8 +2336,12 @@ static int pxa2xx_udc_suspend(struct platform_device *dev, pm_message_t state) static int pxa2xx_udc_resume(struct platform_device *dev) { struct pxa2xx_udc *udc = platform_get_drvdata(dev); + unsigned long flags; - pullup(udc, 1); + udc->suspended = 0; + local_irq_save(flags); + pullup(udc); + local_irq_restore(flags); return 0; } diff --git a/drivers/usb/gadget/pxa2xx_udc.h b/drivers/usb/gadget/pxa2xx_udc.h index b67e3ff5e4eb5baf648b0fcceb457e7e3456af69..e2c19e88c8753b2bd745fab07d6fb8698c855489 100644 --- a/drivers/usb/gadget/pxa2xx_udc.h +++ b/drivers/usb/gadget/pxa2xx_udc.h @@ -119,7 +119,9 @@ struct pxa2xx_udc { has_cfr : 1, req_pending : 1, req_std : 1, - req_config : 1; + req_config : 1, + suspended : 1, + active : 1; #define start_watchdog(dev) mod_timer(&dev->timer, jiffies + (HZ/200)) struct timer_list timer; diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index b8ad55aff84282836425e814c2a84f93d31e7377..46ee7f4c091232f54c16de95e241e5a160ea5e67 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c @@ -281,23 +281,44 @@ static void ehci_iaa_watchdog(unsigned long param) { struct ehci_hcd *ehci = (struct ehci_hcd *) param; unsigned long flags; - u32 status, cmd; spin_lock_irqsave (&ehci->lock, flags); - WARN_ON(!ehci->reclaim); - status = ehci_readl(ehci, &ehci->regs->status); - cmd = ehci_readl(ehci, &ehci->regs->command); - ehci_dbg(ehci, "IAA watchdog: status %x cmd %x\n", status, cmd); - - /* lost IAA irqs wedge things badly; seen first with a vt8235 */ - if (ehci->reclaim) { - if (status & STS_IAA) { - ehci_vdbg (ehci, "lost IAA\n"); + /* Lost IAA irqs wedge things badly; seen first with a vt8235. + * So we need this watchdog, but must protect it against both + * (a) SMP races against real IAA firing and retriggering, and + * (b) clean HC shutdown, when IAA watchdog was pending. + */ + if (ehci->reclaim + && !timer_pending(&ehci->iaa_watchdog) + && HC_IS_RUNNING(ehci_to_hcd(ehci)->state)) { + u32 cmd, status; + + /* If we get here, IAA is *REALLY* late. It's barely + * conceivable that the system is so busy that CMD_IAAD + * is still legitimately set, so let's be sure it's + * clear before we read STS_IAA. (The HC should clear + * CMD_IAAD when it sets STS_IAA.) + */ + cmd = ehci_readl(ehci, &ehci->regs->command); + if (cmd & CMD_IAAD) + ehci_writel(ehci, cmd & ~CMD_IAAD, + &ehci->regs->command); + + /* If IAA is set here it either legitimately triggered + * before we cleared IAAD above (but _way_ late, so we'll + * still count it as lost) ... or a silicon erratum: + * - VIA seems to set IAA without triggering the IRQ; + * - IAAD potentially cleared without setting IAA. + */ + status = ehci_readl(ehci, &ehci->regs->status); + if ((status & STS_IAA) || !(cmd & CMD_IAAD)) { COUNT (ehci->stats.lost_iaa); ehci_writel(ehci, STS_IAA, &ehci->regs->status); } - ehci_writel(ehci, cmd & ~CMD_IAAD, &ehci->regs->command); + + ehci_vdbg(ehci, "IAA watchdog: status %x cmd %x\n", + status, cmd); end_unlink_async(ehci); } @@ -631,7 +652,7 @@ static int ehci_run (struct usb_hcd *hcd) static irqreturn_t ehci_irq (struct usb_hcd *hcd) { struct ehci_hcd *ehci = hcd_to_ehci (hcd); - u32 status, pcd_status = 0; + u32 status, pcd_status = 0, cmd; int bh; spin_lock (&ehci->lock); @@ -652,7 +673,7 @@ static irqreturn_t ehci_irq (struct usb_hcd *hcd) /* clear (just) interrupts */ ehci_writel(ehci, status, &ehci->regs->status); - ehci_readl(ehci, &ehci->regs->command); /* unblock posted write */ + cmd = ehci_readl(ehci, &ehci->regs->command); bh = 0; #ifdef EHCI_VERBOSE_DEBUG @@ -673,8 +694,17 @@ static irqreturn_t ehci_irq (struct usb_hcd *hcd) /* complete the unlinking of some qh [4.15.2.3] */ if (status & STS_IAA) { - COUNT (ehci->stats.reclaim); - end_unlink_async(ehci); + /* guard against (alleged) silicon errata */ + if (cmd & CMD_IAAD) { + ehci_writel(ehci, cmd & ~CMD_IAAD, + &ehci->regs->command); + ehci_dbg(ehci, "IAA with IAAD still set?\n"); + } + if (ehci->reclaim) { + COUNT(ehci->stats.reclaim); + end_unlink_async(ehci); + } else + ehci_dbg(ehci, "IAA with nothing to reclaim?\n"); } /* remote wakeup [4.3.1] */ @@ -781,7 +811,7 @@ static int ehci_urb_enqueue ( static void unlink_async (struct ehci_hcd *ehci, struct ehci_qh *qh) { /* failfast */ - if (!HC_IS_RUNNING(ehci_to_hcd(ehci)->state)) + if (!HC_IS_RUNNING(ehci_to_hcd(ehci)->state) && ehci->reclaim) end_unlink_async(ehci); /* if it's not linked then there's nothing to do */ diff --git a/drivers/usb/host/ehci-q.c b/drivers/usb/host/ehci-q.c index 776a97f33914e05511bc85dcdced2b4febe6a89b..2e49de820b1494b054dfc5c4cd92ad75c5aad2ef 100644 --- a/drivers/usb/host/ehci-q.c +++ b/drivers/usb/host/ehci-q.c @@ -319,10 +319,10 @@ qh_completions (struct ehci_hcd *ehci, struct ehci_qh *qh) if (likely (last->urb != urb)) { ehci_urb_done(ehci, last->urb, last_status); count++; + last_status = -EINPROGRESS; } ehci_qtd_free (ehci, last); last = NULL; - last_status = -EINPROGRESS; } /* ignore urbs submitted during completions we reported */ diff --git a/drivers/usb/host/isp116x-hcd.c b/drivers/usb/host/isp116x-hcd.c index 0130fd8571e4018549db9a5003bd432b72645878..d7071c85575876552841c4bff7397cd8c43bbcb1 100644 --- a/drivers/usb/host/isp116x-hcd.c +++ b/drivers/usb/host/isp116x-hcd.c @@ -911,8 +911,7 @@ static int isp116x_hub_status_data(struct usb_hcd *hcd, char *buf) buf[0] = 0; for (i = 0; i < ports; i++) { - u32 status = isp116x->rhport[i] = - isp116x_read_reg32(isp116x, i ? HCRHPORT2 : HCRHPORT1); + u32 status = isp116x_read_reg32(isp116x, i ? HCRHPORT2 : HCRHPORT1); if (status & (RH_PS_CSC | RH_PS_PESC | RH_PS_PSSC | RH_PS_OCIC | RH_PS_PRSC)) { @@ -1031,7 +1030,9 @@ static int isp116x_hub_control(struct usb_hcd *hcd, DBG("GetPortStatus\n"); if (!wIndex || wIndex > ports) goto error; - tmp = isp116x->rhport[--wIndex]; + spin_lock_irqsave(&isp116x->lock, flags); + tmp = isp116x_read_reg32(isp116x, (--wIndex) ? HCRHPORT2 : HCRHPORT1); + spin_unlock_irqrestore(&isp116x->lock, flags); *(__le32 *) buf = cpu_to_le32(tmp); DBG("GetPortStatus: port[%d] %08x\n", wIndex + 1, tmp); break; @@ -1080,8 +1081,6 @@ static int isp116x_hub_control(struct usb_hcd *hcd, spin_lock_irqsave(&isp116x->lock, flags); isp116x_write_reg32(isp116x, wIndex ? HCRHPORT2 : HCRHPORT1, tmp); - isp116x->rhport[wIndex] = - isp116x_read_reg32(isp116x, wIndex ? HCRHPORT2 : HCRHPORT1); spin_unlock_irqrestore(&isp116x->lock, flags); break; case SetPortFeature: @@ -1095,24 +1094,22 @@ static int isp116x_hub_control(struct usb_hcd *hcd, spin_lock_irqsave(&isp116x->lock, flags); isp116x_write_reg32(isp116x, wIndex ? HCRHPORT2 : HCRHPORT1, RH_PS_PSS); + spin_unlock_irqrestore(&isp116x->lock, flags); break; case USB_PORT_FEAT_POWER: DBG("USB_PORT_FEAT_POWER\n"); spin_lock_irqsave(&isp116x->lock, flags); isp116x_write_reg32(isp116x, wIndex ? HCRHPORT2 : HCRHPORT1, RH_PS_PPS); + spin_unlock_irqrestore(&isp116x->lock, flags); break; case USB_PORT_FEAT_RESET: DBG("USB_PORT_FEAT_RESET\n"); root_port_reset(isp116x, wIndex); - spin_lock_irqsave(&isp116x->lock, flags); break; default: goto error; } - isp116x->rhport[wIndex] = - isp116x_read_reg32(isp116x, wIndex ? HCRHPORT2 : HCRHPORT1); - spin_unlock_irqrestore(&isp116x->lock, flags); break; default: diff --git a/drivers/usb/host/isp116x.h b/drivers/usb/host/isp116x.h index b91e2edd9c5c1415ebecfe7aa056cddcb15c4fc6..595b90a9984880c819011ad4e181a223d8d6d50b 100644 --- a/drivers/usb/host/isp116x.h +++ b/drivers/usb/host/isp116x.h @@ -270,7 +270,6 @@ struct isp116x { u32 rhdesca; u32 rhdescb; u32 rhstatus; - u32 rhport[2]; /* async schedule: control, bulk */ struct list_head async; diff --git a/drivers/usb/serial/cypress_m8.c b/drivers/usb/serial/cypress_m8.c index 08c65c1a377163ded8eaf7f861674250852bcc6c..779d07851a4d820a4e32c372ed2e745798c82a27 100644 --- a/drivers/usb/serial/cypress_m8.c +++ b/drivers/usb/serial/cypress_m8.c @@ -94,6 +94,7 @@ static struct usb_device_id id_table_earthmate [] = { static struct usb_device_id id_table_cyphidcomrs232 [] = { { USB_DEVICE(VENDOR_ID_CYPRESS, PRODUCT_ID_CYPHIDCOM) }, + { USB_DEVICE(VENDOR_ID_POWERCOM, PRODUCT_ID_UPS) }, { } /* Terminating entry */ }; @@ -106,6 +107,7 @@ static struct usb_device_id id_table_combined [] = { { USB_DEVICE(VENDOR_ID_DELORME, PRODUCT_ID_EARTHMATEUSB) }, { USB_DEVICE(VENDOR_ID_DELORME, PRODUCT_ID_EARTHMATEUSB_LT20) }, { USB_DEVICE(VENDOR_ID_CYPRESS, PRODUCT_ID_CYPHIDCOM) }, + { USB_DEVICE(VENDOR_ID_POWERCOM, PRODUCT_ID_UPS) }, { USB_DEVICE(VENDOR_ID_DAZZLE, PRODUCT_ID_CA42) }, { } /* Terminating entry */ }; diff --git a/drivers/usb/serial/cypress_m8.h b/drivers/usb/serial/cypress_m8.h index e1c7c27e18b7d1551f18e97a79d5afaa75667315..0388065bb79451997f35edbdc7cd52f004d683ea 100644 --- a/drivers/usb/serial/cypress_m8.h +++ b/drivers/usb/serial/cypress_m8.h @@ -19,6 +19,10 @@ #define VENDOR_ID_CYPRESS 0x04b4 #define PRODUCT_ID_CYPHIDCOM 0x5500 +/* Powercom UPS, chip CY7C63723 */ +#define VENDOR_ID_POWERCOM 0x0d9f +#define PRODUCT_ID_UPS 0x0002 + /* Nokia CA-42 USB to serial cable */ #define VENDOR_ID_DAZZLE 0x07d0 #define PRODUCT_ID_CA42 0x4101 diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index 76db2fef4657d076b2e35b5285882308dd173659..3abb3c863647832a31937fb3363f415f4a344ed9 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c @@ -92,6 +92,7 @@ struct ftdi_sio_quirk { }; static int ftdi_jtag_probe (struct usb_serial *serial); +static int ftdi_mtxorb_hack_setup (struct usb_serial *serial); static void ftdi_USB_UIRT_setup (struct ftdi_private *priv); static void ftdi_HE_TIRA1_setup (struct ftdi_private *priv); @@ -99,6 +100,10 @@ static struct ftdi_sio_quirk ftdi_jtag_quirk = { .probe = ftdi_jtag_probe, }; +static struct ftdi_sio_quirk ftdi_mtxorb_hack_quirk = { + .probe = ftdi_mtxorb_hack_setup, +}; + static struct ftdi_sio_quirk ftdi_USB_UIRT_quirk = { .port_probe = ftdi_USB_UIRT_setup, }; @@ -161,6 +166,8 @@ static struct usb_device_id id_table_combined [] = { { USB_DEVICE(FTDI_VID, FTDI_MTXORB_4_PID) }, { USB_DEVICE(FTDI_VID, FTDI_MTXORB_5_PID) }, { USB_DEVICE(FTDI_VID, FTDI_MTXORB_6_PID) }, + { USB_DEVICE(MTXORB_VK_VID, MTXORB_VK_PID), + .driver_info = (kernel_ulong_t)&ftdi_mtxorb_hack_quirk }, { USB_DEVICE(FTDI_VID, FTDI_PERLE_ULTRAPORT_PID) }, { USB_DEVICE(FTDI_VID, FTDI_PIEGROUP_PID) }, { USB_DEVICE(FTDI_VID, FTDI_TNC_X_PID) }, @@ -274,6 +281,7 @@ static struct usb_device_id id_table_combined [] = { { USB_DEVICE(FTDI_VID, FTDI_ELV_FS20SIG_PID) }, { USB_DEVICE(FTDI_VID, FTDI_ELV_WS300PC_PID) }, { USB_DEVICE(FTDI_VID, FTDI_ELV_FHZ1300PC_PID) }, + { USB_DEVICE(FTDI_VID, FTDI_ELV_EM1010PC_PID) }, { USB_DEVICE(FTDI_VID, FTDI_ELV_WS500_PID) }, { USB_DEVICE(FTDI_VID, LINX_SDMUSBQSS_PID) }, { USB_DEVICE(FTDI_VID, LINX_MASTERDEVEL2_PID) }, @@ -351,6 +359,7 @@ static struct usb_device_id id_table_combined [] = { { USB_DEVICE(FTDI_VID, FTDI_MAXSTREAM_PID) }, { USB_DEVICE(TML_VID, TML_USB_SERIAL_PID) }, { USB_DEVICE(FTDI_VID, FTDI_ELSTER_UNICOM_PID) }, + { USB_DEVICE(FTDI_VID, FTDI_PROPOX_JTAGCABLEII_PID) }, { USB_DEVICE(OLIMEX_VID, OLIMEX_ARM_USB_OCD_PID), .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, { USB_DEVICE(FIC_VID, FIC_NEO1973_DEBUG_PID), @@ -1088,6 +1097,23 @@ static int ftdi_jtag_probe(struct usb_serial *serial) return 0; } +/* + * The Matrix Orbital VK204-25-USB has an invalid IN endpoint. + * We have to correct it if we want to read from it. + */ +static int ftdi_mtxorb_hack_setup(struct usb_serial *serial) +{ + struct usb_host_endpoint *ep = serial->dev->ep_in[1]; + struct usb_endpoint_descriptor *ep_desc = &ep->desc; + + if (ep->enabled && ep_desc->wMaxPacketSize == 0) { + ep_desc->wMaxPacketSize = 0x40; + info("Fixing invalid wMaxPacketSize on read pipe"); + } + + return 0; +} + /* ftdi_shutdown is called from usbserial:usb_serial_disconnect * it is called when the usb device is disconnected * diff --git a/drivers/usb/serial/ftdi_sio.h b/drivers/usb/serial/ftdi_sio.h index 6eee2ab914eca092d1d3b53dc92b30ee294605d1..6da539ede0ee992185ccb4b789b28f485bc39024 100644 --- a/drivers/usb/serial/ftdi_sio.h +++ b/drivers/usb/serial/ftdi_sio.h @@ -102,6 +102,13 @@ * (http://www.joernonline.de/dw/doku.php?id=start&idx=projects:oocdlink) */ #define FTDI_OOCDLINK_PID 0xbaf8 /* Amontec JTAGkey */ +/* + * The following are the values for the Matrix Orbital VK204-25-USB + * display, which use the FT232RL. + */ +#define MTXORB_VK_VID 0x1b3d +#define MTXORB_VK_PID 0x0158 + /* Interbiometrics USB I/O Board */ /* Developed for Interbiometrics by Rudolf Gugler */ #define INTERBIOMETRICS_VID 0x1209 @@ -550,6 +557,9 @@ #define TML_VID 0x1B91 /* Vendor ID */ #define TML_USB_SERIAL_PID 0x0064 /* USB - Serial Converter */ +/* Propox devices */ +#define FTDI_PROPOX_JTAGCABLEII_PID 0xD738 + /* Commands */ #define FTDI_SIO_RESET 0 /* Reset the port */ #define FTDI_SIO_MODEM_CTRL 1 /* Set the modem control register */ diff --git a/drivers/usb/serial/generic.c b/drivers/usb/serial/generic.c index 97fa3c4284350ab24a32cc9d46d69bc4e4fe39e2..7cfce9dabb9001c0f68bc68503c87e5bd07ed82a 100644 --- a/drivers/usb/serial/generic.c +++ b/drivers/usb/serial/generic.c @@ -323,7 +323,7 @@ static void flush_and_resubmit_read_urb (struct usb_serial_port *port) room = tty_buffer_request_room(tty, urb->actual_length); if (room) { tty_insert_flip_string(tty, urb->transfer_buffer, room); - tty_flip_buffer_push(tty); /* is this allowed from an URB callback ? */ + tty_flip_buffer_push(tty); } } @@ -349,10 +349,12 @@ void usb_serial_generic_read_bulk_callback (struct urb *urb) /* Throttle the device if requested by tty */ spin_lock_irqsave(&port->lock, flags); - if (!(port->throttled = port->throttle_req)) - /* Handle data and continue reading from device */ + if (!(port->throttled = port->throttle_req)) { + spin_unlock_irqrestore(&port->lock, flags); flush_and_resubmit_read_urb(port); - spin_unlock_irqrestore(&port->lock, flags); + } else { + spin_unlock_irqrestore(&port->lock, flags); + } } EXPORT_SYMBOL_GPL(usb_serial_generic_read_bulk_callback); diff --git a/drivers/usb/serial/mos7840.c b/drivers/usb/serial/mos7840.c index 869ecd374cb49e8161b765d23791604c3aff6256..aeeb9cb209994d5a2f0a17c925509605c84d1184 100644 --- a/drivers/usb/serial/mos7840.c +++ b/drivers/usb/serial/mos7840.c @@ -110,11 +110,20 @@ /* vendor id and device id defines */ +/* The native mos7840/7820 component */ #define USB_VENDOR_ID_MOSCHIP 0x9710 #define MOSCHIP_DEVICE_ID_7840 0x7840 #define MOSCHIP_DEVICE_ID_7820 0x7820 +/* The native component can have its vendor/device id's overridden + * in vendor-specific implementations. Such devices can be handled + * by making a change here, in moschip_port_id_table, and in + * moschip_id_table_combined + */ +#define USB_VENDOR_ID_BANDB 0x0856 +#define BANDB_DEVICE_ID_USOPTL4_4 0xAC44 +#define BANDB_DEVICE_ID_USOPTL4_2 0xAC42 -/* Interrupt Rotinue Defines */ +/* Interrupt Routine Defines */ #define SERIAL_IIR_RLS 0x06 #define SERIAL_IIR_MS 0x00 @@ -159,12 +168,16 @@ static struct usb_device_id moschip_port_id_table[] = { {USB_DEVICE(USB_VENDOR_ID_MOSCHIP, MOSCHIP_DEVICE_ID_7840)}, {USB_DEVICE(USB_VENDOR_ID_MOSCHIP, MOSCHIP_DEVICE_ID_7820)}, + {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USOPTL4_4)}, + {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USOPTL4_2)}, {} /* terminating entry */ }; static __devinitdata struct usb_device_id moschip_id_table_combined[] = { {USB_DEVICE(USB_VENDOR_ID_MOSCHIP, MOSCHIP_DEVICE_ID_7840)}, {USB_DEVICE(USB_VENDOR_ID_MOSCHIP, MOSCHIP_DEVICE_ID_7820)}, + {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USOPTL4_4)}, + {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USOPTL4_2)}, {} /* terminating entry */ }; diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index af2674c57414c0acde52258f97dcf795f8215cf8..a396fbbdc9c2cf13fc26f5e6e8390bd0eb625444 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c @@ -111,6 +111,42 @@ static int option_send_setup(struct usb_serial_port *port); #define HUAWEI_PRODUCT_E220BIS 0x1004 #define NOVATELWIRELESS_VENDOR_ID 0x1410 + +/* MERLIN EVDO PRODUCTS */ +#define NOVATELWIRELESS_PRODUCT_V640 0x1100 +#define NOVATELWIRELESS_PRODUCT_V620 0x1110 +#define NOVATELWIRELESS_PRODUCT_V740 0x1120 +#define NOVATELWIRELESS_PRODUCT_V720 0x1130 + +/* MERLIN HSDPA/HSPA PRODUCTS */ +#define NOVATELWIRELESS_PRODUCT_U730 0x1400 +#define NOVATELWIRELESS_PRODUCT_U740 0x1410 +#define NOVATELWIRELESS_PRODUCT_U870 0x1420 +#define NOVATELWIRELESS_PRODUCT_XU870 0x1430 +#define NOVATELWIRELESS_PRODUCT_X950D 0x1450 + +/* EXPEDITE PRODUCTS */ +#define NOVATELWIRELESS_PRODUCT_EV620 0x2100 +#define NOVATELWIRELESS_PRODUCT_ES720 0x2110 +#define NOVATELWIRELESS_PRODUCT_E725 0x2120 +#define NOVATELWIRELESS_PRODUCT_EU730 0x2400 +#define NOVATELWIRELESS_PRODUCT_EU740 0x2410 +#define NOVATELWIRELESS_PRODUCT_EU870D 0x2420 + +/* OVATION PRODUCTS */ +#define NOVATELWIRELESS_PRODUCT_MC727 0x4100 +#define NOVATELWIRELESS_PRODUCT_MC950D 0x4400 + +/* FUTURE NOVATEL PRODUCTS */ +#define NOVATELWIRELESS_PRODUCT_EVDO_1 0x6000 +#define NOVATELWIRELESS_PRODUCT_HSPA_1 0x7000 +#define NOVATELWIRELESS_PRODUCT_EMBEDDED_1 0x8000 +#define NOVATELWIRELESS_PRODUCT_GLOBAL_1 0x9000 +#define NOVATELWIRELESS_PRODUCT_EVDO_2 0x6001 +#define NOVATELWIRELESS_PRODUCT_HSPA_2 0x7001 +#define NOVATELWIRELESS_PRODUCT_EMBEDDED_2 0x8001 +#define NOVATELWIRELESS_PRODUCT_GLOBAL_2 0x9001 + #define DELL_VENDOR_ID 0x413C #define KYOCERA_VENDOR_ID 0x0c88 @@ -120,6 +156,9 @@ static int option_send_setup(struct usb_serial_port *port); #define ANYDATA_PRODUCT_ADU_E100A 0x6501 #define ANYDATA_PRODUCT_ADU_500A 0x6502 +#define AXESSTEL_VENDOR_ID 0x1726 +#define AXESSTEL_PRODUCT_MV110H 0x1000 + #define BANDRICH_VENDOR_ID 0x1A8D #define BANDRICH_PRODUCT_C100_1 0x1002 #define BANDRICH_PRODUCT_C100_2 0x1003 @@ -165,21 +204,34 @@ static struct usb_device_id option_ids[] = { { USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E600) }, { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E220, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E220BIS, 0xff, 0xff, 0xff) }, - { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, 0x1100) }, /* Novatel Merlin XS620/S640 */ - { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, 0x1110) }, /* Novatel Merlin S620 */ - { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, 0x1120) }, /* Novatel Merlin EX720 */ - { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, 0x1130) }, /* Novatel Merlin S720 */ - { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, 0x1400) }, /* Novatel U730 */ - { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, 0x1410) }, /* Novatel U740 */ - { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, 0x1420) }, /* Novatel EU870 */ - { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, 0x1430) }, /* Novatel Merlin XU870 HSDPA/3G */ - { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, 0x2100) }, /* Novatel EV620 CDMA/EV-DO */ - { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, 0x2110) }, /* Novatel Merlin ES620 / Merlin ES720 / Ovation U720 */ + { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_V640) }, /* Novatel Merlin V640/XV620 */ + { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_V620) }, /* Novatel Merlin V620/S620 */ + { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_V740) }, /* Novatel Merlin EX720/V740/X720 */ + { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_V720) }, /* Novatel Merlin V720/S720/PC720 */ + { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_U730) }, /* Novatel U730/U740 (VF version) */ + { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_U740) }, /* Novatel U740 */ + { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_U870) }, /* Novatel U870 */ + { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_XU870) }, /* Novatel Merlin XU870 HSDPA/3G */ + { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_X950D) }, /* Novatel X950D */ + { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EV620) }, /* Novatel EV620/ES620 CDMA/EV-DO */ + { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_ES720) }, /* Novatel ES620/ES720/U720/USB720 */ + { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_E725) }, /* Novatel E725/E726 */ { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, 0x2130) }, /* Novatel Merlin ES620 SM Bus */ - { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, 0x2410) }, /* Novatel EU740 */ - { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, 0x4100) }, /* Novatel U727 */ - { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, 0x4400) }, /* Novatel MC950 */ + { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EU730) }, /* Novatel EU730 and Vodafone EU740 */ + { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EU740) }, /* Novatel non-Vodafone EU740 */ + { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EU870D) }, /* Novatel EU850D/EU860D/EU870D */ + { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_MC950D) }, /* Novatel MC930D/MC950D */ + { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_MC727) }, /* Novatel MC727/U727/USB727 */ { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, 0x5010) }, /* Novatel U727 */ + { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EVDO_1) }, /* Novatel EVDO product */ + { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_HSPA_1) }, /* Novatel HSPA product */ + { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EMBEDDED_1) }, /* Novatel Embedded product */ + { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_GLOBAL_1) }, /* Novatel Global product */ + { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EVDO_2) }, /* Novatel EVDO product */ + { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_HSPA_2) }, /* Novatel HSPA product */ + { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EMBEDDED_2) }, /* Novatel Embedded product */ + { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_GLOBAL_2) }, /* Novatel Global product */ + { USB_DEVICE(DELL_VENDOR_ID, 0x8114) }, /* Dell Wireless 5700 Mobile Broadband CDMA/EVDO Mini-Card == Novatel Expedite EV620 CDMA/EV-DO */ { USB_DEVICE(DELL_VENDOR_ID, 0x8115) }, /* Dell Wireless 5500 Mobile Broadband HSDPA Mini-Card == Novatel Expedite EU740 HSDPA/3G */ { USB_DEVICE(DELL_VENDOR_ID, 0x8116) }, /* Dell Wireless 5505 Mobile Broadband HSDPA Mini-Card == Novatel Expedite EU740 HSDPA/3G */ @@ -192,6 +244,7 @@ static struct usb_device_id option_ids[] = { { USB_DEVICE(DELL_VENDOR_ID, 0x8137) }, /* Dell Wireless HSDPA 5520 */ { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_E100A) }, { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_500A) }, + { USB_DEVICE(AXESSTEL_VENDOR_ID, AXESSTEL_PRODUCT_MV110H) }, { USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_C100_1) }, { USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_C100_2) }, { USB_DEVICE(KYOCERA_VENDOR_ID, KYOCERA_PRODUCT_KPC680) }, diff --git a/drivers/usb/storage/protocol.c b/drivers/usb/storage/protocol.c index 958f5b17847c57748a16a344a833a5a7f8dfe3ae..b9b8ede61fb337bf4927ef2638640bc6723d8102 100644 --- a/drivers/usb/storage/protocol.c +++ b/drivers/usb/storage/protocol.c @@ -170,7 +170,6 @@ unsigned int usb_stor_access_xfer_buf(unsigned char *buffer, if (!sg) sg = scsi_sglist(srb); - buflen = min(buflen, scsi_bufflen(srb)); /* This loop handles a single s-g list entry, which may * include multiple pages. Find the initial page structure @@ -232,6 +231,7 @@ void usb_stor_set_xfer_buf(unsigned char *buffer, unsigned int offset = 0; struct scatterlist *sg = NULL; + buflen = min(buflen, scsi_bufflen(srb)); buflen = usb_stor_access_xfer_buf(buffer, buflen, srb, &sg, &offset, TO_XFER_BUF); if (buflen < scsi_bufflen(srb)) diff --git a/drivers/usb/storage/sddr55.c b/drivers/usb/storage/sddr55.c index d43a3415e12f1d3aa105cfe0b2ff9cdd70c5c62c..6d14327c921d2e2be47cb3370ca9a2a1a349c9fb 100644 --- a/drivers/usb/storage/sddr55.c +++ b/drivers/usb/storage/sddr55.c @@ -522,8 +522,8 @@ int sddr55_reset(struct us_data *us) { static unsigned long sddr55_get_capacity(struct us_data *us) { - unsigned char manufacturerID; - unsigned char deviceID; + unsigned char uninitialized_var(manufacturerID); + unsigned char uninitialized_var(deviceID); int result; struct sddr55_card_info *info = (struct sddr55_card_info *)us->extra; diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig index 758435f8a6f8cb32f4e7413ad0eeafa7d4b74239..e0b0580705e40c70ae8bd679c2be068bed73f97a 100644 --- a/drivers/video/Kconfig +++ b/drivers/video/Kconfig @@ -553,6 +553,19 @@ config FB_BF54X_LQ043 help This is the framebuffer device driver for a SHARP LQ043T1DG01 TFT LCD +config FB_BFIN_T350MCQB + tristate "Varitronix COG-T350MCQB TFT LCD display (BF527 EZKIT)" + depends on FB && BLACKFIN + select BFIN_GPTIMERS + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + help + This is the framebuffer device driver for a Varitronix VL-PS-COG-T350MCQB-01 display TFT LCD + This display is a QVGA 320x240 24-bit RGB display interfaced by an 8-bit wide PPI + It uses PPI[0..7] PPI_FS1, PPI_FS2 and PPI_CLK. + + config FB_STI tristate "HP STI frame buffer device support" depends on FB && PARISC diff --git a/drivers/video/Makefile b/drivers/video/Makefile index 83e02b3429b64e5da5941301612da65806f73df4..03371c789039530bf4bb49cda8481c61e508dc83 100644 --- a/drivers/video/Makefile +++ b/drivers/video/Makefile @@ -122,6 +122,7 @@ obj-$(CONFIG_FB_EFI) += efifb.o obj-$(CONFIG_FB_VGA16) += vga16fb.o obj-$(CONFIG_FB_OF) += offb.o obj-$(CONFIG_FB_BF54X_LQ043) += bf54x-lq043fb.o +obj-$(CONFIG_FB_BFIN_T350MCQB) += bfin-t350mcqb-fb.o # the test framebuffer is last obj-$(CONFIG_FB_VIRTUAL) += vfb.o diff --git a/drivers/video/bf54x-lq043fb.c b/drivers/video/bf54x-lq043fb.c index 0ce791e6f79cee17b7c16072042d6b5d5b26206c..986a550c043926a3d867728f1f824a220cd4b5e1 100644 --- a/drivers/video/bf54x-lq043fb.c +++ b/drivers/video/bf54x-lq043fb.c @@ -8,7 +8,7 @@ * * * Modified: - * Copyright 2004-2007 Analog Devices Inc. + * Copyright 2007-2008 Analog Devices Inc. * * Bugs: Enter bugs at http://blackfin.uclinux.org/ * @@ -241,7 +241,7 @@ static int request_ports(struct bfin_bf54xfb_info *fbi) u16 eppi_req_18[] = EPPI0_18; u16 disp = fbi->mach_info->disp; - if (gpio_request(disp, NULL)) { + if (gpio_request(disp, DRIVER_NAME)) { printk(KERN_ERR "Requesting GPIO %d faild\n", disp); return -EFAULT; } @@ -672,7 +672,7 @@ static int __init bfin_bf54x_probe(struct platform_device *pdev) &bfin_lq043fb_bl_ops); bl_dev->props.max_brightness = 255; - lcd_dev = lcd_device_register(DRIVER_NAME, NULL, &bfin_lcd_ops); + lcd_dev = lcd_device_register(DRIVER_NAME, &pdev->dev, NULL, &bfin_lcd_ops); lcd_dev->props.max_contrast = 255, printk(KERN_INFO "Done.\n"); #endif diff --git a/drivers/video/bfin-t350mcqb-fb.c b/drivers/video/bfin-t350mcqb-fb.c new file mode 100644 index 0000000000000000000000000000000000000000..a2bb2de9e0208ea340b7989965aadb50c0ea4630 --- /dev/null +++ b/drivers/video/bfin-t350mcqb-fb.c @@ -0,0 +1,685 @@ +/* + * File: drivers/video/bfin-t350mcqb-fb.c + * Based on: + * Author: Michael Hennerich + * + * Created: + * Description: Blackfin LCD Framebufer driver + * + * + * Modified: + * Copyright 2004-2007 Analog Devices Inc. + * + * Bugs: Enter bugs at http://blackfin.uclinux.org/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see the file COPYING, or write + * to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#define NO_BL_SUPPORT + +#define LCD_X_RES 320 /* Horizontal Resolution */ +#define LCD_Y_RES 240 /* Vertical Resolution */ +#define LCD_BPP 24 /* Bit Per Pixel */ + +#define DMA_BUS_SIZE 16 +#define LCD_CLK (12*1000*1000) /* 12MHz */ + +#define CLOCKS_PER_PIX 3 + + /* + * HS and VS timing parameters (all in number of PPI clk ticks) + */ + +#define U_LINE 1 /* Blanking Lines */ + +#define H_ACTPIX (LCD_X_RES * CLOCKS_PER_PIX) /* active horizontal pixel */ +#define H_PERIOD (408 * CLOCKS_PER_PIX) /* HS period */ +#define H_PULSE 90 /* HS pulse width */ +#define H_START 204 /* first valid pixel */ + +#define V_LINES (LCD_Y_RES + U_LINE) /* total vertical lines */ +#define V_PULSE (3 * H_PERIOD) /* VS pulse width (1-5 H_PERIODs) */ +#define V_PERIOD (H_PERIOD * V_LINES) /* VS period */ + +#define ACTIVE_VIDEO_MEM_OFFSET (U_LINE * H_ACTPIX) + +#define BFIN_LCD_NBR_PALETTE_ENTRIES 256 + +#define DRIVER_NAME "bfin-t350mcqb" +static char driver_name[] = DRIVER_NAME; + +struct bfin_t350mcqbfb_info { + struct fb_info *fb; + struct device *dev; + unsigned char *fb_buffer; /* RGB Buffer */ + dma_addr_t dma_handle; + int lq043_mmap; + int lq043_open_cnt; + int irq; + spinlock_t lock; /* lock */ +}; + +static int nocursor; +module_param(nocursor, int, 0644); +MODULE_PARM_DESC(nocursor, "cursor enable/disable"); + +#define PPI_TX_MODE 0x2 +#define PPI_XFER_TYPE_11 0xC +#define PPI_PORT_CFG_01 0x10 +#define PPI_PACK_EN 0x80 +#define PPI_POLS_1 0x8000 + +static void bfin_t350mcqb_config_ppi(struct bfin_t350mcqbfb_info *fbi) +{ + bfin_write_PPI_DELAY(H_START); + bfin_write_PPI_COUNT(H_ACTPIX-1); + bfin_write_PPI_FRAME(V_LINES); + + bfin_write_PPI_CONTROL(PPI_TX_MODE | /* output mode , PORT_DIR */ + PPI_XFER_TYPE_11 | /* sync mode XFR_TYPE */ + PPI_PORT_CFG_01 | /* two frame sync PORT_CFG */ + PPI_PACK_EN | /* packing enabled PACK_EN */ + PPI_POLS_1); /* faling edge syncs POLS */ +} + +static inline void bfin_t350mcqb_disable_ppi(void) +{ + bfin_write_PPI_CONTROL(bfin_read_PPI_CONTROL() & ~PORT_EN); +} + +static inline void bfin_t350mcqb_enable_ppi(void) +{ + bfin_write_PPI_CONTROL(bfin_read_PPI_CONTROL() | PORT_EN); +} + +static void bfin_t350mcqb_start_timers(void) +{ + unsigned long flags; + + local_irq_save(flags); + enable_gptimers(TIMER1bit); + enable_gptimers(TIMER0bit); + local_irq_restore(flags); +} + +static void bfin_t350mcqb_stop_timers(void) +{ + disable_gptimers(TIMER0bit | TIMER1bit); + + set_gptimer_status(0, TIMER_STATUS_TRUN0 | TIMER_STATUS_TRUN1 | + TIMER_STATUS_TIMIL0 | TIMER_STATUS_TIMIL1 | + TIMER_STATUS_TOVF0 | TIMER_STATUS_TOVF1); + +} + +static void bfin_t350mcqb_init_timers(void) +{ + + bfin_t350mcqb_stop_timers(); + + set_gptimer_period(TIMER0_id, H_PERIOD); + set_gptimer_pwidth(TIMER0_id, H_PULSE); + set_gptimer_config(TIMER0_id, TIMER_MODE_PWM | TIMER_PERIOD_CNT | + TIMER_TIN_SEL | TIMER_CLK_SEL| + TIMER_EMU_RUN); + + set_gptimer_period(TIMER1_id, V_PERIOD); + set_gptimer_pwidth(TIMER1_id, V_PULSE); + set_gptimer_config(TIMER1_id, TIMER_MODE_PWM | TIMER_PERIOD_CNT | + TIMER_TIN_SEL | TIMER_CLK_SEL | + TIMER_EMU_RUN); + +} + +static void bfin_t350mcqb_config_dma(struct bfin_t350mcqbfb_info *fbi) +{ + + set_dma_config(CH_PPI, + set_bfin_dma_config(DIR_READ, DMA_FLOW_AUTO, + INTR_DISABLE, DIMENSION_2D, + DATA_SIZE_16, + DMA_NOSYNC_KEEP_DMA_BUF)); + set_dma_x_count(CH_PPI, (LCD_X_RES * LCD_BPP) / DMA_BUS_SIZE); + set_dma_x_modify(CH_PPI, DMA_BUS_SIZE / 8); + set_dma_y_count(CH_PPI, V_LINES); + + set_dma_y_modify(CH_PPI, DMA_BUS_SIZE / 8); + set_dma_start_addr(CH_PPI, (unsigned long)fbi->fb_buffer); + +} + +static int bfin_t350mcqb_request_ports(int action) +{ + u16 ppi0_req_8[] = {P_PPI0_CLK, P_PPI0_FS1, P_PPI0_FS2, + P_PPI0_D0, P_PPI0_D1, P_PPI0_D2, + P_PPI0_D3, P_PPI0_D4, P_PPI0_D5, + P_PPI0_D6, P_PPI0_D7, 0}; + + if (action) { + if (peripheral_request_list(ppi0_req_8, DRIVER_NAME)) { + printk(KERN_ERR "Requesting Peripherals faild\n"); + return -EFAULT; + } + } else + peripheral_free_list(ppi0_req_8); + + return 0; +} + +static int bfin_t350mcqb_fb_open(struct fb_info *info, int user) +{ + struct bfin_t350mcqbfb_info *fbi = info->par; + + spin_lock(&fbi->lock); + fbi->lq043_open_cnt++; + + if (fbi->lq043_open_cnt <= 1) { + + bfin_t350mcqb_disable_ppi(); + SSYNC(); + + bfin_t350mcqb_config_dma(fbi); + bfin_t350mcqb_config_ppi(fbi); + bfin_t350mcqb_init_timers(); + + /* start dma */ + enable_dma(CH_PPI); + bfin_t350mcqb_enable_ppi(); + bfin_t350mcqb_start_timers(); + } + + spin_unlock(&fbi->lock); + + return 0; +} + +static int bfin_t350mcqb_fb_release(struct fb_info *info, int user) +{ + struct bfin_t350mcqbfb_info *fbi = info->par; + + spin_lock(&fbi->lock); + + fbi->lq043_open_cnt--; + fbi->lq043_mmap = 0; + + if (fbi->lq043_open_cnt <= 0) { + bfin_t350mcqb_disable_ppi(); + SSYNC(); + disable_dma(CH_PPI); + bfin_t350mcqb_stop_timers(); + memset(fbi->fb_buffer, 0, info->fix.smem_len); + } + + spin_unlock(&fbi->lock); + + return 0; +} + +static int bfin_t350mcqb_fb_check_var(struct fb_var_screeninfo *var, + struct fb_info *info) +{ + + if (var->bits_per_pixel != LCD_BPP) { + pr_debug("%s: depth not supported: %u BPP\n", __FUNCTION__, + var->bits_per_pixel); + return -EINVAL; + } + + if (info->var.xres != var->xres || info->var.yres != var->yres || + info->var.xres_virtual != var->xres_virtual || + info->var.yres_virtual != var->yres_virtual) { + pr_debug("%s: Resolution not supported: X%u x Y%u \n", + __FUNCTION__, var->xres, var->yres); + return -EINVAL; + } + + /* + * Memory limit + */ + + if ((info->fix.line_length * var->yres_virtual) > info->fix.smem_len) { + pr_debug("%s: Memory Limit requested yres_virtual = %u\n", + __FUNCTION__, var->yres_virtual); + return -ENOMEM; + } + + return 0; +} + +static int bfin_t350mcqb_fb_mmap(struct fb_info *info, struct vm_area_struct *vma) +{ + struct bfin_t350mcqbfb_info *fbi = info->par; + + if (fbi->lq043_mmap) + return -1; + + spin_lock(&fbi->lock); + fbi->lq043_mmap = 1; + spin_unlock(&fbi->lock); + + vma->vm_start = (unsigned long)(fbi->fb_buffer + ACTIVE_VIDEO_MEM_OFFSET); + + vma->vm_end = vma->vm_start + info->fix.smem_len; + /* For those who don't understand how mmap works, go read + * Documentation/nommu-mmap.txt. + * For those that do, you will know that the VM_MAYSHARE flag + * must be set in the vma->vm_flags structure on noMMU + * Other flags can be set, and are documented in + * include/linux/mm.h + */ + vma->vm_flags |= VM_MAYSHARE; + + return 0; +} + +int bfin_t350mcqb_fb_cursor(struct fb_info *info, struct fb_cursor *cursor) +{ + if (nocursor) + return 0; + else + return -EINVAL; /* just to force soft_cursor() call */ +} + +static int bfin_t350mcqb_fb_setcolreg(u_int regno, u_int red, u_int green, + u_int blue, u_int transp, + struct fb_info *info) +{ + if (regno >= BFIN_LCD_NBR_PALETTE_ENTRIES) + return -EINVAL; + + if (info->var.grayscale) { + /* grayscale = 0.30*R + 0.59*G + 0.11*B */ + red = green = blue = (red * 77 + green * 151 + blue * 28) >> 8; + } + + if (info->fix.visual == FB_VISUAL_TRUECOLOR) { + + u32 value; + /* Place color in the pseudopalette */ + if (regno > 16) + return -EINVAL; + + red >>= (16 - info->var.red.length); + green >>= (16 - info->var.green.length); + blue >>= (16 - info->var.blue.length); + + value = (red << info->var.red.offset) | + (green << info->var.green.offset) | + (blue << info->var.blue.offset); + value &= 0xFFFFFF; + + ((u32 *) (info->pseudo_palette))[regno] = value; + + } + + return 0; +} + +static struct fb_ops bfin_t350mcqb_fb_ops = { + .owner = THIS_MODULE, + .fb_open = bfin_t350mcqb_fb_open, + .fb_release = bfin_t350mcqb_fb_release, + .fb_check_var = bfin_t350mcqb_fb_check_var, + .fb_fillrect = cfb_fillrect, + .fb_copyarea = cfb_copyarea, + .fb_imageblit = cfb_imageblit, + .fb_mmap = bfin_t350mcqb_fb_mmap, + .fb_cursor = bfin_t350mcqb_fb_cursor, + .fb_setcolreg = bfin_t350mcqb_fb_setcolreg, +}; + +#ifndef NO_BL_SUPPORT +static int bl_get_brightness(struct backlight_device *bd) +{ + return 0; +} + +static struct backlight_ops bfin_lq043fb_bl_ops = { + .get_brightness = bl_get_brightness, +}; + +static struct backlight_device *bl_dev; + +static int bfin_lcd_get_power(struct lcd_device *dev) +{ + return 0; +} + +static int bfin_lcd_set_power(struct lcd_device *dev, int power) +{ + return 0; +} + +static int bfin_lcd_get_contrast(struct lcd_device *dev) +{ + return 0; +} + +static int bfin_lcd_set_contrast(struct lcd_device *dev, int contrast) +{ + + return 0; +} + +static int bfin_lcd_check_fb(struct fb_info *fi) +{ + if (!fi || (fi == &bfin_t350mcqb_fb)) + return 1; + return 0; +} + +static struct lcd_ops bfin_lcd_ops = { + .get_power = bfin_lcd_get_power, + .set_power = bfin_lcd_set_power, + .get_contrast = bfin_lcd_get_contrast, + .set_contrast = bfin_lcd_set_contrast, + .check_fb = bfin_lcd_check_fb, +}; + +static struct lcd_device *lcd_dev; +#endif + +static irqreturn_t bfin_t350mcqb_irq_error(int irq, void *dev_id) +{ + /*struct bfin_t350mcqbfb_info *info = (struct bfin_t350mcqbfb_info *)dev_id;*/ + + u16 status = bfin_read_PPI_STATUS(); + bfin_write_PPI_STATUS(0xFFFF); + + if (status) { + bfin_t350mcqb_disable_ppi(); + disable_dma(CH_PPI); + + /* start dma */ + enable_dma(CH_PPI); + bfin_t350mcqb_enable_ppi(); + bfin_write_PPI_STATUS(0xFFFF); + } + + return IRQ_HANDLED; +} + +static int __init bfin_t350mcqb_probe(struct platform_device *pdev) +{ + struct bfin_t350mcqbfb_info *info; + struct fb_info *fbinfo; + int ret; + + printk(KERN_INFO DRIVER_NAME ": %dx%d %d-bit RGB FrameBuffer initializing...\n", + LCD_X_RES, LCD_Y_RES, LCD_BPP); + + if (request_dma(CH_PPI, "CH_PPI") < 0) { + printk(KERN_ERR DRIVER_NAME + ": couldn't request CH_PPI DMA\n"); + ret = -EFAULT; + goto out1; + } + + fbinfo = + framebuffer_alloc(sizeof(struct bfin_t350mcqbfb_info), &pdev->dev); + if (!fbinfo) { + ret = -ENOMEM; + goto out2; + } + + info = fbinfo->par; + info->fb = fbinfo; + info->dev = &pdev->dev; + + platform_set_drvdata(pdev, fbinfo); + + strcpy(fbinfo->fix.id, driver_name); + + fbinfo->fix.type = FB_TYPE_PACKED_PIXELS; + fbinfo->fix.type_aux = 0; + fbinfo->fix.xpanstep = 0; + fbinfo->fix.ypanstep = 0; + fbinfo->fix.ywrapstep = 0; + fbinfo->fix.accel = FB_ACCEL_NONE; + fbinfo->fix.visual = FB_VISUAL_TRUECOLOR; + + fbinfo->var.nonstd = 0; + fbinfo->var.activate = FB_ACTIVATE_NOW; + fbinfo->var.height = -1; + fbinfo->var.width = -1; + fbinfo->var.accel_flags = 0; + fbinfo->var.vmode = FB_VMODE_NONINTERLACED; + + fbinfo->var.xres = LCD_X_RES; + fbinfo->var.xres_virtual = LCD_X_RES; + fbinfo->var.yres = LCD_Y_RES; + fbinfo->var.yres_virtual = LCD_Y_RES; + fbinfo->var.bits_per_pixel = LCD_BPP; + + fbinfo->var.red.offset = 0; + fbinfo->var.green.offset = 8; + fbinfo->var.blue.offset = 16; + fbinfo->var.transp.offset = 0; + fbinfo->var.red.length = 8; + fbinfo->var.green.length = 8; + fbinfo->var.blue.length = 8; + fbinfo->var.transp.length = 0; + fbinfo->fix.smem_len = LCD_X_RES * LCD_Y_RES * LCD_BPP / 8; + + fbinfo->fix.line_length = fbinfo->var.xres_virtual * + fbinfo->var.bits_per_pixel / 8; + + + fbinfo->fbops = &bfin_t350mcqb_fb_ops; + fbinfo->flags = FBINFO_FLAG_DEFAULT; + + info->fb_buffer = + dma_alloc_coherent(NULL, fbinfo->fix.smem_len, &info->dma_handle, + GFP_KERNEL); + + if (NULL == info->fb_buffer) { + printk(KERN_ERR DRIVER_NAME + ": couldn't allocate dma buffer.\n"); + ret = -ENOMEM; + goto out3; + } + + memset(info->fb_buffer, 0, fbinfo->fix.smem_len); + + fbinfo->screen_base = (void *)info->fb_buffer + ACTIVE_VIDEO_MEM_OFFSET; + fbinfo->fix.smem_start = (int)info->fb_buffer + ACTIVE_VIDEO_MEM_OFFSET; + + fbinfo->fbops = &bfin_t350mcqb_fb_ops; + + fbinfo->pseudo_palette = kmalloc(sizeof(u32) * 16, GFP_KERNEL); + if (!fbinfo->pseudo_palette) { + printk(KERN_ERR DRIVER_NAME + "Fail to allocate pseudo_palette\n"); + + ret = -ENOMEM; + goto out4; + } + + memset(fbinfo->pseudo_palette, 0, sizeof(u32) * 16); + + if (fb_alloc_cmap(&fbinfo->cmap, BFIN_LCD_NBR_PALETTE_ENTRIES, 0) + < 0) { + printk(KERN_ERR DRIVER_NAME + "Fail to allocate colormap (%d entries)\n", + BFIN_LCD_NBR_PALETTE_ENTRIES); + ret = -EFAULT; + goto out5; + } + + if (bfin_t350mcqb_request_ports(1)) { + printk(KERN_ERR DRIVER_NAME ": couldn't request gpio port.\n"); + ret = -EFAULT; + goto out6; + } + + info->irq = platform_get_irq(pdev, 0); + if (info->irq < 0) { + ret = -EINVAL; + goto out7; + } + + if (request_irq(info->irq, (void *)bfin_t350mcqb_irq_error, IRQF_DISABLED, + "PPI ERROR", info) < 0) { + printk(KERN_ERR DRIVER_NAME + ": unable to request PPI ERROR IRQ\n"); + ret = -EFAULT; + goto out7; + } + + if (register_framebuffer(fbinfo) < 0) { + printk(KERN_ERR DRIVER_NAME + ": unable to register framebuffer.\n"); + ret = -EINVAL; + goto out8; + } +#ifndef NO_BL_SUPPORT + bl_dev = + backlight_device_register("bf52x-bl", NULL, NULL, + &bfin_lq043fb_bl_ops); + bl_dev->props.max_brightness = 255; + + lcd_dev = lcd_device_register(DRIVER_NAME, NULL, &bfin_lcd_ops); + lcd_dev->props.max_contrast = 255, printk(KERN_INFO "Done.\n"); +#endif + + return 0; + +out8: + free_irq(info->irq, info); +out7: + bfin_t350mcqb_request_ports(0); +out6: + fb_dealloc_cmap(&fbinfo->cmap); +out5: + kfree(fbinfo->pseudo_palette); +out4: + dma_free_coherent(NULL, fbinfo->fix.smem_len, info->fb_buffer, + info->dma_handle); +out3: + framebuffer_release(fbinfo); +out2: + free_dma(CH_PPI); +out1: + platform_set_drvdata(pdev, NULL); + + return ret; +} + +static int bfin_t350mcqb_remove(struct platform_device *pdev) +{ + + struct fb_info *fbinfo = platform_get_drvdata(pdev); + struct bfin_t350mcqbfb_info *info = fbinfo->par; + + free_dma(CH_PPI); + free_irq(info->irq, info); + + if (info->fb_buffer != NULL) + dma_free_coherent(NULL, fbinfo->fix.smem_len, info->fb_buffer, + info->dma_handle); + + kfree(fbinfo->pseudo_palette); + fb_dealloc_cmap(&fbinfo->cmap); + +#ifndef NO_BL_SUPPORT + lcd_device_unregister(lcd_dev); + backlight_device_unregister(bl_dev); +#endif + + unregister_framebuffer(fbinfo); + + bfin_t350mcqb_request_ports(0); + + printk(KERN_INFO DRIVER_NAME ": Unregister LCD driver.\n"); + + return 0; +} + +#ifdef CONFIG_PM +static int bfin_t350mcqb_suspend(struct platform_device *pdev, pm_message_t state) +{ + struct fb_info *fbinfo = platform_get_drvdata(pdev); + struct bfin_t350mcqbfb_info *info = fbinfo->par; + + bfin_t350mcqb_disable_ppi(); + disable_dma(CH_PPI); + bfin_write_PPI_STATUS(0xFFFF); + + return 0; +} + +static int bfin_t350mcqb_resume(struct platform_device *pdev) +{ + struct fb_info *fbinfo = platform_get_drvdata(pdev); + struct bfin_t350mcqbfb_info *info = fbinfo->par; + + enable_dma(CH_PPI); + bfin_t350mcqb_enable_ppi(); + + return 0; +} +#else +#define bfin_t350mcqb_suspend NULL +#define bfin_t350mcqb_resume NULL +#endif + +static struct platform_driver bfin_t350mcqb_driver = { + .probe = bfin_t350mcqb_probe, + .remove = bfin_t350mcqb_remove, + .suspend = bfin_t350mcqb_suspend, + .resume = bfin_t350mcqb_resume, + .driver = { + .name = DRIVER_NAME, + .owner = THIS_MODULE, + }, +}; + +static int __devinit bfin_t350mcqb_driver_init(void) +{ + return platform_driver_register(&bfin_t350mcqb_driver); +} + +static void __exit bfin_t350mcqb_driver_cleanup(void) +{ + platform_driver_unregister(&bfin_t350mcqb_driver); +} + +MODULE_DESCRIPTION("Blackfin TFT LCD Driver"); +MODULE_LICENSE("GPL"); + +module_init(bfin_t350mcqb_driver_init); +module_exit(bfin_t350mcqb_driver_cleanup); diff --git a/drivers/video/hitfb.c b/drivers/video/hitfb.c index 756c0ce85911fa8d5c27b6a2254d52cac6323488..392a8be6aa76b873cd87b6d3f72ae2f3aef3b4ce 100644 --- a/drivers/video/hitfb.c +++ b/drivers/video/hitfb.c @@ -403,7 +403,7 @@ static int __init hitfb_probe(struct platform_device *dev) return 0; } -static int __devexit hitfb_remove(struct platform_device *dev) +static int __exit hitfb_remove(struct platform_device *dev) { return unregister_framebuffer(&fb_info); } @@ -439,7 +439,7 @@ static int hitfb_resume(struct platform_device *dev) static struct platform_driver hitfb_driver = { .probe = hitfb_probe, - .remove = __devexit_p(hitfb_remove), + .remove = __exit_p(hitfb_remove), #ifdef CONFIG_PM .suspend = hitfb_suspend, .resume = hitfb_resume, diff --git a/drivers/video/mbx/mbxfb.c b/drivers/video/mbx/mbxfb.c index 80cd117ca65c6118954160b1cbcd813a76871ade..01f77bcc68f9f3806488054fc9adf0a559310a2a 100644 --- a/drivers/video/mbx/mbxfb.c +++ b/drivers/video/mbx/mbxfb.c @@ -889,7 +889,7 @@ static int __devinit mbxfb_probe(struct platform_device *dev) struct mbxfb_info *mfbi; struct mbxfb_platform_data *pdata; - dev_dbg(dev, "mbxfb_probe\n"); + dev_dbg(&dev->dev, "mbxfb_probe\n"); pdata = dev->dev.platform_data; if (!pdata) { diff --git a/drivers/video/pvr2fb.c b/drivers/video/pvr2fb.c index 6a3d0b574897f5da14a6840b0dfc07926506387f..8c863a7f654bba9ce667c7942415e4fc09d9417a 100644 --- a/drivers/video/pvr2fb.c +++ b/drivers/video/pvr2fb.c @@ -1,16 +1,12 @@ -/* drivers/video/pvr2fb.c +/* + * drivers/video/pvr2fb.c * * Frame buffer and fbcon support for the NEC PowerVR2 found within the Sega * Dreamcast. * * Copyright (c) 2001 M. R. Brown - * Copyright (c) 2001, 2002, 2003, 2004, 2005 Paul Mundt - * - * This file is part of the LinuxDC project (linuxdc.sourceforge.net). + * Copyright (c) 2001 - 2008 Paul Mundt * - */ - -/* * This driver is mostly based on the excellent amifb and vfb sources. It uses * an odd scheme for converting hardware values to/from framebuffer values, * here are some hacked-up formulas: @@ -490,7 +486,7 @@ static int pvr2fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) } else { var->sync &= ~FB_SYNC_BROADCAST; var->vmode &= ~FB_VMODE_INTERLACED; - var->vmode |= pvr2_var.vmode; + var->vmode |= FB_VMODE_NONINTERLACED; } if ((var->activate & FB_ACTIVATE_MASK) != FB_ACTIVATE_TEST) { diff --git a/drivers/video/sm501fb.c b/drivers/video/sm501fb.c index e83dfba7e6361af564390dcd553dcdd6a1790ee5..742b5c656d668d447b02984d1fe4c2ba237c6743 100644 --- a/drivers/video/sm501fb.c +++ b/drivers/video/sm501fb.c @@ -237,12 +237,14 @@ static int sm501fb_check_var(struct fb_var_screeninfo *var, /* check we can fit these values into the registers */ - if (var->hsync_len > 255 || var->vsync_len > 255) + if (var->hsync_len > 255 || var->vsync_len > 63) return -EINVAL; - if ((var->xres + var->right_margin) >= 4096) + /* hdisplay end and hsync start */ + if ((var->xres + var->right_margin) > 4096) return -EINVAL; + /* vdisplay end and vsync start */ if ((var->yres + var->lower_margin) > 2048) return -EINVAL; @@ -281,19 +283,21 @@ static int sm501fb_check_var(struct fb_var_screeninfo *var, var->blue.length = var->bits_per_pixel; var->blue.offset = 0; var->transp.length = 0; + var->transp.offset = 0; break; case 16: if (sm->pdata->flags & SM501_FBPD_SWAP_FB_ENDIAN) { - var->red.offset = 11; - var->green.offset = 5; - var->blue.offset = 0; - } else { var->blue.offset = 11; var->green.offset = 5; var->red.offset = 0; + } else { + var->red.offset = 11; + var->green.offset = 5; + var->blue.offset = 0; } + var->transp.offset = 0; var->red.length = 5; var->green.length = 6; @@ -397,7 +401,7 @@ static int sm501fb_set_par_common(struct fb_info *info, break; case 16: - info->fix.visual = FB_VISUAL_DIRECTCOLOR; + info->fix.visual = FB_VISUAL_TRUECOLOR; break; case 32: @@ -613,6 +617,7 @@ static int sm501fb_set_par_crt(struct fb_info *info) case 16: control |= SM501_DC_CRT_CONTROL_16BPP; + sm501fb_setup_gamma(fbi, SM501_DC_CRT_PALETTE); break; case 32: @@ -750,6 +755,7 @@ static int sm501fb_set_par_pnl(struct fb_info *info) case 16: control |= SM501_DC_PANEL_CONTROL_16BPP; + sm501fb_setup_gamma(fbi, SM501_DC_PANEL_PALETTE); break; case 32: diff --git a/drivers/video/stifb.c b/drivers/video/stifb.c index e7c8db2eb49b31f4c3553adf72863728795a5e9f..f98be301140cdf5be7e06376dd03888ef505a192 100644 --- a/drivers/video/stifb.c +++ b/drivers/video/stifb.c @@ -505,16 +505,24 @@ ngleSetupAttrPlanes(struct stifb_info *fb, int BufferNumber) static void rattlerSetupPlanes(struct stifb_info *fb) { + int saved_id, y; + + /* Write RAMDAC pixel read mask register so all overlay + * planes are display-enabled. (CRX24 uses Bt462 pixel + * read mask register for overlay planes, not image planes). + */ CRX24_SETUP_RAMDAC(fb); - /* replacement for: SETUP_FB(fb, CRX24_OVERLAY_PLANES); */ - WRITE_WORD(0x83000300, fb, REG_14); - SETUP_HW(fb); - WRITE_BYTE(1, fb, REG_16b1); + /* change fb->id temporarily to fool SETUP_FB() */ + saved_id = fb->id; + fb->id = CRX24_OVERLAY_PLANES; + SETUP_FB(fb); + fb->id = saved_id; + + for (y = 0; y < fb->info.var.yres; ++y) + memset(fb->info.screen_base + y * fb->info.fix.line_length, + 0xff, fb->info.var.xres * fb->info.var.bits_per_pixel/8); - fb_memset((void*)fb->info.fix.smem_start, 0xff, - fb->info.var.yres*fb->info.fix.line_length); - CRX24_SET_OVLY_MASK(fb); SETUP_FB(fb); } diff --git a/drivers/video/tridentfb.c b/drivers/video/tridentfb.c index 70fb4ee2b4215d978208f5edf7693991e4ebdd5c..0a4e07d43d2d44712e66477294175801b98e38fd 100644 --- a/drivers/video/tridentfb.c +++ b/drivers/video/tridentfb.c @@ -564,7 +564,7 @@ static inline void write3CE(int reg, unsigned char val) t_outb(val, 0x3CF); } -static inline void enable_mmio(void) +static void enable_mmio(void) { /* Goto New Mode */ outb(0x0B, 0x3C4); @@ -579,6 +579,21 @@ static inline void enable_mmio(void) outb(inb(0x3D5) | 0x01, 0x3D5); } +static void disable_mmio(void) +{ + /* Goto New Mode */ + t_outb(0x0B, 0x3C4); + t_inb(0x3C5); + + /* Unprotect registers */ + t_outb(NewMode1, 0x3C4); + t_outb(0x80, 0x3C5); + + /* Disable MMIO */ + t_outb(PCIReg, 0x3D4); + t_outb(t_inb(0x3D5) & ~0x01, 0x3D5); +} + #define crtc_unlock() write3X4(CRTVSyncEnd, read3X4(CRTVSyncEnd) & 0x7F) /* Return flat panel's maximum x resolution */ @@ -730,7 +745,7 @@ static unsigned int __devinit get_memsize(void) switch (tmp) { case 0x01: - k = 512; + k = 512 * Kb; break; case 0x02: k = 6 * Mb; /* XP */ @@ -1239,9 +1254,9 @@ static int __devinit trident_pci_probe(struct pci_dev * dev, default_par.io_virt = ioremap_nocache(tridentfb_fix.mmio_start, tridentfb_fix.mmio_len); if (!default_par.io_virt) { - release_region(tridentfb_fix.mmio_start, tridentfb_fix.mmio_len); debug("ioremap failed\n"); - return -1; + err = -1; + goto out_unmap1; } enable_mmio(); @@ -1252,25 +1267,21 @@ static int __devinit trident_pci_probe(struct pci_dev * dev, if (!request_mem_region(tridentfb_fix.smem_start, tridentfb_fix.smem_len, "tridentfb")) { debug("request_mem_region failed!\n"); + disable_mmio(); err = -1; - goto out_unmap; + goto out_unmap1; } fb_info.screen_base = ioremap_nocache(tridentfb_fix.smem_start, tridentfb_fix.smem_len); if (!fb_info.screen_base) { - release_mem_region(tridentfb_fix.smem_start, tridentfb_fix.smem_len); debug("ioremap failed\n"); err = -1; - goto out_unmap; + goto out_unmap2; } output("%s board found\n", pci_name(dev)); -#if 0 - output("Trident board found : mem = %X, io = %X, mem_v = %X, io_v = %X\n", - tridentfb_fix.smem_start, tridentfb_fix.mmio_start, fb_info.screen_base, default_par.io_virt); -#endif displaytype = get_displaytype(); if (flatpanel) @@ -1288,9 +1299,12 @@ static int __devinit trident_pci_probe(struct pci_dev * dev, if (!fb_find_mode(&default_var, &fb_info, mode, NULL, 0, NULL, bpp)) { err = -EINVAL; - goto out_unmap; + goto out_unmap2; } - fb_alloc_cmap(&fb_info.cmap, 256, 0); + err = fb_alloc_cmap(&fb_info.cmap, 256, 0); + if (err < 0) + goto out_unmap2; + if (defaultaccel && acc) default_var.accel_flags |= FB_ACCELF_TEXT; else @@ -1300,19 +1314,24 @@ static int __devinit trident_pci_probe(struct pci_dev * dev, fb_info.device = &dev->dev; if (register_framebuffer(&fb_info) < 0) { printk(KERN_ERR "tridentfb: could not register Trident framebuffer\n"); + fb_dealloc_cmap(&fb_info.cmap); err = -EINVAL; - goto out_unmap; + goto out_unmap2; } output("fb%d: %s frame buffer device %dx%d-%dbpp\n", fb_info.node, fb_info.fix.id, default_var.xres, default_var.yres, default_var.bits_per_pixel); return 0; -out_unmap: - if (default_par.io_virt) - iounmap(default_par.io_virt); +out_unmap2: if (fb_info.screen_base) iounmap(fb_info.screen_base); + release_mem_region(tridentfb_fix.smem_start, tridentfb_fix.smem_len); + disable_mmio(); +out_unmap1: + if (default_par.io_virt) + iounmap(default_par.io_virt); + release_mem_region(tridentfb_fix.mmio_start, tridentfb_fix.mmio_len); return err; } @@ -1323,7 +1342,7 @@ static void __devexit trident_pci_remove(struct pci_dev *dev) iounmap(par->io_virt); iounmap(fb_info.screen_base); release_mem_region(tridentfb_fix.smem_start, tridentfb_fix.smem_len); - release_region(tridentfb_fix.mmio_start, tridentfb_fix.mmio_len); + release_mem_region(tridentfb_fix.mmio_start, tridentfb_fix.mmio_len); } /* List of boards that we are trying to support */ diff --git a/drivers/virtio/virtio_balloon.c b/drivers/virtio/virtio_balloon.c index c8a4332d1132ef465c5aa0d522787cbd255ce293..0b3efc31ee6d38620f97855a8c2d4941eea5f5b9 100644 --- a/drivers/virtio/virtio_balloon.c +++ b/drivers/virtio/virtio_balloon.c @@ -152,7 +152,7 @@ static void virtballoon_changed(struct virtio_device *vdev) wake_up(&vb->config_change); } -static inline int towards_target(struct virtio_balloon *vb) +static inline s64 towards_target(struct virtio_balloon *vb) { u32 v; __virtio_config_val(vb->vdev, @@ -176,7 +176,7 @@ static int balloon(void *_vballoon) set_freezable(); while (!kthread_should_stop()) { - int diff; + s64 diff; try_to_freeze(); wait_event_interruptible(vb->config_change, diff --git a/drivers/virtio/virtio_pci.c b/drivers/virtio/virtio_pci.c index 26f787ddd5ff58b81165d8d443bb3bda23db2586..59a8f73dec730421c3dcff6b52c0c9de59798b43 100644 --- a/drivers/virtio/virtio_pci.c +++ b/drivers/virtio/virtio_pci.c @@ -177,6 +177,7 @@ static irqreturn_t vp_interrupt(int irq, void *opaque) struct virtio_pci_device *vp_dev = opaque; struct virtio_pci_vq_info *info; irqreturn_t ret = IRQ_NONE; + unsigned long flags; u8 isr; /* reading the ISR has the effect of also clearing it so it's very @@ -197,12 +198,12 @@ static irqreturn_t vp_interrupt(int irq, void *opaque) drv->config_changed(&vp_dev->vdev); } - spin_lock(&vp_dev->lock); + spin_lock_irqsave(&vp_dev->lock, flags); list_for_each_entry(info, &vp_dev->virtqueues, node) { if (vring_interrupt(irq, info->vq) == IRQ_HANDLED) ret = IRQ_HANDLED; } - spin_unlock(&vp_dev->lock); + spin_unlock_irqrestore(&vp_dev->lock, flags); return ret; } @@ -214,6 +215,7 @@ static struct virtqueue *vp_find_vq(struct virtio_device *vdev, unsigned index, struct virtio_pci_device *vp_dev = to_vp_device(vdev); struct virtio_pci_vq_info *info; struct virtqueue *vq; + unsigned long flags; u16 num; int err; @@ -255,9 +257,9 @@ static struct virtqueue *vp_find_vq(struct virtio_device *vdev, unsigned index, vq->priv = info; info->vq = vq; - spin_lock(&vp_dev->lock); + spin_lock_irqsave(&vp_dev->lock, flags); list_add(&info->node, &vp_dev->virtqueues); - spin_unlock(&vp_dev->lock); + spin_unlock_irqrestore(&vp_dev->lock, flags); return vq; @@ -274,10 +276,11 @@ static void vp_del_vq(struct virtqueue *vq) { struct virtio_pci_device *vp_dev = to_vp_device(vq->vdev); struct virtio_pci_vq_info *info = vq->priv; + unsigned long flags; - spin_lock(&vp_dev->lock); + spin_lock_irqsave(&vp_dev->lock, flags); list_del(&info->node); - spin_unlock(&vp_dev->lock); + spin_unlock_irqrestore(&vp_dev->lock, flags); vring_del_virtqueue(vq); diff --git a/drivers/virtio/virtio_ring.c b/drivers/virtio/virtio_ring.c index 3a28c1382131d04940035448d24aada5244e7589..aa714028641e630b068f683fc67e6707d6c6a853 100644 --- a/drivers/virtio/virtio_ring.c +++ b/drivers/virtio/virtio_ring.c @@ -232,7 +232,6 @@ static bool vring_enable_cb(struct virtqueue *_vq) vq->vring.avail->flags &= ~VRING_AVAIL_F_NO_INTERRUPT; mb(); if (unlikely(more_used(vq))) { - vq->vring.avail->flags |= VRING_AVAIL_F_NO_INTERRUPT; END_USE(vq); return false; } diff --git a/drivers/w1/masters/ds1wm.c b/drivers/w1/masters/ds1wm.c index 688e435b4d9a60cb56097ee85c82ec3b662bd479..10211e493001582e0a5b27f549a4c9c00f3a6e5a 100644 --- a/drivers/w1/masters/ds1wm.c +++ b/drivers/w1/masters/ds1wm.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include @@ -102,12 +103,12 @@ struct ds1wm_data { static inline void ds1wm_write_register(struct ds1wm_data *ds1wm_data, u32 reg, u8 val) { - __raw_writeb(val, ds1wm_data->map + (reg << ds1wm_data->bus_shift)); + __raw_writeb(val, ds1wm_data->map + (reg << ds1wm_data->bus_shift)); } static inline u8 ds1wm_read_register(struct ds1wm_data *ds1wm_data, u32 reg) { - return __raw_readb(ds1wm_data->map + (reg << ds1wm_data->bus_shift)); + return __raw_readb(ds1wm_data->map + (reg << ds1wm_data->bus_shift)); } @@ -149,8 +150,8 @@ static int ds1wm_reset(struct ds1wm_data *ds1wm_data) timeleft = wait_for_completion_timeout(&reset_done, DS1WM_TIMEOUT); ds1wm_data->reset_complete = NULL; if (!timeleft) { - dev_dbg(&ds1wm_data->pdev->dev, "reset failed\n"); - return 1; + dev_err(&ds1wm_data->pdev->dev, "reset failed\n"); + return 1; } /* Wait for the end of the reset. According to the specs, the time @@ -167,11 +168,11 @@ static int ds1wm_reset(struct ds1wm_data *ds1wm_data) (ds1wm_data->active_high ? DS1WM_INTEN_IAS : 0)); if (!ds1wm_data->slave_present) { - dev_dbg(&ds1wm_data->pdev->dev, "reset: no devices found\n"); - return 1; - } + dev_dbg(&ds1wm_data->pdev->dev, "reset: no devices found\n"); + return 1; + } - return 0; + return 0; } static int ds1wm_write(struct ds1wm_data *ds1wm_data, u8 data) @@ -334,7 +335,7 @@ static int ds1wm_probe(struct platform_device *pdev) if (!pdev) return -ENODEV; - ds1wm_data = kzalloc(sizeof (*ds1wm_data), GFP_KERNEL); + ds1wm_data = kzalloc(sizeof(*ds1wm_data), GFP_KERNEL); if (!ds1wm_data) return -ENOMEM; @@ -374,8 +375,8 @@ static int ds1wm_probe(struct platform_device *pdev) goto err1; ds1wm_data->clk = clk_get(&pdev->dev, "ds1wm"); - if (!ds1wm_data->clk) { - ret = -ENOENT; + if (IS_ERR(ds1wm_data->clk)) { + ret = PTR_ERR(ds1wm_data->clk); goto err2; } diff --git a/drivers/watchdog/cpu5wdt.c b/drivers/watchdog/cpu5wdt.c index 5941ca601a3a17359637753fdc3558b86430252f..df72f90123dfe92bdfa73139a509c9cc67a833d2 100644 --- a/drivers/watchdog/cpu5wdt.c +++ b/drivers/watchdog/cpu5wdt.c @@ -59,9 +59,9 @@ static int ticks = 10000; static struct { struct completion stop; - volatile int running; + int running; struct timer_list timer; - volatile int queue; + int queue; int default_ticks; unsigned long inuse; } cpu5wdt_device; diff --git a/drivers/watchdog/hpwdt.c b/drivers/watchdog/hpwdt.c index a2e174b09fe7bcc91af2fcd7871e35fd6a3fa3f2..6483d1066b95e7feb967a0c77925381302eae61c 100644 --- a/drivers/watchdog/hpwdt.c +++ b/drivers/watchdog/hpwdt.c @@ -58,41 +58,6 @@ struct bios32_service_dir { u8 reserved[5]; }; -/* - * smbios_entry_point - defines SMBIOS entry point structure - * - * anchor[4] - anchor string (_SM_) - * checksum - checksum of the entry point structure - * length - length of the entry point structure - * major_ver - major version (02h for revision 2.1) - * minor_ver - minor version (01h for revision 2.1) - * max_struct_size - size of the largest SMBIOS structure - * revision - entry point structure revision implemented - * formatted_area[5] - reserved - * intermediate_anchor[5] - intermediate anchor string (_DMI_) - * intermediate_checksum - intermediate checksum - * table_length - structure table length - * table_address - structure table address - * table_num_structs - number of SMBIOS structures present - * bcd_revision - BCD revision - */ -struct smbios_entry_point { - u8 anchor[4]; - u8 checksum; - u8 length; - u8 major_ver; - u8 minor_ver; - u16 max_struct_size; - u8 revision; - u8 formatted_area[5]; - u8 intermediate_anchor[5]; - u8 intermediate_checksum; - u16 table_length; - u64 table_address; - u16 table_num_structs; - u8 bcd_revision; -}; - /* type 212 */ struct smbios_cru64_info { u8 type; @@ -175,31 +140,13 @@ static struct pci_device_id hpwdt_devices[] = { }; MODULE_DEVICE_TABLE(pci, hpwdt_devices); -/* - * bios_checksum - */ -static int __devinit bios_checksum(const char __iomem *ptr, int len) -{ - char sum = 0; - int i; - - /* - * calculate checksum of size bytes. This should add up - * to zero if we have a valid header. - */ - for (i = 0; i < len; i++) - sum += ptr[i]; - - return ((sum == 0) && (len > 0)); -} - #ifndef CONFIG_X86_64 /* --32 Bit Bios------------------------------------------------------------ */ #define HPWDT_ARCH 32 -asmlinkage void asminline_call(struct cmn_registers *pi86Regs, - unsigned long *pRomEntry) +static void asminline_call(struct cmn_registers *pi86Regs, + unsigned long *pRomEntry) { asm("pushl %ebp \n\t" "movl %esp, %ebp \n\t" @@ -302,6 +249,24 @@ static int __devinit cru_detect(unsigned long map_entry, return retval; } +/* + * bios_checksum + */ +static int __devinit bios_checksum(const char __iomem *ptr, int len) +{ + char sum = 0; + int i; + + /* + * calculate checksum of size bytes. This should add up + * to zero if we have a valid header. + */ + for (i = 0; i < len; i++) + sum += ptr[i]; + + return ((sum == 0) && (len > 0)); +} + /* * bios32_present * @@ -368,8 +333,8 @@ static int __devinit detect_cru_service(void) #define HPWDT_ARCH 64 -asmlinkage void asminline_call(struct cmn_registers *pi86Regs, - unsigned long *pRomEntry) +static void asminline_call(struct cmn_registers *pi86Regs, + unsigned long *pRomEntry) { asm("pushq %rbp \n\t" "movq %rsp, %rbp \n\t" @@ -410,12 +375,8 @@ asmlinkage void asminline_call(struct cmn_registers *pi86Regs, * dmi_find_cru * * Routine Description: - * This function checks wether or not a SMBIOS/DMI record is + * This function checks whether or not a SMBIOS/DMI record is * the 64bit CRU info or not - * - * Return Value: - * 0 : SUCCESS - if record found - * <0 : FAILURE - if record not found */ static void __devinit dmi_find_cru(const struct dmi_header *dm) { @@ -434,138 +395,11 @@ static void __devinit dmi_find_cru(const struct dmi_header *dm) } } -/* - * dmi_table - * - * Routine Description: - * Decode the SMBIOS/DMI table and check if we have a 64bit CRU record - * or not. - * - * We have to be cautious here. We have seen BIOSes with DMI pointers - * pointing to completely the wrong place for example - */ -static void __devinit dmi_table(u8 *buf, int len, int num, - void (*decode)(const struct dmi_header *)) -{ - u8 *data = buf; - int i = 0; - - /* - * Stop when we see all the items the table claimed to have - * OR we run off the end of the table (also happens) - */ - while ((i < num) && (data - buf + sizeof(struct dmi_header)) <= len) { - const struct dmi_header *dm = (const struct dmi_header *)data; - - /* - * We want to know the total length (formated area and strings) - * before decoding to make sure we won't run off the table in - * dmi_decode or dmi_string - */ - data += dm->length; - while ((data - buf < len - 1) && (data[0] || data[1])) - data++; - if (data - buf < len - 1) - decode(dm); - data += 2; - i++; - } -} - -/* - * smbios_present - * - * Routine Description: - * This function parses the SMBIOS entry point table to retrieve - * the 64 bit CRU Service. - * - * Return Value: - * 0 : SUCCESS - * <0 : FAILURE - */ -static int __devinit smbios_present(const char __iomem *p) -{ - struct smbios_entry_point *eps = - (struct smbios_entry_point *) p; - int length; - u8 *buf; - - /* check if we have indeed the SMBIOS table entry point */ - if ((strncmp((char *)eps->anchor, "_SM_", - sizeof(eps->anchor))) == 0) { - length = eps->length; - - /* SMBIOS v2.1 implementation might use 0x1e */ - if ((length == 0x1e) && - (eps->major_ver == 2) && - (eps->minor_ver == 1)) - length = 0x1f; - - /* - * Now we will check: - * - SMBIOS checksum must be 0 - * - intermediate anchor should be _DMI_ - * - intermediate checksum should be 0 - */ - if ((bios_checksum(p, length)) && - (strncmp((char *)eps->intermediate_anchor, "_DMI_", - sizeof(eps->intermediate_anchor)) == 0) && - (bios_checksum(p+0x10, 15))) { - buf = ioremap(eps->table_address, eps->table_length); - if (buf == NULL) - return -ENODEV; - - - /* Scan the DMI table for the 64 bit CRU service */ - dmi_table(buf, eps->table_length, - eps->table_num_structs, dmi_find_cru); - - iounmap(buf); - return 0; - } - } - - return -ENODEV; -} - -static int __devinit smbios_scan_machine(void) -{ - char __iomem *p, *q; - int rc; - - if (efi_enabled) { - if (efi.smbios == EFI_INVALID_TABLE_ADDR) - return -ENODEV; - - p = ioremap(efi.smbios, 32); - if (p == NULL) - return -ENOMEM; - - rc = smbios_present(p); - iounmap(p); - } else { - /* - * Search from 0x0f0000 through 0x0fffff, inclusive. - */ - p = ioremap(PCI_ROM_BASE1, ROM_SIZE); - if (p == NULL) - return -ENOMEM; - - for (q = p; q < p + ROM_SIZE; q += 16) { - rc = smbios_present(q); - if (!rc) { - break; - } - } - iounmap(p); - } -} - static int __devinit detect_cru_service(void) { cru_rom_addr = NULL; - smbios_scan_machine(); /* will become dmi_walk(dmi_find_cru); */ + dmi_walk(dmi_find_cru); /* if cru_rom_addr has been set then we found a CRU service */ return ((cru_rom_addr != NULL)? 0: -ENODEV); diff --git a/drivers/watchdog/it8712f_wdt.c b/drivers/watchdog/it8712f_wdt.c index 1b6d7d1b715d57f819994e9790ac8be57c12abf3..1efcad3b6fcaf91d3fc677d1641e885d7ecc0402 100644 --- a/drivers/watchdog/it8712f_wdt.c +++ b/drivers/watchdog/it8712f_wdt.c @@ -7,7 +7,8 @@ * * drivers/char/watchdog/scx200_wdt.c * drivers/hwmon/it87.c - * IT8712F EC-LPC I/O Preliminary Specification 0.9.2.pdf + * IT8712F EC-LPC I/O Preliminary Specification 0.8.2 + * IT8712F EC-LPC I/O Preliminary Specification 0.9.3 * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -40,6 +41,7 @@ MODULE_DESCRIPTION("IT8712F Watchdog Driver"); MODULE_LICENSE("GPL"); MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR); +static int max_units = 255; static int margin = 60; /* in seconds */ module_param(margin, int, 0); MODULE_PARM_DESC(margin, "Watchdog margin in seconds"); @@ -51,6 +53,7 @@ MODULE_PARM_DESC(nowayout, "Disable watchdog shutdown on close"); static struct semaphore it8712f_wdt_sem; static unsigned expect_close; static spinlock_t io_lock; +static unsigned char revision; /* Dog Food address - We use the game port address */ static unsigned short address; @@ -108,6 +111,15 @@ superio_inw(int reg) return val; } +static void +superio_outw(int val, int reg) +{ + outb(reg++, REG); + outb((val >> 8) & 0xff, VAL); + outb(reg, REG); + outb(val & 0xff, VAL); +} + static inline void superio_select(int ldn) { @@ -143,15 +155,33 @@ static void it8712f_wdt_update_margin(void) { int config = WDT_OUT_KRST | WDT_OUT_PWROK; - - printk(KERN_INFO NAME ": timer margin %d seconds\n", margin); - - /* The timeout register only has 8bits wide */ - if (margin < 256) - config |= WDT_UNIT_SEC; /* else UNIT are MINUTES */ + int units = margin; + + /* Switch to minutes precision if the configured margin + * value does not fit within the register width. + */ + if (units <= max_units) { + config |= WDT_UNIT_SEC; /* else UNIT is MINUTES */ + printk(KERN_INFO NAME ": timer margin %d seconds\n", units); + } else { + units /= 60; + printk(KERN_INFO NAME ": timer margin %d minutes\n", units); + } superio_outb(config, WDT_CONFIG); - superio_outb((margin > 255) ? (margin / 60) : margin, WDT_TIMEOUT); + if (revision >= 0x08) + superio_outw(units, WDT_TIMEOUT); + else + superio_outb(units, WDT_TIMEOUT); +} + +static int +it8712f_wdt_get_status(void) +{ + if (superio_inb(WDT_CONTROL) & 0x01) + return WDIOF_CARDRESET; + else + return 0; } static void @@ -234,7 +264,7 @@ it8712f_wdt_ioctl(struct inode *inode, struct file *file, .firmware_version = 1, .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING, }; - int new_margin; + int value; switch (cmd) { default: @@ -244,17 +274,27 @@ it8712f_wdt_ioctl(struct inode *inode, struct file *file, return -EFAULT; return 0; case WDIOC_GETSTATUS: + superio_enter(); + superio_select(LDN_GPIO); + + value = it8712f_wdt_get_status(); + + superio_exit(); + + return put_user(value, p); case WDIOC_GETBOOTSTATUS: return put_user(0, p); case WDIOC_KEEPALIVE: it8712f_wdt_ping(); return 0; case WDIOC_SETTIMEOUT: - if (get_user(new_margin, p)) + if (get_user(value, p)) return -EFAULT; - if (new_margin < 1) + if (value < 1) + return -EINVAL; + if (value > (max_units * 60)) return -EINVAL; - margin = new_margin; + margin = value; superio_enter(); superio_select(LDN_GPIO); @@ -262,6 +302,7 @@ it8712f_wdt_ioctl(struct inode *inode, struct file *file, superio_exit(); it8712f_wdt_ping(); + /* Fall through */ case WDIOC_GETTIMEOUT: if (put_user(margin, p)) return -EFAULT; @@ -336,9 +377,18 @@ it8712f_wdt_find(unsigned short *address) } err = 0; - printk(KERN_DEBUG NAME ": Found IT%04xF chip revision %d - " + revision = superio_inb(DEVREV) & 0x0f; + + /* Later revisions have 16-bit values per datasheet 0.9.1 */ + if (revision >= 0x08) + max_units = 65535; + + if (margin > (max_units * 60)) + margin = (max_units * 60); + + printk(KERN_INFO NAME ": Found IT%04xF chip revision %d - " "using DogFood address 0x%x\n", - chip_type, superio_inb(DEVREV) & 0x0f, *address); + chip_type, revision, *address); exit: superio_exit(); diff --git a/drivers/watchdog/machzwd.c b/drivers/watchdog/machzwd.c index e6e07b4575ebee7e031e64e4bc82def7a95157f6..6905135a776c7f58c16733fcc8e30508783437e6 100644 --- a/drivers/watchdog/machzwd.c +++ b/drivers/watchdog/machzwd.c @@ -141,7 +141,7 @@ static unsigned long next_heartbeat = 0; #ifndef ZF_DEBUG # define dprintk(format, args...) #else -# define dprintk(format, args...) printk(KERN_DEBUG PFX ":%s:%d: " format, __FUNCTION__, __LINE__ , ## args) +# define dprintk(format, args...) printk(KERN_DEBUG PFX ":%s:%d: " format, __func__, __LINE__ , ## args) #endif diff --git a/drivers/watchdog/mtx-1_wdt.c b/drivers/watchdog/mtx-1_wdt.c index 789831b3fa00a9cbbe050d4bde6b3053a702c280..10b89f2703bdf37e6a70a8aef124600177620b7f 100644 --- a/drivers/watchdog/mtx-1_wdt.c +++ b/drivers/watchdog/mtx-1_wdt.c @@ -59,9 +59,9 @@ static int ticks = 100 * HZ; static struct { struct completion stop; - volatile int running; + int running; struct timer_list timer; - volatile int queue; + int queue; int default_ticks; unsigned long inuse; unsigned gpio; diff --git a/drivers/watchdog/pcwd_usb.c b/drivers/watchdog/pcwd_usb.c index 0f3fd6c9c354049f5393d802883ab6ce2a8f3b0c..bf443d077a1ea40b9b907b27055f50e7fd56a464 100644 --- a/drivers/watchdog/pcwd_usb.c +++ b/drivers/watchdog/pcwd_usb.c @@ -179,11 +179,11 @@ static void usb_pcwd_intr_done(struct urb *urb) case -ENOENT: case -ESHUTDOWN: /* this urb is terminated, clean up */ - dbg("%s - urb shutting down with status: %d", __FUNCTION__, urb->status); + dbg("%s - urb shutting down with status: %d", __func__, urb->status); return; /* -EPIPE: should clear the halt */ default: /* error */ - dbg("%s - nonzero urb status received: %d", __FUNCTION__, urb->status); + dbg("%s - nonzero urb status received: %d", __func__, urb->status); goto resubmit; } diff --git a/drivers/watchdog/s3c2410_wdt.c b/drivers/watchdog/s3c2410_wdt.c index 5d1c15f83d233a9691e3409f9945a39a092c71ca..7645e8812156c97423b9e97ad37e84f81571ef65 100644 --- a/drivers/watchdog/s3c2410_wdt.c +++ b/drivers/watchdog/s3c2410_wdt.c @@ -144,7 +144,7 @@ static int s3c2410wdt_start(void) } DBG("%s: wdt_count=0x%08x, wtcon=%08lx\n", - __FUNCTION__, wdt_count, wtcon); + __func__, wdt_count, wtcon); writel(wdt_count, wdt_base + S3C2410_WTDAT); writel(wdt_count, wdt_base + S3C2410_WTCNT); @@ -167,7 +167,7 @@ static int s3c2410wdt_set_heartbeat(int timeout) count = timeout * freq; DBG("%s: count=%d, timeout=%d, freq=%d\n", - __FUNCTION__, count, timeout, freq); + __func__, count, timeout, freq); /* if the count is bigger than the watchdog register, then work out what we need to do (and if) we can @@ -189,7 +189,7 @@ static int s3c2410wdt_set_heartbeat(int timeout) tmr_margin = timeout; DBG("%s: timeout=%d, divisor=%d, count=%d (%08x)\n", - __FUNCTION__, timeout, divisor, count, count/divisor); + __func__, timeout, divisor, count, count/divisor); count /= divisor; wdt_count = count; @@ -355,7 +355,7 @@ static int s3c2410wdt_probe(struct platform_device *pdev) int ret; int size; - DBG("%s: probe=%p\n", __FUNCTION__, pdev); + DBG("%s: probe=%p\n", __func__, pdev); dev = &pdev->dev; wdt_dev = &pdev->dev; diff --git a/drivers/watchdog/shwdt.c b/drivers/watchdog/shwdt.c index 61dde863bd40c2da42f04a6472a8407249fd961d..1277f7e9cc54adde6b09a914ab95c67640e9d019 100644 --- a/drivers/watchdog/shwdt.c +++ b/drivers/watchdog/shwdt.c @@ -298,7 +298,7 @@ static int sh_wdt_mmap(struct file *file, struct vm_area_struct *vma) if (io_remap_pfn_range(vma, vma->vm_start, addr >> PAGE_SHIFT, PAGE_SIZE, vma->vm_page_prot)) { printk(KERN_ERR PFX "%s: io_remap_pfn_range failed\n", - __FUNCTION__); + __func__); return -EAGAIN; } diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c index 41a958a7585e750cd800b2d229d5b3b2a04f0898..5e1a4fb5cacb2a3715ad3552bd8e412fdae9b00c 100644 --- a/fs/binfmt_elf.c +++ b/fs/binfmt_elf.c @@ -1424,6 +1424,18 @@ struct elf_note_info { int thread_notes; }; +/* + * When a regset has a writeback hook, we call it on each thread before + * dumping user memory. On register window machines, this makes sure the + * user memory backing the register data is up to date before we read it. + */ +static void do_thread_regset_writeback(struct task_struct *task, + const struct user_regset *regset) +{ + if (regset->writeback) + regset->writeback(task, regset, 1); +} + static int fill_thread_core_info(struct elf_thread_core_info *t, const struct user_regset_view *view, long signr, size_t *total) @@ -1445,6 +1457,8 @@ static int fill_thread_core_info(struct elf_thread_core_info *t, sizeof(t->prstatus), &t->prstatus); *total += notesize(&t->notes[0]); + do_thread_regset_writeback(t->task, &view->regsets[0]); + /* * Each other regset might generate a note too. For each regset * that has no core_note_type or is inactive, we leave t->notes[i] @@ -1452,6 +1466,7 @@ static int fill_thread_core_info(struct elf_thread_core_info *t, */ for (i = 1; i < view->n; ++i) { const struct user_regset *regset = &view->regsets[i]; + do_thread_regset_writeback(t->task, regset); if (regset->core_note_type && (!regset->active || regset->active(t->task, regset))) { int ret; diff --git a/fs/buffer.c b/fs/buffer.c index 3ebccf4aa7e3280318b4ae8fbd2b28514d929749..ddfdd2c80bf9ba22c20901e5a74f9cd449d80ccd 100644 --- a/fs/buffer.c +++ b/fs/buffer.c @@ -627,8 +627,7 @@ repeat: } /** - * sync_mapping_buffers - write out and wait upon a mapping's "associated" - * buffers + * sync_mapping_buffers - write out & wait upon a mapping's "associated" buffers * @mapping: the mapping which wants those buffers written * * Starts I/O against the buffers at mapping->private_list, and waits upon @@ -836,7 +835,7 @@ static int fsync_buffers_list(spinlock_t *lock, struct list_head *list) smp_mb(); if (buffer_dirty(bh)) { list_add(&bh->b_assoc_buffers, - &bh->b_assoc_map->private_list); + &mapping->private_list); bh->b_assoc_map = mapping; } spin_unlock(lock); diff --git a/fs/cifs/CHANGES b/fs/cifs/CHANGES index edd248367b36fe67166053731ab55d0edbcff796..dbd91461853c97fc1c5c4538c53c6514570f85d4 100644 --- a/fs/cifs/CHANGES +++ b/fs/cifs/CHANGES @@ -6,7 +6,9 @@ and sync so that events like out of disk space get reported properly on cached files. Fix setxattr failure to certain Samba versions. Fix mount of second share to disconnected server session (autoreconnect on this). Add ability to modify cifs acls for handling chmod (when mounted with -cifsacl flag). +cifsacl flag). Fix prefixpath path separator so we can handle mounts +with prefixpaths longer than one directory (one path component) when +mounted to Windows servers. Version 1.51 ------------ diff --git a/fs/cifs/README b/fs/cifs/README index c623e2f9c5dbab90e314c54133ea027ff6cbfe4d..50306229b0f9f822b4f4e6d53cca9b9a5986ec07 100644 --- a/fs/cifs/README +++ b/fs/cifs/README @@ -461,7 +461,7 @@ A partial list of the supported mount options follows: cifsacl Report mode bits (e.g. on stat) based on the Windows ACL for the file. (EXPERIMENTAL) servern Specify the server 's netbios name (RFC1001 name) to use - when attempting to setup a session to the server. This is + when attempting to setup a session to the server. This is needed for mounting to some older servers (such as OS/2 or Windows 98 and Windows ME) since they do not support a default server name. A server name can be up diff --git a/fs/cifs/cifs_debug.c b/fs/cifs/cifs_debug.c index 73c4c419663c1dc1a3558d2df405fcb58bc07e66..0228ed06069e95c88b3b4a032b5b423f474ca190 100644 --- a/fs/cifs/cifs_debug.c +++ b/fs/cifs/cifs_debug.c @@ -98,8 +98,7 @@ void cifs_dump_mids(struct TCP_Server_Info *server) if (mid_entry->resp_buf) { cifs_dump_detail(mid_entry->resp_buf); cifs_dump_mem("existing buf: ", - mid_entry->resp_buf, - 62 /* fixme */); + mid_entry->resp_buf, 62); } } } @@ -439,7 +438,7 @@ cifs_stats_read(char *buf, char **beginBuffer, off_t offset, return length; } -#endif +#endif /* STATS */ static struct proc_dir_entry *proc_fs_cifs; read_proc_t cifs_txanchor_read; @@ -482,7 +481,7 @@ cifs_proc_init(void) cifs_stats_read, NULL); if (pde) pde->write_proc = cifs_stats_write; -#endif +#endif /* STATS */ pde = create_proc_read_entry("cifsFYI", 0, proc_fs_cifs, cifsFYI_read, NULL); if (pde) @@ -918,4 +917,12 @@ security_flags_write(struct file *file, const char __user *buffer, /* BB should we turn on MAY flags for other MUST options? */ return count; } -#endif +#else +inline void cifs_proc_init(void) +{ +} + +inline void cifs_proc_clean(void) +{ +} +#endif /* PROC_FS */ diff --git a/fs/cifs/cifs_debug.h b/fs/cifs/cifs_debug.h index c26cd0d2c6d525d64455dfba60e9fdd5b9a4243a..5eb3b83bbfa76b90992f8bfbc805758f6a2e71bf 100644 --- a/fs/cifs/cifs_debug.h +++ b/fs/cifs/cifs_debug.h @@ -25,8 +25,11 @@ void cifs_dump_mem(char *label, void *data, int length); #ifdef CONFIG_CIFS_DEBUG2 +#define DBG2 2 void cifs_dump_detail(struct smb_hdr *); void cifs_dump_mids(struct TCP_Server_Info *); +#else +#define DBG2 0 #endif extern int traceSMB; /* flag which enables the function below */ void dump_smb(struct smb_hdr *, int); @@ -64,10 +67,10 @@ extern int cifsERROR; * --------- */ #else /* _CIFS_DEBUG */ -#define cERROR(button,prspec) -#define cEVENT(format,arg...) +#define cERROR(button, prspec) +#define cEVENT(format, arg...) #define cFYI(button, prspec) -#define cifserror(format,arg...) +#define cifserror(format, arg...) #endif /* _CIFS_DEBUG */ #endif /* _H_CIFS_DEBUG */ diff --git a/fs/cifs/cifs_dfs_ref.c b/fs/cifs/cifs_dfs_ref.c index 6ad447529961c0939c84b1eba822cb7076e3817d..7f8838253410572397725dffd3d92abba884c20c 100644 --- a/fs/cifs/cifs_dfs_ref.c +++ b/fs/cifs/cifs_dfs_ref.c @@ -286,7 +286,7 @@ static void dump_referral(const struct dfs_info3_param *ref) cFYI(1, ("DFS: node path: %s", ref->node_name)); cFYI(1, ("DFS: fl: %hd, srv_type: %hd", ref->flags, ref->server_type)); cFYI(1, ("DFS: ref_flags: %hd, path_consumed: %hd", ref->ref_flag, - ref->PathConsumed)); + ref->path_consumed)); } diff --git a/fs/cifs/cifs_spnego.c b/fs/cifs/cifs_spnego.c index d543accc10dd0be24a870ebaa634bd9c7cb199e7..6653e29637a7ec534c83d53c8a21ddda24130367 100644 --- a/fs/cifs/cifs_spnego.c +++ b/fs/cifs/cifs_spnego.c @@ -125,7 +125,7 @@ cifs_get_spnego_key(struct cifsSesInfo *sesInfo) #ifdef CONFIG_CIFS_DEBUG2 if (cifsFYI && !IS_ERR(spnego_key)) { struct cifs_spnego_msg *msg = spnego_key->payload.data; - cifs_dump_mem("SPNEGO reply blob:", msg->data, min(1024, + cifs_dump_mem("SPNEGO reply blob:", msg->data, min(1024U, msg->secblob_len + msg->sesskey_len)); } #endif /* CONFIG_CIFS_DEBUG2 */ diff --git a/fs/cifs/cifs_unicode.c b/fs/cifs/cifs_unicode.c index b5903b89250d412c93f31eb626252c44861463b4..7d75272a6b3f01499738ce1ba10f961429892855 100644 --- a/fs/cifs/cifs_unicode.c +++ b/fs/cifs/cifs_unicode.c @@ -32,7 +32,7 @@ * */ int -cifs_strfromUCS_le(char *to, const __le16 * from, +cifs_strfromUCS_le(char *to, const __le16 *from, int len, const struct nls_table *codepage) { int i; @@ -61,7 +61,7 @@ cifs_strfromUCS_le(char *to, const __le16 * from, * */ int -cifs_strtoUCS(__le16 * to, const char *from, int len, +cifs_strtoUCS(__le16 *to, const char *from, int len, const struct nls_table *codepage) { int charlen; diff --git a/fs/cifs/cifs_unicode.h b/fs/cifs/cifs_unicode.h index 614c11fcdcb67d0f704badaf029991dddc3682c0..14eb9a2395d3cc3c4020e08c01d8b3b5dbc9faa0 100644 --- a/fs/cifs/cifs_unicode.h +++ b/fs/cifs/cifs_unicode.h @@ -254,7 +254,8 @@ UniStrstr(const wchar_t *ucs1, const wchar_t *ucs2) const wchar_t *anchor2 = ucs2; while (*ucs1) { - if (*ucs1 == *ucs2) { /* Partial match found */ + if (*ucs1 == *ucs2) { + /* Partial match found */ ucs1++; ucs2++; } else { @@ -279,7 +280,8 @@ UniToupper(register wchar_t uc) { register const struct UniCaseRange *rp; - if (uc < sizeof (CifsUniUpperTable)) { /* Latin characters */ + if (uc < sizeof(CifsUniUpperTable)) { + /* Latin characters */ return uc + CifsUniUpperTable[uc]; /* Use base tables */ } else { rp = CifsUniUpperRange; /* Use range tables */ @@ -320,7 +322,8 @@ UniTolower(wchar_t uc) { register struct UniCaseRange *rp; - if (uc < sizeof (UniLowerTable)) { /* Latin characters */ + if (uc < sizeof(UniLowerTable)) { + /* Latin characters */ return uc + UniLowerTable[uc]; /* Use base tables */ } else { rp = UniLowerRange; /* Use range tables */ diff --git a/fs/cifs/cifsacl.c b/fs/cifs/cifsacl.c index a7035bd18e4e4282ed4fcef9c22132c94c9e7f09..f93932c217728861d97ca4b1d4d2754a6f81fa1c 100644 --- a/fs/cifs/cifsacl.c +++ b/fs/cifs/cifsacl.c @@ -46,8 +46,7 @@ static struct cifs_wksid wksidarr[NUM_WK_SIDS] = { static const struct cifs_sid sid_everyone = { 1, 1, {0, 0, 0, 0, 0, 1}, {0} }; /* group users */ -static const struct cifs_sid sid_user = - {1, 2 , {0, 0, 0, 0, 0, 5}, {} }; +static const struct cifs_sid sid_user = {1, 2 , {0, 0, 0, 0, 0, 5}, {} }; int match_sid(struct cifs_sid *ctsid) @@ -195,9 +194,9 @@ static void access_flags_to_mode(__le32 ace_flags, int type, umode_t *pmode, /* For deny ACEs we change the mask so that subsequent allow access control entries do not turn on the bits we are denying */ if (type == ACCESS_DENIED) { - if (flags & GENERIC_ALL) { + if (flags & GENERIC_ALL) *pbits_to_set &= ~S_IRWXUGO; - } + if ((flags & GENERIC_WRITE) || ((flags & FILE_WRITE_RIGHTS) == FILE_WRITE_RIGHTS)) *pbits_to_set &= ~S_IWUGO; @@ -216,9 +215,7 @@ static void access_flags_to_mode(__le32 ace_flags, int type, umode_t *pmode, if (flags & GENERIC_ALL) { *pmode |= (S_IRWXUGO & (*pbits_to_set)); -#ifdef CONFIG_CIFS_DEBUG2 - cFYI(1, ("all perms")); -#endif + cFYI(DBG2, ("all perms")); return; } if ((flags & GENERIC_WRITE) || @@ -231,9 +228,7 @@ static void access_flags_to_mode(__le32 ace_flags, int type, umode_t *pmode, ((flags & FILE_EXEC_RIGHTS) == FILE_EXEC_RIGHTS)) *pmode |= (S_IXUGO & (*pbits_to_set)); -#ifdef CONFIG_CIFS_DEBUG2 - cFYI(1, ("access flags 0x%x mode now 0x%x", flags, *pmode)); -#endif + cFYI(DBG2, ("access flags 0x%x mode now 0x%x", flags, *pmode)); return; } @@ -262,9 +257,7 @@ static void mode_to_access_flags(umode_t mode, umode_t bits_to_use, if (mode & S_IXUGO) *pace_flags |= SET_FILE_EXEC_RIGHTS; -#ifdef CONFIG_CIFS_DEBUG2 - cFYI(1, ("mode: 0x%x, access flags now 0x%x", mode, *pace_flags)); -#endif + cFYI(DBG2, ("mode: 0x%x, access flags now 0x%x", mode, *pace_flags)); return; } @@ -358,11 +351,9 @@ static void parse_dacl(struct cifs_acl *pdacl, char *end_of_acl, return; } -#ifdef CONFIG_CIFS_DEBUG2 - cFYI(1, ("DACL revision %d size %d num aces %d", + cFYI(DBG2, ("DACL revision %d size %d num aces %d", le16_to_cpu(pdacl->revision), le16_to_cpu(pdacl->size), le32_to_cpu(pdacl->num_aces))); -#endif /* reset rwx permissions for user/group/other. Also, if num_aces is 0 i.e. DACL has no ACEs, @@ -381,10 +372,6 @@ static void parse_dacl(struct cifs_acl *pdacl, char *end_of_acl, ppace = kmalloc(num_aces * sizeof(struct cifs_ace *), GFP_KERNEL); -/* cifscred->cecount = pdacl->num_aces; - cifscred->aces = kmalloc(num_aces * - sizeof(struct cifs_ace *), GFP_KERNEL);*/ - for (i = 0; i < num_aces; ++i) { ppace[i] = (struct cifs_ace *) (acl_base + acl_size); #ifdef CONFIG_CIFS_DEBUG2 @@ -437,7 +424,7 @@ static int set_chmod_dacl(struct cifs_acl *pndacl, struct cifs_sid *pownersid, &sid_everyone, nmode, S_IRWXO); pndacl->size = cpu_to_le16(size + sizeof(struct cifs_acl)); - pndacl->num_aces = 3; + pndacl->num_aces = cpu_to_le32(3); return (0); } @@ -495,13 +482,11 @@ static int parse_sec_desc(struct cifs_ntsd *pntsd, int acl_len, le32_to_cpu(pntsd->gsidoffset)); dacloffset = le32_to_cpu(pntsd->dacloffset); dacl_ptr = (struct cifs_acl *)((char *)pntsd + dacloffset); -#ifdef CONFIG_CIFS_DEBUG2 - cFYI(1, ("revision %d type 0x%x ooffset 0x%x goffset 0x%x " + cFYI(DBG2, ("revision %d type 0x%x ooffset 0x%x goffset 0x%x " "sacloffset 0x%x dacloffset 0x%x", pntsd->revision, pntsd->type, le32_to_cpu(pntsd->osidoffset), le32_to_cpu(pntsd->gsidoffset), le32_to_cpu(pntsd->sacloffset), dacloffset)); -#endif /* cifs_dump_mem("owner_sid: ", owner_sid_ptr, 64); */ rc = parse_sid(owner_sid_ptr, end_of_acl); if (rc) @@ -636,9 +621,7 @@ static int set_cifs_acl(struct cifs_ntsd *pnntsd, __u32 acllen, struct super_block *sb; struct cifs_sb_info *cifs_sb; -#ifdef CONFIG_CIFS_DEBUG2 - cFYI(1, ("set ACL for %s from mode 0x%x", path, inode->i_mode)); -#endif + cFYI(DBG2, ("set ACL for %s from mode 0x%x", path, inode->i_mode)); if (!inode) return (rc); @@ -669,9 +652,7 @@ static int set_cifs_acl(struct cifs_ntsd *pnntsd, __u32 acllen, } rc = CIFSSMBSetCIFSACL(xid, cifs_sb->tcon, fid, pnntsd, acllen); -#ifdef CONFIG_CIFS_DEBUG2 - cFYI(1, ("SetCIFSACL rc = %d", rc)); -#endif + cFYI(DBG2, ("SetCIFSACL rc = %d", rc)); if (unlock_file == TRUE) atomic_dec(&open_file->wrtPending); else @@ -689,9 +670,7 @@ void acl_to_uid_mode(struct inode *inode, const char *path) u32 acllen = 0; int rc = 0; -#ifdef CONFIG_CIFS_DEBUG2 - cFYI(1, ("converting ACL to mode for %s", path)); -#endif + cFYI(DBG2, ("converting ACL to mode for %s", path)); pntsd = get_cifs_acl(&acllen, inode, path); /* if we can retrieve the ACL, now parse Access Control Entries, ACEs */ @@ -712,9 +691,7 @@ int mode_to_acl(struct inode *inode, const char *path, __u64 nmode) struct cifs_ntsd *pntsd = NULL; /* acl obtained from server */ struct cifs_ntsd *pnntsd = NULL; /* modified acl to be sent to server */ -#ifdef CONFIG_CIFS_DEBUG2 - cFYI(1, ("set ACL from mode for %s", path)); -#endif + cFYI(DBG2, ("set ACL from mode for %s", path)); /* Get the security descriptor */ pntsd = get_cifs_acl(&acllen, inode, path); @@ -736,16 +713,12 @@ int mode_to_acl(struct inode *inode, const char *path, __u64 nmode) rc = build_sec_desc(pntsd, pnntsd, acllen, inode, nmode); -#ifdef CONFIG_CIFS_DEBUG2 - cFYI(1, ("build_sec_desc rc: %d", rc)); -#endif + cFYI(DBG2, ("build_sec_desc rc: %d", rc)); if (!rc) { /* Set the security descriptor */ rc = set_cifs_acl(pnntsd, acllen, inode, path); -#ifdef CONFIG_CIFS_DEBUG2 - cFYI(1, ("set_cifs_acl rc: %d", rc)); -#endif + cFYI(DBG2, ("set_cifs_acl rc: %d", rc)); } kfree(pnntsd); diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c index fcc434227691fe4cbd57d2d74b7780c0767804fb..a04b17e5a9d01dbf5b8af64323b38b9ec45b20e8 100644 --- a/fs/cifs/cifsfs.c +++ b/fs/cifs/cifsfs.c @@ -204,9 +204,8 @@ cifs_put_super(struct super_block *sb) return; } rc = cifs_umount(sb, cifs_sb); - if (rc) { + if (rc) cERROR(1, ("cifs_umount failed with return code %d", rc)); - } #ifdef CONFIG_CIFS_DFS_UPCALL if (cifs_sb->mountdata) { kfree(cifs_sb->mountdata); @@ -461,7 +460,7 @@ int cifs_xstate_get(struct super_block *sb, struct fs_quota_stat *qstats) static struct quotactl_ops cifs_quotactl_ops = { .set_xquota = cifs_xquota_set, - .get_xquota = cifs_xquota_set, + .get_xquota = cifs_xquota_get, .set_xstate = cifs_xstate_set, .get_xstate = cifs_xstate_get, }; @@ -472,9 +471,7 @@ static void cifs_umount_begin(struct vfsmount *vfsmnt, int flags) struct cifs_sb_info *cifs_sb; struct cifsTconInfo *tcon; -#ifdef CONFIG_CIFS_DFS_UPCALL dfs_shrink_umount_helper(vfsmnt); -#endif /* CONFIG CIFS_DFS_UPCALL */ if (!(flags & MNT_FORCE)) return; @@ -992,9 +989,7 @@ static int __init init_cifs(void) { int rc = 0; -#ifdef CONFIG_PROC_FS cifs_proc_init(); -#endif /* INIT_LIST_HEAD(&GlobalServerList);*/ /* BB not implemented yet */ INIT_LIST_HEAD(&GlobalSMBSessionList); INIT_LIST_HEAD(&GlobalTreeConnectionList); @@ -1095,19 +1090,15 @@ init_cifs(void) out_destroy_inodecache: cifs_destroy_inodecache(); out_clean_proc: -#ifdef CONFIG_PROC_FS cifs_proc_clean(); -#endif return rc; } static void __exit exit_cifs(void) { - cFYI(0, ("exit_cifs")); -#ifdef CONFIG_PROC_FS + cFYI(DBG2, ("exit_cifs")); cifs_proc_clean(); -#endif #ifdef CONFIG_CIFS_DFS_UPCALL unregister_key_type(&key_type_dns_resolver); #endif diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h index 5d32d8ddc82eac91b80ebf552da45f0ea6c9fd22..69a2e1942542e1601e9e66078a1c052b86d51742 100644 --- a/fs/cifs/cifsglob.h +++ b/fs/cifs/cifsglob.h @@ -454,7 +454,7 @@ struct dir_notify_req { struct dfs_info3_param { int flags; /* DFSREF_REFERRAL_SERVER, DFSREF_STORAGE_SERVER*/ - int PathConsumed; + int path_consumed; int server_type; int ref_flag; char *path_name; diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h index 2f09f565a3d9603c02811f4ce47cfb36df41de21..0af63e6b426be4044e5d921c0b2ae53da517e5e5 100644 --- a/fs/cifs/cifsproto.h +++ b/fs/cifs/cifsproto.h @@ -53,11 +53,11 @@ extern int SendReceiveNoRsp(const unsigned int xid, struct cifsSesInfo *ses, extern int SendReceive2(const unsigned int /* xid */ , struct cifsSesInfo *, struct kvec *, int /* nvec to send */, int * /* type of buf returned */ , const int flags); -extern int SendReceiveBlockingLock(const unsigned int /* xid */ , - struct cifsTconInfo *, - struct smb_hdr * /* input */ , - struct smb_hdr * /* out */ , - int * /* bytes returned */); +extern int SendReceiveBlockingLock(const unsigned int xid, + struct cifsTconInfo *ptcon, + struct smb_hdr *in_buf , + struct smb_hdr *out_buf, + int *bytes_returned); extern int checkSMB(struct smb_hdr *smb, __u16 mid, unsigned int length); extern int is_valid_oplock_break(struct smb_hdr *smb, struct TCP_Server_Info *); extern int is_size_safe_to_change(struct cifsInodeInfo *, __u64 eof); @@ -84,7 +84,7 @@ extern __u16 GetNextMid(struct TCP_Server_Info *server); extern struct oplock_q_entry *AllocOplockQEntry(struct inode *, u16, struct cifsTconInfo *); extern void DeleteOplockQEntry(struct oplock_q_entry *); -extern struct timespec cifs_NTtimeToUnix(u64 /* utc nanoseconds since 1601 */ ); +extern struct timespec cifs_NTtimeToUnix(u64 utc_nanoseconds_since_1601); extern u64 cifs_UnixTimeToNT(struct timespec); extern __le64 cnvrtDosCifsTm(__u16 date, __u16 time); extern struct timespec cnvrtDosUnixTm(__u16 date, __u16 time); @@ -104,7 +104,11 @@ extern int cifs_mount(struct super_block *, struct cifs_sb_info *, char *, extern int cifs_umount(struct super_block *, struct cifs_sb_info *); #ifdef CONFIG_CIFS_DFS_UPCALL extern void dfs_shrink_umount_helper(struct vfsmount *vfsmnt); -#endif +#else +static inline void dfs_shrink_umount_helper(struct vfsmount *vfsmnt) +{ +} +#endif /* DFS_UPCALL */ void cifs_proc_init(void); void cifs_proc_clean(void); @@ -175,11 +179,11 @@ extern int CIFSSMBQFSPosixInfo(const int xid, struct cifsTconInfo *tcon, struct kstatfs *FSData); extern int CIFSSMBSetTimes(const int xid, struct cifsTconInfo *tcon, - const char *fileName, const FILE_BASIC_INFO * data, + const char *fileName, const FILE_BASIC_INFO *data, const struct nls_table *nls_codepage, int remap_special_chars); extern int CIFSSMBSetFileTimes(const int xid, struct cifsTconInfo *tcon, - const FILE_BASIC_INFO * data, __u16 fid); + const FILE_BASIC_INFO *data, __u16 fid); #if 0 extern int CIFSSMBSetAttrLegacy(int xid, struct cifsTconInfo *tcon, char *fileName, __u16 dos_attributes, diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c index 9409524e4bf88e5634ebbc94c2a1b30e7df38aeb..30bbe448e260fa931a2a36098057bfdd8364fad3 100644 --- a/fs/cifs/cifssmb.c +++ b/fs/cifs/cifssmb.c @@ -1,7 +1,7 @@ /* * fs/cifs/cifssmb.c * - * Copyright (C) International Business Machines Corp., 2002,2007 + * Copyright (C) International Business Machines Corp., 2002,2008 * Author(s): Steve French (sfrench@us.ibm.com) * * Contains the routines for constructing the SMB PDUs themselves @@ -102,10 +102,12 @@ static void mark_open_files_invalid(struct cifsTconInfo *pTcon) to this tcon */ } -/* If the return code is zero, this function must fill in request_buf pointer */ +/* Allocate and return pointer to an SMB request buffer, and set basic + SMB information in the SMB header. If the return code is zero, this + function must have filled in request_buf pointer */ static int small_smb_init(int smb_command, int wct, struct cifsTconInfo *tcon, - void **request_buf /* returned */) + void **request_buf) { int rc = 0; @@ -363,7 +365,7 @@ smb_init(int smb_command, int wct, struct cifsTconInfo *tcon, *response_buf = *request_buf; header_assemble((struct smb_hdr *) *request_buf, smb_command, tcon, - wct /*wct */ ); + wct); if (tcon != NULL) cifs_stats_inc(&tcon->num_smbs_sent); @@ -523,7 +525,7 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses) if (remain >= (MIN_TZ_ADJ / 2)) result += MIN_TZ_ADJ; if (val < 0) - result = - result; + result = -result; server->timeAdj = result; } else { server->timeAdj = (int)tmp; @@ -600,7 +602,7 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses) server->maxBuf = min(le32_to_cpu(pSMBr->MaxBufferSize), (__u32) CIFSMaxBufSize + MAX_CIFS_HDR_SIZE); server->maxRw = le32_to_cpu(pSMBr->MaxRawSize); - cFYI(0, ("Max buf = %d", ses->server->maxBuf)); + cFYI(DBG2, ("Max buf = %d", ses->server->maxBuf)); GETU32(ses->server->sessid) = le32_to_cpu(pSMBr->SessionKey); server->capabilities = le32_to_cpu(pSMBr->Capabilities); server->timeAdj = (int)(__s16)le16_to_cpu(pSMBr->ServerTimeZone); @@ -868,9 +870,8 @@ PsxDelete: pSMB->ByteCount = cpu_to_le16(byte_count); rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, (struct smb_hdr *) pSMBr, &bytes_returned, 0); - if (rc) { + if (rc) cFYI(1, ("Posix delete returned %d", rc)); - } cifs_buf_release(pSMB); cifs_stats_inc(&tcon->num_deletes); @@ -916,9 +917,8 @@ DelFileRetry: rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, (struct smb_hdr *) pSMBr, &bytes_returned, 0); cifs_stats_inc(&tcon->num_deletes); - if (rc) { + if (rc) cFYI(1, ("Error in RMFile = %d", rc)); - } cifs_buf_release(pSMB); if (rc == -EAGAIN) @@ -961,9 +961,8 @@ RmDirRetry: rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, (struct smb_hdr *) pSMBr, &bytes_returned, 0); cifs_stats_inc(&tcon->num_rmdirs); - if (rc) { + if (rc) cFYI(1, ("Error in RMDir = %d", rc)); - } cifs_buf_release(pSMB); if (rc == -EAGAIN) @@ -1005,9 +1004,8 @@ MkDirRetry: rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, (struct smb_hdr *) pSMBr, &bytes_returned, 0); cifs_stats_inc(&tcon->num_mkdirs); - if (rc) { + if (rc) cFYI(1, ("Error in Mkdir = %d", rc)); - } cifs_buf_release(pSMB); if (rc == -EAGAIN) @@ -1017,7 +1015,7 @@ MkDirRetry: int CIFSPOSIXCreate(const int xid, struct cifsTconInfo *tcon, __u32 posix_flags, - __u64 mode, __u16 * netfid, FILE_UNIX_BASIC_INFO *pRetData, + __u64 mode, __u16 *netfid, FILE_UNIX_BASIC_INFO *pRetData, __u32 *pOplock, const char *name, const struct nls_table *nls_codepage, int remap) { @@ -1027,8 +1025,8 @@ CIFSPOSIXCreate(const int xid, struct cifsTconInfo *tcon, __u32 posix_flags, int rc = 0; int bytes_returned = 0; __u16 params, param_offset, offset, byte_count, count; - OPEN_PSX_REQ * pdata; - OPEN_PSX_RSP * psx_rsp; + OPEN_PSX_REQ *pdata; + OPEN_PSX_RSP *psx_rsp; cFYI(1, ("In POSIX Create")); PsxCreat: @@ -1110,9 +1108,7 @@ PsxCreat: /* check to make sure response data is there */ if (psx_rsp->ReturnedLevel != cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC)) { pRetData->Type = cpu_to_le32(-1); /* unknown */ -#ifdef CONFIG_CIFS_DEBUG2 - cFYI(1, ("unknown type")); -#endif + cFYI(DBG2, ("unknown type")); } else { if (pSMBr->ByteCount < sizeof(OPEN_PSX_RSP) + sizeof(FILE_UNIX_BASIC_INFO)) { @@ -1169,8 +1165,8 @@ static __u16 convert_disposition(int disposition) int SMBLegacyOpen(const int xid, struct cifsTconInfo *tcon, const char *fileName, const int openDisposition, - const int access_flags, const int create_options, __u16 * netfid, - int *pOplock, FILE_ALL_INFO * pfile_info, + const int access_flags, const int create_options, __u16 *netfid, + int *pOplock, FILE_ALL_INFO *pfile_info, const struct nls_table *nls_codepage, int remap) { int rc = -EACCES; @@ -1221,8 +1217,8 @@ OldOpenRetry: if (create_options & CREATE_OPTION_SPECIAL) pSMB->FileAttributes = cpu_to_le16(ATTR_SYSTEM); - else - pSMB->FileAttributes = cpu_to_le16(0/*ATTR_NORMAL*/); /* BB FIXME */ + else /* BB FIXME BB */ + pSMB->FileAttributes = cpu_to_le16(0/*ATTR_NORMAL*/); /* if ((omode & S_IWUGO) == 0) pSMB->FileAttributes |= cpu_to_le32(ATTR_READONLY);*/ @@ -1284,8 +1280,8 @@ OldOpenRetry: int CIFSSMBOpen(const int xid, struct cifsTconInfo *tcon, const char *fileName, const int openDisposition, - const int access_flags, const int create_options, __u16 * netfid, - int *pOplock, FILE_ALL_INFO * pfile_info, + const int access_flags, const int create_options, __u16 *netfid, + int *pOplock, FILE_ALL_INFO *pfile_info, const struct nls_table *nls_codepage, int remap) { int rc = -EACCES; @@ -1556,9 +1552,9 @@ CIFSSMBWrite(const int xid, struct cifsTconInfo *tcon, } /* else setting file size with write of zero bytes */ if (wct == 14) byte_count = bytes_sent + 1; /* pad */ - else /* wct == 12 */ { + else /* wct == 12 */ byte_count = bytes_sent + 5; /* bigger pad, smaller smb hdr */ - } + pSMB->DataLengthLow = cpu_to_le16(bytes_sent & 0xFFFF); pSMB->DataLengthHigh = cpu_to_le16(bytes_sent >> 16); pSMB->hdr.smb_buf_length += byte_count; @@ -1663,7 +1659,7 @@ CIFSSMBWrite2(const int xid, struct cifsTconInfo *tcon, rc = -EIO; *nbytes = 0; } else { - WRITE_RSP * pSMBr = (WRITE_RSP *)iov[0].iov_base; + WRITE_RSP *pSMBr = (WRITE_RSP *)iov[0].iov_base; *nbytes = le16_to_cpu(pSMBr->CountHigh); *nbytes = (*nbytes) << 16; *nbytes += le16_to_cpu(pSMBr->Count); @@ -1744,9 +1740,8 @@ CIFSSMBLock(const int xid, struct cifsTconInfo *tcon, /* SMB buffer freed by function above */ } cifs_stats_inc(&tcon->num_locks); - if (rc) { + if (rc) cFYI(1, ("Send error in Lock = %d", rc)); - } /* Note: On -EAGAIN error only caller can retry on handle based calls since file handle passed in no longer valid */ @@ -1791,7 +1786,7 @@ CIFSSMBPosixLock(const int xid, struct cifsTconInfo *tcon, count = sizeof(struct cifs_posix_lock); pSMB->MaxParameterCount = cpu_to_le16(2); - pSMB->MaxDataCount = cpu_to_le16(1000); /* BB find max SMB PDU from sess */ + pSMB->MaxDataCount = cpu_to_le16(1000); /* BB find max SMB from sess */ pSMB->SetupCount = 1; pSMB->Reserved3 = 0; if (get_flag) @@ -1972,9 +1967,8 @@ renameRetry: rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, (struct smb_hdr *) pSMBr, &bytes_returned, 0); cifs_stats_inc(&tcon->num_renames); - if (rc) { + if (rc) cFYI(1, ("Send error in rename = %d", rc)); - } cifs_buf_release(pSMB); @@ -2016,7 +2010,7 @@ int CIFSSMBRenameOpenFile(const int xid, struct cifsTconInfo *pTcon, data_offset = (char *) (&pSMB->hdr.Protocol) + offset; rename_info = (struct set_file_rename *) data_offset; pSMB->MaxParameterCount = cpu_to_le16(2); - pSMB->MaxDataCount = cpu_to_le16(1000); /* BB find max SMB PDU from sess */ + pSMB->MaxDataCount = cpu_to_le16(1000); /* BB find max SMB from sess */ pSMB->SetupCount = 1; pSMB->Reserved3 = 0; pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION); @@ -2052,9 +2046,8 @@ int CIFSSMBRenameOpenFile(const int xid, struct cifsTconInfo *pTcon, rc = SendReceive(xid, pTcon->ses, (struct smb_hdr *) pSMB, (struct smb_hdr *) pSMBr, &bytes_returned, 0); cifs_stats_inc(&pTcon->num_t2renames); - if (rc) { + if (rc) cFYI(1, ("Send error in Rename (by file handle) = %d", rc)); - } cifs_buf_release(pSMB); @@ -2211,9 +2204,8 @@ createSymLinkRetry: rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, (struct smb_hdr *) pSMBr, &bytes_returned, 0); cifs_stats_inc(&tcon->num_symlinks); - if (rc) { + if (rc) cFYI(1, ("Send error in SetPathInfo create symlink = %d", rc)); - } if (pSMB) cifs_buf_release(pSMB); @@ -2299,9 +2291,8 @@ createHardLinkRetry: rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, (struct smb_hdr *) pSMBr, &bytes_returned, 0); cifs_stats_inc(&tcon->num_hardlinks); - if (rc) { + if (rc) cFYI(1, ("Send error in SetPathInfo (hard link) = %d", rc)); - } cifs_buf_release(pSMB); if (rc == -EAGAIN) @@ -2370,9 +2361,9 @@ winCreateHardLinkRetry: rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, (struct smb_hdr *) pSMBr, &bytes_returned, 0); cifs_stats_inc(&tcon->num_hardlinks); - if (rc) { + if (rc) cFYI(1, ("Send error in hard link (NT rename) = %d", rc)); - } + cifs_buf_release(pSMB); if (rc == -EAGAIN) goto winCreateHardLinkRetry; @@ -2968,9 +2959,8 @@ setAclRetry: pSMB->ByteCount = cpu_to_le16(byte_count); rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, (struct smb_hdr *) pSMBr, &bytes_returned, 0); - if (rc) { + if (rc) cFYI(1, ("Set POSIX ACL returned %d", rc)); - } setACLerrorExit: cifs_buf_release(pSMB); @@ -2982,7 +2972,7 @@ setACLerrorExit: /* BB fix tabs in this function FIXME BB */ int CIFSGetExtAttr(const int xid, struct cifsTconInfo *tcon, - const int netfid, __u64 * pExtAttrBits, __u64 *pMask) + const int netfid, __u64 *pExtAttrBits, __u64 *pMask) { int rc = 0; struct smb_t2_qfi_req *pSMB = NULL; @@ -3000,7 +2990,7 @@ GetExtAttrRetry: if (rc) return rc; - params = 2 /* level */ +2 /* fid */; + params = 2 /* level */ + 2 /* fid */; pSMB->t2.TotalDataCount = 0; pSMB->t2.MaxParameterCount = cpu_to_le16(4); /* BB find exact max data count below from sess structure BB */ @@ -3071,7 +3061,7 @@ CIFSSMBGetCIFSACL(const int xid, struct cifsTconInfo *tcon, __u16 fid, { int rc = 0; int buf_type = 0; - QUERY_SEC_DESC_REQ * pSMB; + QUERY_SEC_DESC_REQ *pSMB; struct kvec iov[1]; cFYI(1, ("GetCifsACL")); @@ -3101,7 +3091,7 @@ CIFSSMBGetCIFSACL(const int xid, struct cifsTconInfo *tcon, __u16 fid, if (rc) { cFYI(1, ("Send error in QuerySecDesc = %d", rc)); } else { /* decode response */ - __le32 * parm; + __le32 *parm; __u32 parm_len; __u32 acl_len; struct smb_com_ntransact_rsp *pSMBr; @@ -3230,8 +3220,8 @@ int SMBQueryInformation(const int xid, struct cifsTconInfo *tcon, FILE_ALL_INFO *pFinfo, const struct nls_table *nls_codepage, int remap) { - QUERY_INFORMATION_REQ * pSMB; - QUERY_INFORMATION_RSP * pSMBr; + QUERY_INFORMATION_REQ *pSMB; + QUERY_INFORMATION_RSP *pSMBr; int rc = 0; int bytes_returned; int name_len; @@ -3263,9 +3253,11 @@ QInfRetry: (struct smb_hdr *) pSMBr, &bytes_returned, 0); if (rc) { cFYI(1, ("Send error in QueryInfo = %d", rc)); - } else if (pFinfo) { /* decode response */ + } else if (pFinfo) { struct timespec ts; __u32 time = le32_to_cpu(pSMBr->last_write_time); + + /* decode response */ /* BB FIXME - add time zone adjustment BB */ memset(pFinfo, 0, sizeof(FILE_ALL_INFO)); ts.tv_nsec = 0; @@ -3296,7 +3288,7 @@ QInfRetry: int CIFSSMBQPathInfo(const int xid, struct cifsTconInfo *tcon, const unsigned char *searchName, - FILE_ALL_INFO * pFindData, + FILE_ALL_INFO *pFindData, int legacy /* old style infolevel */, const struct nls_table *nls_codepage, int remap) { @@ -3371,10 +3363,12 @@ QPathInfoRetry: else if (pFindData) { int size; __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset); - if (legacy) /* we do not read the last field, EAsize, - fortunately since it varies by subdialect - and on Set vs. Get, is two bytes or 4 - bytes depending but we don't care here */ + + /* On legacy responses we do not read the last field, + EAsize, fortunately since it varies by subdialect and + also note it differs on Set vs. Get, ie two bytes or 4 + bytes depending but we don't care here */ + if (legacy) size = sizeof(FILE_INFO_STANDARD); else size = sizeof(FILE_ALL_INFO); @@ -3476,85 +3470,6 @@ UnixQPathInfoRetry: return rc; } -#if 0 /* function unused at present */ -int CIFSFindSingle(const int xid, struct cifsTconInfo *tcon, - const char *searchName, FILE_ALL_INFO * findData, - const struct nls_table *nls_codepage) -{ -/* level 257 SMB_ */ - TRANSACTION2_FFIRST_REQ *pSMB = NULL; - TRANSACTION2_FFIRST_RSP *pSMBr = NULL; - int rc = 0; - int bytes_returned; - int name_len; - __u16 params, byte_count; - - cFYI(1, ("In FindUnique")); -findUniqueRetry: - rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, - (void **) &pSMBr); - if (rc) - return rc; - - if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { - name_len = - cifsConvertToUCS((__le16 *) pSMB->FileName, searchName, - PATH_MAX, nls_codepage); - name_len++; /* trailing null */ - name_len *= 2; - } else { /* BB improve the check for buffer overruns BB */ - name_len = strnlen(searchName, PATH_MAX); - name_len++; /* trailing null */ - strncpy(pSMB->FileName, searchName, name_len); - } - - params = 12 + name_len /* includes null */ ; - pSMB->TotalDataCount = 0; /* no EAs */ - pSMB->MaxParameterCount = cpu_to_le16(2); - pSMB->MaxDataCount = cpu_to_le16(4000); /* BB find exact max SMB PDU from sess structure BB */ - pSMB->MaxSetupCount = 0; - pSMB->Reserved = 0; - pSMB->Flags = 0; - pSMB->Timeout = 0; - pSMB->Reserved2 = 0; - pSMB->ParameterOffset = cpu_to_le16( - offsetof(struct smb_com_transaction2_ffirst_req, InformationLevel)-4); - pSMB->DataCount = 0; - pSMB->DataOffset = 0; - pSMB->SetupCount = 1; /* one byte, no need to le convert */ - pSMB->Reserved3 = 0; - pSMB->SubCommand = cpu_to_le16(TRANS2_FIND_FIRST); - byte_count = params + 1 /* pad */ ; - pSMB->TotalParameterCount = cpu_to_le16(params); - pSMB->ParameterCount = pSMB->TotalParameterCount; - pSMB->SearchAttributes = - cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM | - ATTR_DIRECTORY); - pSMB->SearchCount = cpu_to_le16(16); /* BB increase */ - pSMB->SearchFlags = cpu_to_le16(1); - pSMB->InformationLevel = cpu_to_le16(SMB_FIND_FILE_DIRECTORY_INFO); - pSMB->SearchStorageType = 0; /* BB what should we set this to? BB */ - pSMB->hdr.smb_buf_length += byte_count; - pSMB->ByteCount = cpu_to_le16(byte_count); - - rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, - (struct smb_hdr *) pSMBr, &bytes_returned, 0); - - if (rc) { - cFYI(1, ("Send error in FindFileDirInfo = %d", rc)); - } else { /* decode response */ - cifs_stats_inc(&tcon->num_ffirst); - /* BB fill in */ - } - - cifs_buf_release(pSMB); - if (rc == -EAGAIN) - goto findUniqueRetry; - - return rc; -} -#endif /* end unused (temporarily) function */ - /* xid, tcon, searchName and codepage are input parms, rest are returned */ int CIFSFindFirst(const int xid, struct cifsTconInfo *tcon, @@ -3566,7 +3481,7 @@ CIFSFindFirst(const int xid, struct cifsTconInfo *tcon, /* level 257 SMB_ */ TRANSACTION2_FFIRST_REQ *pSMB = NULL; TRANSACTION2_FFIRST_RSP *pSMBr = NULL; - T2_FFIRST_RSP_PARMS * parms; + T2_FFIRST_RSP_PARMS *parms; int rc = 0; int bytes_returned = 0; int name_len; @@ -3697,7 +3612,7 @@ int CIFSFindNext(const int xid, struct cifsTconInfo *tcon, { TRANSACTION2_FNEXT_REQ *pSMB = NULL; TRANSACTION2_FNEXT_RSP *pSMBr = NULL; - T2_FNEXT_RSP_PARMS * parms; + T2_FNEXT_RSP_PARMS *parms; char *response_data; int rc = 0; int bytes_returned, name_len; @@ -3836,9 +3751,9 @@ CIFSFindClose(const int xid, struct cifsTconInfo *tcon, pSMB->FileID = searchHandle; pSMB->ByteCount = 0; rc = SendReceiveNoRsp(xid, tcon->ses, (struct smb_hdr *) pSMB, 0); - if (rc) { + if (rc) cERROR(1, ("Send error in FindClose = %d", rc)); - } + cifs_stats_inc(&tcon->num_fclose); /* Since session is dead, search handle closed on server already */ @@ -3851,7 +3766,7 @@ CIFSFindClose(const int xid, struct cifsTconInfo *tcon, int CIFSGetSrvInodeNumber(const int xid, struct cifsTconInfo *tcon, const unsigned char *searchName, - __u64 * inode_number, + __u64 *inode_number, const struct nls_table *nls_codepage, int remap) { int rc = 0; @@ -4560,9 +4475,8 @@ SETFSUnixRetry: cERROR(1, ("Send error in SETFSUnixInfo = %d", rc)); } else { /* decode response */ rc = validate_t2((struct smb_t2_rsp *)pSMBr); - if (rc) { + if (rc) rc = -EIO; /* bad smb */ - } } cifs_buf_release(pSMB); @@ -4744,9 +4658,8 @@ SetEOFRetry: pSMB->ByteCount = cpu_to_le16(byte_count); rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, (struct smb_hdr *) pSMBr, &bytes_returned, 0); - if (rc) { + if (rc) cFYI(1, ("SetPathInfo (file size) returned %d", rc)); - } cifs_buf_release(pSMB); @@ -4897,9 +4810,8 @@ CIFSSMBSetFileTimes(const int xid, struct cifsTconInfo *tcon, pSMB->ByteCount = cpu_to_le16(byte_count); memcpy(data_offset, data, sizeof(FILE_BASIC_INFO)); rc = SendReceiveNoRsp(xid, tcon->ses, (struct smb_hdr *) pSMB, 0); - if (rc) { + if (rc) cFYI(1, ("Send error in Set Time (SetFileInfo) = %d", rc)); - } /* Note: On -EAGAIN error only caller can retry on handle based calls since file handle passed in no longer valid */ @@ -4975,9 +4887,8 @@ SetTimesRetry: pSMB->ByteCount = cpu_to_le16(byte_count); rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, (struct smb_hdr *) pSMBr, &bytes_returned, 0); - if (rc) { + if (rc) cFYI(1, ("SetPathInfo (times) returned %d", rc)); - } cifs_buf_release(pSMB); @@ -5027,9 +4938,8 @@ SetAttrLgcyRetry: pSMB->ByteCount = cpu_to_le16(name_len + 1); rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, (struct smb_hdr *) pSMBr, &bytes_returned, 0); - if (rc) { + if (rc) cFYI(1, ("Error in LegacySetAttr = %d", rc)); - } cifs_buf_release(pSMB); @@ -5138,9 +5048,8 @@ setPermsRetry: pSMB->ByteCount = cpu_to_le16(byte_count); rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, (struct smb_hdr *) pSMBr, &bytes_returned, 0); - if (rc) { + if (rc) cFYI(1, ("SetPathInfo (perms) returned %d", rc)); - } if (pSMB) cifs_buf_release(pSMB); @@ -5615,9 +5524,8 @@ SetEARetry: pSMB->ByteCount = cpu_to_le16(byte_count); rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, (struct smb_hdr *) pSMBr, &bytes_returned, 0); - if (rc) { + if (rc) cFYI(1, ("SetPathInfo (EA) returned %d", rc)); - } cifs_buf_release(pSMB); diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index 65d0ba72e78f1e304af44941c74a4a1f9adb2a5d..8dbfa97cd18ca6ae60ba6621e8e9214cb7a1641d 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c @@ -1722,8 +1722,15 @@ void reset_cifs_unix_caps(int xid, struct cifsTconInfo *tcon, originally at mount time */ if ((saved_cap & CIFS_UNIX_POSIX_ACL_CAP) == 0) cap &= ~CIFS_UNIX_POSIX_ACL_CAP; - if ((saved_cap & CIFS_UNIX_POSIX_PATHNAMES_CAP) == 0) + if ((saved_cap & CIFS_UNIX_POSIX_PATHNAMES_CAP) == 0) { + if (cap & CIFS_UNIX_POSIX_PATHNAMES_CAP) + cERROR(1, ("POSIXPATH support change")); cap &= ~CIFS_UNIX_POSIX_PATHNAMES_CAP; + } else if ((cap & CIFS_UNIX_POSIX_PATHNAMES_CAP) == 0) { + cERROR(1, ("possible reconnect error")); + cERROR(1, + ("server disabled POSIX path support")); + } } cap &= CIFS_UNIX_CAP_MASK; @@ -1753,9 +1760,8 @@ void reset_cifs_unix_caps(int xid, struct cifsTconInfo *tcon, if (sb && (CIFS_SB(sb)->rsize > 127 * 1024)) { if ((cap & CIFS_UNIX_LARGE_READ_CAP) == 0) { CIFS_SB(sb)->rsize = 127 * 1024; -#ifdef CONFIG_CIFS_DEBUG2 - cFYI(1, ("larger reads not supported by srv")); -#endif + cFYI(DBG2, + ("larger reads not supported by srv")); } } @@ -1792,6 +1798,26 @@ void reset_cifs_unix_caps(int xid, struct cifsTconInfo *tcon, } } +static void +convert_delimiter(char *path, char delim) +{ + int i; + char old_delim; + + if (path == NULL) + return; + + if (delim == '/') + old_delim = '\\'; + else + old_delim = '/'; + + for (i = 0; path[i] != '\0'; i++) { + if (path[i] == old_delim) + path[i] = delim; + } +} + int cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb, char *mount_data, const char *devname) @@ -2057,7 +2083,11 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb, cifs_sb->prepath = volume_info.prepath; if (cifs_sb->prepath) { cifs_sb->prepathlen = strlen(cifs_sb->prepath); - cifs_sb->prepath[0] = CIFS_DIR_SEP(cifs_sb); + /* we can not convert the / to \ in the path + separators in the prefixpath yet because we do not + know (until reset_cifs_unix_caps is called later) + whether POSIX PATH CAP is available. We normalize + the / to \ after reset_cifs_unix_caps is called */ volume_info.prepath = NULL; } else cifs_sb->prepathlen = 0; @@ -2225,11 +2255,15 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb, else tcon->unix_ext = 0; /* server does not support them */ + /* convert forward to back slashes in prepath here if needed */ + if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS) == 0) + convert_delimiter(cifs_sb->prepath, + CIFS_DIR_SEP(cifs_sb)); + if ((tcon->unix_ext == 0) && (cifs_sb->rsize > (1024 * 127))) { cifs_sb->rsize = 1024 * 127; -#ifdef CONFIG_CIFS_DEBUG2 - cFYI(1, ("no very large read support, rsize now 127K")); -#endif + cFYI(DBG2, + ("no very large read support, rsize now 127K")); } if (!(tcon->ses->capabilities & CAP_LARGE_WRITE_X)) cifs_sb->wsize = min(cifs_sb->wsize, diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c index 699ec11984099bf432cfb44bd780235623321ff4..4e83b47c4b34328c35f9d49fc042440e35623fc6 100644 --- a/fs/cifs/dir.c +++ b/fs/cifs/dir.c @@ -3,7 +3,7 @@ * * vfs operations that deal with dentries * - * Copyright (C) International Business Machines Corp., 2002,2007 + * Copyright (C) International Business Machines Corp., 2002,2008 * Author(s): Steve French (sfrench@us.ibm.com) * * This library is free software; you can redistribute it and/or modify @@ -111,16 +111,6 @@ cifs_bp_rename_retry: return full_path; } -/* char * build_wildcard_path_from_dentry(struct dentry *direntry) -{ - if(full_path == NULL) - return full_path; - - full_path[namelen] = '\\'; - full_path[namelen+1] = '*'; - full_path[namelen+2] = 0; -BB remove above eight lines BB */ - /* Inode operations in similar order to how they appear in Linux file fs.h */ int @@ -171,9 +161,8 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode, disposition = FILE_OVERWRITE_IF; else if ((oflags & O_CREAT) == O_CREAT) disposition = FILE_OPEN_IF; - else { + else cFYI(1, ("Create flag not set in create function")); - } } /* BB add processing to set equivalent of mode - e.g. via CreateX with @@ -367,7 +356,7 @@ int cifs_mknod(struct inode *inode, struct dentry *direntry, int mode, if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) { int oplock = 0; u16 fileHandle; - FILE_ALL_INFO * buf; + FILE_ALL_INFO *buf; cFYI(1, ("sfu compat create special file")); @@ -534,9 +523,8 @@ cifs_d_revalidate(struct dentry *direntry, struct nameidata *nd) int isValid = 1; if (direntry->d_inode) { - if (cifs_revalidate(direntry)) { + if (cifs_revalidate(direntry)) return 0; - } } else { cFYI(1, ("neg dentry 0x%p name = %s", direntry, direntry->d_name.name)); diff --git a/fs/cifs/dns_resolve.h b/fs/cifs/dns_resolve.h index 073fdc3db41950ba15c022deda18bc00ac4718de..966e9288930be75bc9d952cde2960ef3191db212 100644 --- a/fs/cifs/dns_resolve.h +++ b/fs/cifs/dns_resolve.h @@ -1,7 +1,7 @@ /* * fs/cifs/dns_resolve.h -- DNS Resolver upcall management for CIFS DFS * Handles host name to IP address resolution - * + * * Copyright (c) International Business Machines Corp., 2008 * Author(s): Steve French (sfrench@us.ibm.com) * diff --git a/fs/cifs/fcntl.c b/fs/cifs/fcntl.c index 995474c90885c6dab51e2d4e0b86be6fa23d87bb..7d1d5aa4c430b6c904c08a5c65c8be32ba0a0298 100644 --- a/fs/cifs/fcntl.c +++ b/fs/cifs/fcntl.c @@ -35,9 +35,8 @@ static __u32 convert_to_cifs_notify_flags(unsigned long fcntl_notify_flags) /* No way on Linux VFS to ask to monitor xattr changes (and no stream support either */ - if (fcntl_notify_flags & DN_ACCESS) { + if (fcntl_notify_flags & DN_ACCESS) cifs_ntfy_flags |= FILE_NOTIFY_CHANGE_LAST_ACCESS; - } if (fcntl_notify_flags & DN_MODIFY) { /* What does this mean on directories? */ cifs_ntfy_flags |= FILE_NOTIFY_CHANGE_LAST_WRITE | @@ -47,9 +46,8 @@ static __u32 convert_to_cifs_notify_flags(unsigned long fcntl_notify_flags) cifs_ntfy_flags |= FILE_NOTIFY_CHANGE_CREATION | FILE_NOTIFY_CHANGE_LAST_WRITE; } - if (fcntl_notify_flags & DN_DELETE) { + if (fcntl_notify_flags & DN_DELETE) cifs_ntfy_flags |= FILE_NOTIFY_CHANGE_LAST_WRITE; - } if (fcntl_notify_flags & DN_RENAME) { /* BB review this - checking various server behaviors */ cifs_ntfy_flags |= FILE_NOTIFY_CHANGE_DIR_NAME | diff --git a/fs/cifs/file.c b/fs/cifs/file.c index 5f7c374ae89c7b833f45f4a9cdeda5ef006bdc0c..fa849c91d323e605b7696a1592288054ae068ccb 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c @@ -353,9 +353,9 @@ static int cifs_reopen_file(struct file *file, int can_flush) int disposition = FILE_OPEN; __u16 netfid; - if (file->private_data) { + if (file->private_data) pCifsFile = (struct cifsFileInfo *)file->private_data; - } else + else return -EBADF; xid = GetXid(); @@ -499,9 +499,8 @@ int cifs_close(struct inode *inode, struct file *file) the struct would be in each open file, but this should give enough time to clear the socket */ -#ifdef CONFIG_CIFS_DEBUG2 - cFYI(1, ("close delay, write pending")); -#endif /* DEBUG2 */ + cFYI(DBG2, + ("close delay, write pending")); msleep(timeout); timeout *= 4; } @@ -1423,9 +1422,8 @@ static int cifs_writepage(struct page *page, struct writeback_control *wbc) xid = GetXid(); /* BB add check for wbc flags */ page_cache_get(page); - if (!PageUptodate(page)) { + if (!PageUptodate(page)) cFYI(1, ("ppw - page not up to date")); - } /* * Set the "writeback" flag, and clear "dirty" in the radix tree. @@ -1460,9 +1458,9 @@ static int cifs_commit_write(struct file *file, struct page *page, cFYI(1, ("commit write for page %p up to position %lld for %d", page, position, to)); spin_lock(&inode->i_lock); - if (position > inode->i_size) { + if (position > inode->i_size) i_size_write(inode, position); - } + spin_unlock(&inode->i_lock); if (!PageUptodate(page)) { position = ((loff_t)page->index << PAGE_CACHE_SHIFT) + offset; @@ -1596,9 +1594,9 @@ ssize_t cifs_user_read(struct file *file, char __user *read_data, } open_file = (struct cifsFileInfo *)file->private_data; - if ((file->f_flags & O_ACCMODE) == O_WRONLY) { + if ((file->f_flags & O_ACCMODE) == O_WRONLY) cFYI(1, ("attempting read on write only file instance")); - } + for (total_read = 0, current_offset = read_data; read_size > total_read; total_read += bytes_read, current_offset += bytes_read) { @@ -1625,9 +1623,8 @@ ssize_t cifs_user_read(struct file *file, char __user *read_data, smb_read_data + 4 /* RFC1001 length field */ + le16_to_cpu(pSMBr->DataOffset), - bytes_read)) { + bytes_read)) rc = -EFAULT; - } if (buf_type == CIFS_SMALL_BUFFER) cifs_small_buf_release(smb_read_data); @@ -1814,9 +1811,7 @@ static int cifs_readpages(struct file *file, struct address_space *mapping, pTcon = cifs_sb->tcon; pagevec_init(&lru_pvec, 0); -#ifdef CONFIG_CIFS_DEBUG2 - cFYI(1, ("rpages: num pages %d", num_pages)); -#endif + cFYI(DBG2, ("rpages: num pages %d", num_pages)); for (i = 0; i < num_pages; ) { unsigned contig_pages; struct page *tmp_page; @@ -1849,10 +1844,8 @@ static int cifs_readpages(struct file *file, struct address_space *mapping, /* Read size needs to be in multiples of one page */ read_size = min_t(const unsigned int, read_size, cifs_sb->rsize & PAGE_CACHE_MASK); -#ifdef CONFIG_CIFS_DEBUG2 - cFYI(1, ("rpages: read size 0x%x contiguous pages %d", + cFYI(DBG2, ("rpages: read size 0x%x contiguous pages %d", read_size, contig_pages)); -#endif rc = -EAGAIN; while (rc == -EAGAIN) { if ((open_file->invalidHandle) && @@ -2026,7 +2019,7 @@ int is_size_safe_to_change(struct cifsInodeInfo *cifsInode, __u64 end_of_file) struct cifs_sb_info *cifs_sb; cifs_sb = CIFS_SB(cifsInode->vfs_inode.i_sb); - if ( cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO ) { + if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO) { /* since no page cache to corrupt on directio we can change size safely */ return 1; diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c index b1a4a65eaa08e0b24f1c1daf83700113f38a742b..24eb4d392155b8d4482e7ff94f369c0a8c3a035d 100644 --- a/fs/cifs/inode.c +++ b/fs/cifs/inode.c @@ -29,6 +29,130 @@ #include "cifs_debug.h" #include "cifs_fs_sb.h" + +static void cifs_set_ops(struct inode *inode) +{ + struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); + + switch (inode->i_mode & S_IFMT) { + case S_IFREG: + inode->i_op = &cifs_file_inode_ops; + if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO) { + if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL) + inode->i_fop = &cifs_file_direct_nobrl_ops; + else + inode->i_fop = &cifs_file_direct_ops; + } else if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL) + inode->i_fop = &cifs_file_nobrl_ops; + else { /* not direct, send byte range locks */ + inode->i_fop = &cifs_file_ops; + } + + + /* check if server can support readpages */ + if (cifs_sb->tcon->ses->server->maxBuf < + PAGE_CACHE_SIZE + MAX_CIFS_HDR_SIZE) + inode->i_data.a_ops = &cifs_addr_ops_smallbuf; + else + inode->i_data.a_ops = &cifs_addr_ops; + break; + case S_IFDIR: + inode->i_op = &cifs_dir_inode_ops; + inode->i_fop = &cifs_dir_ops; + break; + case S_IFLNK: + inode->i_op = &cifs_symlink_inode_ops; + break; + default: + init_special_inode(inode, inode->i_mode, inode->i_rdev); + break; + } +} + +static void cifs_unix_info_to_inode(struct inode *inode, + FILE_UNIX_BASIC_INFO *info, int force_uid_gid) +{ + struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); + struct cifsInodeInfo *cifsInfo = CIFS_I(inode); + __u64 num_of_bytes = le64_to_cpu(info->NumOfBytes); + __u64 end_of_file = le64_to_cpu(info->EndOfFile); + + inode->i_atime = cifs_NTtimeToUnix(le64_to_cpu(info->LastAccessTime)); + inode->i_mtime = + cifs_NTtimeToUnix(le64_to_cpu(info->LastModificationTime)); + inode->i_ctime = cifs_NTtimeToUnix(le64_to_cpu(info->LastStatusChange)); + inode->i_mode = le64_to_cpu(info->Permissions); + + /* + * Since we set the inode type below we need to mask off + * to avoid strange results if bits set above. + */ + inode->i_mode &= ~S_IFMT; + switch (le32_to_cpu(info->Type)) { + case UNIX_FILE: + inode->i_mode |= S_IFREG; + break; + case UNIX_SYMLINK: + inode->i_mode |= S_IFLNK; + break; + case UNIX_DIR: + inode->i_mode |= S_IFDIR; + break; + case UNIX_CHARDEV: + inode->i_mode |= S_IFCHR; + inode->i_rdev = MKDEV(le64_to_cpu(info->DevMajor), + le64_to_cpu(info->DevMinor) & MINORMASK); + break; + case UNIX_BLOCKDEV: + inode->i_mode |= S_IFBLK; + inode->i_rdev = MKDEV(le64_to_cpu(info->DevMajor), + le64_to_cpu(info->DevMinor) & MINORMASK); + break; + case UNIX_FIFO: + inode->i_mode |= S_IFIFO; + break; + case UNIX_SOCKET: + inode->i_mode |= S_IFSOCK; + break; + default: + /* safest to call it a file if we do not know */ + inode->i_mode |= S_IFREG; + cFYI(1, ("unknown type %d", le32_to_cpu(info->Type))); + break; + } + + if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_UID) && + !force_uid_gid) + inode->i_uid = cifs_sb->mnt_uid; + else + inode->i_uid = le64_to_cpu(info->Uid); + + if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_GID) && + !force_uid_gid) + inode->i_gid = cifs_sb->mnt_gid; + else + inode->i_gid = le64_to_cpu(info->Gid); + + inode->i_nlink = le64_to_cpu(info->Nlinks); + + spin_lock(&inode->i_lock); + if (is_size_safe_to_change(cifsInfo, end_of_file)) { + /* + * We can not safely change the file size here if the client + * is writing to it due to potential races. + */ + i_size_write(inode, end_of_file); + + /* + * i_blocks is not related to (i_size / i_blksize), + * but instead 512 byte (2**9) size is required for + * calculating num blocks. + */ + inode->i_blocks = (512 - 1 + num_of_bytes) >> 9; + } + spin_unlock(&inode->i_lock); +} + int cifs_get_inode_info_unix(struct inode **pinode, const unsigned char *search_path, struct super_block *sb, int xid) { @@ -74,7 +198,6 @@ int cifs_get_inode_info_unix(struct inode **pinode, } } else { struct cifsInodeInfo *cifsInfo; - __u32 type = le32_to_cpu(findData.Type); __u64 num_of_bytes = le64_to_cpu(findData.NumOfBytes); __u64 end_of_file = le64_to_cpu(findData.EndOfFile); @@ -105,112 +228,16 @@ int cifs_get_inode_info_unix(struct inode **pinode, /* this is ok to set on every inode revalidate */ atomic_set(&cifsInfo->inUse, 1); - inode->i_atime = - cifs_NTtimeToUnix(le64_to_cpu(findData.LastAccessTime)); - inode->i_mtime = - cifs_NTtimeToUnix(le64_to_cpu - (findData.LastModificationTime)); - inode->i_ctime = - cifs_NTtimeToUnix(le64_to_cpu(findData.LastStatusChange)); - inode->i_mode = le64_to_cpu(findData.Permissions); - /* since we set the inode type below we need to mask off - to avoid strange results if bits set above */ - inode->i_mode &= ~S_IFMT; - if (type == UNIX_FILE) { - inode->i_mode |= S_IFREG; - } else if (type == UNIX_SYMLINK) { - inode->i_mode |= S_IFLNK; - } else if (type == UNIX_DIR) { - inode->i_mode |= S_IFDIR; - } else if (type == UNIX_CHARDEV) { - inode->i_mode |= S_IFCHR; - inode->i_rdev = MKDEV(le64_to_cpu(findData.DevMajor), - le64_to_cpu(findData.DevMinor) & MINORMASK); - } else if (type == UNIX_BLOCKDEV) { - inode->i_mode |= S_IFBLK; - inode->i_rdev = MKDEV(le64_to_cpu(findData.DevMajor), - le64_to_cpu(findData.DevMinor) & MINORMASK); - } else if (type == UNIX_FIFO) { - inode->i_mode |= S_IFIFO; - } else if (type == UNIX_SOCKET) { - inode->i_mode |= S_IFSOCK; - } else { - /* safest to call it a file if we do not know */ - inode->i_mode |= S_IFREG; - cFYI(1, ("unknown type %d", type)); - } + cifs_unix_info_to_inode(inode, &findData, 0); - if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_UID) - inode->i_uid = cifs_sb->mnt_uid; - else - inode->i_uid = le64_to_cpu(findData.Uid); - - if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_GID) - inode->i_gid = cifs_sb->mnt_gid; - else - inode->i_gid = le64_to_cpu(findData.Gid); - - inode->i_nlink = le64_to_cpu(findData.Nlinks); - - spin_lock(&inode->i_lock); - if (is_size_safe_to_change(cifsInfo, end_of_file)) { - /* can not safely change the file size here if the - client is writing to it due to potential races */ - i_size_write(inode, end_of_file); - - /* blksize needs to be multiple of two. So safer to default to - blksize and blkbits set in superblock so 2**blkbits and blksize - will match rather than setting to: - (pTcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE) & 0xFFFFFE00;*/ - - /* This seems incredibly stupid but it turns out that i_blocks - is not related to (i_size / i_blksize), instead 512 byte size - is required for calculating num blocks */ - - /* 512 bytes (2**9) is the fake blocksize that must be used */ - /* for this calculation */ - inode->i_blocks = (512 - 1 + num_of_bytes) >> 9; - } - spin_unlock(&inode->i_lock); if (num_of_bytes < end_of_file) cFYI(1, ("allocation size less than end of file")); cFYI(1, ("Size %ld and blocks %llu", (unsigned long) inode->i_size, (unsigned long long)inode->i_blocks)); - if (S_ISREG(inode->i_mode)) { - cFYI(1, ("File inode")); - inode->i_op = &cifs_file_inode_ops; - if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO) { - if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL) - inode->i_fop = - &cifs_file_direct_nobrl_ops; - else - inode->i_fop = &cifs_file_direct_ops; - } else if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL) - inode->i_fop = &cifs_file_nobrl_ops; - else /* not direct, send byte range locks */ - inode->i_fop = &cifs_file_ops; - - /* check if server can support readpages */ - if (pTcon->ses->server->maxBuf < - PAGE_CACHE_SIZE + MAX_CIFS_HDR_SIZE) - inode->i_data.a_ops = &cifs_addr_ops_smallbuf; - else - inode->i_data.a_ops = &cifs_addr_ops; - } else if (S_ISDIR(inode->i_mode)) { - cFYI(1, ("Directory inode")); - inode->i_op = &cifs_dir_inode_ops; - inode->i_fop = &cifs_dir_ops; - } else if (S_ISLNK(inode->i_mode)) { - cFYI(1, ("Symbolic Link inode")); - inode->i_op = &cifs_symlink_inode_ops; - /* tmp_inode->i_fop = */ /* do not need to set to anything */ - } else { - cFYI(1, ("Init special inode")); - init_special_inode(inode, inode->i_mode, - inode->i_rdev); - } + + cifs_set_ops(inode); } return rc; } @@ -490,9 +517,9 @@ int cifs_get_inode_info(struct inode **pinode, if (decode_sfu_inode(inode, le64_to_cpu(pfindData->EndOfFile), search_path, - cifs_sb, xid)) { + cifs_sb, xid)) cFYI(1, ("Unrecognized sfu inode type")); - } + cFYI(1, ("sfu mode 0%o", inode->i_mode)); } else { inode->i_mode |= S_IFREG; @@ -546,36 +573,7 @@ int cifs_get_inode_info(struct inode **pinode, atomic_set(&cifsInfo->inUse, 1); } - if (S_ISREG(inode->i_mode)) { - cFYI(1, ("File inode")); - inode->i_op = &cifs_file_inode_ops; - if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO) { - if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL) - inode->i_fop = - &cifs_file_direct_nobrl_ops; - else - inode->i_fop = &cifs_file_direct_ops; - } else if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL) - inode->i_fop = &cifs_file_nobrl_ops; - else /* not direct, send byte range locks */ - inode->i_fop = &cifs_file_ops; - - if (pTcon->ses->server->maxBuf < - PAGE_CACHE_SIZE + MAX_CIFS_HDR_SIZE) - inode->i_data.a_ops = &cifs_addr_ops_smallbuf; - else - inode->i_data.a_ops = &cifs_addr_ops; - } else if (S_ISDIR(inode->i_mode)) { - cFYI(1, ("Directory inode")); - inode->i_op = &cifs_dir_inode_ops; - inode->i_fop = &cifs_dir_ops; - } else if (S_ISLNK(inode->i_mode)) { - cFYI(1, ("Symbolic Link inode")); - inode->i_op = &cifs_symlink_inode_ops; - } else { - init_special_inode(inode, inode->i_mode, - inode->i_rdev); - } + cifs_set_ops(inode); } kfree(buf); return rc; @@ -792,17 +790,12 @@ psx_del_no_retry: } static void posix_fill_in_inode(struct inode *tmp_inode, - FILE_UNIX_BASIC_INFO *pData, int *pobject_type, int isNewInode) + FILE_UNIX_BASIC_INFO *pData, int isNewInode) { + struct cifsInodeInfo *cifsInfo = CIFS_I(tmp_inode); loff_t local_size; struct timespec local_mtime; - struct cifsInodeInfo *cifsInfo = CIFS_I(tmp_inode); - struct cifs_sb_info *cifs_sb = CIFS_SB(tmp_inode->i_sb); - - __u32 type = le32_to_cpu(pData->Type); - __u64 num_of_bytes = le64_to_cpu(pData->NumOfBytes); - __u64 end_of_file = le64_to_cpu(pData->EndOfFile); cifsInfo->time = jiffies; atomic_inc(&cifsInfo->inUse); @@ -810,115 +803,27 @@ static void posix_fill_in_inode(struct inode *tmp_inode, local_mtime = tmp_inode->i_mtime; local_size = tmp_inode->i_size; - tmp_inode->i_atime = - cifs_NTtimeToUnix(le64_to_cpu(pData->LastAccessTime)); - tmp_inode->i_mtime = - cifs_NTtimeToUnix(le64_to_cpu(pData->LastModificationTime)); - tmp_inode->i_ctime = - cifs_NTtimeToUnix(le64_to_cpu(pData->LastStatusChange)); - - tmp_inode->i_mode = le64_to_cpu(pData->Permissions); - /* since we set the inode type below we need to mask off type - to avoid strange results if bits above were corrupt */ - tmp_inode->i_mode &= ~S_IFMT; - if (type == UNIX_FILE) { - *pobject_type = DT_REG; - tmp_inode->i_mode |= S_IFREG; - } else if (type == UNIX_SYMLINK) { - *pobject_type = DT_LNK; - tmp_inode->i_mode |= S_IFLNK; - } else if (type == UNIX_DIR) { - *pobject_type = DT_DIR; - tmp_inode->i_mode |= S_IFDIR; - } else if (type == UNIX_CHARDEV) { - *pobject_type = DT_CHR; - tmp_inode->i_mode |= S_IFCHR; - tmp_inode->i_rdev = MKDEV(le64_to_cpu(pData->DevMajor), - le64_to_cpu(pData->DevMinor) & MINORMASK); - } else if (type == UNIX_BLOCKDEV) { - *pobject_type = DT_BLK; - tmp_inode->i_mode |= S_IFBLK; - tmp_inode->i_rdev = MKDEV(le64_to_cpu(pData->DevMajor), - le64_to_cpu(pData->DevMinor) & MINORMASK); - } else if (type == UNIX_FIFO) { - *pobject_type = DT_FIFO; - tmp_inode->i_mode |= S_IFIFO; - } else if (type == UNIX_SOCKET) { - *pobject_type = DT_SOCK; - tmp_inode->i_mode |= S_IFSOCK; - } else { - /* safest to just call it a file */ - *pobject_type = DT_REG; - tmp_inode->i_mode |= S_IFREG; - cFYI(1, ("unknown inode type %d", type)); - } - -#ifdef CONFIG_CIFS_DEBUG2 - cFYI(1, ("object type: %d", type)); -#endif - tmp_inode->i_uid = le64_to_cpu(pData->Uid); - tmp_inode->i_gid = le64_to_cpu(pData->Gid); - tmp_inode->i_nlink = le64_to_cpu(pData->Nlinks); - - spin_lock(&tmp_inode->i_lock); - if (is_size_safe_to_change(cifsInfo, end_of_file)) { - /* can not safely change the file size here if the - client is writing to it due to potential races */ - i_size_write(tmp_inode, end_of_file); + cifs_unix_info_to_inode(tmp_inode, pData, 1); + cifs_set_ops(tmp_inode); - /* 512 bytes (2**9) is the fake blocksize that must be used */ - /* for this calculation, not the real blocksize */ - tmp_inode->i_blocks = (512 - 1 + num_of_bytes) >> 9; - } - spin_unlock(&tmp_inode->i_lock); - - if (S_ISREG(tmp_inode->i_mode)) { - cFYI(1, ("File inode")); - tmp_inode->i_op = &cifs_file_inode_ops; - - if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO) { - if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL) - tmp_inode->i_fop = &cifs_file_direct_nobrl_ops; - else - tmp_inode->i_fop = &cifs_file_direct_ops; + if (!S_ISREG(tmp_inode->i_mode)) + return; - } else if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL) - tmp_inode->i_fop = &cifs_file_nobrl_ops; - else - tmp_inode->i_fop = &cifs_file_ops; - - if ((cifs_sb->tcon) && (cifs_sb->tcon->ses) && - (cifs_sb->tcon->ses->server->maxBuf < - PAGE_CACHE_SIZE + MAX_CIFS_HDR_SIZE)) - tmp_inode->i_data.a_ops = &cifs_addr_ops_smallbuf; - else - tmp_inode->i_data.a_ops = &cifs_addr_ops; - - if (isNewInode) - return; /* No sense invalidating pages for new inode - since we we have not started caching - readahead file data yet */ + /* + * No sense invalidating pages for new inode + * since we we have not started caching + * readahead file data yet. + */ + if (isNewInode) + return; - if (timespec_equal(&tmp_inode->i_mtime, &local_mtime) && - (local_size == tmp_inode->i_size)) { - cFYI(1, ("inode exists but unchanged")); - } else { - /* file may have changed on server */ - cFYI(1, ("invalidate inode, readdir detected change")); - invalidate_remote_inode(tmp_inode); - } - } else if (S_ISDIR(tmp_inode->i_mode)) { - cFYI(1, ("Directory inode")); - tmp_inode->i_op = &cifs_dir_inode_ops; - tmp_inode->i_fop = &cifs_dir_ops; - } else if (S_ISLNK(tmp_inode->i_mode)) { - cFYI(1, ("Symbolic Link inode")); - tmp_inode->i_op = &cifs_symlink_inode_ops; -/* tmp_inode->i_fop = *//* do not need to set to anything */ + if (timespec_equal(&tmp_inode->i_mtime, &local_mtime) && + (local_size == tmp_inode->i_size)) { + cFYI(1, ("inode exists but unchanged")); } else { - cFYI(1, ("Special inode")); - init_special_inode(tmp_inode, tmp_inode->i_mode, - tmp_inode->i_rdev); + /* file may have changed on server */ + cFYI(1, ("invalidate inode, readdir detected change")); + invalidate_remote_inode(tmp_inode); } } @@ -968,7 +873,6 @@ int cifs_mkdir(struct inode *inode, struct dentry *direntry, int mode) cFYI(1, ("posix mkdir returned 0x%x", rc)); d_drop(direntry); } else { - int obj_type; if (pInfo->Type == cpu_to_le32(-1)) { /* no return info, go query for it */ kfree(pInfo); @@ -1004,7 +908,7 @@ int cifs_mkdir(struct inode *inode, struct dentry *direntry, int mode) /* we already checked in POSIXCreate whether frame was long enough */ posix_fill_in_inode(direntry->d_inode, - pInfo, &obj_type, 1 /* NewInode */); + pInfo, 1 /* NewInode */); #ifdef CONFIG_CIFS_DEBUG2 cFYI(1, ("instantiated dentry %p %s to inode %p", direntry, direntry->d_name.name, newinode)); @@ -1214,9 +1118,8 @@ int cifs_rename(struct inode *source_inode, struct dentry *source_direntry, } /* if we can not get memory just leave rc as EEXIST */ } - if (rc) { + if (rc) cFYI(1, ("rename rc %d", rc)); - } if ((rc == -EIO) || (rc == -EEXIST)) { int oplock = FALSE; diff --git a/fs/cifs/ioctl.c b/fs/cifs/ioctl.c index d24fe6880a04e63f1ea370ef67ca92f0205f3fb5..5c792df13d62f518224378a0c9a795d9440040a7 100644 --- a/fs/cifs/ioctl.c +++ b/fs/cifs/ioctl.c @@ -30,7 +30,7 @@ #define CIFS_IOC_CHECKUMOUNT _IO(0xCF, 2) -int cifs_ioctl (struct inode *inode, struct file *filep, +int cifs_ioctl(struct inode *inode, struct file *filep, unsigned int command, unsigned long arg) { int rc = -ENOTTY; /* strange error - but the precedent */ diff --git a/fs/cifs/md4.c b/fs/cifs/md4.c index a2415c1a14dbbe297326ffd6c00ba2b9c0631361..a725c2609d672f36eab258996163cd476fca354b 100644 --- a/fs/cifs/md4.c +++ b/fs/cifs/md4.c @@ -56,7 +56,7 @@ lshift(__u32 x, int s) /* this applies md4 to 64 byte chunks */ static void -mdfour64(__u32 * M, __u32 * A, __u32 *B, __u32 * C, __u32 *D) +mdfour64(__u32 *M, __u32 *A, __u32 *B, __u32 *C, __u32 *D) { int j; __u32 AA, BB, CC, DD; @@ -137,7 +137,7 @@ mdfour64(__u32 * M, __u32 * A, __u32 *B, __u32 * C, __u32 *D) } static void -copy64(__u32 * M, unsigned char *in) +copy64(__u32 *M, unsigned char *in) { int i; diff --git a/fs/cifs/md5.c b/fs/cifs/md5.c index f13f96d42fcf63ebdfe4c76a1914a3d0afd03738..462bbfefd4b671771a52658ec08fa0efd72e9e5c 100644 --- a/fs/cifs/md5.c +++ b/fs/cifs/md5.c @@ -161,7 +161,7 @@ MD5Final(unsigned char digest[16], struct MD5Context *ctx) /* This is the central step in the MD5 algorithm. */ #define MD5STEP(f, w, x, y, z, data, s) \ - ( w += f(x, y, z) + data, w = w<>(32-s), w += x ) + (w += f(x, y, z) + data, w = w<>(32-s), w += x) /* * The core of the MD5 algorithm, this alters an existing MD5 hash to @@ -302,9 +302,8 @@ hmac_md5_init_limK_to_64(const unsigned char *key, int key_len, int i; /* if key is longer than 64 bytes truncate it */ - if (key_len > 64) { + if (key_len > 64) key_len = 64; - } /* start out by storing key in pads */ memset(ctx->k_ipad, 0, sizeof(ctx->k_ipad)); @@ -359,9 +358,9 @@ hmac_md5(unsigned char key[16], unsigned char *data, int data_len, { struct HMACMD5Context ctx; hmac_md5_init_limK_to_64(key, 16, &ctx); - if (data_len != 0) { + if (data_len != 0) hmac_md5_update(data, data_len, &ctx); - } + hmac_md5_final(digest, &ctx); } #endif diff --git a/fs/cifs/misc.c b/fs/cifs/misc.c index 15546c2354c5800b7930860304a0d043273db7fb..2a42d9fedbb266751f7f9e96dd4fb4a079d75b7e 100644 --- a/fs/cifs/misc.c +++ b/fs/cifs/misc.c @@ -1,7 +1,7 @@ /* * fs/cifs/misc.c * - * Copyright (C) International Business Machines Corp., 2002,2007 + * Copyright (C) International Business Machines Corp., 2002,2008 * Author(s): Steve French (sfrench@us.ibm.com) * * This library is free software; you can redistribute it and/or modify @@ -320,9 +320,9 @@ header_assemble(struct smb_hdr *buffer, char smb_command /* command */ , if (treeCon->ses) { if (treeCon->ses->capabilities & CAP_UNICODE) buffer->Flags2 |= SMBFLG2_UNICODE; - if (treeCon->ses->capabilities & CAP_STATUS32) { + if (treeCon->ses->capabilities & CAP_STATUS32) buffer->Flags2 |= SMBFLG2_ERR_STATUS; - } + /* Uid is not converted */ buffer->Uid = treeCon->ses->Suid; buffer->Mid = GetNextMid(treeCon->ses->server); @@ -610,7 +610,8 @@ dump_smb(struct smb_hdr *smb_buf, int smb_buf_length) buffer = (unsigned char *) smb_buf; for (i = 0, j = 0; i < smb_buf_length; i++, j++) { - if (i % 8 == 0) { /* have reached the beginning of line */ + if (i % 8 == 0) { + /* have reached the beginning of line */ printk(KERN_DEBUG "| "); j = 0; } @@ -621,7 +622,8 @@ dump_smb(struct smb_hdr *smb_buf, int smb_buf_length) else debug_line[1 + (2 * j)] = '_'; - if (i % 8 == 7) { /* reached end of line, time to print ascii */ + if (i % 8 == 7) { + /* reached end of line, time to print ascii */ debug_line[16] = 0; printk(" | %s\n", debug_line); } @@ -631,7 +633,7 @@ dump_smb(struct smb_hdr *smb_buf, int smb_buf_length) debug_line[2 * j] = ' '; debug_line[1 + (2 * j)] = ' '; } - printk( " | %s\n", debug_line); + printk(" | %s\n", debug_line); return; } diff --git a/fs/cifs/netmisc.c b/fs/cifs/netmisc.c index 646e1f06941b5c8062e9c8e590c2e2790736ab7f..3b5a5ce882b63083f492c34a3e1b007fe54be87f 100644 --- a/fs/cifs/netmisc.c +++ b/fs/cifs/netmisc.c @@ -1,7 +1,7 @@ /* * fs/cifs/netmisc.c * - * Copyright (c) International Business Machines Corp., 2002 + * Copyright (c) International Business Machines Corp., 2002,2008 * Author(s): Steve French (sfrench@us.ibm.com) * * Error mapping routines from Samba libsmb/errormap.c @@ -150,9 +150,7 @@ static int canonicalize_unc(char *cp) if (cp[i] == '\\') break; if (cp[i] == '/') { -#ifdef CONFIG_CIFS_DEBUG2 - cFYI(1, ("change slash to backslash in malformed UNC")); -#endif + cFYI(DBG2, ("change slash to \\ in malformed UNC")); cp[i] = '\\'; return 1; } @@ -178,9 +176,7 @@ cifs_inet_pton(int address_family, char *cp, void *dst) } else if (address_family == AF_INET6) { ret = in6_pton(cp, -1 /* len */, dst , '\\', NULL); } -#ifdef CONFIG_CIFS_DEBUG2 - cFYI(1, ("address conversion returned %d for %s", ret, cp)); -#endif + cFYI(DBG2, ("address conversion returned %d for %s", ret, cp)); if (ret > 0) ret = 1; return ret; @@ -253,7 +249,8 @@ static const struct { ERRDOS, 87, NT_STATUS_INVALID_PARAMETER_MIX}, { ERRHRD, ERRgeneral, NT_STATUS_INVALID_QUOTA_LOWER}, { ERRHRD, ERRgeneral, NT_STATUS_DISK_CORRUPT_ERROR}, { - ERRDOS, ERRbadfile, NT_STATUS_OBJECT_NAME_INVALID}, { /* mapping changed since shell does lookup on * and expects file not found */ + /* mapping changed since shell does lookup on * expects FileNotFound */ + ERRDOS, ERRbadfile, NT_STATUS_OBJECT_NAME_INVALID}, { ERRDOS, ERRbadfile, NT_STATUS_OBJECT_NAME_NOT_FOUND}, { ERRDOS, ERRalreadyexists, NT_STATUS_OBJECT_NAME_COLLISION}, { ERRHRD, ERRgeneral, NT_STATUS_HANDLE_NOT_WAITABLE}, { @@ -820,7 +817,8 @@ map_smb_to_linux_error(struct smb_hdr *smb, int logErr) /* old style errors */ /* DOS class smb error codes - map DOS */ - if (smberrclass == ERRDOS) { /* 1 byte field no need to byte reverse */ + if (smberrclass == ERRDOS) { + /* 1 byte field no need to byte reverse */ for (i = 0; i < sizeof(mapping_table_ERRDOS) / @@ -834,7 +832,8 @@ map_smb_to_linux_error(struct smb_hdr *smb, int logErr) } /* else try next error mapping one to see if match */ } - } else if (smberrclass == ERRSRV) { /* server class of error codes */ + } else if (smberrclass == ERRSRV) { + /* server class of error codes */ for (i = 0; i < sizeof(mapping_table_ERRSRV) / @@ -922,8 +921,8 @@ struct timespec cnvrtDosUnixTm(__u16 date, __u16 time) { struct timespec ts; int sec, min, days, month, year; - SMB_TIME * st = (SMB_TIME *)&time; - SMB_DATE * sd = (SMB_DATE *)&date; + SMB_TIME *st = (SMB_TIME *)&time; + SMB_DATE *sd = (SMB_DATE *)&date; cFYI(1, ("date %d time %d", date, time)); diff --git a/fs/cifs/readdir.c b/fs/cifs/readdir.c index 0f22def4bdff47e30300dec9bcad5be12cd193d6..32b445edc88282d2ce55ab1bd5a8f7bc2b9d7b3d 100644 --- a/fs/cifs/readdir.c +++ b/fs/cifs/readdir.c @@ -3,7 +3,7 @@ * * Directory search handling * - * Copyright (C) International Business Machines Corp., 2004, 2007 + * Copyright (C) International Business Machines Corp., 2004, 2008 * Author(s): Steve French (sfrench@us.ibm.com) * * This library is free software; you can redistribute it and/or modify @@ -42,17 +42,18 @@ static void dump_cifs_file_struct(struct file *file, char *label) cFYI(1, ("empty cifs private file data")); return; } - if (cf->invalidHandle) { + if (cf->invalidHandle) cFYI(1, ("invalid handle")); - } - if (cf->srch_inf.endOfSearch) { + if (cf->srch_inf.endOfSearch) cFYI(1, ("end of search")); - } - if (cf->srch_inf.emptyDir) { + if (cf->srch_inf.emptyDir) cFYI(1, ("empty dir")); - } } } +#else +static inline void dump_cifs_file_struct(struct file *file, char *label) +{ +} #endif /* DEBUG2 */ /* Returns one if new inode created (which therefore needs to be hashed) */ @@ -150,7 +151,7 @@ static void fill_in_inode(struct inode *tmp_inode, int new_buf_type, cifs_NTtimeToUnix(le64_to_cpu(pfindData->ChangeTime)); } else { /* legacy, OS2 and DOS style */ /* struct timespec ts;*/ - FIND_FILE_STANDARD_INFO * pfindData = + FIND_FILE_STANDARD_INFO *pfindData = (FIND_FILE_STANDARD_INFO *)buf; tmp_inode->i_mtime = cnvrtDosUnixTm( @@ -198,9 +199,8 @@ static void fill_in_inode(struct inode *tmp_inode, int new_buf_type, if (attr & ATTR_DIRECTORY) { *pobject_type = DT_DIR; /* override default perms since we do not lock dirs */ - if (atomic_read(&cifsInfo->inUse) == 0) { + if (atomic_read(&cifsInfo->inUse) == 0) tmp_inode->i_mode = cifs_sb->mnt_dir_mode; - } tmp_inode->i_mode |= S_IFDIR; } else if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) && (attr & ATTR_SYSTEM)) { @@ -231,9 +231,8 @@ static void fill_in_inode(struct inode *tmp_inode, int new_buf_type, } /* could add code here - to validate if device or weird share type? */ /* can not fill in nlink here as in qpathinfo version and Unx search */ - if (atomic_read(&cifsInfo->inUse) == 0) { + if (atomic_read(&cifsInfo->inUse) == 0) atomic_set(&cifsInfo->inUse, 1); - } spin_lock(&tmp_inode->i_lock); if (is_size_safe_to_change(cifsInfo, end_of_file)) { @@ -461,9 +460,8 @@ static int initiate_cifs_search(const int xid, struct file *file) full_path = build_path_from_dentry(file->f_path.dentry); - if (full_path == NULL) { + if (full_path == NULL) return -ENOMEM; - } cFYI(1, ("Full path: %s start at: %lld", full_path, file->f_pos)); @@ -471,9 +469,9 @@ ffirst_retry: /* test for Unix extensions */ /* but now check for them on the share/mount not on the SMB session */ /* if (pTcon->ses->capabilities & CAP_UNIX) { */ - if (pTcon->unix_ext) { + if (pTcon->unix_ext) cifsFile->srch_inf.info_level = SMB_FIND_FILE_UNIX; - } else if ((pTcon->ses->capabilities & + else if ((pTcon->ses->capabilities & (CAP_NT_SMBS | CAP_NT_FIND)) == 0) { cifsFile->srch_inf.info_level = SMB_FIND_FILE_INFO_STANDARD; } else if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) { @@ -514,10 +512,10 @@ static int cifs_unicode_bytelen(char *str) static char *nxt_dir_entry(char *old_entry, char *end_of_smb, int level) { char *new_entry; - FILE_DIRECTORY_INFO * pDirInfo = (FILE_DIRECTORY_INFO *)old_entry; + FILE_DIRECTORY_INFO *pDirInfo = (FILE_DIRECTORY_INFO *)old_entry; if (level == SMB_FIND_FILE_INFO_STANDARD) { - FIND_FILE_STANDARD_INFO * pfData; + FIND_FILE_STANDARD_INFO *pfData; pfData = (FIND_FILE_STANDARD_INFO *)pDirInfo; new_entry = old_entry + sizeof(FIND_FILE_STANDARD_INFO) + @@ -553,7 +551,7 @@ static int cifs_entry_is_dot(char *current_entry, struct cifsFileInfo *cfile) int len = 0; if (cfile->srch_inf.info_level == SMB_FIND_FILE_UNIX) { - FILE_UNIX_INFO * pFindData = (FILE_UNIX_INFO *)current_entry; + FILE_UNIX_INFO *pFindData = (FILE_UNIX_INFO *)current_entry; filename = &pFindData->FileName[0]; if (cfile->srch_inf.unicode) { len = cifs_unicode_bytelen(filename); @@ -562,30 +560,30 @@ static int cifs_entry_is_dot(char *current_entry, struct cifsFileInfo *cfile) len = strnlen(filename, 5); } } else if (cfile->srch_inf.info_level == SMB_FIND_FILE_DIRECTORY_INFO) { - FILE_DIRECTORY_INFO * pFindData = + FILE_DIRECTORY_INFO *pFindData = (FILE_DIRECTORY_INFO *)current_entry; filename = &pFindData->FileName[0]; len = le32_to_cpu(pFindData->FileNameLength); } else if (cfile->srch_inf.info_level == SMB_FIND_FILE_FULL_DIRECTORY_INFO) { - FILE_FULL_DIRECTORY_INFO * pFindData = + FILE_FULL_DIRECTORY_INFO *pFindData = (FILE_FULL_DIRECTORY_INFO *)current_entry; filename = &pFindData->FileName[0]; len = le32_to_cpu(pFindData->FileNameLength); } else if (cfile->srch_inf.info_level == SMB_FIND_FILE_ID_FULL_DIR_INFO) { - SEARCH_ID_FULL_DIR_INFO * pFindData = + SEARCH_ID_FULL_DIR_INFO *pFindData = (SEARCH_ID_FULL_DIR_INFO *)current_entry; filename = &pFindData->FileName[0]; len = le32_to_cpu(pFindData->FileNameLength); } else if (cfile->srch_inf.info_level == SMB_FIND_FILE_BOTH_DIRECTORY_INFO) { - FILE_BOTH_DIRECTORY_INFO * pFindData = + FILE_BOTH_DIRECTORY_INFO *pFindData = (FILE_BOTH_DIRECTORY_INFO *)current_entry; filename = &pFindData->FileName[0]; len = le32_to_cpu(pFindData->FileNameLength); } else if (cfile->srch_inf.info_level == SMB_FIND_FILE_INFO_STANDARD) { - FIND_FILE_STANDARD_INFO * pFindData = + FIND_FILE_STANDARD_INFO *pFindData = (FIND_FILE_STANDARD_INFO *)current_entry; filename = &pFindData->FileName[0]; len = pFindData->FileNameLength; @@ -666,9 +664,7 @@ static int find_cifs_entry(const int xid, struct cifsTconInfo *pTcon, . and .. for the root of a drive and for those we need to start two entries earlier */ -#ifdef CONFIG_CIFS_DEBUG2 dump_cifs_file_struct(file, "In fce "); -#endif if (((index_to_find < cifsFile->srch_inf.index_of_last_entry) && is_dir_changed(file)) || (index_to_find < first_entry_in_buffer)) { @@ -718,7 +714,7 @@ static int find_cifs_entry(const int xid, struct cifsTconInfo *pTcon, pos_in_buf = index_to_find - first_entry_in_buffer; cFYI(1, ("found entry - pos_in_buf %d", pos_in_buf)); - for (i=0; (i < (pos_in_buf)) && (current_entry != NULL); i++) { + for (i = 0; (i < (pos_in_buf)) && (current_entry != NULL); i++) { /* go entry by entry figuring out which is first */ current_entry = nxt_dir_entry(current_entry, end_of_smb, cifsFile->srch_inf.info_level); @@ -793,7 +789,7 @@ static int cifs_get_name_from_search_buf(struct qstr *pqst, filename = &pFindData->FileName[0]; len = le32_to_cpu(pFindData->FileNameLength); } else if (level == SMB_FIND_FILE_INFO_STANDARD) { - FIND_FILE_STANDARD_INFO * pFindData = + FIND_FILE_STANDARD_INFO *pFindData = (FIND_FILE_STANDARD_INFO *)current_entry; filename = &pFindData->FileName[0]; /* one byte length, no name conversion */ @@ -928,7 +924,7 @@ static int cifs_save_resume_key(const char *current_entry, level = cifsFile->srch_inf.info_level; if (level == SMB_FIND_FILE_UNIX) { - FILE_UNIX_INFO * pFindData = (FILE_UNIX_INFO *)current_entry; + FILE_UNIX_INFO *pFindData = (FILE_UNIX_INFO *)current_entry; filename = &pFindData->FileName[0]; if (cifsFile->srch_inf.unicode) { diff --git a/fs/cifs/sess.c b/fs/cifs/sess.c index d2153abcba6d7983678e8e08df39eee7bf4083a3..ed150efbe27c93fbec1834767262453c47619e14 100644 --- a/fs/cifs/sess.c +++ b/fs/cifs/sess.c @@ -417,10 +417,6 @@ CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses, int first_time, calc_lanman_hash(ses, lnm_session_key); ses->flags |= CIFS_SES_LANMAN; -/* #ifdef CONFIG_CIFS_DEBUG2 - cifs_dump_mem("cryptkey: ",ses->server->cryptKey, - CIFS_SESS_KEY_SIZE); -#endif */ memcpy(bcc_ptr, (char *)lnm_session_key, CIFS_SESS_KEY_SIZE); bcc_ptr += CIFS_SESS_KEY_SIZE; diff --git a/fs/cifs/smbdes.c b/fs/cifs/smbdes.c index cfa6d21fb4e871c4e09a94be0271d0eaf490a531..04943c976f98d1df3810d42d2a362cc940c27131 100644 --- a/fs/cifs/smbdes.c +++ b/fs/cifs/smbdes.c @@ -114,42 +114,42 @@ static uchar sbox[8][4][16] = { {{14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7}, {0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8}, {4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0}, - {15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13}}, + {15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13} }, {{15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10}, {3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5}, {0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15}, - {13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9}}, + {13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9} }, {{10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8}, {13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1}, {13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7}, - {1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12}}, + {1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12} }, {{7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15}, {13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9}, {10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4}, - {3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14}}, + {3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14} }, {{2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9}, {14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6}, {4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14}, - {11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3}}, + {11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3} }, {{12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11}, {10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8}, {9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6}, - {4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13}}, + {4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13} }, {{4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1}, {13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6}, {1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2}, - {6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12}}, + {6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12} }, {{13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7}, {1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2}, {7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8}, - {2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11}} + {2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11} } }; static void @@ -313,9 +313,8 @@ str_to_key(unsigned char *str, unsigned char *key) key[5] = ((str[4] & 0x1F) << 2) | (str[5] >> 6); key[6] = ((str[5] & 0x3F) << 1) | (str[6] >> 7); key[7] = str[6] & 0x7F; - for (i = 0; i < 8; i++) { + for (i = 0; i < 8; i++) key[i] = (key[i] << 1); - } } static void @@ -344,9 +343,8 @@ smbhash(unsigned char *out, unsigned char *in, unsigned char *key, int forw) dohash(outb, inb, keyb, forw); - for (i = 0; i < 8; i++) { + for (i = 0; i < 8; i++) out[i] = 0; - } for (i = 0; i < 64; i++) { if (outb[i]) diff --git a/fs/cifs/transport.c b/fs/cifs/transport.c index 50b623ad93205700822888e00c1e684186aac05e..3612d6c0a0bbc1a4c9f64c2ce0f674517ce86d72 100644 --- a/fs/cifs/transport.c +++ b/fs/cifs/transport.c @@ -1,7 +1,7 @@ /* * fs/cifs/transport.c * - * Copyright (C) International Business Machines Corp., 2002,2007 + * Copyright (C) International Business Machines Corp., 2002,2008 * Author(s): Steve French (sfrench@us.ibm.com) * Jeremy Allison (jra@samba.org) 2006. * @@ -358,9 +358,9 @@ static int allocate_mid(struct cifsSesInfo *ses, struct smb_hdr *in_buf, } else if (ses->status != CifsGood) { /* check if SMB session is bad because we are setting it up */ if ((in_buf->Command != SMB_COM_SESSION_SETUP_ANDX) && - (in_buf->Command != SMB_COM_NEGOTIATE)) { + (in_buf->Command != SMB_COM_NEGOTIATE)) return -EAGAIN; - } /* else ok - we are setting up session */ + /* else ok - we are setting up session */ } *ppmidQ = AllocMidQEntry(in_buf, ses); if (*ppmidQ == NULL) @@ -437,9 +437,8 @@ SendReceiveNoRsp(const unsigned int xid, struct cifsSesInfo *ses, iov[0].iov_len = in_buf->smb_buf_length + 4; flags |= CIFS_NO_RESP; rc = SendReceive2(xid, ses, iov, 1, &resp_buf_type, flags); -#ifdef CONFIG_CIFS_DEBUG2 - cFYI(1, ("SendRcvNoR flags %d rc %d", flags, rc)); -#endif + cFYI(DBG2, ("SendRcvNoRsp flags %d rc %d", flags, rc)); + return rc; } diff --git a/fs/cifs/xattr.c b/fs/cifs/xattr.c index 54e8ef96cb7930c07734aa9f0b808eaa2e215953..8cd6a445b017ae62c2028b083dce8593d5c894fc 100644 --- a/fs/cifs/xattr.c +++ b/fs/cifs/xattr.c @@ -139,9 +139,9 @@ int cifs_setxattr(struct dentry *direntry, const char *ea_name, } else if (strncmp(ea_name, CIFS_XATTR_USER_PREFIX, 5) == 0) { if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_XATTR) goto set_ea_exit; - if (strncmp(ea_name, CIFS_XATTR_DOS_ATTRIB, 14) == 0) { + if (strncmp(ea_name, CIFS_XATTR_DOS_ATTRIB, 14) == 0) cFYI(1, ("attempt to set cifs inode metadata")); - } + ea_name += 5; /* skip past user. prefix */ rc = CIFSSMBSetEA(xid, pTcon, full_path, ea_name, ea_value, (__u16)value_size, cifs_sb->local_nls, @@ -262,7 +262,7 @@ ssize_t cifs_getxattr(struct dentry *direntry, const char *ea_name, cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); #ifdef CONFIG_CIFS_EXPERIMENTAL - else if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) { + else if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) { __u16 fid; int oplock = FALSE; struct cifs_ntsd *pacl = NULL; @@ -303,11 +303,10 @@ ssize_t cifs_getxattr(struct dentry *direntry, const char *ea_name, } else if (strncmp(ea_name, CIFS_XATTR_SECURITY_PREFIX, XATTR_SECURITY_PREFIX_LEN) == 0) { cFYI(1, ("Security xattr namespace not supported yet")); - } else { + } else cFYI(1, ("illegal xattr request %s (only user namespace supported)", ea_name)); - } /* We could add an additional check for streams ie if proc/fs/cifs/streamstoxattr is set then diff --git a/fs/debugfs/inode.c b/fs/debugfs/inode.c index d26e2826ba5b8242ec3a4ad1bcf3b849d64b5a8a..e9602d85c11d0220d5cbccf7817c25b10a6d068e 100644 --- a/fs/debugfs/inode.c +++ b/fs/debugfs/inode.c @@ -29,10 +29,6 @@ #define DEBUGFS_MAGIC 0x64626720 -/* declared over in file.c */ -extern struct file_operations debugfs_file_operations; -extern struct inode_operations debugfs_link_operations; - static struct vfsmount *debugfs_mount; static int debugfs_mount_count; diff --git a/fs/ecryptfs/mmap.c b/fs/ecryptfs/mmap.c index dc74b186145d74db8a56470d5ef2e63ea5c0a3c0..6df1debdccce14aabbf0e63193b66ec0c8366d3e 100644 --- a/fs/ecryptfs/mmap.c +++ b/fs/ecryptfs/mmap.c @@ -263,52 +263,102 @@ out: return 0; } -/* This function must zero any hole we create */ +/** + * ecryptfs_prepare_write + * @file: The eCryptfs file + * @page: The eCryptfs page + * @from: The start byte from which we will write + * @to: The end byte to which we will write + * + * This function must zero any hole we create + * + * Returns zero on success; non-zero otherwise + */ static int ecryptfs_prepare_write(struct file *file, struct page *page, unsigned from, unsigned to) { - int rc = 0; loff_t prev_page_end_size; + int rc = 0; if (!PageUptodate(page)) { - rc = ecryptfs_read_lower_page_segment(page, page->index, 0, - PAGE_CACHE_SIZE, - page->mapping->host); - if (rc) { - printk(KERN_ERR "%s: Error attemping to read lower " - "page segment; rc = [%d]\n", __FUNCTION__, rc); - ClearPageUptodate(page); - goto out; - } else + struct ecryptfs_crypt_stat *crypt_stat = + &ecryptfs_inode_to_private( + file->f_path.dentry->d_inode)->crypt_stat; + + if (!(crypt_stat->flags & ECRYPTFS_ENCRYPTED) + || (crypt_stat->flags & ECRYPTFS_NEW_FILE)) { + rc = ecryptfs_read_lower_page_segment( + page, page->index, 0, PAGE_CACHE_SIZE, + page->mapping->host); + if (rc) { + printk(KERN_ERR "%s: Error attemping to read " + "lower page segment; rc = [%d]\n", + __FUNCTION__, rc); + ClearPageUptodate(page); + goto out; + } else + SetPageUptodate(page); + } else if (crypt_stat->flags & ECRYPTFS_VIEW_AS_ENCRYPTED) { + if (crypt_stat->flags & ECRYPTFS_METADATA_IN_XATTR) { + rc = ecryptfs_copy_up_encrypted_with_header( + page, crypt_stat); + if (rc) { + printk(KERN_ERR "%s: Error attempting " + "to copy the encrypted content " + "from the lower file whilst " + "inserting the metadata from " + "the xattr into the header; rc " + "= [%d]\n", __FUNCTION__, rc); + ClearPageUptodate(page); + goto out; + } + SetPageUptodate(page); + } else { + rc = ecryptfs_read_lower_page_segment( + page, page->index, 0, PAGE_CACHE_SIZE, + page->mapping->host); + if (rc) { + printk(KERN_ERR "%s: Error reading " + "page; rc = [%d]\n", + __FUNCTION__, rc); + ClearPageUptodate(page); + goto out; + } + SetPageUptodate(page); + } + } else { + rc = ecryptfs_decrypt_page(page); + if (rc) { + printk(KERN_ERR "%s: Error decrypting page " + "at index [%ld]; rc = [%d]\n", + __FUNCTION__, page->index, rc); + ClearPageUptodate(page); + goto out; + } SetPageUptodate(page); + } } - prev_page_end_size = ((loff_t)page->index << PAGE_CACHE_SHIFT); - - /* - * If creating a page or more of holes, zero them out via truncate. - * Note, this will increase i_size. - */ + /* If creating a page or more of holes, zero them out via truncate. + * Note, this will increase i_size. */ if (page->index != 0) { if (prev_page_end_size > i_size_read(page->mapping->host)) { rc = ecryptfs_truncate(file->f_path.dentry, prev_page_end_size); if (rc) { - printk(KERN_ERR "Error on attempt to " + printk(KERN_ERR "%s: Error on attempt to " "truncate to (higher) offset [%lld];" - " rc = [%d]\n", prev_page_end_size, rc); + " rc = [%d]\n", __FUNCTION__, + prev_page_end_size, rc); goto out; } } } - /* - * Writing to a new page, and creating a small hole from start of page? - * Zero it out. - */ - if ((i_size_read(page->mapping->host) == prev_page_end_size) && - (from != 0)) { + /* Writing to a new page, and creating a small hole from start + * of page? Zero it out. */ + if ((i_size_read(page->mapping->host) == prev_page_end_size) + && (from != 0)) zero_user(page, 0, PAGE_CACHE_SIZE); - } out: return rc; } diff --git a/fs/exec.c b/fs/exec.c index a44b142fb4607baee2d832b1056103b5d157e5a7..54a0a557b6781ecf379015bbd60dc6f3fd37c176 100644 --- a/fs/exec.c +++ b/fs/exec.c @@ -173,8 +173,15 @@ static struct page *get_arg_page(struct linux_binprm *bprm, unsigned long pos, return NULL; if (write) { - struct rlimit *rlim = current->signal->rlim; unsigned long size = bprm->vma->vm_end - bprm->vma->vm_start; + struct rlimit *rlim; + + /* + * We've historically supported up to 32 pages (ARG_MAX) + * of argument strings even with small stacks + */ + if (size <= ARG_MAX) + return page; /* * Limit to 1/4-th the stack size for the argv+env strings. @@ -183,6 +190,7 @@ static struct page *get_arg_page(struct linux_binprm *bprm, unsigned long pos, * - the program will have a reasonable amount of stack left * to work from. */ + rlim = current->signal->rlim; if (size > rlim[RLIMIT_STACK].rlim_cur / 4) { put_page(page); return NULL; diff --git a/fs/ext3/super.c b/fs/ext3/super.c index 18769cc3237703e3426012378b31ca2e8c6024aa..ad536066408229da9955e41e27a0f5e72756cccd 100644 --- a/fs/ext3/super.c +++ b/fs/ext3/super.c @@ -806,8 +806,8 @@ static match_table_t tokens = { {Opt_quota, "quota"}, {Opt_usrquota, "usrquota"}, {Opt_barrier, "barrier=%u"}, - {Opt_err, NULL}, {Opt_resize, "resize"}, + {Opt_err, NULL}, }; static ext3_fsblk_t get_sb_block(void **data) diff --git a/fs/ext4/dir.c b/fs/ext4/dir.c index 33888bb58144fc1660d4106dbcbd689b560d2aa0..2c23bade9aa676451972905449e8d8cc0bbcfec3 100644 --- a/fs/ext4/dir.c +++ b/fs/ext4/dir.c @@ -46,7 +46,7 @@ const struct file_operations ext4_dir_operations = { #ifdef CONFIG_COMPAT .compat_ioctl = ext4_compat_ioctl, #endif - .fsync = ext4_sync_file, /* BKL held */ + .fsync = ext4_sync_file, .release = ext4_release_dir, }; diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c index bc7081f1fbe80dd5add381c5746b1bbc74e4883a..9ae6e67090cdfad1bd52a7e7169ba725dea19c82 100644 --- a/fs/ext4/extents.c +++ b/fs/ext4/extents.c @@ -148,6 +148,7 @@ static ext4_fsblk_t ext4_ext_find_goal(struct inode *inode, { struct ext4_inode_info *ei = EXT4_I(inode); ext4_fsblk_t bg_start; + ext4_fsblk_t last_block; ext4_grpblk_t colour; int depth; @@ -169,8 +170,13 @@ static ext4_fsblk_t ext4_ext_find_goal(struct inode *inode, /* OK. use inode's group */ bg_start = (ei->i_block_group * EXT4_BLOCKS_PER_GROUP(inode->i_sb)) + le32_to_cpu(EXT4_SB(inode->i_sb)->s_es->s_first_data_block); - colour = (current->pid % 16) * + last_block = ext4_blocks_count(EXT4_SB(inode->i_sb)->s_es) - 1; + + if (bg_start + EXT4_BLOCKS_PER_GROUP(inode->i_sb) <= last_block) + colour = (current->pid % 16) * (EXT4_BLOCKS_PER_GROUP(inode->i_sb) / 16); + else + colour = (current->pid % 16) * ((last_block - bg_start) / 16); return bg_start + colour + block; } @@ -349,7 +355,7 @@ static void ext4_ext_show_leaf(struct inode *inode, struct ext4_ext_path *path) #define ext4_ext_show_leaf(inode,path) #endif -static void ext4_ext_drop_refs(struct ext4_ext_path *path) +void ext4_ext_drop_refs(struct ext4_ext_path *path) { int depth = path->p_depth; int i; @@ -2168,6 +2174,10 @@ static int ext4_ext_convert_to_initialized(handle_t *handle, newblock = iblock - ee_block + ext_pblock(ex); ex2 = ex; + err = ext4_ext_get_access(handle, inode, path + depth); + if (err) + goto out; + /* ex1: ee_block to iblock - 1 : uninitialized */ if (iblock > ee_block) { ex1 = ex; @@ -2200,16 +2210,20 @@ static int ext4_ext_convert_to_initialized(handle_t *handle, newdepth = ext_depth(inode); if (newdepth != depth) { depth = newdepth; - path = ext4_ext_find_extent(inode, iblock, NULL); + ext4_ext_drop_refs(path); + path = ext4_ext_find_extent(inode, iblock, path); if (IS_ERR(path)) { err = PTR_ERR(path); - path = NULL; goto out; } eh = path[depth].p_hdr; ex = path[depth].p_ext; if (ex2 != &newex) ex2 = ex; + + err = ext4_ext_get_access(handle, inode, path + depth); + if (err) + goto out; } allocated = max_blocks; } @@ -2230,9 +2244,6 @@ static int ext4_ext_convert_to_initialized(handle_t *handle, ex2->ee_len = cpu_to_le16(allocated); if (ex2 != ex) goto insert; - err = ext4_ext_get_access(handle, inode, path + depth); - if (err) - goto out; /* * New (initialized) extent starts from the first block * in the current extent. i.e., ex2 == ex @@ -2276,9 +2287,22 @@ out: } /* + * Block allocation/map/preallocation routine for extents based files + * + * * Need to be called with * down_read(&EXT4_I(inode)->i_data_sem) if not allocating file system block * (ie, create is zero). Otherwise down_write(&EXT4_I(inode)->i_data_sem) + * + * return > 0, number of of blocks already mapped/allocated + * if create == 0 and these are pre-allocated blocks + * buffer head is unmapped + * otherwise blocks are mapped + * + * return = 0, if plain look up failed (blocks have not been allocated) + * buffer head is unmapped + * + * return < 0, error case. */ int ext4_ext_get_blocks(handle_t *handle, struct inode *inode, ext4_lblk_t iblock, @@ -2623,7 +2647,7 @@ long ext4_fallocate(struct inode *inode, int mode, loff_t offset, loff_t len) * modify 1 super block, 1 block bitmap and 1 group descriptor. */ credits = EXT4_DATA_TRANS_BLOCKS(inode->i_sb) + 3; - down_write((&EXT4_I(inode)->i_data_sem)); + mutex_lock(&inode->i_mutex); retry: while (ret >= 0 && ret < max_blocks) { block = block + ret; @@ -2634,16 +2658,17 @@ retry: break; } - ret = ext4_ext_get_blocks(handle, inode, block, + ret = ext4_get_blocks_wrap(handle, inode, block, max_blocks, &map_bh, EXT4_CREATE_UNINITIALIZED_EXT, 0); - WARN_ON(ret <= 0); if (ret <= 0) { - ext4_error(inode->i_sb, "ext4_fallocate", - "ext4_ext_get_blocks returned error: " - "inode#%lu, block=%u, max_blocks=%lu", +#ifdef EXT4FS_DEBUG + WARN_ON(ret <= 0); + printk(KERN_ERR "%s: ext4_ext_get_blocks " + "returned error inode#%lu, block=%u, " + "max_blocks=%lu", __func__, inode->i_ino, block, max_blocks); - ret = -EIO; +#endif ext4_mark_inode_dirty(handle, inode); ret2 = ext4_journal_stop(handle); break; @@ -2680,7 +2705,6 @@ retry: if (ret == -ENOSPC && ext4_should_retry_alloc(inode->i_sb, &retries)) goto retry; - up_write((&EXT4_I(inode)->i_data_sem)); /* * Time to update the file size. * Update only when preallocation was requested beyond the file size. @@ -2692,21 +2716,18 @@ retry: * if no error, we assume preallocation succeeded * completely */ - mutex_lock(&inode->i_mutex); i_size_write(inode, offset + len); EXT4_I(inode)->i_disksize = i_size_read(inode); - mutex_unlock(&inode->i_mutex); } else if (ret < 0 && nblocks) { /* Handle partial allocation scenario */ loff_t newsize; - mutex_lock(&inode->i_mutex); newsize = (nblocks << blkbits) + i_size_read(inode); i_size_write(inode, EXT4_BLOCK_ALIGN(newsize, blkbits)); EXT4_I(inode)->i_disksize = i_size_read(inode); - mutex_unlock(&inode->i_mutex); } } + mutex_unlock(&inode->i_mutex); return ret > 0 ? ret2 : ret; } diff --git a/fs/ext4/ialloc.c b/fs/ext4/ialloc.c index da18a74b966a91da09ae9710ba8976a111f3946f..8036b9b5376bd8f7ac50e1dffe1da5aceebbc487 100644 --- a/fs/ext4/ialloc.c +++ b/fs/ext4/ialloc.c @@ -702,7 +702,12 @@ got: ei->i_dir_start_lookup = 0; ei->i_disksize = 0; - ei->i_flags = EXT4_I(dir)->i_flags & ~EXT4_INDEX_FL; + /* + * Don't inherit extent flag from directory. We set extent flag on + * newly created directory and file only if -o extent mount option is + * specified + */ + ei->i_flags = EXT4_I(dir)->i_flags & ~(EXT4_INDEX_FL|EXT4_EXTENTS_FL); if (S_ISLNK(mode)) ei->i_flags &= ~(EXT4_IMMUTABLE_FL|EXT4_APPEND_FL); /* dirsync only applies to directories */ @@ -745,12 +750,15 @@ got: goto fail_free_drop; } if (test_opt(sb, EXTENTS)) { - EXT4_I(inode)->i_flags |= EXT4_EXTENTS_FL; - ext4_ext_tree_init(handle, inode); - err = ext4_update_incompat_feature(handle, sb, - EXT4_FEATURE_INCOMPAT_EXTENTS); - if (err) - goto fail; + /* set extent flag only for directory and file */ + if (S_ISDIR(mode) || S_ISREG(mode)) { + EXT4_I(inode)->i_flags |= EXT4_EXTENTS_FL; + ext4_ext_tree_init(handle, inode); + err = ext4_update_incompat_feature(handle, sb, + EXT4_FEATURE_INCOMPAT_EXTENTS); + if (err) + goto fail; + } } ext4_debug("allocating inode %lu\n", inode->i_ino); diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index 7dd9b50d5ebc7d10f2a0dc2f7e09560ee7784db8..945cbf6cb1fc6d686c5ef89ba2663ce753dab160 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -403,6 +403,7 @@ static ext4_fsblk_t ext4_find_near(struct inode *inode, Indirect *ind) __le32 *start = ind->bh ? (__le32*) ind->bh->b_data : ei->i_data; __le32 *p; ext4_fsblk_t bg_start; + ext4_fsblk_t last_block; ext4_grpblk_t colour; /* Try to find previous block */ @@ -420,8 +421,13 @@ static ext4_fsblk_t ext4_find_near(struct inode *inode, Indirect *ind) * into the same cylinder group then. */ bg_start = ext4_group_first_block_no(inode->i_sb, ei->i_block_group); - colour = (current->pid % 16) * + last_block = ext4_blocks_count(EXT4_SB(inode->i_sb)->s_es) - 1; + + if (bg_start + EXT4_BLOCKS_PER_GROUP(inode->i_sb) <= last_block) + colour = (current->pid % 16) * (EXT4_BLOCKS_PER_GROUP(inode->i_sb) / 16); + else + colour = (current->pid % 16) * ((last_block - bg_start) / 16); return bg_start + colour; } @@ -768,7 +774,6 @@ err_out: * * `handle' can be NULL if create == 0. * - * The BKL may not be held on entry here. Be sure to take it early. * return > 0, # of blocks mapped or allocated. * return = 0, if plain lookup failed. * return < 0, error case. @@ -903,11 +908,38 @@ out: */ #define DIO_CREDITS 25 + +/* + * + * + * ext4_ext4 get_block() wrapper function + * It will do a look up first, and returns if the blocks already mapped. + * Otherwise it takes the write lock of the i_data_sem and allocate blocks + * and store the allocated blocks in the result buffer head and mark it + * mapped. + * + * If file type is extents based, it will call ext4_ext_get_blocks(), + * Otherwise, call with ext4_get_blocks_handle() to handle indirect mapping + * based files + * + * On success, it returns the number of blocks being mapped or allocate. + * if create==0 and the blocks are pre-allocated and uninitialized block, + * the result buffer head is unmapped. If the create ==1, it will make sure + * the buffer head is mapped. + * + * It returns 0 if plain look up failed (blocks have not been allocated), in + * that casem, buffer head is unmapped + * + * It returns the error in case of allocation failure. + */ int ext4_get_blocks_wrap(handle_t *handle, struct inode *inode, sector_t block, unsigned long max_blocks, struct buffer_head *bh, int create, int extend_disksize) { int retval; + + clear_buffer_mapped(bh); + /* * Try to see if we can get the block without requesting * for new file system block. @@ -921,12 +953,26 @@ int ext4_get_blocks_wrap(handle_t *handle, struct inode *inode, sector_t block, inode, block, max_blocks, bh, 0, 0); } up_read((&EXT4_I(inode)->i_data_sem)); - if (!create || (retval > 0)) + + /* If it is only a block(s) look up */ + if (!create) + return retval; + + /* + * Returns if the blocks have already allocated + * + * Note that if blocks have been preallocated + * ext4_ext_get_block() returns th create = 0 + * with buffer head unmapped. + */ + if (retval > 0 && buffer_mapped(bh)) return retval; /* - * We need to allocate new blocks which will result - * in i_data update + * New blocks allocate and/or writing to uninitialized extent + * will possibly result in updating i_data, so we take + * the write lock of i_data_sem, and call get_blocks() + * with create == 1 flag. */ down_write((&EXT4_I(inode)->i_data_sem)); /* diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c index dd0fcfcb35ce85f9af3b81331a20b14348b48694..ef97f19c2f9d7a51d68ccb281ca982e79a53e823 100644 --- a/fs/ext4/mballoc.c +++ b/fs/ext4/mballoc.c @@ -627,21 +627,19 @@ static ext4_fsblk_t ext4_grp_offs_to_block(struct super_block *sb, return block; } +static inline void *mb_correct_addr_and_bit(int *bit, void *addr) +{ #if BITS_PER_LONG == 64 -#define mb_correct_addr_and_bit(bit, addr) \ -{ \ - bit += ((unsigned long) addr & 7UL) << 3; \ - addr = (void *) ((unsigned long) addr & ~7UL); \ -} + *bit += ((unsigned long) addr & 7UL) << 3; + addr = (void *) ((unsigned long) addr & ~7UL); #elif BITS_PER_LONG == 32 -#define mb_correct_addr_and_bit(bit, addr) \ -{ \ - bit += ((unsigned long) addr & 3UL) << 3; \ - addr = (void *) ((unsigned long) addr & ~3UL); \ -} + *bit += ((unsigned long) addr & 3UL) << 3; + addr = (void *) ((unsigned long) addr & ~3UL); #else #error "how many bits you are?!" #endif + return addr; +} static inline int mb_test_bit(int bit, void *addr) { @@ -649,34 +647,54 @@ static inline int mb_test_bit(int bit, void *addr) * ext4_test_bit on architecture like powerpc * needs unsigned long aligned address */ - mb_correct_addr_and_bit(bit, addr); + addr = mb_correct_addr_and_bit(&bit, addr); return ext4_test_bit(bit, addr); } static inline void mb_set_bit(int bit, void *addr) { - mb_correct_addr_and_bit(bit, addr); + addr = mb_correct_addr_and_bit(&bit, addr); ext4_set_bit(bit, addr); } static inline void mb_set_bit_atomic(spinlock_t *lock, int bit, void *addr) { - mb_correct_addr_and_bit(bit, addr); + addr = mb_correct_addr_and_bit(&bit, addr); ext4_set_bit_atomic(lock, bit, addr); } static inline void mb_clear_bit(int bit, void *addr) { - mb_correct_addr_and_bit(bit, addr); + addr = mb_correct_addr_and_bit(&bit, addr); ext4_clear_bit(bit, addr); } static inline void mb_clear_bit_atomic(spinlock_t *lock, int bit, void *addr) { - mb_correct_addr_and_bit(bit, addr); + addr = mb_correct_addr_and_bit(&bit, addr); ext4_clear_bit_atomic(lock, bit, addr); } +static inline int mb_find_next_zero_bit(void *addr, int max, int start) +{ + int fix = 0; + addr = mb_correct_addr_and_bit(&fix, addr); + max += fix; + start += fix; + + return ext4_find_next_zero_bit(addr, max, start) - fix; +} + +static inline int mb_find_next_bit(void *addr, int max, int start) +{ + int fix = 0; + addr = mb_correct_addr_and_bit(&fix, addr); + max += fix; + start += fix; + + return ext4_find_next_bit(addr, max, start) - fix; +} + static void *mb_find_buddy(struct ext4_buddy *e4b, int order, int *max) { char *bb; @@ -906,7 +924,7 @@ static void ext4_mb_mark_free_simple(struct super_block *sb, unsigned short chunk; unsigned short border; - BUG_ON(len >= EXT4_BLOCKS_PER_GROUP(sb)); + BUG_ON(len > EXT4_BLOCKS_PER_GROUP(sb)); border = 2 << sb->s_blocksize_bits; @@ -946,12 +964,12 @@ static void ext4_mb_generate_buddy(struct super_block *sb, /* initialize buddy from bitmap which is aggregation * of on-disk bitmap and preallocations */ - i = ext4_find_next_zero_bit(bitmap, max, 0); + i = mb_find_next_zero_bit(bitmap, max, 0); grp->bb_first_free = i; while (i < max) { fragments++; first = i; - i = ext4_find_next_bit(bitmap, max, i); + i = mb_find_next_bit(bitmap, max, i); len = i - first; free += len; if (len > 1) @@ -959,7 +977,7 @@ static void ext4_mb_generate_buddy(struct super_block *sb, else grp->bb_counters[0]++; if (i < max) - i = ext4_find_next_zero_bit(bitmap, max, i); + i = mb_find_next_zero_bit(bitmap, max, i); } grp->bb_fragments = fragments; @@ -967,6 +985,10 @@ static void ext4_mb_generate_buddy(struct super_block *sb, ext4_error(sb, __FUNCTION__, "EXT4-fs: group %lu: %u blocks in bitmap, %u in gd\n", group, free, grp->bb_free); + /* + * If we intent to continue, we consider group descritor + * corrupt and update bb_free using bitmap value + */ grp->bb_free = free; } @@ -1778,7 +1800,7 @@ static void ext4_mb_simple_scan_group(struct ext4_allocation_context *ac, buddy = mb_find_buddy(e4b, i, &max); BUG_ON(buddy == NULL); - k = ext4_find_next_zero_bit(buddy, max, 0); + k = mb_find_next_zero_bit(buddy, max, 0); BUG_ON(k >= max); ac->ac_found++; @@ -1818,11 +1840,11 @@ static void ext4_mb_complex_scan_group(struct ext4_allocation_context *ac, i = e4b->bd_info->bb_first_free; while (free && ac->ac_status == AC_STATUS_CONTINUE) { - i = ext4_find_next_zero_bit(bitmap, + i = mb_find_next_zero_bit(bitmap, EXT4_BLOCKS_PER_GROUP(sb), i); if (i >= EXT4_BLOCKS_PER_GROUP(sb)) { /* - * IF we corrupt the bitmap we won't find any + * IF we have corrupt bitmap, we won't find any * free blocks even though group info says we * we have free blocks */ @@ -1838,6 +1860,12 @@ static void ext4_mb_complex_scan_group(struct ext4_allocation_context *ac, ext4_error(sb, __FUNCTION__, "%d free blocks as per " "group info. But got %d blocks\n", free, ex.fe_len); + /* + * The number of free blocks differs. This mostly + * indicate that the bitmap is corrupt. So exit + * without claiming the space. + */ + break; } ext4_mb_measure_extent(ac, &ex, e4b); @@ -3740,10 +3768,10 @@ static int ext4_mb_release_inode_pa(struct ext4_buddy *e4b, } while (bit < end) { - bit = ext4_find_next_zero_bit(bitmap_bh->b_data, end, bit); + bit = mb_find_next_zero_bit(bitmap_bh->b_data, end, bit); if (bit >= end) break; - next = ext4_find_next_bit(bitmap_bh->b_data, end, bit); + next = mb_find_next_bit(bitmap_bh->b_data, end, bit); if (next > end) next = end; start = group * EXT4_BLOCKS_PER_GROUP(sb) + bit + @@ -3771,6 +3799,10 @@ static int ext4_mb_release_inode_pa(struct ext4_buddy *e4b, (unsigned long) pa->pa_len); ext4_error(sb, __FUNCTION__, "free %u, pa_free %u\n", free, pa->pa_free); + /* + * pa is already deleted so we use the value obtained + * from the bitmap and continue. + */ } atomic_add(free, &sbi->s_mb_discarded); if (ac) diff --git a/fs/ext4/migrate.c b/fs/ext4/migrate.c index 8c6c685b9d22e1d399d34066e5e6a497150c81a9..5c1e27de7755b46552c3fd85dd11ad66d0ec1490 100644 --- a/fs/ext4/migrate.c +++ b/fs/ext4/migrate.c @@ -43,6 +43,7 @@ static int finish_range(handle_t *handle, struct inode *inode, if (IS_ERR(path)) { retval = PTR_ERR(path); + path = NULL; goto err_out; } @@ -74,6 +75,10 @@ static int finish_range(handle_t *handle, struct inode *inode, } retval = ext4_ext_insert_extent(handle, inode, path, &newext); err_out: + if (path) { + ext4_ext_drop_refs(path); + kfree(path); + } lb->first_pblock = 0; return retval; } diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c index a9347fb43bcca34dde35173aa1eb1dcccbc50d27..28aa2ed4297ecb30aeedb1d04f3c5470410c7e9a 100644 --- a/fs/ext4/namei.c +++ b/fs/ext4/namei.c @@ -1804,12 +1804,8 @@ retry: inode->i_fop = &ext4_dir_operations; inode->i_size = EXT4_I(inode)->i_disksize = inode->i_sb->s_blocksize; dir_block = ext4_bread (handle, inode, 0, 1, &err); - if (!dir_block) { - ext4_dec_count(handle, inode); /* is this nlink == 0? */ - ext4_mark_inode_dirty(handle, inode); - iput (inode); - goto out_stop; - } + if (!dir_block) + goto out_clear_inode; BUFFER_TRACE(dir_block, "get_write_access"); ext4_journal_get_write_access(handle, dir_block); de = (struct ext4_dir_entry_2 *) dir_block->b_data; @@ -1832,7 +1828,8 @@ retry: ext4_mark_inode_dirty(handle, inode); err = ext4_add_entry (handle, dentry, inode); if (err) { - inode->i_nlink = 0; +out_clear_inode: + clear_nlink(inode); ext4_mark_inode_dirty(handle, inode); iput (inode); goto out_stop; @@ -2164,7 +2161,7 @@ static int ext4_unlink(struct inode * dir, struct dentry *dentry) dir->i_ctime = dir->i_mtime = ext4_current_time(dir); ext4_update_dx_flag(dir); ext4_mark_inode_dirty(handle, dir); - ext4_dec_count(handle, inode); + drop_nlink(inode); if (!inode->i_nlink) ext4_orphan_add(handle, inode); inode->i_ctime = ext4_current_time(inode); @@ -2214,7 +2211,7 @@ retry: err = __page_symlink(inode, symname, l, mapping_gfp_mask(inode->i_mapping) & ~__GFP_FS); if (err) { - ext4_dec_count(handle, inode); + clear_nlink(inode); ext4_mark_inode_dirty(handle, inode); iput (inode); goto out_stop; @@ -2223,7 +2220,6 @@ retry: inode->i_op = &ext4_fast_symlink_inode_operations; memcpy((char*)&EXT4_I(inode)->i_data,symname,l); inode->i_size = l-1; - EXT4_I(inode)->i_flags &= ~EXT4_EXTENTS_FL; } EXT4_I(inode)->i_disksize = inode->i_size; err = ext4_add_nondir(handle, dentry, inode); @@ -2407,7 +2403,7 @@ static int ext4_rename (struct inode * old_dir, struct dentry *old_dentry, ext4_dec_count(handle, old_dir); if (new_inode) { /* checked empty_dir above, can't have another parent, - * ext3_dec_count() won't work for many-linked dirs */ + * ext4_dec_count() won't work for many-linked dirs */ new_inode->i_nlink = 0; } else { ext4_inc_count(handle, new_dir); diff --git a/fs/ext4/resize.c b/fs/ext4/resize.c index 9477a2bd6ff2ea0c2ae9180c89a0166d470df1b6..e29efa0f9d6298402bf35b588838d9737b08c551 100644 --- a/fs/ext4/resize.c +++ b/fs/ext4/resize.c @@ -1037,6 +1037,7 @@ int ext4_group_extend(struct super_block *sb, struct ext4_super_block *es, ext4_warning(sb, __FUNCTION__, "multiple resizers run on filesystem!"); unlock_super(sb); + ext4_journal_stop(handle); err = -EBUSY; goto exit_put; } diff --git a/fs/hfs/brec.c b/fs/hfs/brec.c index 878bf25dbc6a8c60d8ffc9736c0d6bf5c20ed699..92fb358ce824325e6b8275388b111e70728463dc 100644 --- a/fs/hfs/brec.c +++ b/fs/hfs/brec.c @@ -229,7 +229,7 @@ skip: static struct hfs_bnode *hfs_bnode_split(struct hfs_find_data *fd) { struct hfs_btree *tree; - struct hfs_bnode *node, *new_node; + struct hfs_bnode *node, *new_node, *next_node; struct hfs_bnode_desc node_desc; int num_recs, new_rec_off, new_off, old_rec_off; int data_start, data_end, size; @@ -248,6 +248,17 @@ static struct hfs_bnode *hfs_bnode_split(struct hfs_find_data *fd) new_node->type = node->type; new_node->height = node->height; + if (node->next) + next_node = hfs_bnode_find(tree, node->next); + else + next_node = NULL; + + if (IS_ERR(next_node)) { + hfs_bnode_put(node); + hfs_bnode_put(new_node); + return next_node; + } + size = tree->node_size / 2 - node->num_recs * 2 - 14; old_rec_off = tree->node_size - 4; num_recs = 1; @@ -261,6 +272,8 @@ static struct hfs_bnode *hfs_bnode_split(struct hfs_find_data *fd) /* panic? */ hfs_bnode_put(node); hfs_bnode_put(new_node); + if (next_node) + hfs_bnode_put(next_node); return ERR_PTR(-ENOSPC); } @@ -315,8 +328,7 @@ static struct hfs_bnode *hfs_bnode_split(struct hfs_find_data *fd) hfs_bnode_write(node, &node_desc, 0, sizeof(node_desc)); /* update next bnode header */ - if (new_node->next) { - struct hfs_bnode *next_node = hfs_bnode_find(tree, new_node->next); + if (next_node) { next_node->prev = new_node->this; hfs_bnode_read(next_node, &node_desc, 0, sizeof(node_desc)); node_desc.prev = cpu_to_be32(next_node->prev); diff --git a/fs/jbd/transaction.c b/fs/jbd/transaction.c index 038ed743619911799dfff8e27623e75f593fc60c..c6cbb6cd59b25588ea68b49c69062362c65b3e0b 100644 --- a/fs/jbd/transaction.c +++ b/fs/jbd/transaction.c @@ -369,7 +369,7 @@ out: /** - * int journal_restart() - restart a handle . + * int journal_restart() - restart a handle. * @handle: handle to restart * @nblocks: nr credits requested * @@ -844,8 +844,7 @@ out: } /** - * int journal_get_undo_access() - Notify intent to modify metadata with - * non-rewindable consequences + * int journal_get_undo_access() - Notify intent to modify metadata with non-rewindable consequences * @handle: transaction * @bh: buffer to undo * @credits: store the number of taken credits here (if not NULL) @@ -921,12 +920,14 @@ out: } /** - * int journal_dirty_data() - mark a buffer as containing dirty data which - * needs to be flushed before we can commit the - * current transaction. + * int journal_dirty_data() - mark a buffer as containing dirty data to be flushed * @handle: transaction * @bh: bufferhead to mark * + * Description: + * Mark a buffer as containing dirty data which needs to be flushed before + * we can commit the current transaction. + * * The buffer is placed on the transaction's data list and is marked as * belonging to the transaction. * @@ -1098,11 +1099,11 @@ no_journal: } /** - * int journal_dirty_metadata() - mark a buffer as containing dirty metadata + * int journal_dirty_metadata() - mark a buffer as containing dirty metadata * @handle: transaction to add buffer to. * @bh: buffer to mark * - * mark dirty metadata which needs to be journaled as part of the current + * Mark dirty metadata which needs to be journaled as part of the current * transaction. * * The buffer is placed on the transaction's metadata list and is marked diff --git a/fs/mpage.c b/fs/mpage.c index 5df564366f36b5ea287245b3b5fd060ab1012f31..235e4d3873a88d17837f1a9551f09664c8ffcb54 100644 --- a/fs/mpage.c +++ b/fs/mpage.c @@ -325,16 +325,12 @@ confused: } /** - * mpage_readpages - populate an address space with some pages, and - * start reads against them. - * + * mpage_readpages - populate an address space with some pages & start reads against them * @mapping: the address_space * @pages: The address of a list_head which contains the target pages. These * pages have their ->index populated and are otherwise uninitialised. - * * The page at @pages->prev has the lowest file offset, and reads should be * issued in @pages->prev to @pages->next order. - * * @nr_pages: The number of pages at *@pages * @get_block: The filesystem's block mapper function. * @@ -360,6 +356,7 @@ confused: * So an mpage read of the first 16 blocks of an ext2 file will cause I/O to be * submitted in the following order: * 12 0 1 2 3 4 5 6 7 8 9 10 11 13 14 15 16 + * * because the indirect block has to be read to get the mappings of blocks * 13,14,15,16. Obviously, this impacts performance. * @@ -656,9 +653,7 @@ out: } /** - * mpage_writepages - walk the list of dirty pages of the given - * address space and writepage() all of them. - * + * mpage_writepages - walk the list of dirty pages of the given address space & writepage() all of them * @mapping: address space structure to write * @wbc: subtract the number of written pages from *@wbc->nr_to_write * @get_block: the filesystem's block mapper function. diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index ae04892a5e5d23922cec2575ffa4609ced0afde7..6cea7479c5b4d13136fb753eecc453f19dc43229 100644 --- a/fs/nfs/dir.c +++ b/fs/nfs/dir.c @@ -710,6 +710,8 @@ int nfs_lookup_verify_inode(struct inode *inode, struct nameidata *nd) { struct nfs_server *server = NFS_SERVER(inode); + if (test_bit(NFS_INO_MOUNTPOINT, &NFS_I(inode)->flags)) + return 0; if (nd != NULL) { /* VFS wants an on-the-wire revalidation */ if (nd->flags & LOOKUP_REVAL) diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c index 966a8850aa30be5330a524699069718cd00932ce..a4c7cf2bff3a61131d1de68dbb770833e3c8e124 100644 --- a/fs/nfs/inode.c +++ b/fs/nfs/inode.c @@ -299,6 +299,7 @@ nfs_fhget(struct super_block *sb, struct nfs_fh *fh, struct nfs_fattr *fattr) else inode->i_op = &nfs_mountpoint_inode_operations; inode->i_fop = NULL; + set_bit(NFS_INO_MOUNTPOINT, &nfsi->flags); } } else if (S_ISLNK(inode->i_mode)) inode->i_op = &nfs_symlink_inode_operations; @@ -1003,8 +1004,9 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr) server = NFS_SERVER(inode); /* Update the fsid? */ - if (S_ISDIR(inode->i_mode) - && !nfs_fsid_equal(&server->fsid, &fattr->fsid)) + if (S_ISDIR(inode->i_mode) && + !nfs_fsid_equal(&server->fsid, &fattr->fsid) && + !test_bit(NFS_INO_MOUNTPOINT, &nfsi->flags)) server->fsid = fattr->fsid; /* diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h index 0f5619611b8dc5d313accd81658fd6dd32e6a647..931992763e68c2e68f7e1f3501de25a8340dc50b 100644 --- a/fs/nfs/internal.h +++ b/fs/nfs/internal.h @@ -3,6 +3,7 @@ */ #include +#include struct nfs_string; @@ -57,6 +58,8 @@ struct nfs_parsed_mount_data { char *export_path; int protocol; } nfs_server; + + struct security_mnt_opts lsm_opts; }; /* client.c */ diff --git a/fs/nfs/super.c b/fs/nfs/super.c index 1fb3818436501bc7bfd7637d7744576fe09e6041..dd4dfcd632ec76aa78c1c2e603c88a4e4401644a 100644 --- a/fs/nfs/super.c +++ b/fs/nfs/super.c @@ -632,7 +632,7 @@ static int nfs_verify_server_address(struct sockaddr *addr) switch (addr->sa_family) { case AF_INET: { struct sockaddr_in *sa = (struct sockaddr_in *)addr; - return sa->sin_addr.s_addr != INADDR_ANY; + return sa->sin_addr.s_addr != htonl(INADDR_ANY); } case AF_INET6: { struct in6_addr *sa = &((struct sockaddr_in6 *)addr)->sin6_addr; @@ -684,8 +684,9 @@ static void nfs_parse_server_address(char *value, static int nfs_parse_mount_options(char *raw, struct nfs_parsed_mount_data *mnt) { - char *p, *string; + char *p, *string, *secdata; unsigned short port = 0; + int rc; if (!raw) { dfprintk(MOUNT, "NFS: mount options string was NULL.\n"); @@ -693,6 +694,20 @@ static int nfs_parse_mount_options(char *raw, } dfprintk(MOUNT, "NFS: nfs mount opts='%s'\n", raw); + secdata = alloc_secdata(); + if (!secdata) + goto out_nomem; + + rc = security_sb_copy_data(raw, secdata); + if (rc) + goto out_security_failure; + + rc = security_sb_parse_opts_str(secdata, &mnt->lsm_opts); + if (rc) + goto out_security_failure; + + free_secdata(secdata); + while ((p = strsep(&raw, ",")) != NULL) { substring_t args[MAX_OPT_ARGS]; int option, token; @@ -1042,7 +1057,10 @@ static int nfs_parse_mount_options(char *raw, out_nomem: printk(KERN_INFO "NFS: not enough memory to parse option\n"); return 0; - +out_security_failure: + free_secdata(secdata); + printk(KERN_INFO "NFS: security options invalid: %d\n", rc); + return 0; out_unrec_vers: printk(KERN_INFO "NFS: unrecognized NFS version number\n"); return 0; @@ -1214,6 +1232,33 @@ static int nfs_validate_mount_data(void *options, args->namlen = data->namlen; args->bsize = data->bsize; args->auth_flavors[0] = data->pseudoflavor; + + /* + * The legacy version 6 binary mount data from userspace has a + * field used only to transport selinux information into the + * the kernel. To continue to support that functionality we + * have a touch of selinux knowledge here in the NFS code. The + * userspace code converted context=blah to just blah so we are + * converting back to the full string selinux understands. + */ + if (data->context[0]){ +#ifdef CONFIG_SECURITY_SELINUX + int rc; + char *opts_str = kmalloc(sizeof(data->context) + 8, GFP_KERNEL); + if (!opts_str) + return -ENOMEM; + strcpy(opts_str, "context="); + data->context[NFS_MAX_CONTEXT_LEN] = '\0'; + strcat(opts_str, &data->context[0]); + rc = security_sb_parse_opts_str(opts_str, &args->lsm_opts); + kfree(opts_str); + if (rc) + return rc; +#else + return -EINVAL; +#endif + } + break; default: { unsigned int len; @@ -1476,6 +1521,8 @@ static int nfs_get_sb(struct file_system_type *fs_type, }; int error; + security_init_mnt_opts(&data.lsm_opts); + /* Validate the mount data */ error = nfs_validate_mount_data(raw_data, &data, &mntfh, dev_name); if (error < 0) @@ -1515,6 +1562,10 @@ static int nfs_get_sb(struct file_system_type *fs_type, goto error_splat_super; } + error = security_sb_set_mnt_opts(s, &data.lsm_opts); + if (error) + goto error_splat_root; + s->s_flags |= MS_ACTIVE; mnt->mnt_sb = s; mnt->mnt_root = mntroot; @@ -1523,12 +1574,15 @@ static int nfs_get_sb(struct file_system_type *fs_type, out: kfree(data.nfs_server.hostname); kfree(data.mount_server.hostname); + security_free_mnt_opts(&data.lsm_opts); return error; out_err_nosb: nfs_free_server(server); goto out; +error_splat_root: + dput(mntroot); error_splat_super: up_write(&s->s_umount); deactivate_super(s); @@ -1608,6 +1662,9 @@ static int nfs_xdev_get_sb(struct file_system_type *fs_type, int flags, mnt->mnt_sb = s; mnt->mnt_root = mntroot; + /* clone any lsm security options from the parent to the new sb */ + security_sb_clone_mnt_opts(data->sb, s); + dprintk("<-- nfs_xdev_get_sb() = 0\n"); return 0; @@ -1850,6 +1907,8 @@ static int nfs4_get_sb(struct file_system_type *fs_type, }; int error; + security_init_mnt_opts(&data.lsm_opts); + /* Validate the mount data */ error = nfs4_validate_mount_data(raw_data, &data, dev_name); if (error < 0) @@ -1898,6 +1957,7 @@ out: kfree(data.client_address); kfree(data.nfs_server.export_path); kfree(data.nfs_server.hostname); + security_free_mnt_opts(&data.lsm_opts); return error; out_free: diff --git a/fs/nfs/write.c b/fs/nfs/write.c index f55c437124a2287e1ae80834af5059c0f3388d38..80c61fdb2720c4b05f86ff7c590cd0af566e2b8d 100644 --- a/fs/nfs/write.c +++ b/fs/nfs/write.c @@ -734,7 +734,7 @@ int nfs_updatepage(struct file *file, struct page *page, */ if (nfs_write_pageuptodate(page, inode) && inode->i_flock == NULL && - !(file->f_mode & O_SYNC)) { + !(file->f_flags & O_SYNC)) { count = max(count + offset, nfs_page_length(page)); offset = 0; } diff --git a/fs/nfsd/nfsfh.c b/fs/nfsd/nfsfh.c index 1eb771d79cca09a51326541dc76f3db3405f9245..3e6b3f41ee1f342918e6e3f57493f3c0ab21b033 100644 --- a/fs/nfsd/nfsfh.c +++ b/fs/nfsd/nfsfh.c @@ -232,6 +232,7 @@ fh_verify(struct svc_rqst *rqstp, struct svc_fh *fhp, int type, int access) fhp->fh_dentry = dentry; fhp->fh_export = exp; nfsd_nr_verified++; + cache_get(&exp->h); } else { /* * just rechecking permissions @@ -241,6 +242,7 @@ fh_verify(struct svc_rqst *rqstp, struct svc_fh *fhp, int type, int access) dprintk("nfsd: fh_verify - just checking\n"); dentry = fhp->fh_dentry; exp = fhp->fh_export; + cache_get(&exp->h); /* * Set user creds for this exportpoint; necessary even * in the "just checking" case because this may be a @@ -252,8 +254,6 @@ fh_verify(struct svc_rqst *rqstp, struct svc_fh *fhp, int type, int access) if (error) goto out; } - cache_get(&exp->h); - error = nfsd_mode_check(rqstp, dentry->d_inode->i_mode, type); if (error) diff --git a/fs/ocfs2/aops.c b/fs/ocfs2/aops.c index 82243127eebf6b81d80acd239609bdc1fd26ae43..90383ed6100530d6d10e5edae9b437278138fa0e 100644 --- a/fs/ocfs2/aops.c +++ b/fs/ocfs2/aops.c @@ -257,7 +257,7 @@ static int ocfs2_readpage_inline(struct inode *inode, struct page *page) struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); BUG_ON(!PageLocked(page)); - BUG_ON(!OCFS2_I(inode)->ip_dyn_features & OCFS2_INLINE_DATA_FL); + BUG_ON(!(OCFS2_I(inode)->ip_dyn_features & OCFS2_INLINE_DATA_FL)); ret = ocfs2_read_block(osb, OCFS2_I(inode)->ip_blkno, &di_bh, OCFS2_BH_CACHED, inode); diff --git a/fs/ocfs2/cluster/tcp.c b/fs/ocfs2/cluster/tcp.c index ee50c9610e7fc1267a87d1e6d210947b0e0f4cf8..b8057c51b20523f560a1bb2cbe5e12b8d6a3403a 100644 --- a/fs/ocfs2/cluster/tcp.c +++ b/fs/ocfs2/cluster/tcp.c @@ -451,9 +451,9 @@ static void o2net_set_nn_state(struct o2net_node *nn, /* delay if we're withing a RECONNECT_DELAY of the * last attempt */ delay = (nn->nn_last_connect_attempt + - msecs_to_jiffies(o2net_reconnect_delay(sc->sc_node))) + msecs_to_jiffies(o2net_reconnect_delay(NULL))) - jiffies; - if (delay > msecs_to_jiffies(o2net_reconnect_delay(sc->sc_node))) + if (delay > msecs_to_jiffies(o2net_reconnect_delay(NULL))) delay = 0; mlog(ML_CONN, "queueing conn attempt in %lu jiffies\n", delay); queue_delayed_work(o2net_wq, &nn->nn_connect_work, delay); @@ -1552,12 +1552,11 @@ static void o2net_connect_expired(struct work_struct *work) spin_lock(&nn->nn_lock); if (!nn->nn_sc_valid) { - struct o2nm_node *node = nn->nn_sc->sc_node; mlog(ML_ERROR, "no connection established with node %u after " "%u.%u seconds, giving up and returning errors.\n", o2net_num_from_nn(nn), - o2net_idle_timeout(node) / 1000, - o2net_idle_timeout(node) % 1000); + o2net_idle_timeout(NULL) / 1000, + o2net_idle_timeout(NULL) % 1000); o2net_set_nn_state(nn, NULL, 0, -ENOTCONN); } diff --git a/fs/ocfs2/dir.c b/fs/ocfs2/dir.c index e280833ceb9aa76bd8404ded84b6047948b0ca9d..8a18758480805504c453ed291908b36764b9f722 100644 --- a/fs/ocfs2/dir.c +++ b/fs/ocfs2/dir.c @@ -390,9 +390,8 @@ static int __ocfs2_delete_entry(handle_t *handle, struct inode *dir, goto bail; } if (pde) - pde->rec_len = - cpu_to_le16(le16_to_cpu(pde->rec_len) + - le16_to_cpu(de->rec_len)); + le16_add_cpu(&pde->rec_len, + le16_to_cpu(de->rec_len)); else de->inode = 0; dir->i_version++; diff --git a/fs/ocfs2/dlm/dlmcommon.h b/fs/ocfs2/dlm/dlmcommon.h index 9843ee17ea2783015244a9cbfb72f0dbb2190f10..dc8ea666efdb77004aece531c3a7a6670d6288db 100644 --- a/fs/ocfs2/dlm/dlmcommon.h +++ b/fs/ocfs2/dlm/dlmcommon.h @@ -176,6 +176,7 @@ struct dlm_mig_lockres_priv { struct dlm_lock_resource *lockres; u8 real_master; + u8 extra_ref; }; struct dlm_assert_master_priv @@ -602,17 +603,19 @@ enum dlm_query_join_response_code { JOIN_PROTOCOL_MISMATCH, }; +struct dlm_query_join_packet { + u8 code; /* Response code. dlm_minor and fs_minor + are only valid if this is JOIN_OK */ + u8 dlm_minor; /* The minor version of the protocol the + dlm is speaking. */ + u8 fs_minor; /* The minor version of the protocol the + filesystem is speaking. */ + u8 reserved; +}; + union dlm_query_join_response { u32 intval; - struct { - u8 code; /* Response code. dlm_minor and fs_minor - are only valid if this is JOIN_OK */ - u8 dlm_minor; /* The minor version of the protocol the - dlm is speaking. */ - u8 fs_minor; /* The minor version of the protocol the - filesystem is speaking. */ - u8 reserved; - } packet; + struct dlm_query_join_packet packet; }; struct dlm_lock_request diff --git a/fs/ocfs2/dlm/dlmconvert.c b/fs/ocfs2/dlm/dlmconvert.c index ecb4d997221e6460b33efa9e2747bda6b78fa3bb..75997b4deaf3ff9fafd4fcf25293c9312fb17fc8 100644 --- a/fs/ocfs2/dlm/dlmconvert.c +++ b/fs/ocfs2/dlm/dlmconvert.c @@ -487,7 +487,7 @@ int dlm_convert_lock_handler(struct o2net_msg *msg, u32 len, void *data, "cookie=%u:%llu\n", dlm_get_lock_cookie_node(be64_to_cpu(cnv->cookie)), dlm_get_lock_cookie_seq(be64_to_cpu(cnv->cookie))); - __dlm_print_one_lock_resource(res); + dlm_print_one_lock_resource(res); goto leave; } diff --git a/fs/ocfs2/dlm/dlmdomain.c b/fs/ocfs2/dlm/dlmdomain.c index 638d2ebb892bbdbb20c17f7bd4ba0d9f4aea4aee..0879d86113e347d2706d215223b81bda575cc002 100644 --- a/fs/ocfs2/dlm/dlmdomain.c +++ b/fs/ocfs2/dlm/dlmdomain.c @@ -713,14 +713,46 @@ static int dlm_query_join_proto_check(char *proto_type, int node, return rc; } +/* + * struct dlm_query_join_packet is made up of four one-byte fields. They + * are effectively in big-endian order already. However, little-endian + * machines swap them before putting the packet on the wire (because + * query_join's response is a status, and that status is treated as a u32 + * on the wire). Thus, a big-endian and little-endian machines will treat + * this structure differently. + * + * The solution is to have little-endian machines swap the structure when + * converting from the structure to the u32 representation. This will + * result in the structure having the correct format on the wire no matter + * the host endian format. + */ +static void dlm_query_join_packet_to_wire(struct dlm_query_join_packet *packet, + u32 *wire) +{ + union dlm_query_join_response response; + + response.packet = *packet; + *wire = cpu_to_be32(response.intval); +} + +static void dlm_query_join_wire_to_packet(u32 wire, + struct dlm_query_join_packet *packet) +{ + union dlm_query_join_response response; + + response.intval = cpu_to_be32(wire); + *packet = response.packet; +} + static int dlm_query_join_handler(struct o2net_msg *msg, u32 len, void *data, void **ret_data) { struct dlm_query_join_request *query; - union dlm_query_join_response response = { - .packet.code = JOIN_DISALLOW, + struct dlm_query_join_packet packet = { + .code = JOIN_DISALLOW, }; struct dlm_ctxt *dlm = NULL; + u32 response; u8 nodenum; query = (struct dlm_query_join_request *) msg->buf; @@ -737,11 +769,11 @@ static int dlm_query_join_handler(struct o2net_msg *msg, u32 len, void *data, mlog(0, "node %u is not in our live map yet\n", query->node_idx); - response.packet.code = JOIN_DISALLOW; + packet.code = JOIN_DISALLOW; goto respond; } - response.packet.code = JOIN_OK_NO_MAP; + packet.code = JOIN_OK_NO_MAP; spin_lock(&dlm_domain_lock); dlm = __dlm_lookup_domain_full(query->domain, query->name_len); @@ -760,7 +792,7 @@ static int dlm_query_join_handler(struct o2net_msg *msg, u32 len, void *data, mlog(0, "disallow join as node %u does not " "have node %u in its nodemap\n", query->node_idx, nodenum); - response.packet.code = JOIN_DISALLOW; + packet.code = JOIN_DISALLOW; goto unlock_respond; } } @@ -780,23 +812,23 @@ static int dlm_query_join_handler(struct o2net_msg *msg, u32 len, void *data, /*If this is a brand new context and we * haven't started our join process yet, then * the other node won the race. */ - response.packet.code = JOIN_OK_NO_MAP; + packet.code = JOIN_OK_NO_MAP; } else if (dlm->joining_node != DLM_LOCK_RES_OWNER_UNKNOWN) { /* Disallow parallel joins. */ - response.packet.code = JOIN_DISALLOW; + packet.code = JOIN_DISALLOW; } else if (dlm->reco.state & DLM_RECO_STATE_ACTIVE) { mlog(0, "node %u trying to join, but recovery " "is ongoing.\n", bit); - response.packet.code = JOIN_DISALLOW; + packet.code = JOIN_DISALLOW; } else if (test_bit(bit, dlm->recovery_map)) { mlog(0, "node %u trying to join, but it " "still needs recovery.\n", bit); - response.packet.code = JOIN_DISALLOW; + packet.code = JOIN_DISALLOW; } else if (test_bit(bit, dlm->domain_map)) { mlog(0, "node %u trying to join, but it " "is still in the domain! needs recovery?\n", bit); - response.packet.code = JOIN_DISALLOW; + packet.code = JOIN_DISALLOW; } else { /* Alright we're fully a part of this domain * so we keep some state as to who's joining @@ -807,19 +839,15 @@ static int dlm_query_join_handler(struct o2net_msg *msg, u32 len, void *data, if (dlm_query_join_proto_check("DLM", bit, &dlm->dlm_locking_proto, &query->dlm_proto)) { - response.packet.code = - JOIN_PROTOCOL_MISMATCH; + packet.code = JOIN_PROTOCOL_MISMATCH; } else if (dlm_query_join_proto_check("fs", bit, &dlm->fs_locking_proto, &query->fs_proto)) { - response.packet.code = - JOIN_PROTOCOL_MISMATCH; + packet.code = JOIN_PROTOCOL_MISMATCH; } else { - response.packet.dlm_minor = - query->dlm_proto.pv_minor; - response.packet.fs_minor = - query->fs_proto.pv_minor; - response.packet.code = JOIN_OK; + packet.dlm_minor = query->dlm_proto.pv_minor; + packet.fs_minor = query->fs_proto.pv_minor; + packet.code = JOIN_OK; __dlm_set_joining_node(dlm, query->node_idx); } } @@ -830,9 +858,10 @@ unlock_respond: spin_unlock(&dlm_domain_lock); respond: - mlog(0, "We respond with %u\n", response.packet.code); + mlog(0, "We respond with %u\n", packet.code); - return response.intval; + dlm_query_join_packet_to_wire(&packet, &response); + return response; } static int dlm_assert_joined_handler(struct o2net_msg *msg, u32 len, void *data, @@ -937,7 +966,7 @@ static int dlm_send_join_cancels(struct dlm_ctxt *dlm, sizeof(unsigned long))) { mlog(ML_ERROR, "map_size %u != BITS_TO_LONGS(O2NM_MAX_NODES) %u\n", - map_size, BITS_TO_LONGS(O2NM_MAX_NODES)); + map_size, (unsigned)BITS_TO_LONGS(O2NM_MAX_NODES)); return -EINVAL; } @@ -968,7 +997,8 @@ static int dlm_request_join(struct dlm_ctxt *dlm, { int status; struct dlm_query_join_request join_msg; - union dlm_query_join_response join_resp; + struct dlm_query_join_packet packet; + u32 join_resp; mlog(0, "querying node %d\n", node); @@ -984,11 +1014,12 @@ static int dlm_request_join(struct dlm_ctxt *dlm, status = o2net_send_message(DLM_QUERY_JOIN_MSG, DLM_MOD_KEY, &join_msg, sizeof(join_msg), node, - &join_resp.intval); + &join_resp); if (status < 0 && status != -ENOPROTOOPT) { mlog_errno(status); goto bail; } + dlm_query_join_wire_to_packet(join_resp, &packet); /* -ENOPROTOOPT from the net code means the other side isn't listening for our message type -- that's fine, it means @@ -997,10 +1028,10 @@ static int dlm_request_join(struct dlm_ctxt *dlm, if (status == -ENOPROTOOPT) { status = 0; *response = JOIN_OK_NO_MAP; - } else if (join_resp.packet.code == JOIN_DISALLOW || - join_resp.packet.code == JOIN_OK_NO_MAP) { - *response = join_resp.packet.code; - } else if (join_resp.packet.code == JOIN_PROTOCOL_MISMATCH) { + } else if (packet.code == JOIN_DISALLOW || + packet.code == JOIN_OK_NO_MAP) { + *response = packet.code; + } else if (packet.code == JOIN_PROTOCOL_MISMATCH) { mlog(ML_NOTICE, "This node requested DLM locking protocol %u.%u and " "filesystem locking protocol %u.%u. At least one of " @@ -1012,14 +1043,12 @@ static int dlm_request_join(struct dlm_ctxt *dlm, dlm->fs_locking_proto.pv_minor, node); status = -EPROTO; - *response = join_resp.packet.code; - } else if (join_resp.packet.code == JOIN_OK) { - *response = join_resp.packet.code; + *response = packet.code; + } else if (packet.code == JOIN_OK) { + *response = packet.code; /* Use the same locking protocol as the remote node */ - dlm->dlm_locking_proto.pv_minor = - join_resp.packet.dlm_minor; - dlm->fs_locking_proto.pv_minor = - join_resp.packet.fs_minor; + dlm->dlm_locking_proto.pv_minor = packet.dlm_minor; + dlm->fs_locking_proto.pv_minor = packet.fs_minor; mlog(0, "Node %d responds JOIN_OK with DLM locking protocol " "%u.%u and fs locking protocol %u.%u\n", @@ -1031,11 +1060,11 @@ static int dlm_request_join(struct dlm_ctxt *dlm, } else { status = -EINVAL; mlog(ML_ERROR, "invalid response %d from node %u\n", - join_resp.packet.code, node); + packet.code, node); } mlog(0, "status %d, node %d response is %d\n", status, node, - *response); + *response); bail: return status; diff --git a/fs/ocfs2/dlm/dlmmaster.c b/fs/ocfs2/dlm/dlmmaster.c index a54d33d95ada49f6a993c0518168870e1b58c1a2..ea6b8957786062ad91ab213155fc44ea078724b1 100644 --- a/fs/ocfs2/dlm/dlmmaster.c +++ b/fs/ocfs2/dlm/dlmmaster.c @@ -1663,7 +1663,12 @@ way_up_top: dlm_put_mle(tmpmle); } send_response: - + /* + * __dlm_lookup_lockres() grabbed a reference to this lockres. + * The reference is released by dlm_assert_master_worker() under + * the call to dlm_dispatch_assert_master(). If + * dlm_assert_master_worker() isn't called, we drop it here. + */ if (dispatch_assert) { if (response != DLM_MASTER_RESP_YES) mlog(ML_ERROR, "invalid response %d\n", response); @@ -1678,7 +1683,11 @@ send_response: if (ret < 0) { mlog(ML_ERROR, "failed to dispatch assert master work\n"); response = DLM_MASTER_RESP_ERROR; + dlm_lockres_put(res); } + } else { + if (res) + dlm_lockres_put(res); } dlm_put(dlm); @@ -1695,9 +1704,9 @@ send_response: * can periodically run all locks owned by this node * and re-assert across the cluster... */ -int dlm_do_assert_master(struct dlm_ctxt *dlm, - struct dlm_lock_resource *res, - void *nodemap, u32 flags) +static int dlm_do_assert_master(struct dlm_ctxt *dlm, + struct dlm_lock_resource *res, + void *nodemap, u32 flags) { struct dlm_assert_master assert; int to, tmpret; @@ -2348,7 +2357,7 @@ int dlm_deref_lockres_handler(struct o2net_msg *msg, u32 len, void *data, mlog(ML_ERROR, "%s:%.*s: node %u trying to drop ref " "but it is already dropped!\n", dlm->name, res->lockname.len, res->lockname.name, node); - __dlm_print_one_lock_resource(res); + dlm_print_one_lock_resource(res); } ret = 0; goto done; @@ -2408,7 +2417,7 @@ static void dlm_deref_lockres_worker(struct dlm_work_item *item, void *data) mlog(ML_ERROR, "%s:%.*s: node %u trying to drop ref " "but it is already dropped!\n", dlm->name, res->lockname.len, res->lockname.name, node); - __dlm_print_one_lock_resource(res); + dlm_print_one_lock_resource(res); } dlm_lockres_put(res); @@ -2933,6 +2942,9 @@ static void dlm_remove_nonlocal_locks(struct dlm_ctxt *dlm, dlm_lockres_clear_refmap_bit(lock->ml.node, res); list_del_init(&lock->list); dlm_lock_put(lock); + /* In a normal unlock, we would have added a + * DLM_UNLOCK_FREE_LOCK action. Force it. */ + dlm_lock_put(lock); } } queue++; diff --git a/fs/ocfs2/dlm/dlmrecovery.c b/fs/ocfs2/dlm/dlmrecovery.c index 91f747b8a538b0eb4217f176140064189594211d..bcb9260c37359a832c601f0c00e718094063af25 100644 --- a/fs/ocfs2/dlm/dlmrecovery.c +++ b/fs/ocfs2/dlm/dlmrecovery.c @@ -519,9 +519,9 @@ static int dlm_do_recovery(struct dlm_ctxt *dlm) return 0; master_here: - mlog(0, "(%d) mastering recovery of %s:%u here(this=%u)!\n", - task_pid_nr(dlm->dlm_reco_thread_task), - dlm->name, dlm->reco.dead_node, dlm->node_num); + mlog(ML_NOTICE, "(%d) Node %u is the Recovery Master for the Dead Node " + "%u for Domain %s\n", task_pid_nr(dlm->dlm_reco_thread_task), + dlm->node_num, dlm->reco.dead_node, dlm->name); status = dlm_remaster_locks(dlm, dlm->reco.dead_node); if (status < 0) { @@ -1191,7 +1191,7 @@ static int dlm_add_lock_to_array(struct dlm_lock *lock, (ml->type == LKM_EXMODE || memcmp(mres->lvb, lock->lksb->lvb, DLM_LVB_LEN))) { mlog(ML_ERROR, "mismatched lvbs!\n"); - __dlm_print_one_lock_resource(lock->lockres); + dlm_print_one_lock_resource(lock->lockres); BUG(); } memcpy(mres->lvb, lock->lksb->lvb, DLM_LVB_LEN); @@ -1327,6 +1327,7 @@ int dlm_mig_lockres_handler(struct o2net_msg *msg, u32 len, void *data, (struct dlm_migratable_lockres *)msg->buf; int ret = 0; u8 real_master; + u8 extra_refs = 0; char *buf = NULL; struct dlm_work_item *item = NULL; struct dlm_lock_resource *res = NULL; @@ -1404,16 +1405,28 @@ int dlm_mig_lockres_handler(struct o2net_msg *msg, u32 len, void *data, __dlm_insert_lockres(dlm, res); spin_unlock(&dlm->spinlock); + /* Add an extra ref for this lock-less lockres lest the + * dlm_thread purges it before we get the chance to add + * locks to it */ + dlm_lockres_get(res); + + /* There are three refs that need to be put. + * 1. Taken above. + * 2. kref_init in dlm_new_lockres()->dlm_init_lockres(). + * 3. dlm_lookup_lockres() + * The first one is handled at the end of this function. The + * other two are handled in the worker thread after locks have + * been attached. Yes, we don't wait for purge time to match + * kref_init. The lockres will still have atleast one ref + * added because it is in the hash __dlm_insert_lockres() */ + extra_refs++; + /* now that the new lockres is inserted, * make it usable by other processes */ spin_lock(&res->spinlock); res->state &= ~DLM_LOCK_RES_IN_PROGRESS; spin_unlock(&res->spinlock); wake_up(&res->wq); - - /* add an extra ref for just-allocated lockres - * otherwise the lockres will be purged immediately */ - dlm_lockres_get(res); } /* at this point we have allocated everything we need, @@ -1443,12 +1456,17 @@ int dlm_mig_lockres_handler(struct o2net_msg *msg, u32 len, void *data, dlm_init_work_item(dlm, item, dlm_mig_lockres_worker, buf); item->u.ml.lockres = res; /* already have a ref */ item->u.ml.real_master = real_master; + item->u.ml.extra_ref = extra_refs; spin_lock(&dlm->work_lock); list_add_tail(&item->list, &dlm->work_list); spin_unlock(&dlm->work_lock); queue_work(dlm->dlm_worker, &dlm->dispatched_work); leave: + /* One extra ref taken needs to be put here */ + if (extra_refs) + dlm_lockres_put(res); + dlm_put(dlm); if (ret < 0) { if (buf) @@ -1464,17 +1482,19 @@ leave: static void dlm_mig_lockres_worker(struct dlm_work_item *item, void *data) { - struct dlm_ctxt *dlm = data; + struct dlm_ctxt *dlm; struct dlm_migratable_lockres *mres; int ret = 0; struct dlm_lock_resource *res; u8 real_master; + u8 extra_ref; dlm = item->dlm; mres = (struct dlm_migratable_lockres *)data; res = item->u.ml.lockres; real_master = item->u.ml.real_master; + extra_ref = item->u.ml.extra_ref; if (real_master == DLM_LOCK_RES_OWNER_UNKNOWN) { /* this case is super-rare. only occurs if @@ -1517,6 +1537,12 @@ again: } leave: + /* See comment in dlm_mig_lockres_handler() */ + if (res) { + if (extra_ref) + dlm_lockres_put(res); + dlm_lockres_put(res); + } kfree(data); mlog_exit(ret); } @@ -1644,7 +1670,8 @@ int dlm_master_requery_handler(struct o2net_msg *msg, u32 len, void *data, /* retry!? */ BUG(); } - } + } else /* put.. incase we are not the master */ + dlm_lockres_put(res); spin_unlock(&res->spinlock); } spin_unlock(&dlm->spinlock); @@ -1921,6 +1948,7 @@ void dlm_move_lockres_to_recovery_list(struct dlm_ctxt *dlm, "Recovering res %s:%.*s, is already on recovery list!\n", dlm->name, res->lockname.len, res->lockname.name); list_del_init(&res->recovering); + dlm_lockres_put(res); } /* We need to hold a reference while on the recovery list */ dlm_lockres_get(res); @@ -2130,11 +2158,16 @@ static void dlm_free_dead_locks(struct dlm_ctxt *dlm, assert_spin_locked(&dlm->spinlock); assert_spin_locked(&res->spinlock); + /* We do two dlm_lock_put(). One for removing from list and the other is + * to force the DLM_UNLOCK_FREE_LOCK action so as to free the locks */ + /* TODO: check pending_asts, pending_basts here */ list_for_each_entry_safe(lock, next, &res->granted, list) { if (lock->ml.node == dead_node) { list_del_init(&lock->list); dlm_lock_put(lock); + /* Can't schedule DLM_UNLOCK_FREE_LOCK - do manually */ + dlm_lock_put(lock); freed++; } } @@ -2142,6 +2175,8 @@ static void dlm_free_dead_locks(struct dlm_ctxt *dlm, if (lock->ml.node == dead_node) { list_del_init(&lock->list); dlm_lock_put(lock); + /* Can't schedule DLM_UNLOCK_FREE_LOCK - do manually */ + dlm_lock_put(lock); freed++; } } @@ -2149,6 +2184,8 @@ static void dlm_free_dead_locks(struct dlm_ctxt *dlm, if (lock->ml.node == dead_node) { list_del_init(&lock->list); dlm_lock_put(lock); + /* Can't schedule DLM_UNLOCK_FREE_LOCK - do manually */ + dlm_lock_put(lock); freed++; } } diff --git a/fs/ocfs2/dlm/dlmthread.c b/fs/ocfs2/dlm/dlmthread.c index cebd089f8955f65a17548b44b658ea2043d87a2f..4060bb328bc8a08c22bbd77c59835d757ebdcda5 100644 --- a/fs/ocfs2/dlm/dlmthread.c +++ b/fs/ocfs2/dlm/dlmthread.c @@ -176,12 +176,14 @@ static int dlm_purge_lockres(struct dlm_ctxt *dlm, res->lockname.name, master); if (!master) { + /* drop spinlock... retake below */ + spin_unlock(&dlm->spinlock); + spin_lock(&res->spinlock); /* This ensures that clear refmap is sent after the set */ __dlm_wait_on_lockres_flags(res, DLM_LOCK_RES_SETREF_INPROG); spin_unlock(&res->spinlock); - /* drop spinlock to do messaging, retake below */ - spin_unlock(&dlm->spinlock); + /* clear our bit from the master's refmap, ignore errors */ ret = dlm_drop_lockres_ref(dlm, res); if (ret < 0) { diff --git a/fs/ocfs2/dlmglue.c b/fs/ocfs2/dlmglue.c index 351130c9b7346c7d26faa5d4215720baa8e92f1a..1f1873bf41fb3f5f50f61582b38ecf0c5cb2e0fe 100644 --- a/fs/ocfs2/dlmglue.c +++ b/fs/ocfs2/dlmglue.c @@ -2409,7 +2409,7 @@ static int ocfs2_dlm_seq_show(struct seq_file *m, void *v) return 0; } -static struct seq_operations ocfs2_dlm_seq_ops = { +static const struct seq_operations ocfs2_dlm_seq_ops = { .start = ocfs2_dlm_seq_start, .stop = ocfs2_dlm_seq_stop, .next = ocfs2_dlm_seq_next, @@ -3042,7 +3042,7 @@ static int ocfs2_data_convert_worker(struct ocfs2_lock_res *lockres, inode = ocfs2_lock_res_inode(lockres); mapping = inode->i_mapping; - if (S_ISREG(inode->i_mode)) + if (!S_ISREG(inode->i_mode)) goto out; /* @@ -3219,8 +3219,8 @@ static int ocfs2_dentry_convert_worker(struct ocfs2_lock_res *lockres, return UNBLOCK_CONTINUE_POST; } -void ocfs2_process_blocked_lock(struct ocfs2_super *osb, - struct ocfs2_lock_res *lockres) +static void ocfs2_process_blocked_lock(struct ocfs2_super *osb, + struct ocfs2_lock_res *lockres) { int status; struct ocfs2_unblock_ctl ctl = {0, 0,}; @@ -3356,7 +3356,7 @@ static int ocfs2_downconvert_thread_should_wake(struct ocfs2_super *osb) return should_wake; } -int ocfs2_downconvert_thread(void *arg) +static int ocfs2_downconvert_thread(void *arg) { int status = 0; struct ocfs2_super *osb = arg; diff --git a/fs/ocfs2/dlmglue.h b/fs/ocfs2/dlmglue.h index 1d5b0699d0a9bb0adc67a85d4720778be9f81773..e3cf902404b45e3caaec642d450cf626d09ecb74 100644 --- a/fs/ocfs2/dlmglue.h +++ b/fs/ocfs2/dlmglue.h @@ -109,8 +109,6 @@ void ocfs2_simple_drop_lockres(struct ocfs2_super *osb, struct ocfs2_lock_res *lockres); /* for the downconvert thread */ -void ocfs2_process_blocked_lock(struct ocfs2_super *osb, - struct ocfs2_lock_res *lockres); void ocfs2_wake_downconvert_thread(struct ocfs2_super *osb); struct ocfs2_dlm_debug *ocfs2_new_dlm_debug(void); diff --git a/fs/ocfs2/heartbeat.c b/fs/ocfs2/heartbeat.c index c0efd9489fe8168f88d28c1abe6acdb2cedb3385..0758daf64da07c41fcf4f73a7b55d634589ab87d 100644 --- a/fs/ocfs2/heartbeat.c +++ b/fs/ocfs2/heartbeat.c @@ -49,10 +49,15 @@ static inline void __ocfs2_node_map_set_bit(struct ocfs2_node_map *map, static inline void __ocfs2_node_map_clear_bit(struct ocfs2_node_map *map, int bit); static inline int __ocfs2_node_map_is_empty(struct ocfs2_node_map *map); -static void __ocfs2_node_map_dup(struct ocfs2_node_map *target, - struct ocfs2_node_map *from); -static void __ocfs2_node_map_set(struct ocfs2_node_map *target, - struct ocfs2_node_map *from); + +/* special case -1 for now + * TODO: should *really* make sure the calling func never passes -1!! */ +static void ocfs2_node_map_init(struct ocfs2_node_map *map) +{ + map->num_nodes = OCFS2_NODE_MAP_MAX_NODES; + memset(map->map, 0, BITS_TO_LONGS(OCFS2_NODE_MAP_MAX_NODES) * + sizeof(unsigned long)); +} void ocfs2_init_node_maps(struct ocfs2_super *osb) { @@ -136,15 +141,6 @@ void ocfs2_stop_heartbeat(struct ocfs2_super *osb) mlog_errno(ret); } -/* special case -1 for now - * TODO: should *really* make sure the calling func never passes -1!! */ -void ocfs2_node_map_init(struct ocfs2_node_map *map) -{ - map->num_nodes = OCFS2_NODE_MAP_MAX_NODES; - memset(map->map, 0, BITS_TO_LONGS(OCFS2_NODE_MAP_MAX_NODES) * - sizeof(unsigned long)); -} - static inline void __ocfs2_node_map_set_bit(struct ocfs2_node_map *map, int bit) { @@ -216,6 +212,8 @@ int ocfs2_node_map_is_empty(struct ocfs2_super *osb, return ret; } +#if 0 + static void __ocfs2_node_map_dup(struct ocfs2_node_map *target, struct ocfs2_node_map *from) { @@ -254,6 +252,8 @@ static void __ocfs2_node_map_set(struct ocfs2_node_map *target, target->map[i] = from->map[i]; } +#endif /* 0 */ + /* Returns whether the recovery bit was actually set - it may not be * if a node is still marked as needing recovery */ int ocfs2_recovery_map_set(struct ocfs2_super *osb, diff --git a/fs/ocfs2/heartbeat.h b/fs/ocfs2/heartbeat.h index 56859211888a18cd6f22ed9a9fecf20eaba040ce..eac63aed7611c2105d5026c58affea7f2b562ed4 100644 --- a/fs/ocfs2/heartbeat.h +++ b/fs/ocfs2/heartbeat.h @@ -33,7 +33,6 @@ void ocfs2_stop_heartbeat(struct ocfs2_super *osb); /* node map functions - used to keep track of mounted and in-recovery * nodes. */ -void ocfs2_node_map_init(struct ocfs2_node_map *map); int ocfs2_node_map_is_empty(struct ocfs2_super *osb, struct ocfs2_node_map *map); void ocfs2_node_map_set_bit(struct ocfs2_super *osb, @@ -57,9 +56,5 @@ int ocfs2_recovery_map_set(struct ocfs2_super *osb, int num); void ocfs2_recovery_map_clear(struct ocfs2_super *osb, int num); -/* returns 1 if bit is the only bit set in target, 0 otherwise */ -int ocfs2_node_map_is_only(struct ocfs2_super *osb, - struct ocfs2_node_map *target, - int bit); #endif /* OCFS2_HEARTBEAT_H */ diff --git a/fs/ocfs2/localalloc.c b/fs/ocfs2/localalloc.c index add1ffdc5c6c75bb2accdb65972466f2651e80c8..ab83fd5624294561541dba9663f128336f296116 100644 --- a/fs/ocfs2/localalloc.c +++ b/fs/ocfs2/localalloc.c @@ -120,9 +120,6 @@ int ocfs2_load_local_alloc(struct ocfs2_super *osb) mlog_entry_void(); - if (ocfs2_mount_local(osb)) - goto bail; - if (osb->local_alloc_size == 0) goto bail; @@ -588,8 +585,7 @@ int ocfs2_claim_local_alloc_bits(struct ocfs2_super *osb, while(bits_wanted--) ocfs2_set_bit(start++, bitmap); - alloc->id1.bitmap1.i_used = cpu_to_le32(*num_bits + - le32_to_cpu(alloc->id1.bitmap1.i_used)); + le32_add_cpu(&alloc->id1.bitmap1.i_used, *num_bits); status = ocfs2_journal_dirty(handle, osb->local_alloc_bh); if (status < 0) { diff --git a/fs/ocfs2/resize.c b/fs/ocfs2/resize.c index 37835ffcb03985f7bd61a1322538d96ca8f8830d..8166968e9015d8634f1987cd8af84f07595c86b9 100644 --- a/fs/ocfs2/resize.c +++ b/fs/ocfs2/resize.c @@ -597,7 +597,7 @@ int ocfs2_group_add(struct inode *inode, struct ocfs2_new_group_input *input) memset(cr, 0, sizeof(struct ocfs2_chain_rec)); } - cr->c_blkno = le64_to_cpu(input->group); + cr->c_blkno = cpu_to_le64(input->group); le32_add_cpu(&cr->c_total, input->clusters * cl_bpc); le32_add_cpu(&cr->c_free, input->frees * cl_bpc); diff --git a/fs/proc/base.c b/fs/proc/base.c index 96ee899d65020e76e5c0c8d49b0683c74214ebed..9a4da0aae02e442e5be76fa84a0907a43e1bf848 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c @@ -314,9 +314,12 @@ static int proc_pid_schedstat(struct task_struct *task, char *buffer) static int lstats_show_proc(struct seq_file *m, void *v) { int i; - struct task_struct *task = m->private; - seq_puts(m, "Latency Top version : v0.1\n"); + struct inode *inode = m->private; + struct task_struct *task = get_proc_task(inode); + if (!task) + return -ESRCH; + seq_puts(m, "Latency Top version : v0.1\n"); for (i = 0; i < 32; i++) { if (task->latency_record[i].backtrace[0]) { int q; @@ -341,32 +344,24 @@ static int lstats_show_proc(struct seq_file *m, void *v) } } + put_task_struct(task); return 0; } static int lstats_open(struct inode *inode, struct file *file) { - int ret; - struct seq_file *m; - struct task_struct *task = get_proc_task(inode); - - ret = single_open(file, lstats_show_proc, NULL); - if (!ret) { - m = file->private_data; - m->private = task; - } - return ret; + return single_open(file, lstats_show_proc, inode); } static ssize_t lstats_write(struct file *file, const char __user *buf, size_t count, loff_t *offs) { - struct seq_file *m; - struct task_struct *task; + struct task_struct *task = get_proc_task(file->f_dentry->d_inode); - m = file->private_data; - task = m->private; + if (!task) + return -ESRCH; clear_all_latency_tracing(task); + put_task_struct(task); return count; } @@ -2274,6 +2269,9 @@ static const struct pid_entry tgid_base_stuff[] = { DIR("task", S_IRUGO|S_IXUGO, task), DIR("fd", S_IRUSR|S_IXUSR, fd), DIR("fdinfo", S_IRUSR|S_IXUSR, fdinfo), +#ifdef CONFIG_NET + DIR("net", S_IRUGO|S_IXUSR, net), +#endif REG("environ", S_IRUSR, environ), INF("auxv", S_IRUSR, pid_auxv), ONE("status", S_IRUGO, pid_status), diff --git a/fs/proc/generic.c b/fs/proc/generic.c index 68971e66cd41ca438f7dff0e6047322fca2b5d5f..a36ad3c75cf43bbc0cb9f34d550893d952316ac1 100644 --- a/fs/proc/generic.c +++ b/fs/proc/generic.c @@ -377,15 +377,14 @@ static struct dentry_operations proc_dentry_operations = * Don't create negative dentries here, return -ENOENT by hand * instead. */ -struct dentry *proc_lookup(struct inode * dir, struct dentry *dentry, struct nameidata *nd) +struct dentry *proc_lookup_de(struct proc_dir_entry *de, struct inode *dir, + struct dentry *dentry) { struct inode *inode = NULL; - struct proc_dir_entry * de; int error = -ENOENT; lock_kernel(); spin_lock(&proc_subdir_lock); - de = PDE(dir); if (de) { for (de = de->subdir; de ; de = de->next) { if (de->namelen != dentry->d_name.len) @@ -393,8 +392,6 @@ struct dentry *proc_lookup(struct inode * dir, struct dentry *dentry, struct nam if (!memcmp(dentry->d_name.name, de->name, de->namelen)) { unsigned int ino; - if (de->shadow_proc) - de = de->shadow_proc(current, de); ino = de->low_ino; de_get(de); spin_unlock(&proc_subdir_lock); @@ -417,6 +414,12 @@ out_unlock: return ERR_PTR(error); } +struct dentry *proc_lookup(struct inode *dir, struct dentry *dentry, + struct nameidata *nd) +{ + return proc_lookup_de(PDE(dir), dir, dentry); +} + /* * This returns non-zero if at EOF, so that the /proc * root directory can use this and check if it should @@ -426,10 +429,9 @@ out_unlock: * value of the readdir() call, as long as it's non-negative * for success.. */ -int proc_readdir(struct file * filp, - void * dirent, filldir_t filldir) +int proc_readdir_de(struct proc_dir_entry *de, struct file *filp, void *dirent, + filldir_t filldir) { - struct proc_dir_entry * de; unsigned int ino; int i; struct inode *inode = filp->f_path.dentry->d_inode; @@ -438,7 +440,6 @@ int proc_readdir(struct file * filp, lock_kernel(); ino = inode->i_ino; - de = PDE(inode); if (!de) { ret = -EINVAL; goto out; @@ -499,6 +500,13 @@ out: unlock_kernel(); return ret; } +int proc_readdir(struct file *filp, void *dirent, filldir_t filldir) +{ + struct inode *inode = filp->f_path.dentry->d_inode; + + return proc_readdir_de(PDE(inode), filp, dirent, filldir); +} + /* * These are the generic /proc directory operations. They * use the in-memory "struct proc_dir_entry" tree to parse diff --git a/fs/proc/internal.h b/fs/proc/internal.h index 1c81c8f1aeed411d05331e3bcd61c39e43343b4e..bc72f5c8c47d34704cb6a76ef450e1bd6dc84f0d 100644 --- a/fs/proc/internal.h +++ b/fs/proc/internal.h @@ -64,6 +64,8 @@ extern const struct file_operations proc_numa_maps_operations; extern const struct file_operations proc_smaps_operations; extern const struct file_operations proc_clear_refs_operations; extern const struct file_operations proc_pagemap_operations; +extern const struct file_operations proc_net_operations; +extern const struct inode_operations proc_net_inode_operations; void free_proc_entry(struct proc_dir_entry *de); @@ -83,3 +85,8 @@ static inline int proc_fd(struct inode *inode) { return PROC_I(inode)->fd; } + +struct dentry *proc_lookup_de(struct proc_dir_entry *de, struct inode *ino, + struct dentry *dentry); +int proc_readdir_de(struct proc_dir_entry *de, struct file *filp, void *dirent, + filldir_t filldir); diff --git a/fs/proc/proc_misc.c b/fs/proc/proc_misc.c index 468805d40e2bdb44daeb43bfccf4a1b5919c7add..2d563979cb025412dce7847bd79979c34a8456eb 100644 --- a/fs/proc/proc_misc.c +++ b/fs/proc/proc_misc.c @@ -32,6 +32,7 @@ #include #include #include +#include #include #include #include @@ -377,7 +378,6 @@ static int stram_read_proc(char *page, char **start, off_t off, #endif #ifdef CONFIG_BLOCK -extern const struct seq_operations partitions_op; static int partitions_open(struct inode *inode, struct file *file) { return seq_open(file, &partitions_op); @@ -389,7 +389,6 @@ static const struct file_operations proc_partitions_operations = { .release = seq_release, }; -extern const struct seq_operations diskstats_op; static int diskstats_open(struct inode *inode, struct file *file) { return seq_open(file, &diskstats_op); diff --git a/fs/proc/proc_net.c b/fs/proc/proc_net.c index 14e9b5aaf863bce23d6ccb03aa582cb9b6a4c566..4caa5f774fb7975136d04e2baf81826e1c392dba 100644 --- a/fs/proc/proc_net.c +++ b/fs/proc/proc_net.c @@ -63,6 +63,82 @@ int seq_release_net(struct inode *ino, struct file *f) } EXPORT_SYMBOL_GPL(seq_release_net); +static struct net *get_proc_task_net(struct inode *dir) +{ + struct task_struct *task; + struct nsproxy *ns; + struct net *net = NULL; + + rcu_read_lock(); + task = pid_task(proc_pid(dir), PIDTYPE_PID); + if (task != NULL) { + ns = task_nsproxy(task); + if (ns != NULL) + net = get_net(ns->net_ns); + } + rcu_read_unlock(); + + return net; +} + +static struct dentry *proc_tgid_net_lookup(struct inode *dir, + struct dentry *dentry, struct nameidata *nd) +{ + struct dentry *de; + struct net *net; + + de = ERR_PTR(-ENOENT); + net = get_proc_task_net(dir); + if (net != NULL) { + de = proc_lookup_de(net->proc_net, dir, dentry); + put_net(net); + } + return de; +} + +static int proc_tgid_net_getattr(struct vfsmount *mnt, struct dentry *dentry, + struct kstat *stat) +{ + struct inode *inode = dentry->d_inode; + struct net *net; + + net = get_proc_task_net(inode); + + generic_fillattr(inode, stat); + + if (net != NULL) { + stat->nlink = net->proc_net->nlink; + put_net(net); + } + + return 0; +} + +const struct inode_operations proc_net_inode_operations = { + .lookup = proc_tgid_net_lookup, + .getattr = proc_tgid_net_getattr, +}; + +static int proc_tgid_net_readdir(struct file *filp, void *dirent, + filldir_t filldir) +{ + int ret; + struct net *net; + + ret = -EINVAL; + net = get_proc_task_net(filp->f_path.dentry->d_inode); + if (net != NULL) { + ret = proc_readdir_de(net->proc_net, filp, dirent, filldir); + put_net(net); + } + return ret; +} + +const struct file_operations proc_net_operations = { + .read = generic_read_dir, + .readdir = proc_tgid_net_readdir, +}; + struct proc_dir_entry *proc_net_fops_create(struct net *net, const char *name, mode_t mode, const struct file_operations *fops) @@ -83,14 +159,6 @@ struct net *get_proc_net(const struct inode *inode) } EXPORT_SYMBOL_GPL(get_proc_net); -static struct proc_dir_entry *shadow_pde; - -static struct proc_dir_entry *proc_net_shadow(struct task_struct *task, - struct proc_dir_entry *de) -{ - return task->nsproxy->net_ns->proc_net; -} - struct proc_dir_entry *proc_net_mkdir(struct net *net, const char *name, struct proc_dir_entry *parent) { @@ -104,45 +172,39 @@ EXPORT_SYMBOL_GPL(proc_net_mkdir); static __net_init int proc_net_ns_init(struct net *net) { - struct proc_dir_entry *root, *netd, *net_statd; + struct proc_dir_entry *netd, *net_statd; int err; err = -ENOMEM; - root = kzalloc(sizeof(*root), GFP_KERNEL); - if (!root) + netd = kzalloc(sizeof(*netd), GFP_KERNEL); + if (!netd) goto out; - err = -EEXIST; - netd = proc_net_mkdir(net, "net", root); - if (!netd) - goto free_root; + netd->data = net; + netd->nlink = 2; + netd->name = "net"; + netd->namelen = 3; + netd->parent = &proc_root; err = -EEXIST; net_statd = proc_net_mkdir(net, "stat", netd); if (!net_statd) goto free_net; - root->data = net; - - net->proc_net_root = root; net->proc_net = netd; net->proc_net_stat = net_statd; - err = 0; + return 0; +free_net: + kfree(netd); out: return err; -free_net: - remove_proc_entry("net", root); -free_root: - kfree(root); - goto out; } static __net_exit void proc_net_ns_exit(struct net *net) { remove_proc_entry("stat", net->proc_net); - remove_proc_entry("net", net->proc_net_root); - kfree(net->proc_net_root); + kfree(net->proc_net); } static struct pernet_operations __net_initdata proc_net_ns_ops = { @@ -152,8 +214,7 @@ static struct pernet_operations __net_initdata proc_net_ns_ops = { int __init proc_net_init(void) { - shadow_pde = proc_mkdir("net", NULL); - shadow_pde->shadow_proc = proc_net_shadow; + proc_symlink("net", NULL, "self/net"); return register_pernet_subsys(&proc_net_ns_ops); } diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c index 6dc0334815f7f1243691ff714b175e2bc2b4dd54..4206454734e09d464d34a5c5a3bd86a6b51cfa9d 100644 --- a/fs/proc/task_mmu.c +++ b/fs/proc/task_mmu.c @@ -640,17 +640,17 @@ static ssize_t pagemap_read(struct file *file, char __user *buf, ret = -EACCES; if (!ptrace_may_attach(task)) - goto out; + goto out_task; ret = -EINVAL; /* file position must be aligned */ if (*ppos % PM_ENTRY_BYTES) - goto out; + goto out_task; ret = 0; mm = get_task_mm(task); if (!mm) - goto out; + goto out_task; ret = -ENOMEM; uaddr = (unsigned long)buf & PAGE_MASK; @@ -658,7 +658,7 @@ static ssize_t pagemap_read(struct file *file, char __user *buf, pagecount = (PAGE_ALIGN(uend) - uaddr) / PAGE_SIZE; pages = kmalloc(pagecount * sizeof(struct page *), GFP_KERNEL); if (!pages) - goto out_task; + goto out_mm; down_read(¤t->mm->mmap_sem); ret = get_user_pages(current, current->mm, uaddr, pagecount, @@ -668,6 +668,12 @@ static ssize_t pagemap_read(struct file *file, char __user *buf, if (ret < 0) goto out_free; + if (ret != pagecount) { + pagecount = ret; + ret = -EFAULT; + goto out_pages; + } + pm.out = buf; pm.end = buf + count; @@ -699,15 +705,17 @@ static ssize_t pagemap_read(struct file *file, char __user *buf, ret = pm.out - buf; } +out_pages: for (; pagecount; pagecount--) { page = pages[pagecount-1]; if (!PageReserved(page)) SetPageDirty(page); page_cache_release(page); } - mmput(mm); out_free: kfree(pages); +out_mm: + mmput(mm); out_task: put_task_struct(task); out: diff --git a/fs/reiserfs/super.c b/fs/reiserfs/super.c index 6841452e0dea00620cd2053f9cd02356f94f6169..393cc22c1717d582dc9e03d401ec514fd8ac4c99 100644 --- a/fs/reiserfs/super.c +++ b/fs/reiserfs/super.c @@ -2031,7 +2031,7 @@ static int reiserfs_quota_on(struct super_block *sb, int type, int format_id, return -EXDEV; } /* We must not pack tails for quota files on reiserfs for quota IO to work */ - if (!REISERFS_I(nd.path.dentry->d_inode)->i_flags & i_nopack_mask) { + if (!(REISERFS_I(nd.path.dentry->d_inode)->i_flags & i_nopack_mask)) { reiserfs_warning(sb, "reiserfs: Quota file must have tail packing disabled."); path_put(&nd.path); diff --git a/fs/splice.c b/fs/splice.c index 9b559ee711a8e59f8e12fb0029b4d5a0356b7df4..0670c915cd35c5e8b653494d4d5b1efe76867e2e 100644 --- a/fs/splice.c +++ b/fs/splice.c @@ -1669,6 +1669,13 @@ static int link_pipe(struct pipe_inode_info *ipipe, i++; } while (len); + /* + * return EAGAIN if we have the potential of some data in the + * future, otherwise just return 0 + */ + if (!ret && ipipe->waiting_writers && (flags & SPLICE_F_NONBLOCK)) + ret = -EAGAIN; + inode_double_unlock(ipipe->inode, opipe->inode); /* @@ -1709,11 +1716,8 @@ static long do_tee(struct file *in, struct file *out, size_t len, ret = link_ipipe_prep(ipipe, flags); if (!ret) { ret = link_opipe_prep(opipe, flags); - if (!ret) { + if (!ret) ret = link_pipe(ipipe, opipe, len, flags); - if (!ret && (flags & SPLICE_F_NONBLOCK)) - ret = -EAGAIN; - } } } diff --git a/fs/super.c b/fs/super.c index 88811f60c8de517829ce7828c1971bfb4f90d8a1..010446d8c40a03512e4c1a8dc689581a67c5bbf3 100644 --- a/fs/super.c +++ b/fs/super.c @@ -870,12 +870,12 @@ vfs_kern_mount(struct file_system_type *type, int flags, const char *name, void if (!mnt) goto out; - if (data) { + if (data && !(type->fs_flags & FS_BINARY_MOUNTDATA)) { secdata = alloc_secdata(); if (!secdata) goto out_mnt; - error = security_sb_copy_data(type, data, secdata); + error = security_sb_copy_data(data, secdata); if (error) goto out_free_secdata; } diff --git a/fs/xfs/linux-2.6/xfs_super.c b/fs/xfs/linux-2.6/xfs_super.c index 21dfc9da235e623ef77a330076edb6269f375f48..8831d95187904f0ecf4a1aa1ac5b77cc767aec77 100644 --- a/fs/xfs/linux-2.6/xfs_super.c +++ b/fs/xfs/linux-2.6/xfs_super.c @@ -171,7 +171,7 @@ xfs_parseargs( char *this_char, *value, *eov; int dsunit, dswidth, vol_dsunit, vol_dswidth; int iosize; - int ikeep = 0; + int dmapi_implies_ikeep = 1; args->flags |= XFSMNT_BARRIER; args->flags2 |= XFSMNT2_COMPAT_IOSIZE; @@ -302,10 +302,10 @@ xfs_parseargs( } else if (!strcmp(this_char, MNTOPT_NOBARRIER)) { args->flags &= ~XFSMNT_BARRIER; } else if (!strcmp(this_char, MNTOPT_IKEEP)) { - ikeep = 1; - args->flags &= ~XFSMNT_IDELETE; + args->flags |= XFSMNT_IKEEP; } else if (!strcmp(this_char, MNTOPT_NOIKEEP)) { - args->flags |= XFSMNT_IDELETE; + dmapi_implies_ikeep = 0; + args->flags &= ~XFSMNT_IKEEP; } else if (!strcmp(this_char, MNTOPT_LARGEIO)) { args->flags2 &= ~XFSMNT2_COMPAT_IOSIZE; } else if (!strcmp(this_char, MNTOPT_NOLARGEIO)) { @@ -410,8 +410,8 @@ xfs_parseargs( * Note that if "ikeep" or "noikeep" mount options are * supplied, then they are honored. */ - if (!(args->flags & XFSMNT_DMAPI) && !ikeep) - args->flags |= XFSMNT_IDELETE; + if ((args->flags & XFSMNT_DMAPI) && dmapi_implies_ikeep) + args->flags |= XFSMNT_IKEEP; if ((args->flags & XFSMNT_NOALIGN) != XFSMNT_NOALIGN) { if (dsunit) { @@ -446,6 +446,7 @@ xfs_showargs( { static struct proc_xfs_info xfs_info_set[] = { /* the few simple ones we can get from the mount struct */ + { XFS_MOUNT_IKEEP, "," MNTOPT_IKEEP }, { XFS_MOUNT_WSYNC, "," MNTOPT_WSYNC }, { XFS_MOUNT_INO64, "," MNTOPT_INO64 }, { XFS_MOUNT_NOALIGN, "," MNTOPT_NOALIGN }, @@ -461,7 +462,6 @@ xfs_showargs( }; static struct proc_xfs_info xfs_info_unset[] = { /* the few simple ones we can get from the mount struct */ - { XFS_MOUNT_IDELETE, "," MNTOPT_IKEEP }, { XFS_MOUNT_COMPAT_IOSIZE, "," MNTOPT_LARGEIO }, { XFS_MOUNT_BARRIER, "," MNTOPT_NOBARRIER }, { XFS_MOUNT_SMALL_INUMS, "," MNTOPT_64BITINODE }, diff --git a/fs/xfs/xfs_bit.c b/fs/xfs/xfs_bit.c index 48228848f5ae3e2e6f52900b6d0ea7215274a36d..fab0b6d5a41be3916ac8893a2f82f142cd4443f4 100644 --- a/fs/xfs/xfs_bit.c +++ b/fs/xfs/xfs_bit.c @@ -25,6 +25,109 @@ * XFS bit manipulation routines, used in non-realtime code. */ +#ifndef HAVE_ARCH_HIGHBIT +/* + * Index of high bit number in byte, -1 for none set, 0..7 otherwise. + */ +static const char xfs_highbit[256] = { + -1, 0, 1, 1, 2, 2, 2, 2, /* 00 .. 07 */ + 3, 3, 3, 3, 3, 3, 3, 3, /* 08 .. 0f */ + 4, 4, 4, 4, 4, 4, 4, 4, /* 10 .. 17 */ + 4, 4, 4, 4, 4, 4, 4, 4, /* 18 .. 1f */ + 5, 5, 5, 5, 5, 5, 5, 5, /* 20 .. 27 */ + 5, 5, 5, 5, 5, 5, 5, 5, /* 28 .. 2f */ + 5, 5, 5, 5, 5, 5, 5, 5, /* 30 .. 37 */ + 5, 5, 5, 5, 5, 5, 5, 5, /* 38 .. 3f */ + 6, 6, 6, 6, 6, 6, 6, 6, /* 40 .. 47 */ + 6, 6, 6, 6, 6, 6, 6, 6, /* 48 .. 4f */ + 6, 6, 6, 6, 6, 6, 6, 6, /* 50 .. 57 */ + 6, 6, 6, 6, 6, 6, 6, 6, /* 58 .. 5f */ + 6, 6, 6, 6, 6, 6, 6, 6, /* 60 .. 67 */ + 6, 6, 6, 6, 6, 6, 6, 6, /* 68 .. 6f */ + 6, 6, 6, 6, 6, 6, 6, 6, /* 70 .. 77 */ + 6, 6, 6, 6, 6, 6, 6, 6, /* 78 .. 7f */ + 7, 7, 7, 7, 7, 7, 7, 7, /* 80 .. 87 */ + 7, 7, 7, 7, 7, 7, 7, 7, /* 88 .. 8f */ + 7, 7, 7, 7, 7, 7, 7, 7, /* 90 .. 97 */ + 7, 7, 7, 7, 7, 7, 7, 7, /* 98 .. 9f */ + 7, 7, 7, 7, 7, 7, 7, 7, /* a0 .. a7 */ + 7, 7, 7, 7, 7, 7, 7, 7, /* a8 .. af */ + 7, 7, 7, 7, 7, 7, 7, 7, /* b0 .. b7 */ + 7, 7, 7, 7, 7, 7, 7, 7, /* b8 .. bf */ + 7, 7, 7, 7, 7, 7, 7, 7, /* c0 .. c7 */ + 7, 7, 7, 7, 7, 7, 7, 7, /* c8 .. cf */ + 7, 7, 7, 7, 7, 7, 7, 7, /* d0 .. d7 */ + 7, 7, 7, 7, 7, 7, 7, 7, /* d8 .. df */ + 7, 7, 7, 7, 7, 7, 7, 7, /* e0 .. e7 */ + 7, 7, 7, 7, 7, 7, 7, 7, /* e8 .. ef */ + 7, 7, 7, 7, 7, 7, 7, 7, /* f0 .. f7 */ + 7, 7, 7, 7, 7, 7, 7, 7, /* f8 .. ff */ +}; +#endif + +/* + * xfs_highbit32: get high bit set out of 32-bit argument, -1 if none set. + */ +inline int +xfs_highbit32( + __uint32_t v) +{ +#ifdef HAVE_ARCH_HIGHBIT + return highbit32(v); +#else + int i; + + if (v & 0xffff0000) + if (v & 0xff000000) + i = 24; + else + i = 16; + else if (v & 0x0000ffff) + if (v & 0x0000ff00) + i = 8; + else + i = 0; + else + return -1; + return i + xfs_highbit[(v >> i) & 0xff]; +#endif +} + +/* + * xfs_lowbit64: get low bit set out of 64-bit argument, -1 if none set. + */ +int +xfs_lowbit64( + __uint64_t v) +{ + __uint32_t w = (__uint32_t)v; + int n = 0; + + if (w) { /* lower bits */ + n = ffs(w); + } else { /* upper bits */ + w = (__uint32_t)(v >> 32); + if (w && (n = ffs(w))) + n += 32; + } + return n - 1; +} + +/* + * xfs_highbit64: get high bit set out of 64-bit argument, -1 if none set. + */ +int +xfs_highbit64( + __uint64_t v) +{ + __uint32_t h = (__uint32_t)(v >> 32); + + if (h) + return xfs_highbit32(h) + 32; + return xfs_highbit32((__uint32_t)v); +} + + /* * Return whether bitmap is empty. * Size is number of words in the bitmap, which is padded to word boundary diff --git a/fs/xfs/xfs_bit.h b/fs/xfs/xfs_bit.h index 325a007dec91de7942df66db18afc0be2199a61c..082641a9782c073e832fab360d88d98020f87310 100644 --- a/fs/xfs/xfs_bit.h +++ b/fs/xfs/xfs_bit.h @@ -47,30 +47,13 @@ static inline __uint64_t xfs_mask64lo(int n) } /* Get high bit set out of 32-bit argument, -1 if none set */ -static inline int xfs_highbit32(__uint32_t v) -{ - return fls(v) - 1; -} - -/* Get high bit set out of 64-bit argument, -1 if none set */ -static inline int xfs_highbit64(__uint64_t v) -{ - return fls64(v) - 1; -} - -/* Get low bit set out of 32-bit argument, -1 if none set */ -static inline int xfs_lowbit32(__uint32_t v) -{ - __uint32_t t = v; - return (t) ? find_first_bit((unsigned long *)&t, 32) : -1; -} +extern int xfs_highbit32(__uint32_t v); /* Get low bit set out of 64-bit argument, -1 if none set */ -static inline int xfs_lowbit64(__uint64_t v) -{ - __uint64_t t = v; - return (t) ? find_first_bit((unsigned long *)&t, 64) : -1; -} +extern int xfs_lowbit64(__uint64_t v); + +/* Get high bit set out of 64-bit argument, -1 if none set */ +extern int xfs_highbit64(__uint64_t); /* Return whether bitmap is empty (1 == empty) */ extern int xfs_bitmap_empty(uint *map, uint size); diff --git a/fs/xfs/xfs_clnt.h b/fs/xfs/xfs_clnt.h index d16c1b971074ba0cb95403b522f1efe083771070..d5d1e60ee2247ba7281954888a0412c51a0bbd3f 100644 --- a/fs/xfs/xfs_clnt.h +++ b/fs/xfs/xfs_clnt.h @@ -86,7 +86,7 @@ struct xfs_mount_args { #define XFSMNT_NOUUID 0x01000000 /* Ignore fs uuid */ #define XFSMNT_DMAPI 0x02000000 /* enable dmapi/xdsm */ #define XFSMNT_BARRIER 0x04000000 /* use write barriers */ -#define XFSMNT_IDELETE 0x08000000 /* inode cluster delete */ +#define XFSMNT_IKEEP 0x08000000 /* inode cluster delete */ #define XFSMNT_SWALLOC 0x10000000 /* turn on stripe width * allocation */ #define XFSMNT_DIRSYNC 0x40000000 /* sync creat,link,unlink,rename diff --git a/fs/xfs/xfs_ialloc.c b/fs/xfs/xfs_ialloc.c index c5836b951d0c1a80ef9f71a2e0eeba511a437af1..db9d5fa600af04ea5a1a0b31e3111c8a38347af7 100644 --- a/fs/xfs/xfs_ialloc.c +++ b/fs/xfs/xfs_ialloc.c @@ -1053,7 +1053,7 @@ xfs_difree( /* * When an inode cluster is free, it becomes eligible for removal */ - if ((mp->m_flags & XFS_MOUNT_IDELETE) && + if (!(mp->m_flags & XFS_MOUNT_IKEEP) && (rec.ir_freecount == XFS_IALLOC_INODES(mp))) { *delete = 1; diff --git a/fs/xfs/xfs_iget.c b/fs/xfs/xfs_iget.c index f01b07687faf93103ff7964f266607b3a6a3ce17..8e09b71f4104a91e0e6e2ba00ce8384d1b780499 100644 --- a/fs/xfs/xfs_iget.c +++ b/fs/xfs/xfs_iget.c @@ -235,6 +235,7 @@ finish_inode: */ new_icl = kmem_zone_alloc(xfs_icluster_zone, KM_SLEEP); if (radix_tree_preload(GFP_KERNEL)) { + xfs_idestroy(ip); delay(1); goto again; } diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h index f7c620ec6e695eb338b4da9a21692bf5d0c59608..1d8a4728d847c104403cbaa8117b6b2c6a8089a3 100644 --- a/fs/xfs/xfs_mount.h +++ b/fs/xfs/xfs_mount.h @@ -366,7 +366,7 @@ typedef struct xfs_mount { #define XFS_MOUNT_SMALL_INUMS (1ULL << 15) /* users wants 32bit inodes */ #define XFS_MOUNT_NOUUID (1ULL << 16) /* ignore uuid during mount */ #define XFS_MOUNT_BARRIER (1ULL << 17) -#define XFS_MOUNT_IDELETE (1ULL << 18) /* delete empty inode clusters*/ +#define XFS_MOUNT_IKEEP (1ULL << 18) /* keep empty inode clusters*/ #define XFS_MOUNT_SWALLOC (1ULL << 19) /* turn on stripe width * allocation */ #define XFS_MOUNT_RDONLY (1ULL << 20) /* read-only fs */ diff --git a/fs/xfs/xfs_rtalloc.c b/fs/xfs/xfs_rtalloc.c index ca83ddf72af4569ab8cfa1b3cdfcbbf16c80ffb6..47082c01872d0621f0c8499862e16c6ef33d2aee 100644 --- a/fs/xfs/xfs_rtalloc.c +++ b/fs/xfs/xfs_rtalloc.c @@ -72,6 +72,18 @@ STATIC int xfs_rtmodify_summary(xfs_mount_t *, xfs_trans_t *, int, * Internal functions. */ +/* + * xfs_lowbit32: get low bit set out of 32-bit argument, -1 if none set. + */ +STATIC int +xfs_lowbit32( + __uint32_t v) +{ + if (v) + return ffs(v) - 1; + return -1; +} + /* * Allocate space to the bitmap or summary file, and zero it, for growfs. */ @@ -432,7 +444,6 @@ xfs_rtallocate_extent_near( } bbno = XFS_BITTOBLOCK(mp, bno); i = 0; - ASSERT(minlen != 0); log2len = xfs_highbit32(minlen); /* * Loop over all bitmap blocks (bbno + i is current block). @@ -601,8 +612,6 @@ xfs_rtallocate_extent_size( xfs_suminfo_t sum; /* summary information for extents */ ASSERT(minlen % prod == 0 && maxlen % prod == 0); - ASSERT(maxlen != 0); - /* * Loop over all the levels starting with maxlen. * At each level, look at all the bitmap blocks, to see if there @@ -660,9 +669,6 @@ xfs_rtallocate_extent_size( *rtblock = NULLRTBLOCK; return 0; } - ASSERT(minlen != 0); - ASSERT(maxlen != 0); - /* * Loop over sizes, from maxlen down to minlen. * This time, when we do the allocations, allow smaller ones @@ -1948,7 +1954,6 @@ xfs_growfs_rt( nsbp->sb_blocksize * nsbp->sb_rextsize); nsbp->sb_rextents = nsbp->sb_rblocks; do_div(nsbp->sb_rextents, nsbp->sb_rextsize); - ASSERT(nsbp->sb_rextents != 0); nsbp->sb_rextslog = xfs_highbit32(nsbp->sb_rextents); nrsumlevels = nmp->m_rsumlevels = nsbp->sb_rextslog + 1; nrsumsize = diff --git a/fs/xfs/xfs_trans_ail.c b/fs/xfs/xfs_trans_ail.c index 4d6330eddc8d32e60ddfc8228290d904665b7cf6..76d470d8a1e63b8ece4dc74ffb69881f057eeb13 100644 --- a/fs/xfs/xfs_trans_ail.c +++ b/fs/xfs/xfs_trans_ail.c @@ -261,16 +261,19 @@ xfsaild_push( xfs_log_force(mp, (xfs_lsn_t)0, XFS_LOG_FORCE); } - /* - * We reached the target so wait a bit longer for I/O to complete and - * remove pushed items from the AIL before we start the next scan from - * the start of the AIL. - */ - if ((XFS_LSN_CMP(lsn, target) >= 0)) { + if (!count) { + /* We're past our target or empty, so idle */ + tout = 1000; + } else if (XFS_LSN_CMP(lsn, target) >= 0) { + /* + * We reached the target so wait a bit longer for I/O to + * complete and remove pushed items from the AIL before we + * start the next scan from the start of the AIL. + */ tout += 20; last_pushed_lsn = 0; } else if ((restarts > XFS_TRANS_PUSH_AIL_RESTARTS) || - (count && ((stuck * 100) / count > 90))) { + ((stuck * 100) / count > 90)) { /* * Either there is a lot of contention on the AIL or we * are stuck due to operations in progress. "Stuck" in this diff --git a/fs/xfs/xfs_vfsops.c b/fs/xfs/xfs_vfsops.c index 413587f0215578760d0109dc3825ceb296ce0fab..7321304a69ccc129452c674dc298cdef25d5480a 100644 --- a/fs/xfs/xfs_vfsops.c +++ b/fs/xfs/xfs_vfsops.c @@ -281,8 +281,8 @@ xfs_start_flags( mp->m_readio_log = mp->m_writeio_log = ap->iosizelog; } - if (ap->flags & XFSMNT_IDELETE) - mp->m_flags |= XFS_MOUNT_IDELETE; + if (ap->flags & XFSMNT_IKEEP) + mp->m_flags |= XFS_MOUNT_IKEEP; if (ap->flags & XFSMNT_DIRSYNC) mp->m_flags |= XFS_MOUNT_DIRSYNC; if (ap->flags & XFSMNT_ATTR2) diff --git a/include/asm-arm/arch-omap/board-h3.h b/include/asm-arm/arch-omap/board-h3.h index 1c2b55c61ca013b1f4704511a8e04b645368fdac..0f6404435ea8f11d38ab1998fdb98696076e5168 100644 --- a/include/asm-arm/arch-omap/board-h3.h +++ b/include/asm-arm/arch-omap/board-h3.h @@ -36,7 +36,7 @@ #define NR_IRQS (MAXIRQNUM + 1) -extern void __init h3_mmc_init(void); +extern void h3_mmc_init(void); extern void h3_mmc_slot_cover_handler(void *arg, int state); #endif /* __ASM_ARCH_OMAP_H3_H */ diff --git a/include/asm-arm/arch-omap/common.h b/include/asm-arm/arch-omap/common.h index 442aecbb8f44b23f3392906b9c790dc5e651f626..224e009e529633a07042429c4f51cf93c5781799 100644 --- a/include/asm-arm/arch-omap/common.h +++ b/include/asm-arm/arch-omap/common.h @@ -27,9 +27,7 @@ #ifndef __ARCH_ARM_MACH_OMAP_COMMON_H #define __ARCH_ARM_MACH_OMAP_COMMON_H -#ifdef CONFIG_I2C_OMAP #include -#endif struct sys_timer; @@ -41,7 +39,12 @@ extern int omap_register_i2c_bus(int bus_id, u32 clkrate, struct i2c_board_info const *info, unsigned len); #else -#define omap_register_i2c_bus(a, b, c, d) 0 +static inline int omap_register_i2c_bus(int bus_id, u32 clkrate, + struct i2c_board_info const *info, + unsigned len) +{ + return 0; +} #endif #endif /* __ARCH_ARM_MACH_OMAP_COMMON_H */ diff --git a/include/asm-arm/arch-omap/gpioexpander.h b/include/asm-arm/arch-omap/gpioexpander.h index 7a43b0a912e4ec9826440cf6ab4d30fe031a8065..4eed1f80e2fb57c6ae4cd7c84d2b9ddefede12be 100644 --- a/include/asm-arm/arch-omap/gpioexpander.h +++ b/include/asm-arm/arch-omap/gpioexpander.h @@ -18,7 +18,18 @@ /* Function Prototypes for GPIO Expander functions */ +#ifdef CONFIG_GPIOEXPANDER_OMAP int read_gpio_expa(u8 *, int); int write_gpio_expa(u8 , int); +#else +static inline int read_gpio_expa(u8 *val, int addr) +{ + return 0; +} +static inline int write_gpio_expa(u8 val, int addr) +{ + return 0; +} +#endif #endif /* __ASM_ARCH_OMAP_GPIOEXPANDER_H */ diff --git a/include/asm-arm/arch-pxa/entry-macro.S b/include/asm-arm/arch-pxa/entry-macro.S index b7e730851461d635f38eff192b9ab6011053f98f..c145bb01bc8fa573a6a1884fc37c9b0aae5bbf6d 100644 --- a/include/asm-arm/arch-pxa/entry-macro.S +++ b/include/asm-arm/arch-pxa/entry-macro.S @@ -35,7 +35,7 @@ 1004: mrc p6, 0, \irqstat, c6, c0, 0 @ ICIP2 mrc p6, 0, \irqnr, c7, c0, 0 @ ICMR2 - ands \irqstat, \irqstat, \irqnr + ands \irqnr, \irqstat, \irqnr beq 1003f rsb \irqstat, \irqnr, #0 and \irqstat, \irqstat, \irqnr diff --git a/include/asm-arm/arch-pxa/pxa-regs.h b/include/asm-arm/arch-pxa/pxa-regs.h index ac175b4d10cbfa859880be062163be2526eaab4c..2357a73340d4200c39743268fe930826d341a601 100644 --- a/include/asm-arm/arch-pxa/pxa-regs.h +++ b/include/asm-arm/arch-pxa/pxa-regs.h @@ -520,6 +520,9 @@ #define MCCR_FSRIE (1 << 1) /* FIFO Service Request Interrupt Enable */ #define GCR __REG(0x4050000C) /* Global Control Register */ +#ifdef CONFIG_PXA3xx +#define GCR_CLKBPB (1 << 31) /* Internal clock enable */ +#endif #define GCR_nDMAEN (1 << 24) /* non DMA Enable */ #define GCR_CDONE_IE (1 << 19) /* Command Done Interrupt Enable */ #define GCR_SDONE_IE (1 << 18) /* Status Done Interrupt Enable */ diff --git a/include/asm-arm/kexec.h b/include/asm-arm/kexec.h index 1ee17b6951d02f9057867594dbb5f3d268c4e038..47fe34d692dab57555a0b8e6af72b09660eca39f 100644 --- a/include/asm-arm/kexec.h +++ b/include/asm-arm/kexec.h @@ -8,7 +8,7 @@ /* Maximum address we can reach in physical address mode */ #define KEXEC_DESTINATION_MEMORY_LIMIT (-1UL) /* Maximum address we can use for the control code buffer */ -#define KEXEC_CONTROL_MEMORY_LIMIT TASK_SIZE +#define KEXEC_CONTROL_MEMORY_LIMIT (-1UL) #define KEXEC_CONTROL_CODE_SIZE 4096 diff --git a/include/asm-arm/kprobes.h b/include/asm-arm/kprobes.h index 4e7bd32288ae6196a2fa5082173d5510cacd0b7a..c042194d3ab55fc19be196d9db37640d260f224b 100644 --- a/include/asm-arm/kprobes.h +++ b/include/asm-arm/kprobes.h @@ -20,7 +20,6 @@ #include #include -#define ARCH_SUPPORTS_KRETPROBES #define __ARCH_WANT_KPROBES_INSN_SLOT #define MAX_INSN_SIZE 2 #define MAX_STACK_SIZE 64 /* 32 would probably be OK */ diff --git a/include/asm-arm/pgtable-nommu.h b/include/asm-arm/pgtable-nommu.h index 33c83dd879654aa5e3c83f18b4ad022a1603ac3a..2e5868bbe03bd9dba8c0a3c791cbe1d9c02642ea 100644 --- a/include/asm-arm/pgtable-nommu.h +++ b/include/asm-arm/pgtable-nommu.h @@ -92,6 +92,8 @@ extern unsigned int kobjsize(const void *objp); #define FIRST_USER_ADDRESS (0) +#include + #else /* diff --git a/include/asm-arm/plat-s3c/uncompress.h b/include/asm-arm/plat-s3c/uncompress.h index b5e6208175d1738fb203450bd39793aa053fc040..19b9eda39485191ac13405ce02b8e0531f997ae1 100644 --- a/include/asm-arm/plat-s3c/uncompress.h +++ b/include/asm-arm/plat-s3c/uncompress.h @@ -27,8 +27,8 @@ static void arch_detect_cpu(void); /* defines for UART registers */ -#include "asm/plat-s3c/regs-serial.h" -#include "asm/plat-s3c/regs-watchdog.h" +#include +#include /* working in physical space... */ #undef S3C2410_WDOGREG diff --git a/include/asm-arm/proc-fns.h b/include/asm-arm/proc-fns.h index a4ce457199d3279fb3d07856cf5a5b178e9be687..75ec760f4c748a0bb9ab5722e552c45b866599b8 100644 --- a/include/asm-arm/proc-fns.h +++ b/include/asm-arm/proc-fns.h @@ -214,9 +214,9 @@ #ifndef __ASSEMBLY__ #ifndef MULTI_CPU -#include "asm/cpu-single.h" +#include #else -#include "asm/cpu-multi32.h" +#include #endif #include diff --git a/include/asm-arm/unaligned.h b/include/asm-arm/unaligned.h index 8431f6eed5c6b6a5ebee2c067032e32f40302952..5db03cf3b90525d2164175288bd0f5a28f3efe7a 100644 --- a/include/asm-arm/unaligned.h +++ b/include/asm-arm/unaligned.h @@ -40,16 +40,16 @@ extern int __bug_unaligned_x(const void *ptr); */ #define __get_unaligned_2_le(__p) \ - (__p[0] | __p[1] << 8) + (unsigned int)(__p[0] | __p[1] << 8) #define __get_unaligned_2_be(__p) \ - (__p[0] << 8 | __p[1]) + (unsigned int)(__p[0] << 8 | __p[1]) #define __get_unaligned_4_le(__p) \ - (__p[0] | __p[1] << 8 | __p[2] << 16 | __p[3] << 24) + (unsigned int)(__p[0] | __p[1] << 8 | __p[2] << 16 | __p[3] << 24) #define __get_unaligned_4_be(__p) \ - (__p[0] << 24 | __p[1] << 16 | __p[2] << 8 | __p[3]) + (unsigned int)(__p[0] << 24 | __p[1] << 16 | __p[2] << 8 | __p[3]) #define __get_unaligned_8_le(__p) \ ((unsigned long long)__get_unaligned_4_le((__p+4)) << 32 | \ diff --git a/include/asm-avr32/pgtable.h b/include/asm-avr32/pgtable.h index 018f6e2a02425d4acc7372fc0111c701332cff68..3ae7b548fce764bc04dd2e00a93e9b2f330dce9a 100644 --- a/include/asm-avr32/pgtable.h +++ b/include/asm-avr32/pgtable.h @@ -157,6 +157,7 @@ extern struct page *empty_zero_page; #define _PAGE_S(x) _PAGE_NORMAL(x) #define PAGE_COPY _PAGE_P(PAGE_WRITE | PAGE_READ) +#define PAGE_SHARED _PAGE_S(PAGE_WRITE | PAGE_READ) #ifndef __ASSEMBLY__ /* diff --git a/include/asm-blackfin/gptimers.h b/include/asm-blackfin/gptimers.h index 8265ea473d5bc566cd2f7acc087b74d8f511f617..4f318f1fd2d901214b5771c53d3e19854db971c6 100644 --- a/include/asm-blackfin/gptimers.h +++ b/include/asm-blackfin/gptimers.h @@ -1,12 +1,11 @@ /* - * include/asm/bf5xx_timers.h - * - * This file contains the major Data structures and constants - * used for General Purpose Timer Implementation in BF5xx + * gptimers.h - Blackfin General Purpose Timer structs/defines/prototypes * + * Copyright (c) 2005-2008 Analog Devices Inc. * Copyright (C) 2005 John DeHority * Copyright (C) 2006 Hella Aglaia GmbH (awe@aglaia-gmbh.de) * + * Licensed under the GPL-2. */ #ifndef _BLACKFIN_TIMERS_H_ diff --git a/include/asm-blackfin/irq.h b/include/asm-blackfin/irq.h index 65480dab244ef72dc9c338ff65c053e7a676a22d..86b67834354da4a86603eb4cf15f3485ab7d78c0 100644 --- a/include/asm-blackfin/irq.h +++ b/include/asm-blackfin/irq.h @@ -67,4 +67,6 @@ static __inline__ int irq_canonicalize(int irq) #define NO_IRQ ((unsigned int)(-1)) #endif +#define SIC_SYSIRQ(irq) (irq - (IRQ_CORETMR + 1)) + #endif /* _BFIN_IRQ_H_ */ diff --git a/include/asm-blackfin/mach-bf527/bfin_serial_5xx.h b/include/asm-blackfin/mach-bf527/bfin_serial_5xx.h index 15dbc21eed8bd30c34da9f747ccf88bc1f92b347..c0694ecd2ecde47ecb91b99c43e26bed588d28f2 100644 --- a/include/asm-blackfin/mach-bf527/bfin_serial_5xx.h +++ b/include/asm-blackfin/mach-bf527/bfin_serial_5xx.h @@ -23,7 +23,6 @@ #define UART_GET_DLH(uart) bfin_read16(((uart)->port.membase + OFFSET_DLH)) #define UART_GET_IIR(uart) bfin_read16(((uart)->port.membase + OFFSET_IIR)) #define UART_GET_LCR(uart) bfin_read16(((uart)->port.membase + OFFSET_LCR)) -#define UART_GET_LSR(uart) bfin_read16(((uart)->port.membase + OFFSET_LSR)) #define UART_GET_GCTL(uart) bfin_read16(((uart)->port.membase + OFFSET_GCTL)) #define UART_PUT_CHAR(uart, v) bfin_write16(((uart)->port.membase + OFFSET_THR), v) @@ -58,6 +57,7 @@ struct bfin_serial_port { struct uart_port port; unsigned int old_status; + unsigned int lsr; #ifdef CONFIG_SERIAL_BFIN_DMA int tx_done; int tx_count; @@ -67,15 +67,31 @@ struct bfin_serial_port { unsigned int tx_dma_channel; unsigned int rx_dma_channel; struct work_struct tx_dma_workqueue; -#else - struct work_struct cts_workqueue; #endif #ifdef CONFIG_SERIAL_BFIN_CTSRTS + struct work_struct cts_workqueue; int cts_pin; int rts_pin; #endif }; +/* The hardware clears the LSR bits upon read, so we need to cache + * some of the more fun bits in software so they don't get lost + * when checking the LSR in other code paths (TX). + */ +static inline unsigned int UART_GET_LSR(struct bfin_serial_port *uart) +{ + unsigned int lsr = bfin_read16(uart->port.membase + OFFSET_LSR); + uart->lsr |= (lsr & (BI|FE|PE|OE)); + return lsr | uart->lsr; +} + +static inline void UART_CLEAR_LSR(struct bfin_serial_port *uart) +{ + uart->lsr = 0; + bfin_write16(uart->port.membase + OFFSET_LSR, -1); +} + struct bfin_serial_port bfin_serial_ports[NR_PORTS]; struct bfin_serial_res { unsigned long uart_base_addr; diff --git a/include/asm-blackfin/mach-bf533/bfin_serial_5xx.h b/include/asm-blackfin/mach-bf533/bfin_serial_5xx.h index 7871d4313f49b3d7751c4cbe779d5fa321ea789c..b6f513bee56ece582d69bdba072e722b557099f0 100644 --- a/include/asm-blackfin/mach-bf533/bfin_serial_5xx.h +++ b/include/asm-blackfin/mach-bf533/bfin_serial_5xx.h @@ -23,7 +23,6 @@ #define UART_GET_DLH(uart) bfin_read16(((uart)->port.membase + OFFSET_DLH)) #define UART_GET_IIR(uart) bfin_read16(((uart)->port.membase + OFFSET_IIR)) #define UART_GET_LCR(uart) bfin_read16(((uart)->port.membase + OFFSET_LCR)) -#define UART_GET_LSR(uart) bfin_read16(((uart)->port.membase + OFFSET_LSR)) #define UART_GET_GCTL(uart) bfin_read16(((uart)->port.membase + OFFSET_GCTL)) #define UART_PUT_CHAR(uart,v) bfin_write16(((uart)->port.membase + OFFSET_THR),v) @@ -46,6 +45,7 @@ struct bfin_serial_port { struct uart_port port; unsigned int old_status; + unsigned int lsr; #ifdef CONFIG_SERIAL_BFIN_DMA int tx_done; int tx_count; @@ -56,14 +56,34 @@ struct bfin_serial_port { unsigned int rx_dma_channel; struct work_struct tx_dma_workqueue; #else - struct work_struct cts_workqueue; +# if ANOMALY_05000230 + unsigned int anomaly_threshold; +# endif #endif #ifdef CONFIG_SERIAL_BFIN_CTSRTS + struct work_struct cts_workqueue; int cts_pin; int rts_pin; #endif }; +/* The hardware clears the LSR bits upon read, so we need to cache + * some of the more fun bits in software so they don't get lost + * when checking the LSR in other code paths (TX). + */ +static inline unsigned int UART_GET_LSR(struct bfin_serial_port *uart) +{ + unsigned int lsr = bfin_read16(uart->port.membase + OFFSET_LSR); + uart->lsr |= (lsr & (BI|FE|PE|OE)); + return lsr | uart->lsr; +} + +static inline void UART_CLEAR_LSR(struct bfin_serial_port *uart) +{ + uart->lsr = 0; + bfin_write16(uart->port.membase + OFFSET_LSR, -1); +} + struct bfin_serial_port bfin_serial_ports[NR_PORTS]; struct bfin_serial_res { unsigned long uart_base_addr; diff --git a/include/asm-blackfin/mach-bf537/bfin_serial_5xx.h b/include/asm-blackfin/mach-bf537/bfin_serial_5xx.h index 86e45c3798389270f6feb33cfb40205ced3afc52..8fc672d3105747a75efa3cb86676f6877c176a0c 100644 --- a/include/asm-blackfin/mach-bf537/bfin_serial_5xx.h +++ b/include/asm-blackfin/mach-bf537/bfin_serial_5xx.h @@ -23,7 +23,6 @@ #define UART_GET_DLH(uart) bfin_read16(((uart)->port.membase + OFFSET_DLH)) #define UART_GET_IIR(uart) bfin_read16(((uart)->port.membase + OFFSET_IIR)) #define UART_GET_LCR(uart) bfin_read16(((uart)->port.membase + OFFSET_LCR)) -#define UART_GET_LSR(uart) bfin_read16(((uart)->port.membase + OFFSET_LSR)) #define UART_GET_GCTL(uart) bfin_read16(((uart)->port.membase + OFFSET_GCTL)) #define UART_PUT_CHAR(uart,v) bfin_write16(((uart)->port.membase + OFFSET_THR),v) @@ -58,6 +57,7 @@ struct bfin_serial_port { struct uart_port port; unsigned int old_status; + unsigned int lsr; #ifdef CONFIG_SERIAL_BFIN_DMA int tx_done; int tx_count; @@ -67,15 +67,31 @@ struct bfin_serial_port { unsigned int tx_dma_channel; unsigned int rx_dma_channel; struct work_struct tx_dma_workqueue; -#else - struct work_struct cts_workqueue; #endif #ifdef CONFIG_SERIAL_BFIN_CTSRTS + struct work_struct cts_workqueue; int cts_pin; int rts_pin; #endif }; +/* The hardware clears the LSR bits upon read, so we need to cache + * some of the more fun bits in software so they don't get lost + * when checking the LSR in other code paths (TX). + */ +static inline unsigned int UART_GET_LSR(struct bfin_serial_port *uart) +{ + unsigned int lsr = bfin_read16(uart->port.membase + OFFSET_LSR); + uart->lsr |= (lsr & (BI|FE|PE|OE)); + return lsr | uart->lsr; +} + +static inline void UART_CLEAR_LSR(struct bfin_serial_port *uart) +{ + uart->lsr = 0; + bfin_write16(uart->port.membase + OFFSET_LSR, -1); +} + struct bfin_serial_port bfin_serial_ports[NR_PORTS]; struct bfin_serial_res { unsigned long uart_base_addr; diff --git a/include/asm-blackfin/mach-bf548/bfin_serial_5xx.h b/include/asm-blackfin/mach-bf548/bfin_serial_5xx.h index 3770aa38ee9f9f6b039316ca1714997e431933d3..7e6339f62a5058ae5e4226fef033c9985968f96e 100644 --- a/include/asm-blackfin/mach-bf548/bfin_serial_5xx.h +++ b/include/asm-blackfin/mach-bf548/bfin_serial_5xx.h @@ -24,6 +24,8 @@ #define UART_GET_LCR(uart) bfin_read16(((uart)->port.membase + OFFSET_LCR)) #define UART_GET_LSR(uart) bfin_read16(((uart)->port.membase + OFFSET_LSR)) #define UART_GET_GCTL(uart) bfin_read16(((uart)->port.membase + OFFSET_GCTL)) +#define UART_GET_MSR(uart) bfin_read16(((uart)->port.membase + OFFSET_MSR)) +#define UART_GET_MCR(uart) bfin_read16(((uart)->port.membase + OFFSET_MCR)) #define UART_PUT_CHAR(uart,v) bfin_write16(((uart)->port.membase + OFFSET_THR),v) #define UART_PUT_DLL(uart,v) bfin_write16(((uart)->port.membase + OFFSET_DLL),v) @@ -32,7 +34,9 @@ #define UART_PUT_DLH(uart,v) bfin_write16(((uart)->port.membase + OFFSET_DLH),v) #define UART_PUT_LSR(uart,v) bfin_write16(((uart)->port.membase + OFFSET_LSR),v) #define UART_PUT_LCR(uart,v) bfin_write16(((uart)->port.membase + OFFSET_LCR),v) +#define UART_CLEAR_LSR(uart) bfin_write16(((uart)->port.membase + OFFSET_LSR), -1) #define UART_PUT_GCTL(uart,v) bfin_write16(((uart)->port.membase + OFFSET_GCTL),v) +#define UART_PUT_MCR(uart,v) bfin_write16(((uart)->port.membase + OFFSET_MCR),v) #if defined(CONFIG_BFIN_UART0_CTSRTS) || defined(CONFIG_BFIN_UART1_CTSRTS) # define CONFIG_SERIAL_BFIN_CTSRTS @@ -68,10 +72,9 @@ struct bfin_serial_port { unsigned int tx_dma_channel; unsigned int rx_dma_channel; struct work_struct tx_dma_workqueue; -#else - struct work_struct cts_workqueue; #endif #ifdef CONFIG_SERIAL_BFIN_CTSRTS + struct work_struct cts_workqueue; int cts_pin; int rts_pin; #endif diff --git a/include/asm-blackfin/mach-bf561/bfin_serial_5xx.h b/include/asm-blackfin/mach-bf561/bfin_serial_5xx.h index 7871d4313f49b3d7751c4cbe779d5fa321ea789c..b6f513bee56ece582d69bdba072e722b557099f0 100644 --- a/include/asm-blackfin/mach-bf561/bfin_serial_5xx.h +++ b/include/asm-blackfin/mach-bf561/bfin_serial_5xx.h @@ -23,7 +23,6 @@ #define UART_GET_DLH(uart) bfin_read16(((uart)->port.membase + OFFSET_DLH)) #define UART_GET_IIR(uart) bfin_read16(((uart)->port.membase + OFFSET_IIR)) #define UART_GET_LCR(uart) bfin_read16(((uart)->port.membase + OFFSET_LCR)) -#define UART_GET_LSR(uart) bfin_read16(((uart)->port.membase + OFFSET_LSR)) #define UART_GET_GCTL(uart) bfin_read16(((uart)->port.membase + OFFSET_GCTL)) #define UART_PUT_CHAR(uart,v) bfin_write16(((uart)->port.membase + OFFSET_THR),v) @@ -46,6 +45,7 @@ struct bfin_serial_port { struct uart_port port; unsigned int old_status; + unsigned int lsr; #ifdef CONFIG_SERIAL_BFIN_DMA int tx_done; int tx_count; @@ -56,14 +56,34 @@ struct bfin_serial_port { unsigned int rx_dma_channel; struct work_struct tx_dma_workqueue; #else - struct work_struct cts_workqueue; +# if ANOMALY_05000230 + unsigned int anomaly_threshold; +# endif #endif #ifdef CONFIG_SERIAL_BFIN_CTSRTS + struct work_struct cts_workqueue; int cts_pin; int rts_pin; #endif }; +/* The hardware clears the LSR bits upon read, so we need to cache + * some of the more fun bits in software so they don't get lost + * when checking the LSR in other code paths (TX). + */ +static inline unsigned int UART_GET_LSR(struct bfin_serial_port *uart) +{ + unsigned int lsr = bfin_read16(uart->port.membase + OFFSET_LSR); + uart->lsr |= (lsr & (BI|FE|PE|OE)); + return lsr | uart->lsr; +} + +static inline void UART_CLEAR_LSR(struct bfin_serial_port *uart) +{ + uart->lsr = 0; + bfin_write16(uart->port.membase + OFFSET_LSR, -1); +} + struct bfin_serial_port bfin_serial_ports[NR_PORTS]; struct bfin_serial_res { unsigned long uart_base_addr; diff --git a/include/asm-blackfin/mach-bf561/blackfin.h b/include/asm-blackfin/mach-bf561/blackfin.h index 362617f9384574b36457c0e56bbb4dcad0b0c511..3a16df2c86d857fe5df7f0768919fba6158e4594 100644 --- a/include/asm-blackfin/mach-bf561/blackfin.h +++ b/include/asm-blackfin/mach-bf561/blackfin.h @@ -49,7 +49,8 @@ #define bfin_read_FIO_INEN() bfin_read_FIO0_INEN() #define bfin_write_FIO_INEN(val) bfin_write_FIO0_INEN(val) - +#define SIC_IWR0 SICA_IWR0 +#define SIC_IWR1 SICA_IWR1 #define SIC_IAR0 SICA_IAR0 #define bfin_write_SIC_IMASK0 bfin_write_SICA_IMASK0 #define bfin_write_SIC_IMASK1 bfin_write_SICA_IMASK1 diff --git a/include/asm-blackfin/mach-bf561/cdefBF561.h b/include/asm-blackfin/mach-bf561/cdefBF561.h index d667816486c095cfe162b143e4c7ff68449a5a21..1bc8d2f89cccf7ae69baaa1a29477f20406b7b2d 100644 --- a/include/asm-blackfin/mach-bf561/cdefBF561.h +++ b/include/asm-blackfin/mach-bf561/cdefBF561.h @@ -559,6 +559,7 @@ static __inline__ void bfin_write_VR_CTL(unsigned int val) #define bfin_write_PPI0_CONTROL(val) bfin_write16(PPI0_CONTROL,val) #define bfin_read_PPI0_STATUS() bfin_read16(PPI0_STATUS) #define bfin_write_PPI0_STATUS(val) bfin_write16(PPI0_STATUS,val) +#define bfin_clear_PPI0_STATUS() bfin_read_PPI0_STATUS() #define bfin_read_PPI0_COUNT() bfin_read16(PPI0_COUNT) #define bfin_write_PPI0_COUNT(val) bfin_write16(PPI0_COUNT,val) #define bfin_read_PPI0_DELAY() bfin_read16(PPI0_DELAY) @@ -570,6 +571,7 @@ static __inline__ void bfin_write_VR_CTL(unsigned int val) #define bfin_write_PPI1_CONTROL(val) bfin_write16(PPI1_CONTROL,val) #define bfin_read_PPI1_STATUS() bfin_read16(PPI1_STATUS) #define bfin_write_PPI1_STATUS(val) bfin_write16(PPI1_STATUS,val) +#define bfin_clear_PPI1_STATUS() bfin_read_PPI1_STATUS() #define bfin_read_PPI1_COUNT() bfin_read16(PPI1_COUNT) #define bfin_write_PPI1_COUNT(val) bfin_write16(PPI1_COUNT,val) #define bfin_read_PPI1_DELAY() bfin_read16(PPI1_DELAY) diff --git a/include/asm-blackfin/mmu_context.h b/include/asm-blackfin/mmu_context.h index b5eb67596ad59e79df4e891d4c42541b57b341d0..f55ec3c23a924eacd227f23ece059d4d06936933 100644 --- a/include/asm-blackfin/mmu_context.h +++ b/include/asm-blackfin/mmu_context.h @@ -73,7 +73,7 @@ static inline void destroy_context(struct mm_struct *mm) struct sram_list_struct *tmp; if (current_l1_stack_save == mm->context.l1_stack_save) - current_l1_stack_save = 0; + current_l1_stack_save = NULL; if (mm->context.l1_stack_save) free_l1stack(); diff --git a/include/asm-blackfin/unistd.h b/include/asm-blackfin/unistd.h index e98167358d262a6a847bb7d791f565700b6f12e9..c18a399f6e3ed863a64693eeaa573b04465cd0d0 100644 --- a/include/asm-blackfin/unistd.h +++ b/include/asm-blackfin/unistd.h @@ -361,7 +361,7 @@ #define __NR_epoll_pwait 346 #define __NR_utimensat 347 #define __NR_signalfd 348 -#define __NR_timerfd 349 +#define __NR_timerfd_create 349 #define __NR_eventfd 350 #define __NR_pread64 351 #define __NR_pwrite64 352 @@ -370,8 +370,10 @@ #define __NR_get_robust_list 355 #define __NR_fallocate 356 #define __NR_semtimedop 357 +#define __NR_timerfd_settime 358 +#define __NR_timerfd_gettime 359 -#define __NR_syscall 358 +#define __NR_syscall 360 #define NR_syscalls __NR_syscall /* Old optional stuff no one actually uses */ diff --git a/include/asm-cris/uaccess.h b/include/asm-cris/uaccess.h index 69d48a2dc8e13ee15fa7c493fbe89eadc9bbaac9..ea11eaf0e922dfef1018ddae25fbee4625595e26 100644 --- a/include/asm-cris/uaccess.h +++ b/include/asm-cris/uaccess.h @@ -1,43 +1,6 @@ /* * Authors: Bjorn Wesen (bjornw@axis.com) * Hans-Peter Nilsson (hp@axis.com) - * - * $Log: uaccess.h,v $ - * Revision 1.8 2001/10/29 13:01:48 bjornw - * Removed unused variable tmp2 in strnlen_user - * - * Revision 1.7 2001/10/02 12:44:52 hp - * Add support for 64-bit put_user/get_user - * - * Revision 1.6 2001/10/01 14:51:17 bjornw - * Added register prefixes and removed underscores - * - * Revision 1.5 2000/10/25 03:33:21 hp - * - Provide implementation for everything else but get_user and put_user; - * copying inline to/from user for constant length 0..16, 20, 24, and - * clearing for 0..4, 8, 12, 16, 20, 24, strncpy_from_user and strnlen_user - * always inline. - * - Constraints for destination addr in get_user cannot be memory, only reg. - * - Correct labels for PC at expected fault points. - * - Nits with assembly code. - * - Don't use statement expressions without value; use "do {} while (0)". - * - Return correct values from __generic_... functions. - * - * Revision 1.4 2000/09/12 16:28:25 bjornw - * * Removed comments from the get/put user asm code - * * Constrains for destination addr in put_user cannot be memory, only reg - * - * Revision 1.3 2000/09/12 14:30:20 bjornw - * MAX_ADDR_USER does not exist anymore - * - * Revision 1.2 2000/07/13 15:52:48 bjornw - * New user-access functions - * - * Revision 1.1.1.1 2000/07/10 16:32:31 bjornw - * CRIS architecture, working draft - * - * - * */ /* Asm:s have been tweaked (within the domain of correctness) to give @@ -209,9 +172,9 @@ extern long __get_user_bad(void); /* More complex functions. Most are inline, but some call functions that live in lib/usercopy.c */ -extern unsigned long __copy_user(void *to, const void *from, unsigned long n); -extern unsigned long __copy_user_zeroing(void *to, const void *from, unsigned long n); -extern unsigned long __do_clear_user(void *to, unsigned long n); +extern unsigned long __copy_user(void __user *to, const void *from, unsigned long n); +extern unsigned long __copy_user_zeroing(void *to, const void __user *from, unsigned long n); +extern unsigned long __do_clear_user(void __user *to, unsigned long n); static inline unsigned long __generic_copy_to_user(void __user *to, const void *from, unsigned long n) @@ -253,7 +216,7 @@ strncpy_from_user(char *dst, const char __user *src, long count) } -/* Note that if these expand awfully if made into switch constructs, so +/* Note that these expand awfully if made into switch constructs, so don't do that. */ static inline unsigned long @@ -407,19 +370,21 @@ __constant_clear_user(void __user *to, unsigned long n) */ static inline unsigned long -__generic_copy_from_user_nocheck(void *to, const void *from, unsigned long n) +__generic_copy_from_user_nocheck(void *to, const void __user *from, + unsigned long n) { return __copy_user_zeroing(to,from,n); } static inline unsigned long -__generic_copy_to_user_nocheck(void *to, const void *from, unsigned long n) +__generic_copy_to_user_nocheck(void __user *to, const void *from, + unsigned long n) { return __copy_user(to,from,n); } static inline unsigned long -__generic_clear_user_nocheck(void *to, unsigned long n) +__generic_clear_user_nocheck(void __user *to, unsigned long n) { return __do_clear_user(to,n); } diff --git a/include/asm-cris/unistd.h b/include/asm-cris/unistd.h index 007cb16a6b5b7cc4b59606485ecf24aaf28a9858..76398ef87e9bcb730c864a624ed77b88be08068a 100644 --- a/include/asm-cris/unistd.h +++ b/include/asm-cris/unistd.h @@ -329,12 +329,12 @@ #define __NR_timerfd_create 322 #define __NR_eventfd 323 #define __NR_fallocate 324 -#define __NR_timerfd_settime 315 -#define __NR_timerfd_gettime 316 +#define __NR_timerfd_settime 325 +#define __NR_timerfd_gettime 326 #ifdef __KERNEL__ -#define NR_syscalls 325 +#define NR_syscalls 327 #include diff --git a/include/asm-h8300/uaccess.h b/include/asm-h8300/uaccess.h index a22350ec271aae96e494fdcc6c90c432010a296d..356068cd0879bdf145bd68f12857b75cfd95ab4c 100644 --- a/include/asm-h8300/uaccess.h +++ b/include/asm-h8300/uaccess.h @@ -91,22 +91,19 @@ extern int __put_user_bad(void); #define get_user(x, ptr) \ ({ \ int __gu_err = 0; \ - uint32_t __gu_val = 0; \ + typeof(*(ptr)) __gu_val = *ptr; \ switch (sizeof(*(ptr))) { \ case 1: \ case 2: \ case 4: \ - __gu_val = *(ptr); \ - break; \ - case 8: \ - memcpy(&__gu_val, ptr, sizeof (*(ptr))); \ + case 8: \ break; \ default: \ - __gu_val = 0; \ __gu_err = __get_user_bad(); \ + __gu_val = 0; \ break; \ } \ - (x) = (typeof(*(ptr)))__gu_val; \ + (x) = __gu_val; \ __gu_err; \ }) #define __get_user(x, ptr) get_user(x, ptr) diff --git a/include/asm-ia64/Kbuild b/include/asm-ia64/Kbuild index 4a1e48b9f4031b2808d973d2679e7a52cdbbab11..eb24a3f47caa212b94b7d2c1736ea7be2b59e992 100644 --- a/include/asm-ia64/Kbuild +++ b/include/asm-ia64/Kbuild @@ -3,7 +3,6 @@ include include/asm-generic/Kbuild.asm header-y += break.h header-y += fpu.h header-y += fpswa.h -header-y += gcc_intrin.h header-y += ia64regs.h header-y += intel_intrin.h header-y += intrinsics.h @@ -12,5 +11,6 @@ header-y += ptrace_offsets.h header-y += rse.h header-y += ucontext.h +unifdef-y += gcc_intrin.h unifdef-y += perfmon.h unifdef-y += ustack.h diff --git a/include/asm-ia64/hw_irq.h b/include/asm-ia64/hw_irq.h index 7e6e3779670a3c82690a92d357d0d992247fba12..76366dc9c1a0473ead7124ddce204252537d8ebc 100644 --- a/include/asm-ia64/hw_irq.h +++ b/include/asm-ia64/hw_irq.h @@ -93,6 +93,9 @@ extern __u8 isa_irq_to_vector_map[16]; struct irq_cfg { ia64_vector vector; cpumask_t domain; + cpumask_t old_domain; + unsigned move_cleanup_count; + u8 move_in_progress : 1; }; extern spinlock_t vector_lock; extern struct irq_cfg irq_cfg[NR_IRQS]; @@ -106,12 +109,19 @@ extern int assign_irq_vector (int irq); /* allocate a free vector */ extern void free_irq_vector (int vector); extern int reserve_irq_vector (int vector); extern void __setup_vector_irq(int cpu); -extern int reassign_irq_vector(int irq, int cpu); extern void ia64_send_ipi (int cpu, int vector, int delivery_mode, int redirect); extern void register_percpu_irq (ia64_vector vec, struct irqaction *action); extern int check_irq_used (int irq); extern void destroy_and_reserve_irq (unsigned int irq); +#if defined(CONFIG_SMP) && (defined(CONFIG_IA64_GENERIC) || defined(CONFIG_IA64_DIG)) +extern int irq_prepare_move(int irq, int cpu); +extern void irq_complete_move(unsigned int irq); +#else +static inline int irq_prepare_move(int irq, int cpu) { return 0; } +static inline void irq_complete_move(unsigned int irq) {} +#endif + static inline void ia64_resend_irq(unsigned int vector) { platform_send_ipi(smp_processor_id(), vector, IA64_IPI_DM_INT, 0); diff --git a/include/asm-ia64/kprobes.h b/include/asm-ia64/kprobes.h index a93ce9ef07ff7a5497a4806d99df460030b080aa..d03bf9ff68e376b76aa3a27545c55f9cf164d982 100644 --- a/include/asm-ia64/kprobes.h +++ b/include/asm-ia64/kprobes.h @@ -82,7 +82,6 @@ struct kprobe_ctlblk { struct prev_kprobe prev_kprobe[ARCH_PREV_KPROBE_SZ]; }; -#define ARCH_SUPPORTS_KRETPROBES #define kretprobe_blacklist_size 0 #define SLOT0_OPCODE_SHIFT (37) @@ -118,14 +117,10 @@ struct arch_specific_insn { unsigned short slot; }; -extern int kprobes_fault_handler(struct pt_regs *regs, int trapnr); +extern int kprobe_fault_handler(struct pt_regs *regs, int trapnr); extern int kprobe_exceptions_notify(struct notifier_block *self, unsigned long val, void *data); -/* ia64 does not need this */ -static inline void jprobe_return(void) -{ -} extern void invalidate_stacked_regs(void); extern void flush_register_stack(void); extern void arch_remove_kprobe(struct kprobe *p); diff --git a/include/asm-ia64/ptrace.h b/include/asm-ia64/ptrace.h index 0bdce7dde1b01b6f75067447b10d2a4b6d2c036a..4b2a8d40ebc5ed398538a5aa63650605b561d803 100644 --- a/include/asm-ia64/ptrace.h +++ b/include/asm-ia64/ptrace.h @@ -233,8 +233,6 @@ struct switch_stack { #include #include -#define __ARCH_SYS_PTRACE 1 - /* * We use the ia64_psr(regs)->ri to determine which of the three * instructions in bundle (16 bytes) took the sample. Generate @@ -314,6 +312,13 @@ struct switch_stack { #define arch_ptrace_attach(child) \ ptrace_attach_sync_user_rbs(child) + #define arch_has_single_step() (1) + extern void user_enable_single_step(struct task_struct *); + extern void user_disable_single_step(struct task_struct *); + + #define arch_has_block_step() (1) + extern void user_enable_block_step(struct task_struct *); + #endif /* !__KERNEL__ */ /* pt_all_user_regs is used for PTRACE_GETREGS PTRACE_SETREGS */ diff --git a/include/asm-ia64/sal.h b/include/asm-ia64/sal.h index 2251118894ae0005f193a2befa8c5a11b963f4e0..f4904db3b0573c486d7bfe303076245d8d76a8f1 100644 --- a/include/asm-ia64/sal.h +++ b/include/asm-ia64/sal.h @@ -807,6 +807,10 @@ static inline s64 ia64_sal_physical_id_info(u16 *splid) { struct ia64_sal_retval isrv; + + if (sal_revision < SAL_VERSION_CODE(3,2)) + return -1; + SAL_CALL(isrv, SAL_PHYSICAL_ID_INFO, 0, 0, 0, 0, 0, 0, 0); if (splid) *splid = isrv.v0; diff --git a/include/asm-m68k/unistd.h b/include/asm-m68k/unistd.h index 87f77b11931772245001d68e10ea863d3de446eb..e72ba563f10229389eb429417e39815e370662e4 100644 --- a/include/asm-m68k/unistd.h +++ b/include/asm-m68k/unistd.h @@ -320,13 +320,15 @@ #define __NR_epoll_pwait 315 #define __NR_utimensat 316 #define __NR_signalfd 317 -#define __NR_timerfd 318 +#define __NR_timerfd_create 318 #define __NR_eventfd 319 #define __NR_fallocate 320 +#define __NR_timerfd_settime 321 +#define __NR_timerfd_gettime 322 #ifdef __KERNEL__ -#define NR_syscalls 321 +#define NR_syscalls 323 #define __ARCH_WANT_IPC_PARSE_VERSION #define __ARCH_WANT_OLD_READDIR diff --git a/include/asm-m68knommu/machdep.h b/include/asm-m68knommu/machdep.h index 1cf26d240d839922d97e2aceb8cbcc5618b477c7..de9f47a51cc215e04d19f1a40fb413045d9d572b 100644 --- a/include/asm-m68knommu/machdep.h +++ b/include/asm-m68knommu/machdep.h @@ -21,4 +21,6 @@ extern void (*mach_power_off)( void ); extern void config_BSP(char *command, int len); +extern void do_IRQ(int irq, struct pt_regs *fp); + #endif /* _M68KNOMMU_MACHDEP_H */ diff --git a/include/asm-m68knommu/unistd.h b/include/asm-m68knommu/unistd.h index 27c2f9bb4dbdd7a6528203ccd3a98e95b17486ab..4ba98b9c5d799abc7b6df69f1477bd57fd1d3eaf 100644 --- a/include/asm-m68knommu/unistd.h +++ b/include/asm-m68knommu/unistd.h @@ -321,13 +321,15 @@ #define __NR_epoll_pwait 315 #define __NR_utimensat 316 #define __NR_signalfd 317 -#define __NR_timerfd 318 +#define __NR_timerfd_create 318 #define __NR_eventfd 319 #define __NR_fallocate 320 +#define __NR_timerfd_settime 321 +#define __NR_timerfd_gettime 322 #ifdef __KERNEL__ -#define NR_syscalls 321 +#define NR_syscalls 323 #define __ARCH_WANT_IPC_PARSE_VERSION #define __ARCH_WANT_OLD_READDIR diff --git a/include/asm-mips/cacheflush.h b/include/asm-mips/cacheflush.h index 4933b4947ed0c9008b761e95c9d4ff1aab25879d..01e7eadc97e2fdbd28d79f056f2c3336a8aeb652 100644 --- a/include/asm-mips/cacheflush.h +++ b/include/asm-mips/cacheflush.h @@ -93,7 +93,7 @@ extern void (*flush_data_cache_page)(unsigned long addr); clear_bit(PG_dcache_dirty, &(page)->flags) /* Run kernel code uncached, useful for cache probing functions. */ -unsigned long __init run_uncached(void *func); +unsigned long run_uncached(void *func); extern void *kmap_coherent(struct page *page, unsigned long addr); extern void kunmap_coherent(void); diff --git a/include/asm-mips/highmem.h b/include/asm-mips/highmem.h index 4d6bd5c31c7bf38f5551d08a2db3b980ed1cac37..4374ab2adc756626cd5d9278b37679737a9db6ca 100644 --- a/include/asm-mips/highmem.h +++ b/include/asm-mips/highmem.h @@ -39,7 +39,6 @@ extern pte_t *pkmap_page_table; * easily, subsequent pte tables have to be allocated in one physical * chunk of RAM. */ -#define PKMAP_BASE (0xfe000000UL) #define LAST_PKMAP 1024 #define LAST_PKMAP_MASK (LAST_PKMAP-1) #define PKMAP_NR(virt) ((virt-PKMAP_BASE) >> PAGE_SHIFT) diff --git a/include/asm-mips/mach-ip27/cpu-feature-overrides.h b/include/asm-mips/mach-ip27/cpu-feature-overrides.h index fe076380c1891175549b62b180dea3dba1aaf122..7d3112b148d905f999049f596c3caf6eeb84ab50 100644 --- a/include/asm-mips/mach-ip27/cpu-feature-overrides.h +++ b/include/asm-mips/mach-ip27/cpu-feature-overrides.h @@ -34,7 +34,11 @@ #define cpu_has_64bits 1 #define cpu_has_4kex 1 +#define cpu_has_3k_cache 0 +#define cpu_has_6k_cache 0 #define cpu_has_4k_cache 1 +#define cpu_has_8k_cache 0 +#define cpu_has_tx39_cache 0 #define cpu_has_inclusive_pcaches 1 diff --git a/include/asm-mips/mach-jmr3927/ioremap.h b/include/asm-mips/mach-jmr3927/ioremap.h index aa131ad7f7177c9de0698ddfdcfea3061e361ff7..29989ff10d663254da95f7dcb4619f7ef5da2dcb 100644 --- a/include/asm-mips/mach-jmr3927/ioremap.h +++ b/include/asm-mips/mach-jmr3927/ioremap.h @@ -25,7 +25,7 @@ static inline void __iomem *plat_ioremap(phys_t offset, unsigned long size, { #define TXX9_DIRECTMAP_BASE 0xff000000ul if (offset >= TXX9_DIRECTMAP_BASE && - offset < TXX9_DIRECTMAP_BASE + 0xf0000) + offset < TXX9_DIRECTMAP_BASE + 0xff0000) return (void __iomem *)offset; return NULL; } diff --git a/include/asm-mips/mach-lasat/irq.h b/include/asm-mips/mach-lasat/irq.h index da75f89f37235900e4c06620f94bfc4d783953b0..3a282419d5f93a87dc2da42891aab61b3de60076 100644 --- a/include/asm-mips/mach-lasat/irq.h +++ b/include/asm-mips/mach-lasat/irq.h @@ -1,7 +1,7 @@ #ifndef _ASM_MACH_LASAT_IRQ_H #define _ASM_MACH_LASAT_IRQ_H -#define LASAT_CASCADE_IRQ (MIPS_CPU_IRQ_BASE + 0) +#define LASAT_CASCADE_IRQ (MIPS_CPU_IRQ_BASE + 2) #define LASAT_IRQ_BASE 8 #define LASAT_IRQ_END 23 diff --git a/include/asm-mips/pgtable-32.h b/include/asm-mips/pgtable-32.h index a0947092d0e0f11607f03193a87ee098dc061bf3..ceefe027c76104176a985751ea45d76a972db76f 100644 --- a/include/asm-mips/pgtable-32.h +++ b/include/asm-mips/pgtable-32.h @@ -65,6 +65,8 @@ extern int add_temporary_entry(unsigned long entrylo0, unsigned long entrylo1, #define VMALLOC_START MAP_BASE +#define PKMAP_BASE (0xfe000000UL) + #ifdef CONFIG_HIGHMEM # define VMALLOC_END (PKMAP_BASE-2*PAGE_SIZE) #else diff --git a/include/asm-mips/time.h b/include/asm-mips/time.h index a8fd16e1981f36fd7837835366cc412b32465506..d3bd5c5aa2ecd0ae1fa34c9083debcac6c4107e0 100644 --- a/include/asm-mips/time.h +++ b/include/asm-mips/time.h @@ -64,10 +64,11 @@ static inline int mips_clockevent_init(void) * Initialize the count register as a clocksource */ #ifdef CONFIG_CEVT_R4K -extern void init_mips_clocksource(void); +extern int init_mips_clocksource(void); #else -static inline void init_mips_clocksource(void) +static inline int init_mips_clocksource(void) { + return 0; } #endif diff --git a/include/asm-mn10300/Kbuild b/include/asm-mn10300/Kbuild index 79384c537dc6299c9d352ed1cbcea52b03704542..c68e1680da0173d5754d1a1df4944120a5239e58 100644 --- a/include/asm-mn10300/Kbuild +++ b/include/asm-mn10300/Kbuild @@ -1,5 +1 @@ include include/asm-generic/Kbuild.asm - -unifdef-y += termios.h -unifdef-y += ptrace.h -unifdef-y += page.h diff --git a/include/asm-parisc/elf.h b/include/asm-parisc/elf.h index ce0c0d844c7dfe40addc2488e94d2af5c7b2cb72..d0a4a82628181578a943ae082c60ae8b63959411 100644 --- a/include/asm-parisc/elf.h +++ b/include/asm-parisc/elf.h @@ -204,7 +204,7 @@ typedef struct elf64_fdesc { /* * The following definitions are those for 32-bit ELF binaries on a 32-bit * kernel and for 64-bit binaries on a 64-bit kernel. To run 32-bit binaries - * on a 64-bit kernel, arch/parisc64/kernel/binfmt_elf32.c defines these + * on a 64-bit kernel, arch/parisc/kernel/binfmt_elf32.c defines these * macros appropriately and then #includes binfmt_elf.c, which then includes * this file. */ @@ -216,26 +216,25 @@ typedef struct elf64_fdesc { * Note that this header file is used by default in fs/binfmt_elf.c. So * the following macros are for the default case. However, for the 64 * bit kernel we also support 32 bit parisc binaries. To do that - * arch/parisc64/kernel/binfmt_elf32.c defines its own set of these + * arch/parisc/kernel/binfmt_elf32.c defines its own set of these * macros, and then it includes fs/binfmt_elf.c to provide an alternate * elf binary handler for 32 bit binaries (on the 64 bit kernel). */ #ifdef CONFIG_64BIT -#define ELF_CLASS ELFCLASS64 +#define ELF_CLASS ELFCLASS64 #else #define ELF_CLASS ELFCLASS32 #endif typedef unsigned long elf_greg_t; -/* This yields a string that ld.so will use to load implementation - specific libraries for optimization. This is more specific in - intent than poking at uname or /proc/cpuinfo. - - For the moment, we have only optimizations for the Intel generations, - but that could change... */ +/* + * This yields a string that ld.so will use to load implementation + * specific libraries for optimization. This is more specific in + * intent than poking at uname or /proc/cpuinfo. + */ -#define ELF_PLATFORM ("PARISC\0" /*+((boot_cpu_data.x86-3)*5) */) +#define ELF_PLATFORM ("PARISC\0") #define SET_PERSONALITY(ex, ibcs2) \ current->personality = PER_LINUX; \ @@ -310,7 +309,7 @@ struct pt_regs; /* forward declaration... */ #define ELF_OSABI ELFOSABI_LINUX /* %r23 is set by ld.so to a pointer to a function which might be - registered using atexit. This provides a mean for the dynamic + registered using atexit. This provides a means for the dynamic linker to call DT_FINI functions for shared libraries that have been loaded before the code runs. @@ -339,6 +338,5 @@ struct pt_regs; /* forward declaration... */ but it's not easy, and we've already done it here. */ #define ELF_HWCAP 0 -/* (boot_cpu_data.x86_capability) */ #endif diff --git a/include/asm-parisc/fixmap.h b/include/asm-parisc/fixmap.h index a5caf4b122b7c323b5abc9d233006d992214ceca..de3fe3a18229a23e99cea0ec2ec6a7cc7a9e6669 100644 --- a/include/asm-parisc/fixmap.h +++ b/include/asm-parisc/fixmap.h @@ -20,4 +20,11 @@ #define KERNEL_MAP_START (GATEWAY_PAGE_SIZE) #define KERNEL_MAP_END (TMPALIAS_MAP_START) -#endif +#ifndef __ASSEMBLY__ +extern void *vmalloc_start; +#define PCXL_DMA_MAP_SIZE (8*1024*1024) +#define VMALLOC_START ((unsigned long)vmalloc_start) +#define VMALLOC_END (KERNEL_MAP_END) +#endif /*__ASSEMBLY__*/ + +#endif /*_ASM_FIXMAP_H*/ diff --git a/include/asm-parisc/futex.h b/include/asm-parisc/futex.h index dbee6e60aa8139e66897ba65ba4ac9155bf00dab..fdc6d055ef7f2af68872f2f195d8b417ebb9558f 100644 --- a/include/asm-parisc/futex.h +++ b/include/asm-parisc/futex.h @@ -56,6 +56,12 @@ futex_atomic_cmpxchg_inatomic(int __user *uaddr, int oldval, int newval) int err = 0; int uval; + /* futex.c wants to do a cmpxchg_inatomic on kernel NULL, which is + * our gateway page, and causes no end of trouble... + */ + if (segment_eq(KERNEL_DS, get_fs()) && !uaddr) + return -EFAULT; + if (!access_ok(VERIFY_WRITE, uaddr, sizeof(int))) return -EFAULT; @@ -67,5 +73,5 @@ futex_atomic_cmpxchg_inatomic(int __user *uaddr, int oldval, int newval) return uval; } -#endif -#endif +#endif /*__KERNEL__*/ +#endif /*_ASM_PARISC_FUTEX_H*/ diff --git a/include/asm-parisc/pdc.h b/include/asm-parisc/pdc.h index deda8c311373bb685771e38c44bc44668772d4d0..9eaa794c3e4a3f1de70716e450896e1cddf8d570 100644 --- a/include/asm-parisc/pdc.h +++ b/include/asm-parisc/pdc.h @@ -645,8 +645,7 @@ int pdc_soft_power_button(int sw_control); void pdc_io_reset(void); void pdc_io_reset_devices(void); int pdc_iodc_getc(void); -int pdc_iodc_print(unsigned char *str, unsigned count); -void pdc_printf(const char *fmt, ...); +int pdc_iodc_print(const unsigned char *str, unsigned count); void pdc_emergency_unlock(void); int pdc_sti_call(unsigned long func, unsigned long flags, diff --git a/include/asm-parisc/pgalloc.h b/include/asm-parisc/pgalloc.h index 3996dfc30a3f3366aebd714d63b35fb8455fcbac..fc987a1c12a88828d66c9c322da3d0a514fd5143 100644 --- a/include/asm-parisc/pgalloc.h +++ b/include/asm-parisc/pgalloc.h @@ -138,10 +138,10 @@ static inline void pte_free_kernel(struct mm_struct *mm, pte_t *pte) free_page((unsigned long)pte); } -static inline void pte_free_kernel(struct mm_struct *mm, struct page *pte) +static inline void pte_free(struct mm_struct *mm, struct page *pte) { pgtable_page_dtor(pte); - pte_free_kernel(page_address((pte)); + pte_free_kernel(mm, page_address(pte)); } #define check_pgt_cache() do { } while (0) diff --git a/include/asm-parisc/pgtable.h b/include/asm-parisc/pgtable.h index cd0fa4f73320fdbe72dd63b9a9aae1d425978d17..dc86adbec916da26e7825523324c39dc8a642fec 100644 --- a/include/asm-parisc/pgtable.h +++ b/include/asm-parisc/pgtable.h @@ -116,14 +116,6 @@ #define FIRST_USER_ADDRESS 0 -#ifndef __ASSEMBLY__ -extern void *vmalloc_start; -#define PCXL_DMA_MAP_SIZE (8*1024*1024) -#define VMALLOC_START ((unsigned long)vmalloc_start) -/* this is a fixmap remnant, see fixmap.h */ -#define VMALLOC_END (KERNEL_MAP_END) -#endif - /* NB: The tlb miss handlers make certain assumptions about the order */ /* of the following bits, so be careful (One example, bits 25-31 */ /* are moved together in one instruction). */ diff --git a/include/asm-parisc/unistd.h b/include/asm-parisc/unistd.h index 081b4ae6186682aeaeffff35a677eab29b869f95..a7d857f0e4f404963c86f2baeb240f80d7a6f110 100644 --- a/include/asm-parisc/unistd.h +++ b/include/asm-parisc/unistd.h @@ -798,8 +798,11 @@ #define __NR_timerfd (__NR_Linux + 303) #define __NR_eventfd (__NR_Linux + 304) #define __NR_fallocate (__NR_Linux + 305) +#define __NR_timerfd_create (__NR_Linux + 306) +#define __NR_timerfd_settime (__NR_Linux + 307) +#define __NR_timerfd_gettime (__NR_Linux + 308) -#define __NR_Linux_syscalls (__NR_fallocate + 1) +#define __NR_Linux_syscalls (__NR_timerfd_gettime + 1) #define __IGNORE_select /* newselect */ diff --git a/include/asm-powerpc/kprobes.h b/include/asm-powerpc/kprobes.h index afabad230dbb4f212d057449f03f3fec3b79d171..d0e7701fa1f6cbff19370ef0a2dc6e4856e5a27f 100644 --- a/include/asm-powerpc/kprobes.h +++ b/include/asm-powerpc/kprobes.h @@ -80,7 +80,6 @@ typedef unsigned int kprobe_opcode_t; #define is_trap(instr) (IS_TW(instr) || IS_TWI(instr)) #endif -#define ARCH_SUPPORTS_KRETPROBES #define flush_insn_slot(p) do { } while (0) #define kretprobe_blacklist_size 0 diff --git a/include/asm-powerpc/pgtable-ppc32.h b/include/asm-powerpc/pgtable-ppc32.h index d1332bbcbd9ba29eee90b389cffdc6ea90d3e5ca..2c79f550272bf08bade81d3ec7cd3eb88e02895a 100644 --- a/include/asm-powerpc/pgtable-ppc32.h +++ b/include/asm-powerpc/pgtable-ppc32.h @@ -339,14 +339,6 @@ extern int icache_44x_need_flush; #define _PMD_PAGE_MASK 0x000c #define _PMD_PAGE_8M 0x000c -/* - * The 8xx TLB miss handler allegedly sets _PAGE_ACCESSED in the PTE - * for an address even if _PAGE_PRESENT is not set, as a performance - * optimization. This is a bug if you ever want to use swap unless - * _PAGE_ACCESSED is 2, which it isn't, or unless you have 8xx-specific - * definitions for __swp_entry etc. below, which would be gross. - * -- paulus - */ #define _PTE_NONE_MASK _PAGE_ACCESSED #else /* CONFIG_6xx */ diff --git a/include/asm-powerpc/reg.h b/include/asm-powerpc/reg.h index 0d6238987df864f9b7f2d4f1cff8a6b7fade4fda..edc0cfd7f6e28b205d8b17df52000be78bbe1aa2 100644 --- a/include/asm-powerpc/reg.h +++ b/include/asm-powerpc/reg.h @@ -153,6 +153,9 @@ #define CTRL_RUNLATCH 0x1 #define SPRN_DABR 0x3F5 /* Data Address Breakpoint Register */ #define DABR_TRANSLATION (1UL << 2) +#define SPRN_DABRX 0x3F7 /* Data Address Breakpoint Register Extension */ +#define DABRX_USER (1UL << 0) +#define DABRX_KERNEL (1UL << 1) #define SPRN_DAR 0x013 /* Data Address Register */ #define SPRN_DSISR 0x012 /* Data Storage Interrupt Status Register */ #define DSISR_NOHPTE 0x40000000 /* no translation found */ diff --git a/include/asm-ppc/pgtable.h b/include/asm-ppc/pgtable.h index 69347bdbb4015617eb2ac5c30d615a32d0af654b..70435d32129a5dd3ea43335ed46755148ac4fe3e 100644 --- a/include/asm-ppc/pgtable.h +++ b/include/asm-ppc/pgtable.h @@ -299,14 +299,6 @@ extern unsigned long ioremap_bot, ioremap_base; #define _PMD_PAGE_MASK 0x000c #define _PMD_PAGE_8M 0x000c -/* - * The 8xx TLB miss handler allegedly sets _PAGE_ACCESSED in the PTE - * for an address even if _PAGE_PRESENT is not set, as a performance - * optimization. This is a bug if you ever want to use swap unless - * _PAGE_ACCESSED is 2, which it isn't, or unless you have 8xx-specific - * definitions for __swp_entry etc. below, which would be gross. - * -- paulus - */ #define _PTE_NONE_MASK _PAGE_ACCESSED #else /* CONFIG_6xx */ diff --git a/include/asm-s390/kprobes.h b/include/asm-s390/kprobes.h index 948db3d0d05c194d4715706fe4c932a781d23e4e..330f68caffe4b167eb70ed5d79db31cb48078919 100644 --- a/include/asm-s390/kprobes.h +++ b/include/asm-s390/kprobes.h @@ -46,7 +46,6 @@ typedef u16 kprobe_opcode_t; ? (MAX_STACK_SIZE) \ : (((unsigned long)current_thread_info()) + THREAD_SIZE - (ADDR))) -#define ARCH_SUPPORTS_KRETPROBES #define kretprobe_blacklist_size 0 #define KPROBE_SWAP_INST 0x10 diff --git a/include/asm-sh/cpu-sh3/cache.h b/include/asm-sh/cpu-sh3/cache.h index 56bd838b7db4b692ccc3acc580745d048b5a2f66..bee2d81c56bfbde6392866f1d4bb05b58d1aa4b8 100644 --- a/include/asm-sh/cpu-sh3/cache.h +++ b/include/asm-sh/cpu-sh3/cache.h @@ -35,7 +35,7 @@ defined(CONFIG_CPU_SUBTYPE_SH7710) || \ defined(CONFIG_CPU_SUBTYPE_SH7720) || \ defined(CONFIG_CPU_SUBTYPE_SH7721) -#define CCR3 0xa40000b4 +#define CCR3_REG 0xa40000b4 #define CCR_CACHE_16KB 0x00010000 #define CCR_CACHE_32KB 0x00020000 #endif diff --git a/include/asm-sh/delay.h b/include/asm-sh/delay.h index d5d464041003bb68104895c2e54ca5d32a46f195..4b16bf9b56bdcefb528b7115ea9954dd154c8b59 100644 --- a/include/asm-sh/delay.h +++ b/include/asm-sh/delay.h @@ -15,7 +15,6 @@ extern void __ndelay(unsigned long nsecs); extern void __const_udelay(unsigned long xloops); extern void __delay(unsigned long loops); -#ifdef CONFIG_SUPERH32 #define udelay(n) (__builtin_constant_p(n) ? \ ((n) > 20000 ? __bad_udelay() : __const_udelay((n) * 0x10c6ul)) : \ __udelay(n)) @@ -23,9 +22,5 @@ extern void __delay(unsigned long loops); #define ndelay(n) (__builtin_constant_p(n) ? \ ((n) > 20000 ? __bad_ndelay() : __const_udelay((n) * 5ul)) : \ __ndelay(n)) -#else -extern void udelay(unsigned long usecs); -extern void ndelay(unsigned long nsecs); -#endif #endif /* __ASM_SH_DELAY_H */ diff --git a/include/asm-sh/entry-macros.S b/include/asm-sh/entry-macros.S index 500030eae7aa8d1352c5ac6dbba0385ba57b1da2..2dab0b8d9454f8d8b67afa46016b2924b6b9b28f 100644 --- a/include/asm-sh/entry-macros.S +++ b/include/asm-sh/entry-macros.S @@ -12,7 +12,7 @@ not r11, r11 stc sr, r10 and r11, r10 -#ifdef CONFIG_HAS_SR_RB +#ifdef CONFIG_CPU_HAS_SR_RB stc k_g_imask, r11 or r11, r10 #endif @@ -20,7 +20,7 @@ .endm .macro get_current_thread_info, ti, tmp -#ifdef CONFIG_HAS_SR_RB +#ifdef CONFIG_CPU_HAS_SR_RB stc r7_bank, \ti #else mov #((THREAD_SIZE - 1) >> 10) ^ 0xff, \tmp diff --git a/include/asm-sparc/system.h b/include/asm-sparc/system.h index 45e47c159a6e55316e74a35cdd2303b8fb0586a0..4e08210cd4c2a33b22eceb46c1788071deae9cdc 100644 --- a/include/asm-sparc/system.h +++ b/include/asm-sparc/system.h @@ -44,6 +44,8 @@ extern enum sparc_cpu sparc_cpu_model; #define SUN4M_NCPUS 4 /* Architectural limit of sun4m. */ +extern char reboot_command[]; + extern struct thread_info *current_set[NR_CPUS]; extern unsigned long empty_bad_page; diff --git a/include/asm-sparc64/kprobes.h b/include/asm-sparc64/kprobes.h index 7237dd87663ec4857f9ae957c54acad25831745e..5879d71afdaa799b2bd18f038ee390e680390c4c 100644 --- a/include/asm-sparc64/kprobes.h +++ b/include/asm-sparc64/kprobes.h @@ -14,8 +14,6 @@ typedef u32 kprobe_opcode_t; #define arch_remove_kprobe(p) do {} while (0) -#define ARCH_SUPPORTS_KRETPROBES - #define flush_insn_slot(p) \ do { flushi(&(p)->ainsn.insn[0]); \ flushi(&(p)->ainsn.insn[1]); \ diff --git a/include/asm-sparc64/system.h b/include/asm-sparc64/system.h index ed91a5d8d4f05dce3c5ebe2f54d5e3f0ce510907..53eae091a171920d90dbc083d5fb96d0a8f67b3e 100644 --- a/include/asm-sparc64/system.h +++ b/include/asm-sparc64/system.h @@ -30,6 +30,8 @@ enum sparc_cpu { #define ARCH_SUN4C_SUN4 0 #define ARCH_SUN4 0 +extern char reboot_command[]; + /* These are here in an effort to more fully work around Spitfire Errata * #51. Essentially, if a memory barrier occurs soon after a mispredicted * branch, the chip can stop executing instructions until a trap occurs. diff --git a/include/asm-x86/Kbuild b/include/asm-x86/Kbuild index b04a7ff46df17c2261476741b6e704c8d65ccd52..3b8160a2b47e0eaa145610a3b092b40769a9cd92 100644 --- a/include/asm-x86/Kbuild +++ b/include/asm-x86/Kbuild @@ -16,7 +16,6 @@ unifdef-y += ist.h unifdef-y += mce.h unifdef-y += msr.h unifdef-y += mtrr.h -unifdef-y += page.h unifdef-y += posix_types_32.h unifdef-y += posix_types_64.h unifdef-y += ptrace.h diff --git a/include/asm-x86/futex.h b/include/asm-x86/futex.h index cd9f894dd2d7c778fe4d85fdeb0f83168a16804d..c9952ea9f6980cdb3620470ff285c59e28f8acd2 100644 --- a/include/asm-x86/futex.h +++ b/include/asm-x86/futex.h @@ -102,6 +102,13 @@ futex_atomic_op_inuser(int encoded_op, int __user *uaddr) static inline int futex_atomic_cmpxchg_inatomic(int __user *uaddr, int oldval, int newval) { + +#if defined(CONFIG_X86_32) && !defined(CONFIG_X86_BSWAP) + /* Real i386 machines have no cmpxchg instruction */ + if (boot_cpu_data.x86 == 3) + return -ENOSYS; +#endif + if (!access_ok(VERIFY_WRITE, uaddr, sizeof(int))) return -EFAULT; diff --git a/include/asm-x86/kprobes.h b/include/asm-x86/kprobes.h index 143476a3cb52c8328dc653c5b60b535ea5248f30..61ad7b5d142e1d4cc1baae2d18e186369c7907c9 100644 --- a/include/asm-x86/kprobes.h +++ b/include/asm-x86/kprobes.h @@ -42,7 +42,6 @@ typedef u8 kprobe_opcode_t; : (((unsigned long)current_thread_info()) + THREAD_SIZE \ - (unsigned long)(ADDR))) -#define ARCH_SUPPORTS_KRETPROBES #define flush_insn_slot(p) do { } while (0) extern const int kretprobe_blacklist_size; diff --git a/include/asm-x86/lguest.h b/include/asm-x86/lguest.h index 4d9367b72976a1601897af8ce3f448ad58245c11..9b17571e9bc35f3aaf68c4eb451ae4fa384578d7 100644 --- a/include/asm-x86/lguest.h +++ b/include/asm-x86/lguest.h @@ -23,6 +23,17 @@ /* Found in switcher.S */ extern unsigned long default_idt_entries[]; +/* Declarations for definitions in lguest_guest.S */ +extern char lguest_noirq_start[], lguest_noirq_end[]; +extern const char lgstart_cli[], lgend_cli[]; +extern const char lgstart_sti[], lgend_sti[]; +extern const char lgstart_popf[], lgend_popf[]; +extern const char lgstart_pushf[], lgend_pushf[]; +extern const char lgstart_iret[], lgend_iret[]; + +extern void lguest_iret(void); +extern void lguest_init(void); + struct lguest_regs { /* Manually saved part. */ diff --git a/include/asm-x86/nops.h b/include/asm-x86/nops.h index fec025c7f58cf0b375f94dc4335ca39fdf113125..e3b2bce0aff8e741305068fd41602e06cbf26ba4 100644 --- a/include/asm-x86/nops.h +++ b/include/asm-x86/nops.h @@ -3,17 +3,29 @@ /* Define nops for use with alternative() */ -/* generic versions from gas */ -#define GENERIC_NOP1 ".byte 0x90\n" -#define GENERIC_NOP2 ".byte 0x89,0xf6\n" -#define GENERIC_NOP3 ".byte 0x8d,0x76,0x00\n" -#define GENERIC_NOP4 ".byte 0x8d,0x74,0x26,0x00\n" -#define GENERIC_NOP5 GENERIC_NOP1 GENERIC_NOP4 -#define GENERIC_NOP6 ".byte 0x8d,0xb6,0x00,0x00,0x00,0x00\n" -#define GENERIC_NOP7 ".byte 0x8d,0xb4,0x26,0x00,0x00,0x00,0x00\n" -#define GENERIC_NOP8 GENERIC_NOP1 GENERIC_NOP7 +/* generic versions from gas + 1: nop + 2: movl %esi,%esi + 3: leal 0x00(%esi),%esi + 4: leal 0x00(,%esi,1),%esi + 6: leal 0x00000000(%esi),%esi + 7: leal 0x00000000(,%esi,1),%esi +*/ +#define GENERIC_NOP1 ".byte 0x90\n" +#define GENERIC_NOP2 ".byte 0x89,0xf6\n" +#define GENERIC_NOP3 ".byte 0x8d,0x76,0x00\n" +#define GENERIC_NOP4 ".byte 0x8d,0x74,0x26,0x00\n" +#define GENERIC_NOP5 GENERIC_NOP1 GENERIC_NOP4 +#define GENERIC_NOP6 ".byte 0x8d,0xb6,0x00,0x00,0x00,0x00\n" +#define GENERIC_NOP7 ".byte 0x8d,0xb4,0x26,0x00,0x00,0x00,0x00\n" +#define GENERIC_NOP8 GENERIC_NOP1 GENERIC_NOP7 -/* Opteron 64bit nops */ +/* Opteron 64bit nops + 1: nop + 2: osp nop + 3: osp osp nop + 4: osp osp osp nop +*/ #define K8_NOP1 GENERIC_NOP1 #define K8_NOP2 ".byte 0x66,0x90\n" #define K8_NOP3 ".byte 0x66,0x66,0x90\n" @@ -23,19 +35,35 @@ #define K8_NOP7 K8_NOP4 K8_NOP3 #define K8_NOP8 K8_NOP4 K8_NOP4 -/* K7 nops */ -/* uses eax dependencies (arbitary choice) */ -#define K7_NOP1 GENERIC_NOP1 +/* K7 nops + uses eax dependencies (arbitary choice) + 1: nop + 2: movl %eax,%eax + 3: leal (,%eax,1),%eax + 4: leal 0x00(,%eax,1),%eax + 6: leal 0x00000000(%eax),%eax + 7: leal 0x00000000(,%eax,1),%eax +*/ +#define K7_NOP1 GENERIC_NOP1 #define K7_NOP2 ".byte 0x8b,0xc0\n" #define K7_NOP3 ".byte 0x8d,0x04,0x20\n" #define K7_NOP4 ".byte 0x8d,0x44,0x20,0x00\n" #define K7_NOP5 K7_NOP4 ASM_NOP1 #define K7_NOP6 ".byte 0x8d,0x80,0,0,0,0\n" -#define K7_NOP7 ".byte 0x8D,0x04,0x05,0,0,0,0\n" -#define K7_NOP8 K7_NOP7 ASM_NOP1 +#define K7_NOP7 ".byte 0x8D,0x04,0x05,0,0,0,0\n" +#define K7_NOP8 K7_NOP7 ASM_NOP1 -/* P6 nops */ -/* uses eax dependencies (Intel-recommended choice) */ +/* P6 nops + uses eax dependencies (Intel-recommended choice) + 1: nop + 2: osp nop + 3: nopl (%eax) + 4: nopl 0x00(%eax) + 5: nopl 0x00(%eax,%eax,1) + 6: osp nopl 0x00(%eax,%eax,1) + 7: nopl 0x00000000(%eax) + 8: nopl 0x00000000(%eax,%eax,1) +*/ #define P6_NOP1 GENERIC_NOP1 #define P6_NOP2 ".byte 0x66,0x90\n" #define P6_NOP3 ".byte 0x0f,0x1f,0x00\n" @@ -63,9 +91,7 @@ #define ASM_NOP6 K7_NOP6 #define ASM_NOP7 K7_NOP7 #define ASM_NOP8 K7_NOP8 -#elif defined(CONFIG_M686) || defined(CONFIG_MPENTIUMII) || \ - defined(CONFIG_MPENTIUMIII) || defined(CONFIG_MPENTIUMM) || \ - defined(CONFIG_MCORE2) || defined(CONFIG_PENTIUM4) +#elif defined(CONFIG_X86_P6_NOP) #define ASM_NOP1 P6_NOP1 #define ASM_NOP2 P6_NOP2 #define ASM_NOP3 P6_NOP3 diff --git a/include/asm-x86/page_64.h b/include/asm-x86/page_64.h index f7393bc516eff1c1d25ad799f0441f734a151280..143546073b958097eef072e4d8849b820995232b 100644 --- a/include/asm-x86/page_64.h +++ b/include/asm-x86/page_64.h @@ -47,8 +47,12 @@ #define __PHYSICAL_MASK_SHIFT 46 #define __VIRTUAL_MASK_SHIFT 48 -#define KERNEL_TEXT_SIZE (40*1024*1024) -#define KERNEL_TEXT_START _AC(0xffffffff80000000, UL) +/* + * Kernel image size is limited to 128 MB (see level2_kernel_pgt in + * arch/x86/kernel/head_64.S), and it is mapped here: + */ +#define KERNEL_IMAGE_SIZE (128*1024*1024) +#define KERNEL_IMAGE_START _AC(0xffffffff80000000, UL) #ifndef __ASSEMBLY__ void clear_page(void *page); diff --git a/include/asm-x86/pgtable_32.h b/include/asm-x86/pgtable_32.h index a842c7222b1eef0f598a8de4a4c5375506e0b2c5..4e6a0fca0b47c1fc1941ef368618c3ef691ddfcb 100644 --- a/include/asm-x86/pgtable_32.h +++ b/include/asm-x86/pgtable_32.h @@ -26,10 +26,9 @@ struct mm_struct; struct vm_area_struct; extern pgd_t swapper_pg_dir[1024]; -extern struct kmem_cache *pmd_cache; -void check_pgt_cache(void); -static inline void pgtable_cache_init(void) {} +static inline void pgtable_cache_init(void) { } +static inline void check_pgt_cache(void) { } void paging_init(void); diff --git a/include/asm-x86/ptrace-abi.h b/include/asm-x86/ptrace-abi.h index 81a8ee4c55fc50a941373d5c16de01da455bdee7..f224eb3c3157591ac69a53466609ea0841beefbc 100644 --- a/include/asm-x86/ptrace-abi.h +++ b/include/asm-x86/ptrace-abi.h @@ -89,13 +89,13 @@ */ struct ptrace_bts_config { /* requested or actual size of BTS buffer in bytes */ - u32 size; + __u32 size; /* bitmask of below flags */ - u32 flags; + __u32 flags; /* buffer overflow signal */ - u32 signal; + __u32 signal; /* actual size of bts_struct in bytes */ - u32 bts_size; + __u32 bts_size; }; #endif diff --git a/include/crypto/internal/skcipher.h b/include/crypto/internal/skcipher.h index 2ba42cd7d6aa4c4fa708ba2733b6a20a59c3c526..ccc32bad9a890df12d3662401a4de87e60cdbaff 100644 --- a/include/crypto/internal/skcipher.h +++ b/include/crypto/internal/skcipher.h @@ -15,6 +15,7 @@ #include #include +#include #include struct rtattr; @@ -64,6 +65,11 @@ void skcipher_geniv_free(struct crypto_instance *inst); int skcipher_geniv_init(struct crypto_tfm *tfm); void skcipher_geniv_exit(struct crypto_tfm *tfm); +int __init eseqiv_module_init(void); +void __exit eseqiv_module_exit(void); +int __init chainiv_module_init(void); +void chainiv_module_exit(void); + static inline struct crypto_ablkcipher *skcipher_geniv_cipher( struct crypto_ablkcipher *geniv) { diff --git a/include/linux/Kbuild b/include/linux/Kbuild index aada32fffec2b18fa0ae39516ea0622fcfcba631..0fac822c115727c36822e232963b9cc49ef3cb1a 100644 --- a/include/linux/Kbuild +++ b/include/linux/Kbuild @@ -61,6 +61,7 @@ header-y += efs_fs_sb.h header-y += elf-fdpic.h header-y += elf-em.h header-y += fadvise.h +header-y += falloc.h header-y += fd.h header-y += fdreg.h header-y += fib_rules.h @@ -204,7 +205,6 @@ unifdef-y += futex.h unifdef-y += fs.h unifdef-y += gameport.h unifdef-y += generic_serial.h -unifdef-y += genhd.h unifdef-y += gfs2_ondisk.h unifdef-y += hayesesp.h unifdef-y += hdlcdrv.h diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index 6fe67d1939c27919c0f53396da0718d58ef71b42..6f79d40dd3c01f25c105b9bdae4f5e70a7c88e1e 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -216,8 +216,8 @@ struct request { unsigned int cmd_len; unsigned char cmd[BLK_MAX_CDB]; - unsigned int raw_data_len; unsigned int data_len; + unsigned int extra_len; /* length of alignment and padding */ unsigned int sense_len; void *data; void *sense; @@ -362,6 +362,7 @@ struct request_queue unsigned long seg_boundary_mask; void *dma_drain_buffer; unsigned int dma_drain_size; + unsigned int dma_pad_mask; unsigned int dma_alignment; struct blk_queue_tag *queue_tags; @@ -701,6 +702,7 @@ extern void blk_queue_max_hw_segments(struct request_queue *, unsigned short); extern void blk_queue_max_segment_size(struct request_queue *, unsigned int); extern void blk_queue_hardsect_size(struct request_queue *, unsigned short); extern void blk_queue_stack_limits(struct request_queue *t, struct request_queue *b); +extern void blk_queue_dma_pad(struct request_queue *, unsigned int); extern int blk_queue_dma_drain(struct request_queue *q, dma_drain_needed_fn *dma_drain_needed, void *buf, unsigned int size); diff --git a/include/linux/cgroup_subsys.h b/include/linux/cgroup_subsys.h index ac6aad98b6073ef7cd3a16b088b02ffccaadae32..1ddebfc52565f3eb4894c422c1fc5dd831ae523c 100644 --- a/include/linux/cgroup_subsys.h +++ b/include/linux/cgroup_subsys.h @@ -37,7 +37,7 @@ SUBSYS(cpuacct) /* */ -#ifdef CONFIG_CGROUP_MEM_CONT +#ifdef CONFIG_CGROUP_MEM_RES_CTLR SUBSYS(mem_cgroup) #endif diff --git a/include/linux/compiler.h b/include/linux/compiler.h index d0e17e1657dca11b86f151084a10bc87204c80a1..dcae0c8d97e6e2d04a8db04494e899eb403e1c18 100644 --- a/include/linux/compiler.h +++ b/include/linux/compiler.h @@ -138,6 +138,12 @@ extern void __chk_io_ptr(const volatile void __iomem *); #define noinline #endif +/* + * Rather then using noinline to prevent stack consumption, use + * noinline_for_stack instead. For documentaiton reasons. + */ +#define noinline_for_stack noinline + #ifndef __always_inline #define __always_inline inline #endif diff --git a/include/linux/debugfs.h b/include/linux/debugfs.h index f592d6de3b971592a2b289e57175d776c212f3b1..7266124361b44f24259db727c7dc23d0694fb8de 100644 --- a/include/linux/debugfs.h +++ b/include/linux/debugfs.h @@ -27,6 +27,11 @@ struct debugfs_blob_wrapper { }; #if defined(CONFIG_DEBUG_FS) + +/* declared over in file.c */ +extern const struct file_operations debugfs_file_operations; +extern const struct inode_operations debugfs_link_operations; + struct dentry *debugfs_create_file(const char *name, mode_t mode, struct dentry *parent, void *data, const struct file_operations *fops); diff --git a/include/linux/delay.h b/include/linux/delay.h index 17ddb55430ae19c28704a3da24f230b7a2e2ff6a..54552d21296efe9037de1d034ef45cafa4199067 100644 --- a/include/linux/delay.h +++ b/include/linux/delay.h @@ -7,6 +7,8 @@ * Delay routines, using a pre-computed "loops_per_jiffy" value. */ +#include + extern unsigned long loops_per_jiffy; #include @@ -32,7 +34,11 @@ extern unsigned long loops_per_jiffy; #endif #ifndef ndelay -#define ndelay(x) udelay(((x)+999)/1000) +static inline void ndelay(unsigned long x) +{ + udelay(DIV_ROUND_UP(x, 1000)); +} +#define ndelay(x) ndelay(x) #endif void calibrate_delay(void); diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h index acbb364674ff1f8516f50747d0d48375f15df49a..261e43a4c873042c687138db87e9e1a242e6ffd8 100644 --- a/include/linux/dmaengine.h +++ b/include/linux/dmaengine.h @@ -366,7 +366,7 @@ __dma_has_cap(enum dma_transaction_type tx_type, dma_cap_mask_t *srcp) */ static inline void dma_async_issue_pending(struct dma_chan *chan) { - return chan->device->device_issue_pending(chan); + chan->device->device_issue_pending(chan); } #define dma_async_memcpy_issue_pending(chan) dma_async_issue_pending(chan) diff --git a/include/linux/elfcore-compat.h b/include/linux/elfcore-compat.h index 532d13adabc4f5648dafee76f6edb319063f7a02..0a90e1c3a42207c9d961ff29315dc48c95e0ddec 100644 --- a/include/linux/elfcore-compat.h +++ b/include/linux/elfcore-compat.h @@ -45,8 +45,8 @@ struct compat_elf_prpsinfo char pr_zomb; char pr_nice; compat_ulong_t pr_flag; - compat_uid_t pr_uid; - compat_gid_t pr_gid; + __compat_uid_t pr_uid; + __compat_gid_t pr_gid; compat_pid_t pr_pid, pr_ppid, pr_pgrp, pr_sid; char pr_fname[16]; char pr_psargs[ELF_PRARGSZ]; diff --git a/include/linux/ethtool.h b/include/linux/ethtool.h index fcbe8b640ffba57f04a35c986728bf850717bb6c..c8d216357865dda3e22bd503df478055b3d888b9 100644 --- a/include/linux/ethtool.h +++ b/include/linux/ethtool.h @@ -12,6 +12,7 @@ #ifndef _LINUX_ETHTOOL_H #define _LINUX_ETHTOOL_H +#include /* This should work for both 32 and 64 bit userland. */ struct ethtool_cmd { diff --git a/include/linux/exportfs.h b/include/linux/exportfs.h index 51d214138814a509803e22db093c8a9f91108227..adcbb05b120b156758c4a8894990869ad473e103 100644 --- a/include/linux/exportfs.h +++ b/include/linux/exportfs.h @@ -49,11 +49,11 @@ struct fid { /** * struct export_operations - for nfsd to communicate with file systems - * @decode_fh: decode a file handle fragment and return a &struct dentry * @encode_fh: encode a file handle fragment from a dentry + * @fh_to_dentry: find the implied object and get a dentry for it + * @fh_to_parent: find the implied object's parent and get a dentry for it * @get_name: find the name for a given inode in a given directory * @get_parent: find the parent of a given directory - * @get_dentry: find a dentry for the inode given a file handle sub-fragment * * See Documentation/filesystems/Exporting for details on how to use * this interface correctly. diff --git a/include/linux/ext4_fs_extents.h b/include/linux/ext4_fs_extents.h index 697da4bce6c513b003e9118d95e8bda34eeeb81a..1285c583b2d868421366fc71bb05cc12c507225f 100644 --- a/include/linux/ext4_fs_extents.h +++ b/include/linux/ext4_fs_extents.h @@ -227,5 +227,6 @@ extern int ext4_ext_search_left(struct inode *, struct ext4_ext_path *, ext4_lblk_t *, ext4_fsblk_t *); extern int ext4_ext_search_right(struct inode *, struct ext4_ext_path *, ext4_lblk_t *, ext4_fsblk_t *); +extern void ext4_ext_drop_refs(struct ext4_ext_path *); #endif /* _LINUX_EXT4_EXTENTS */ diff --git a/include/linux/firmware.h b/include/linux/firmware.h index 33d8f2087b6ea92557c6497a605e3f925e7700e4..4d10c7328d2dabafcee9cf285bf263ba6988b3cd 100644 --- a/include/linux/firmware.h +++ b/include/linux/firmware.h @@ -10,7 +10,10 @@ struct firmware { size_t size; u8 *data; }; + struct device; + +#if defined(CONFIG_FW_LOADER) || defined(CONFIG_FW_LOADER_MODULE) int request_firmware(const struct firmware **fw, const char *name, struct device *device); int request_firmware_nowait( @@ -19,4 +22,24 @@ int request_firmware_nowait( void (*cont)(const struct firmware *fw, void *context)); void release_firmware(const struct firmware *fw); +#else +static inline int request_firmware(const struct firmware **fw, + const char *name, + struct device *device) +{ + return -EINVAL; +} +static inline int request_firmware_nowait( + struct module *module, int uevent, + const char *name, struct device *device, void *context, + void (*cont)(const struct firmware *fw, void *context)) +{ + return -EINVAL; +} + +static inline void release_firmware(const struct firmware *fw) +{ +} +#endif + #endif diff --git a/include/linux/genhd.h b/include/linux/genhd.h index 09a3b18918c70d89c9ab795ce40620d4c0067803..ecd2bf63fc849e201f4825010293ba20a736d09b 100644 --- a/include/linux/genhd.h +++ b/include/linux/genhd.h @@ -18,11 +18,13 @@ #define dev_to_disk(device) container_of(device, struct gendisk, dev) #define dev_to_part(device) container_of(device, struct hd_struct, dev) -extern struct device_type disk_type; extern struct device_type part_type; extern struct kobject *block_depr; extern struct class block_class; +extern const struct seq_operations partitions_op; +extern const struct seq_operations diskstats_op; + enum { /* These three have identical behaviour; use the second one if DOS FDISK gets confused about extended/logical partitions starting past cylinder 1023. */ @@ -53,24 +55,6 @@ enum { UNIXWARE_PARTITION = 0x63, /* Same as GNU_HURD and SCO Unix */ }; -#ifndef __KERNEL__ - -struct partition { - unsigned char boot_ind; /* 0x80 - active */ - unsigned char head; /* starting head */ - unsigned char sector; /* starting sector */ - unsigned char cyl; /* starting cylinder */ - unsigned char sys_ind; /* What partition type */ - unsigned char end_head; /* end head */ - unsigned char end_sector; /* end sector */ - unsigned char end_cyl; /* end cylinder */ - unsigned int start_sect; /* starting sector counting from 0 */ - unsigned int nr_sects; /* nr of sectors in partition */ -} __attribute__((packed)); - -#endif - -#ifdef __KERNEL__ #include #include #include @@ -226,7 +210,7 @@ static inline void part_stat_set_all(struct hd_struct *part, int value) { sizeof(struct disk_stats)); } -#else +#else /* !CONFIG_SMP */ #define __disk_stat_add(gendiskp, field, addnd) \ (gendiskp->dkstats.field += addnd) #define disk_stat_read(gendiskp, field) (gendiskp->dkstats.field) @@ -254,7 +238,7 @@ static inline void part_stat_set_all(struct hd_struct *part, int value) memset(&part->dkstats, value, sizeof(struct disk_stats)); } -#endif +#endif /* CONFIG_SMP */ #define disk_stat_add(gendiskp, field, addnd) \ do { \ @@ -393,8 +377,6 @@ static inline void set_capacity(struct gendisk *disk, sector_t size) disk->capacity = size; } -#endif /* __KERNEL__ */ - #ifdef CONFIG_SOLARIS_X86_PARTITION #define SOLARIS_X86_NUMSLICE 16 @@ -538,8 +520,6 @@ struct unixware_disklabel { # define MINIX_NR_SUBPARTITIONS 4 #endif /* CONFIG_MINIX_SUBPARTITION */ -#ifdef __KERNEL__ - #define ADDPART_FLAG_NONE 0 #define ADDPART_FLAG_RAID 1 #define ADDPART_FLAG_WHOLEDISK 2 @@ -556,7 +536,6 @@ extern struct gendisk *alloc_disk_node(int minors, int node_id); extern struct gendisk *alloc_disk(int minors); extern struct kobject *get_disk(struct gendisk *disk); extern void put_disk(struct gendisk *disk); -extern void genhd_media_change_notify(struct gendisk *disk); extern void blk_register_region(dev_t devt, unsigned long range, struct module *module, struct kobject *(*probe)(dev_t, int *, void *), @@ -569,8 +548,6 @@ static inline struct block_device *bdget_disk(struct gendisk *disk, int index) return bdget(MKDEV(disk->major, disk->first_minor) + index); } -#endif - #else /* CONFIG_BLOCK */ static inline void printk_all_partitions(void) { } @@ -583,4 +560,4 @@ static inline dev_t blk_lookup_devt(const char *name) #endif /* CONFIG_BLOCK */ -#endif +#endif /* _LINUX_GENHD_H */ diff --git a/include/linux/gpio.h b/include/linux/gpio.h new file mode 100644 index 0000000000000000000000000000000000000000..4987a84078ef0bb380ac8c5dd3238aaf9ab15c30 --- /dev/null +++ b/include/linux/gpio.h @@ -0,0 +1,95 @@ +#ifndef __LINUX_GPIO_H +#define __LINUX_GPIO_H + +/* see Documentation/gpio.txt */ + +#ifdef CONFIG_GENERIC_GPIO +#include + +#else + +/* + * Some platforms don't support the GPIO programming interface. + * + * In case some driver uses it anyway (it should normally have + * depended on GENERIC_GPIO), these routines help the compiler + * optimize out much GPIO-related code ... or trigger a runtime + * warning when something is wrongly called. + */ + +static inline int gpio_is_valid(int number) +{ + return 0; +} + +static inline int gpio_request(unsigned gpio, const char *label) +{ + return -ENOSYS; +} + +static inline void gpio_free(unsigned gpio) +{ + /* GPIO can never have been requested */ + WARN_ON(1); +} + +static inline int gpio_direction_input(unsigned gpio) +{ + return -ENOSYS; +} + +static inline int gpio_direction_output(unsigned gpio, int value) +{ + return -ENOSYS; +} + +static inline int gpio_get_value(unsigned gpio) +{ + /* GPIO can never have been requested or set as {in,out}put */ + WARN_ON(1); + return 0; +} + +static inline void gpio_set_value(unsigned gpio, int value) +{ + /* GPIO can never have been requested or set as output */ + WARN_ON(1); +} + +static inline int gpio_cansleep(unsigned gpio) +{ + /* GPIO can never have been requested or set as {in,out}put */ + WARN_ON(1); + return 0; +} + +static inline int gpio_get_value_cansleep(unsigned gpio) +{ + /* GPIO can never have been requested or set as {in,out}put */ + WARN_ON(1); + return 0; +} + +static inline void gpio_set_value_cansleep(unsigned gpio, int value) +{ + /* GPIO can never have been requested or set as output */ + WARN_ON(1); +} + +static inline int gpio_to_irq(unsigned gpio) +{ + /* GPIO can never have been requested or set as input */ + WARN_ON(1); + return -EINVAL; +} + +static inline int irq_to_gpio(unsigned irq) +{ + /* irq can never have been returned from gpio_to_irq() */ + WARN_ON(1); + return -EINVAL; +} + +#endif + +#endif /* __LINUX_GPIO_H */ diff --git a/include/linux/hardirq.h b/include/linux/hardirq.h index 2961ec788046627c823feb291d7d522f15982fbf..49829988bfa02cb85a02e38db87f81d077261060 100644 --- a/include/linux/hardirq.h +++ b/include/linux/hardirq.h @@ -109,6 +109,14 @@ static inline void account_system_vtime(struct task_struct *tsk) } #endif +#if defined(CONFIG_PREEMPT_RCU) && defined(CONFIG_NO_HZ) +extern void rcu_irq_enter(void); +extern void rcu_irq_exit(void); +#else +# define rcu_irq_enter() do { } while (0) +# define rcu_irq_exit() do { } while (0) +#endif /* CONFIG_PREEMPT_RCU */ + /* * It is safe to do non-atomic ops on ->hardirq_context, * because NMI handlers may not preempt and the ops are @@ -117,6 +125,7 @@ static inline void account_system_vtime(struct task_struct *tsk) */ #define __irq_enter() \ do { \ + rcu_irq_enter(); \ account_system_vtime(current); \ add_preempt_count(HARDIRQ_OFFSET); \ trace_hardirq_enter(); \ @@ -135,6 +144,7 @@ extern void irq_enter(void); trace_hardirq_exit(); \ account_system_vtime(current); \ sub_preempt_count(HARDIRQ_OFFSET); \ + rcu_irq_exit(); \ } while (0) /* diff --git a/include/linux/in.h b/include/linux/in.h index 70c6df882694b70c6ba372b9fedc21b35bce396c..4065313cd7eee7f3a287d3cd0629ffcb726041f1 100644 --- a/include/linux/in.h +++ b/include/linux/in.h @@ -265,7 +265,7 @@ static inline bool ipv4_is_local_multicast(__be32 addr) static inline bool ipv4_is_lbcast(__be32 addr) { /* limited broadcast */ - return addr == INADDR_BROADCAST; + return addr == htonl(INADDR_BROADCAST); } static inline bool ipv4_is_zeronet(__be32 addr) diff --git a/include/linux/iommu-helper.h b/include/linux/iommu-helper.h index 4dd4c04ff2f468a1fddbbeb47cbf7c69bea1ed1b..c975caf75385d2e634cdb151dae416e2487533a0 100644 --- a/include/linux/iommu-helper.h +++ b/include/linux/iommu-helper.h @@ -1,3 +1,6 @@ +extern int iommu_is_span_boundary(unsigned int index, unsigned int nr, + unsigned long shift, + unsigned long boundary_size); extern unsigned long iommu_area_alloc(unsigned long *map, unsigned long size, unsigned long start, unsigned int nr, unsigned long shift, diff --git a/include/linux/kprobes.h b/include/linux/kprobes.h index 4a6ce82ba03971f832a8f325eb150907090213bc..0f28486f636067677cf9b80c1279c7da88ffc4c9 100644 --- a/include/linux/kprobes.h +++ b/include/linux/kprobes.h @@ -125,11 +125,11 @@ struct jprobe { DECLARE_PER_CPU(struct kprobe *, current_kprobe); DECLARE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk); -#ifdef ARCH_SUPPORTS_KRETPROBES +#ifdef CONFIG_KRETPROBES extern void arch_prepare_kretprobe(struct kretprobe_instance *ri, struct pt_regs *regs); extern int arch_trampoline_kprobe(struct kprobe *p); -#else /* ARCH_SUPPORTS_KRETPROBES */ +#else /* CONFIG_KRETPROBES */ static inline void arch_prepare_kretprobe(struct kretprobe *rp, struct pt_regs *regs) { @@ -138,7 +138,7 @@ static inline int arch_trampoline_kprobe(struct kprobe *p) { return 0; } -#endif /* ARCH_SUPPORTS_KRETPROBES */ +#endif /* CONFIG_KRETPROBES */ /* * Function-return probe - * Note: diff --git a/include/linux/kvm.h b/include/linux/kvm.h index 4de4fd2d8607d19df5f9eb4cb3a88325fd3d60f8..c1ec04fd000d42d27d310ce79c92944f09d63c5f 100644 --- a/include/linux/kvm.h +++ b/include/linux/kvm.h @@ -221,6 +221,7 @@ struct kvm_vapic_addr { * Get size for mmap(vcpu_fd) */ #define KVM_GET_VCPU_MMAP_SIZE _IO(KVMIO, 0x04) /* in bytes */ +#define KVM_GET_SUPPORTED_CPUID _IOWR(KVMIO, 0x05, struct kvm_cpuid2) /* * Extension capability list. @@ -230,8 +231,8 @@ struct kvm_vapic_addr { #define KVM_CAP_MMU_SHADOW_CACHE_CONTROL 2 #define KVM_CAP_USER_MEMORY 3 #define KVM_CAP_SET_TSS_ADDR 4 -#define KVM_CAP_EXT_CPUID 5 #define KVM_CAP_VAPIC 6 +#define KVM_CAP_EXT_CPUID 7 /* * ioctls for VM fds @@ -249,7 +250,6 @@ struct kvm_vapic_addr { #define KVM_CREATE_VCPU _IO(KVMIO, 0x41) #define KVM_GET_DIRTY_LOG _IOW(KVMIO, 0x42, struct kvm_dirty_log) #define KVM_SET_MEMORY_ALIAS _IOW(KVMIO, 0x43, struct kvm_memory_alias) -#define KVM_GET_SUPPORTED_CPUID _IOWR(KVMIO, 0x48, struct kvm_cpuid2) /* Device model IOC */ #define KVM_CREATE_IRQCHIP _IO(KVMIO, 0x60) #define KVM_IRQ_LINE _IOW(KVMIO, 0x61, struct kvm_irq_level) diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h index ea4764b0a2f49dc40772be7e0ad98053a83d3084..928b0d59e9ba07d64686975f5db6022ad608ef8d 100644 --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h @@ -107,6 +107,7 @@ struct kvm_memory_slot { struct kvm { struct mutex lock; /* protects the vcpus array and APIC accesses */ spinlock_t mmu_lock; + struct rw_semaphore slots_lock; struct mm_struct *mm; /* userspace tied to this vm */ int nmemslots; struct kvm_memory_slot memslots[KVM_MEMORY_SLOTS + diff --git a/include/linux/maple.h b/include/linux/maple.h index 3f01e2bae1a1dcb22303b7f1edd1399c20d47f6c..d31e36ebb436fd25ec087ac135b5fdbef68ff815 100644 --- a/include/linux/maple.h +++ b/include/linux/maple.h @@ -64,7 +64,6 @@ struct maple_driver { int (*connect) (struct maple_device * dev); void (*disconnect) (struct maple_device * dev); struct device_driver drv; - int registered; }; void maple_getcond_callback(struct maple_device *dev, diff --git a/include/linux/marker.h b/include/linux/marker.h index 5df879dc3776c732dc62e017850f0eb4739429e3..430f6adf9762d175096246d92dfe999f6b6bba9c 100644 --- a/include/linux/marker.h +++ b/include/linux/marker.h @@ -104,10 +104,16 @@ static inline void marker_update_probe_range(struct marker *begin, #define MARK_NOARGS " " /* To be used for string format validity checking with gcc */ -static inline void __printf(1, 2) __mark_check_format(const char *fmt, ...) +static inline void __printf(1, 2) ___mark_check_format(const char *fmt, ...) { } +#define __mark_check_format(format, args...) \ + do { \ + if (0) \ + ___mark_check_format(format, ## args); \ + } while (0) + extern marker_probe_func __mark_empty_function; extern void marker_probe_cb(const struct marker *mdata, diff --git a/include/linux/memcontrol.h b/include/linux/memcontrol.h index 04075628cb9a315d31acc90bf2bc165606d80e15..8b1c4295848b77b6808c1f451434e02e599fffb2 100644 --- a/include/linux/memcontrol.h +++ b/include/linux/memcontrol.h @@ -25,18 +25,20 @@ struct page_cgroup; struct page; struct mm_struct; -#ifdef CONFIG_CGROUP_MEM_CONT +#ifdef CONFIG_CGROUP_MEM_RES_CTLR extern void mm_init_cgroup(struct mm_struct *mm, struct task_struct *p); extern void mm_free_cgroup(struct mm_struct *mm); -extern void page_assign_page_cgroup(struct page *page, - struct page_cgroup *pc); + +#define page_reset_bad_cgroup(page) ((page)->page_cgroup = 0) + extern struct page_cgroup *page_get_page_cgroup(struct page *page); extern int mem_cgroup_charge(struct page *page, struct mm_struct *mm, gfp_t gfp_mask); -extern void mem_cgroup_uncharge(struct page_cgroup *pc); +extern int mem_cgroup_cache_charge(struct page *page, struct mm_struct *mm, + gfp_t gfp_mask); extern void mem_cgroup_uncharge_page(struct page *page); -extern void mem_cgroup_move_lists(struct page_cgroup *pc, bool active); +extern void mem_cgroup_move_lists(struct page *page, bool active); extern unsigned long mem_cgroup_isolate_pages(unsigned long nr_to_scan, struct list_head *dst, unsigned long *scanned, int order, @@ -44,11 +46,9 @@ extern unsigned long mem_cgroup_isolate_pages(unsigned long nr_to_scan, struct mem_cgroup *mem_cont, int active); extern void mem_cgroup_out_of_memory(struct mem_cgroup *mem, gfp_t gfp_mask); -extern int mem_cgroup_cache_charge(struct page *page, struct mm_struct *mm, - gfp_t gfp_mask); int task_in_mem_cgroup(struct task_struct *task, const struct mem_cgroup *mem); -#define vm_match_cgroup(mm, cgroup) \ +#define mm_match_cgroup(mm, cgroup) \ ((cgroup) == rcu_dereference((mm)->mem_cgroup)) extern int mem_cgroup_prepare_migration(struct page *page); @@ -72,7 +72,7 @@ extern long mem_cgroup_calc_reclaim_active(struct mem_cgroup *mem, extern long mem_cgroup_calc_reclaim_inactive(struct mem_cgroup *mem, struct zone *zone, int priority); -#else /* CONFIG_CGROUP_MEM_CONT */ +#else /* CONFIG_CGROUP_MEM_RES_CTLR */ static inline void mm_init_cgroup(struct mm_struct *mm, struct task_struct *p) { @@ -82,8 +82,7 @@ static inline void mm_free_cgroup(struct mm_struct *mm) { } -static inline void page_assign_page_cgroup(struct page *page, - struct page_cgroup *pc) +static inline void page_reset_bad_cgroup(struct page *page) { } @@ -92,33 +91,27 @@ static inline struct page_cgroup *page_get_page_cgroup(struct page *page) return NULL; } -static inline int mem_cgroup_charge(struct page *page, struct mm_struct *mm, - gfp_t gfp_mask) +static inline int mem_cgroup_charge(struct page *page, + struct mm_struct *mm, gfp_t gfp_mask) { return 0; } -static inline void mem_cgroup_uncharge(struct page_cgroup *pc) +static inline int mem_cgroup_cache_charge(struct page *page, + struct mm_struct *mm, gfp_t gfp_mask) { + return 0; } static inline void mem_cgroup_uncharge_page(struct page *page) { } -static inline void mem_cgroup_move_lists(struct page_cgroup *pc, - bool active) -{ -} - -static inline int mem_cgroup_cache_charge(struct page *page, - struct mm_struct *mm, - gfp_t gfp_mask) +static inline void mem_cgroup_move_lists(struct page *page, bool active) { - return 0; } -static inline int vm_match_cgroup(struct mm_struct *mm, struct mem_cgroup *mem) +static inline int mm_match_cgroup(struct mm_struct *mm, struct mem_cgroup *mem) { return 1; } diff --git a/include/linux/memstick.h b/include/linux/memstick.h index 334d059d67944e1bd651580df57a482be62079c8..b7ee25888836761e38ad6a3f3db90225961ec573 100644 --- a/include/linux/memstick.h +++ b/include/linux/memstick.h @@ -22,6 +22,8 @@ struct ms_status_register { unsigned char reserved; unsigned char interrupt; #define MEMSTICK_INT_CMDNAK 0x0001 +#define MEMSTICK_INT_IOREQ 0x0008 +#define MEMSTICK_INT_IOBREQ 0x0010 #define MEMSTICK_INT_BREQ 0x0020 #define MEMSTICK_INT_ERR 0x0040 #define MEMSTICK_INT_CED 0x0080 @@ -47,13 +49,17 @@ struct ms_status_register { struct ms_id_register { unsigned char type; - unsigned char reserved; + unsigned char if_mode; unsigned char category; unsigned char class; } __attribute__((packed)); struct ms_param_register { unsigned char system; +#define MEMSTICK_SYS_ATEN 0xc0 +#define MEMSTICK_SYS_BAMD 0x80 +#define MEMSTICK_SYS_PAM 0x08 + unsigned char block_address_msb; unsigned short block_address; unsigned char cp; @@ -90,16 +96,48 @@ struct ms_register { struct mspro_param_register { unsigned char system; +#define MEMSTICK_SYS_SERIAL 0x80 +#define MEMSTICK_SYS_PAR4 0x00 +#define MEMSTICK_SYS_PAR8 0x40 + + unsigned short data_count; + unsigned int data_address; + unsigned char tpc_param; +} __attribute__((packed)); + +struct mspro_io_info_register { + unsigned char version; + unsigned char io_category; + unsigned char current_req; + unsigned char card_opt_info; + unsigned char rdy_wait_time; +} __attribute__((packed)); + +struct mspro_io_func_register { + unsigned char func_enable; + unsigned char func_select; + unsigned char func_intmask; + unsigned char transfer_mode; +} __attribute__((packed)); + +struct mspro_io_cmd_register { + unsigned short tpc_param; unsigned short data_count; unsigned int data_address; - unsigned char cmd_param; } __attribute__((packed)); struct mspro_register { - struct ms_status_register status; - struct ms_id_register id; - unsigned char reserved[8]; - struct mspro_param_register param; + struct ms_status_register status; + struct ms_id_register id; + unsigned char reserved0[8]; + struct mspro_param_register param; + unsigned char reserved1[8]; + struct mspro_io_info_register io_info; + struct mspro_io_func_register io_func; + unsigned char reserved2[7]; + struct mspro_io_cmd_register io_cmd; + unsigned char io_int; + unsigned char io_int_func; } __attribute__((packed)); struct ms_register_addr { @@ -110,49 +148,55 @@ struct ms_register_addr { } __attribute__((packed)); enum { + MS_TPC_READ_MG_STATUS = 0x01, MS_TPC_READ_LONG_DATA = 0x02, MS_TPC_READ_SHORT_DATA = 0x03, + MS_TPC_READ_MG_DATA = 0x03, MS_TPC_READ_REG = 0x04, - MS_TPC_READ_IO_DATA = 0x05, /* unverified */ + MS_TPC_READ_QUAD_DATA = 0x05, + MS_TPC_READ_IO_DATA = 0x05, MS_TPC_GET_INT = 0x07, MS_TPC_SET_RW_REG_ADRS = 0x08, MS_TPC_EX_SET_CMD = 0x09, - MS_TPC_WRITE_IO_DATA = 0x0a, /* unverified */ + MS_TPC_WRITE_QUAD_DATA = 0x0a, + MS_TPC_WRITE_IO_DATA = 0x0a, MS_TPC_WRITE_REG = 0x0b, MS_TPC_WRITE_SHORT_DATA = 0x0c, + MS_TPC_WRITE_MG_DATA = 0x0c, MS_TPC_WRITE_LONG_DATA = 0x0d, MS_TPC_SET_CMD = 0x0e }; enum { - MS_CMD_BLOCK_END = 0x33, - MS_CMD_RESET = 0x3c, - MS_CMD_BLOCK_WRITE = 0x55, - MS_CMD_SLEEP = 0x5a, - MS_CMD_BLOCK_ERASE = 0x99, - MS_CMD_BLOCK_READ = 0xaa, - MS_CMD_CLEAR_BUF = 0xc3, - MS_CMD_FLASH_STOP = 0xcc, - MSPRO_CMD_FORMAT = 0x10, - MSPRO_CMD_SLEEP = 0x11, - MSPRO_CMD_READ_DATA = 0x20, - MSPRO_CMD_WRITE_DATA = 0x21, - MSPRO_CMD_READ_ATRB = 0x24, - MSPRO_CMD_STOP = 0x25, - MSPRO_CMD_ERASE = 0x26, - MSPRO_CMD_SET_IBA = 0x46, - MSPRO_CMD_SET_IBD = 0x47 -/* - MSPRO_CMD_RESET - MSPRO_CMD_WAKEUP - MSPRO_CMD_IN_IO_DATA - MSPRO_CMD_OUT_IO_DATA - MSPRO_CMD_READ_IO_ATRB - MSPRO_CMD_IN_IO_FIFO - MSPRO_CMD_OUT_IO_FIFO - MSPRO_CMD_IN_IOM - MSPRO_CMD_OUT_IOM -*/ + MS_CMD_BLOCK_END = 0x33, + MS_CMD_RESET = 0x3c, + MS_CMD_BLOCK_WRITE = 0x55, + MS_CMD_SLEEP = 0x5a, + MS_CMD_BLOCK_ERASE = 0x99, + MS_CMD_BLOCK_READ = 0xaa, + MS_CMD_CLEAR_BUF = 0xc3, + MS_CMD_FLASH_STOP = 0xcc, + MS_CMD_LOAD_ID = 0x60, + MS_CMD_CMP_ICV = 0x7f, + MSPRO_CMD_FORMAT = 0x10, + MSPRO_CMD_SLEEP = 0x11, + MSPRO_CMD_WAKEUP = 0x12, + MSPRO_CMD_READ_DATA = 0x20, + MSPRO_CMD_WRITE_DATA = 0x21, + MSPRO_CMD_READ_ATRB = 0x24, + MSPRO_CMD_STOP = 0x25, + MSPRO_CMD_ERASE = 0x26, + MSPRO_CMD_READ_QUAD = 0x27, + MSPRO_CMD_WRITE_QUAD = 0x28, + MSPRO_CMD_SET_IBD = 0x46, + MSPRO_CMD_GET_IBD = 0x47, + MSPRO_CMD_IN_IO_DATA = 0xb0, + MSPRO_CMD_OUT_IO_DATA = 0xb1, + MSPRO_CMD_READ_IO_ATRB = 0xb2, + MSPRO_CMD_IN_IO_FIFO = 0xb3, + MSPRO_CMD_OUT_IO_FIFO = 0xb4, + MSPRO_CMD_IN_IOM = 0xb5, + MSPRO_CMD_OUT_IOM = 0xb6, }; /*** Driver structures and functions ***/ @@ -165,7 +209,8 @@ enum memstick_param { MEMSTICK_POWER = 1, MEMSTICK_INTERFACE }; #define MEMSTICK_POWER_ON 1 #define MEMSTICK_SERIAL 0 -#define MEMSTICK_PARALLEL 1 +#define MEMSTICK_PAR4 1 +#define MEMSTICK_PAR8 2 struct memstick_host; struct memstick_driver; @@ -195,11 +240,7 @@ struct memstick_request { unsigned char data_dir:1, need_card_int:1, get_int_reg:1, - io_type:2; -#define MEMSTICK_IO_NONE 0 -#define MEMSTICK_IO_VAL 1 -#define MEMSTICK_IO_SG 2 - + long_data:1; unsigned char int_reg; int error; union { @@ -231,8 +272,9 @@ struct memstick_host { struct mutex lock; unsigned int id; unsigned int caps; -#define MEMSTICK_CAP_PARALLEL 1 -#define MEMSTICK_CAP_AUTO_GET_INT 2 +#define MEMSTICK_CAP_AUTO_GET_INT 1 +#define MEMSTICK_CAP_PAR4 2 +#define MEMSTICK_CAP_PAR8 4 struct work_struct media_checker; struct class_device cdev; @@ -270,6 +312,8 @@ int memstick_add_host(struct memstick_host *host); void memstick_remove_host(struct memstick_host *host); void memstick_free_host(struct memstick_host *host); void memstick_detect_change(struct memstick_host *host); +void memstick_suspend_host(struct memstick_host *host); +void memstick_resume_host(struct memstick_host *host); void memstick_init_req_sg(struct memstick_request *mrq, unsigned char tpc, struct scatterlist *sg); diff --git a/include/linux/mm.h b/include/linux/mm.h index 3f3ccfe42de015f23c2350322c4ff053d3a41d38..b695875d63e308bcc9086e5889c0040438f0a363 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -235,15 +235,22 @@ static inline int get_page_unless_zero(struct page *page) struct page *vmalloc_to_page(const void *addr); unsigned long vmalloc_to_pfn(const void *addr); -#ifdef CONFIG_MMU -/* Determine if an address is within the vmalloc range */ +/* + * Determine if an address is within the vmalloc range + * + * On nommu, vmalloc/vfree wrap through kmalloc/kfree directly, so there + * is no special casing required. + */ static inline int is_vmalloc_addr(const void *x) { +#ifdef CONFIG_MMU unsigned long addr = (unsigned long)x; return addr >= VMALLOC_START && addr < VMALLOC_END; -} +#else + return 0; #endif +} static inline struct page *compound_head(struct page *page) { diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h index bfee0bd1d43545742504225e0ab0754a315e7aa9..af190ceab9719dc68b148e3b22b05b28a54c64d2 100644 --- a/include/linux/mm_types.h +++ b/include/linux/mm_types.h @@ -64,10 +64,7 @@ struct page { #if NR_CPUS >= CONFIG_SPLIT_PTLOCK_CPUS spinlock_t ptl; #endif - struct { - struct kmem_cache *slab; /* SLUB: Pointer to slab */ - void *end; /* SLUB: end marker */ - }; + struct kmem_cache *slab; /* SLUB: Pointer to slab */ struct page *first_page; /* Compound tail pages */ }; union { @@ -91,7 +88,7 @@ struct page { void *virtual; /* Kernel virtual address (NULL if not kmapped, ie. highmem) */ #endif /* WANT_PAGE_VIRTUAL */ -#ifdef CONFIG_CGROUP_MEM_CONT +#ifdef CONFIG_CGROUP_MEM_RES_CTLR unsigned long page_cgroup; #endif }; @@ -225,7 +222,7 @@ struct mm_struct { /* aio bits */ rwlock_t ioctx_list_lock; struct kioctx *ioctx_list; -#ifdef CONFIG_CGROUP_MEM_CONT +#ifdef CONFIG_CGROUP_MEM_RES_CTLR struct mem_cgroup *mem_cgroup; #endif }; diff --git a/include/linux/netfilter/nfnetlink_compat.h b/include/linux/netfilter/nfnetlink_compat.h index 02a42d875cf74810305e87b3a9e222a088308ae9..e1451760c9cd3dfc991c707d2b4d90b7062b5fb2 100644 --- a/include/linux/netfilter/nfnetlink_compat.h +++ b/include/linux/netfilter/nfnetlink_compat.h @@ -1,6 +1,6 @@ #ifndef _NFNETLINK_COMPAT_H #define _NFNETLINK_COMPAT_H -#ifndef __KERNEL +#ifndef __KERNEL__ /* Old nfnetlink macros for userspace */ /* nfnetlink groups: Up to 32 maximum */ diff --git a/include/linux/nfs_fs.h b/include/linux/nfs_fs.h index a69ba80f2dfe1398b9de602e0b793fedc69e4db9..f4a0e4c218df0411fb358d2d2dad5e5d8a53baec 100644 --- a/include/linux/nfs_fs.h +++ b/include/linux/nfs_fs.h @@ -195,6 +195,7 @@ struct nfs_inode { #define NFS_INO_ADVISE_RDPLUS (1) /* advise readdirplus */ #define NFS_INO_STALE (2) /* possible stale inode */ #define NFS_INO_ACL_LRU_SET (3) /* Inode is on the LRU list */ +#define NFS_INO_MOUNTPOINT (4) /* inode is remote mountpoint */ static inline struct nfs_inode *NFS_I(const struct inode *inode) { diff --git a/include/linux/pci.h b/include/linux/pci.h index 87195b62de5261cf0bc6dd31e171386de769ccdf..b7e4b633c69b002d85bda6c7baa6da8341b48d35 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -278,6 +278,7 @@ struct pci_bus { struct device dev; struct bin_attribute *legacy_io; /* legacy I/O for this bus */ struct bin_attribute *legacy_mem; /* legacy mem */ + unsigned int is_added:1; }; #define pci_bus_b(n) list_entry(n, struct pci_bus, node) @@ -388,6 +389,16 @@ struct pci_driver { #define to_pci_driver(drv) container_of(drv, struct pci_driver, driver) +/** + * DEFINE_PCI_DEVICE_TABLE - macro used to describe a pci device table + * @_table: device table name + * + * This macro is used to create a struct pci_device_id array (a device table) + * in a generic manner. + */ +#define DEFINE_PCI_DEVICE_TABLE(_table) \ + const struct pci_device_id _table[] __devinitconst + /** * PCI_DEVICE - macro used to describe a specific pci device * @vend: the 16 bit PCI Vendor ID @@ -1034,6 +1045,8 @@ void __iomem *pcim_iomap(struct pci_dev *pdev, int bar, unsigned long maxlen); void pcim_iounmap(struct pci_dev *pdev, void __iomem *addr); void __iomem * const *pcim_iomap_table(struct pci_dev *pdev); int pcim_iomap_regions(struct pci_dev *pdev, u16 mask, const char *name); +int pcim_iomap_regions_request_all(struct pci_dev *pdev, u16 mask, + const char *name); void pcim_iounmap_regions(struct pci_dev *pdev, u16 mask); extern int pci_pci_problems; diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index effdb558a5884972583df53a881ccf8c99e022d8..70eb3c803d47825118844484c60384b523534f41 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -2184,6 +2184,7 @@ #define PCI_DEVICE_ID_JMICRON_JMB366 0x2366 #define PCI_DEVICE_ID_JMICRON_JMB368 0x2368 #define PCI_DEVICE_ID_JMICRON_JMB38X_SD 0x2381 +#define PCI_DEVICE_ID_JMICRON_JMB38X_MS 0x2383 #define PCI_VENDOR_ID_KORENIX 0x1982 #define PCI_DEVICE_ID_KORENIX_JETCARDF0 0x1600 diff --git a/include/linux/pkt_cls.h b/include/linux/pkt_cls.h index 28dfc61cf79e590d18c6ba62cbb8ee66b8101d89..99efbed81fa2ed1b72a3594b4be1a3b3ada4e1b7 100644 --- a/include/linux/pkt_cls.h +++ b/include/linux/pkt_cls.h @@ -201,8 +201,8 @@ enum struct tc_u32_key { - __u32 mask; - __u32 val; + __be32 mask; + __be32 val; int off; int offmask; }; @@ -213,12 +213,12 @@ struct tc_u32_sel unsigned char offshift; unsigned char nkeys; - __u16 offmask; + __be16 offmask; __u16 off; short offoff; short hoff; - __u32 hmask; + __be32 hmask; struct tc_u32_key keys[0]; }; diff --git a/include/linux/pmu.h b/include/linux/pmu.h index 4c5f65392d36e832be841716eee2ebd752723f59..cafe98d969480dff52bd1e32887319f771627a3b 100644 --- a/include/linux/pmu.h +++ b/include/linux/pmu.h @@ -147,8 +147,15 @@ extern void pmu_wait_complete(struct adb_request *req); /* For use before switching interrupts off for a long time; * warning: not stackable */ +#if defined(CONFIG_ADB_PMU) extern void pmu_suspend(void); extern void pmu_resume(void); +#else +static inline void pmu_suspend(void) +{} +static inline void pmu_resume(void) +{} +#endif extern void pmu_enable_irled(int on); @@ -192,7 +199,7 @@ extern unsigned int pmu_power_flags; extern void pmu_backlight_init(void); /* some code needs to know if the PMU was suspended for hibernation */ -#if defined(CONFIG_PM_SLEEP) && defined(CONFIG_PPC32) +#if defined(CONFIG_SUSPEND) && defined(CONFIG_PPC32) extern int pmu_sys_suspended; #else /* if power management is not configured it can't be suspended */ diff --git a/include/linux/proc_fs.h b/include/linux/proc_fs.h index d9a9e718ad19f84395ee9736c04ddedbd7e4acb0..9b6c935f69cf6d1986677b968bb17c2ca000e4b0 100644 --- a/include/linux/proc_fs.h +++ b/include/linux/proc_fs.h @@ -50,8 +50,6 @@ typedef int (read_proc_t)(char *page, char **start, off_t off, typedef int (write_proc_t)(struct file *file, const char __user *buffer, unsigned long count, void *data); typedef int (get_info_t)(char *, char **, off_t, int); -typedef struct proc_dir_entry *(shadow_proc_t)(struct task_struct *task, - struct proc_dir_entry *pde); struct proc_dir_entry { unsigned int low_ino; @@ -82,7 +80,6 @@ struct proc_dir_entry { int pde_users; /* number of callers into module in progress */ spinlock_t pde_unload_lock; /* proc_fops checks and pde_users bumps */ struct completion *pde_unload_completion; - shadow_proc_t *shadow_proc; }; struct kcore_list { diff --git a/include/linux/raid/bitmap.h b/include/linux/raid/bitmap.h index e51b531cd0b2d970631bc6097019869b74c55830..47fbcba118506c04f628e7a0337067f9ea94fa86 100644 --- a/include/linux/raid/bitmap.h +++ b/include/linux/raid/bitmap.h @@ -235,6 +235,8 @@ struct bitmap { unsigned long flags; + int allclean; + unsigned long max_write_behind; /* write-behind mode */ atomic_t behind_writes; diff --git a/include/linux/raid/md_k.h b/include/linux/raid/md_k.h index 85a068bab625a85d9a62e34859eed5e580a31b16..7bb6d1abf71e85944bc20e82243cc88df8353e71 100644 --- a/include/linux/raid/md_k.h +++ b/include/linux/raid/md_k.h @@ -83,6 +83,7 @@ struct mdk_rdev_s #define BarriersNotsupp 5 /* BIO_RW_BARRIER is not supported */ #define AllReserved 6 /* If whole device is reserved for * one array */ +#define AutoDetected 7 /* added by auto-detect */ int desc_nr; /* descriptor index in the superblock */ int raid_disk; /* role of device in array */ diff --git a/include/linux/rcuclassic.h b/include/linux/rcuclassic.h index 4d6624260b4c241e7f6299ea6396642e26b400ca..b3dccd68629e1c0481dd41471798ec25884fafd8 100644 --- a/include/linux/rcuclassic.h +++ b/include/linux/rcuclassic.h @@ -160,5 +160,8 @@ extern void rcu_restart_cpu(int cpu); extern long rcu_batches_completed(void); extern long rcu_batches_completed_bh(void); +#define rcu_enter_nohz() do { } while (0) +#define rcu_exit_nohz() do { } while (0) + #endif /* __KERNEL__ */ #endif /* __LINUX_RCUCLASSIC_H */ diff --git a/include/linux/rcupreempt.h b/include/linux/rcupreempt.h index 60c2a033b19e0fa7333b29d591a5f00d497a838a..01152ed532c8025decbf57fbf6859273a2e3994d 100644 --- a/include/linux/rcupreempt.h +++ b/include/linux/rcupreempt.h @@ -82,5 +82,27 @@ extern struct rcupreempt_trace *rcupreempt_trace_cpu(int cpu); struct softirq_action; +#ifdef CONFIG_NO_HZ +DECLARE_PER_CPU(long, dynticks_progress_counter); + +static inline void rcu_enter_nohz(void) +{ + __get_cpu_var(dynticks_progress_counter)++; + WARN_ON(__get_cpu_var(dynticks_progress_counter) & 0x1); + mb(); +} + +static inline void rcu_exit_nohz(void) +{ + mb(); + __get_cpu_var(dynticks_progress_counter)++; + WARN_ON(!(__get_cpu_var(dynticks_progress_counter) & 0x1)); +} + +#else /* CONFIG_NO_HZ */ +#define rcu_enter_nohz() do { } while (0) +#define rcu_exit_nohz() do { } while (0) +#endif /* CONFIG_NO_HZ */ + #endif /* __KERNEL__ */ #endif /* __LINUX_RCUPREEMPT_H */ diff --git a/include/linux/sched.h b/include/linux/sched.h index e217d188a102bec8b15693f6a871945f823431be..11d8e9a74effd57af24a7f8143b093da6d34f486 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -242,6 +242,7 @@ struct task_struct; extern void sched_init(void); extern void sched_init_smp(void); +extern asmlinkage void schedule_tail(struct task_struct *prev); extern void init_idle(struct task_struct *idle, int cpu); extern void init_idle_bootup_task(struct task_struct *idle); @@ -898,6 +899,10 @@ struct sched_class { int running); void (*prio_changed) (struct rq *this_rq, struct task_struct *task, int oldprio, int running); + +#ifdef CONFIG_FAIR_GROUP_SCHED + void (*moved_group) (struct task_struct *p); +#endif }; struct load_weight { @@ -1189,7 +1194,7 @@ struct task_struct { int softirq_context; #endif #ifdef CONFIG_LOCKDEP -# define MAX_LOCK_DEPTH 30UL +# define MAX_LOCK_DEPTH 48UL u64 curr_chain_key; int lockdep_depth; struct held_lock held_locks[MAX_LOCK_DEPTH]; @@ -1541,10 +1546,6 @@ extern unsigned int sysctl_sched_child_runs_first; extern unsigned int sysctl_sched_features; extern unsigned int sysctl_sched_migration_cost; extern unsigned int sysctl_sched_nr_migrate; -#if defined(CONFIG_FAIR_GROUP_SCHED) && defined(CONFIG_SMP) -extern unsigned int sysctl_sched_min_bal_int_shares; -extern unsigned int sysctl_sched_max_bal_int_shares; -#endif int sched_nr_latency_handler(struct ctl_table *table, int write, struct file *file, void __user *buffer, size_t *length, diff --git a/include/linux/security.h b/include/linux/security.h index fe52cdeab0a67ba5cd1220383b9bd0872efd78e1..b07357ca2137c6b6b5c3bb031336e84941f6c1a8 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -34,12 +34,6 @@ #include #include -/* only a char in selinux superblock security struct flags */ -#define FSCONTEXT_MNT 0x01 -#define CONTEXT_MNT 0x02 -#define ROOTCONTEXT_MNT 0x04 -#define DEFCONTEXT_MNT 0x08 - extern unsigned securebits; struct ctl_table; @@ -114,6 +108,32 @@ struct request_sock; #ifdef CONFIG_SECURITY +struct security_mnt_opts { + char **mnt_opts; + int *mnt_opts_flags; + int num_mnt_opts; +}; + +static inline void security_init_mnt_opts(struct security_mnt_opts *opts) +{ + opts->mnt_opts = NULL; + opts->mnt_opts_flags = NULL; + opts->num_mnt_opts = 0; +} + +static inline void security_free_mnt_opts(struct security_mnt_opts *opts) +{ + int i; + if (opts->mnt_opts) + for(i = 0; i < opts->num_mnt_opts; i++) + kfree(opts->mnt_opts[i]); + kfree(opts->mnt_opts); + opts->mnt_opts = NULL; + kfree(opts->mnt_opts_flags); + opts->mnt_opts_flags = NULL; + opts->num_mnt_opts = 0; +} + /** * struct security_operations - main security structure * @@ -262,19 +282,19 @@ struct request_sock; * @sb_get_mnt_opts: * Get the security relevant mount options used for a superblock * @sb the superblock to get security mount options from - * @mount_options array for pointers to mount options - * @mount_flags array of ints specifying what each mount options is - * @num_opts number of options in the arrays + * @opts binary data structure containing all lsm mount data * @sb_set_mnt_opts: * Set the security relevant mount options used for a superblock * @sb the superblock to set security mount options for - * @mount_options array for pointers to mount options - * @mount_flags array of ints specifying what each mount options is - * @num_opts number of options in the arrays + * @opts binary data structure containing all lsm mount data * @sb_clone_mnt_opts: * Copy all security options from a given superblock to another * @oldsb old superblock which contain information to clone * @newsb new superblock which needs filled in + * @sb_parse_opts_str: + * Parse a string of security data filling in the opts structure + * @options string containing all mount options known by the LSM + * @opts binary data structure usable by the LSM * * Security hooks for inode operations. * @@ -1238,8 +1258,7 @@ struct security_operations { int (*sb_alloc_security) (struct super_block * sb); void (*sb_free_security) (struct super_block * sb); - int (*sb_copy_data)(struct file_system_type *type, - void *orig, void *copy); + int (*sb_copy_data)(char *orig, char *copy); int (*sb_kern_mount) (struct super_block *sb, void *data); int (*sb_statfs) (struct dentry *dentry); int (*sb_mount) (char *dev_name, struct nameidata * nd, @@ -1257,12 +1276,12 @@ struct security_operations { void (*sb_post_pivotroot) (struct nameidata * old_nd, struct nameidata * new_nd); int (*sb_get_mnt_opts) (const struct super_block *sb, - char ***mount_options, int **flags, - int *num_opts); - int (*sb_set_mnt_opts) (struct super_block *sb, char **mount_options, - int *flags, int num_opts); + struct security_mnt_opts *opts); + int (*sb_set_mnt_opts) (struct super_block *sb, + struct security_mnt_opts *opts); void (*sb_clone_mnt_opts) (const struct super_block *oldsb, struct super_block *newsb); + int (*sb_parse_opts_str) (char *options, struct security_mnt_opts *opts); int (*inode_alloc_security) (struct inode *inode); void (*inode_free_security) (struct inode *inode); @@ -1507,7 +1526,7 @@ int security_bprm_check(struct linux_binprm *bprm); int security_bprm_secureexec(struct linux_binprm *bprm); int security_sb_alloc(struct super_block *sb); void security_sb_free(struct super_block *sb); -int security_sb_copy_data(struct file_system_type *type, void *orig, void *copy); +int security_sb_copy_data(char *orig, char *copy); int security_sb_kern_mount(struct super_block *sb, void *data); int security_sb_statfs(struct dentry *dentry); int security_sb_mount(char *dev_name, struct nameidata *nd, @@ -1520,12 +1539,12 @@ void security_sb_post_remount(struct vfsmount *mnt, unsigned long flags, void *d void security_sb_post_addmount(struct vfsmount *mnt, struct nameidata *mountpoint_nd); int security_sb_pivotroot(struct nameidata *old_nd, struct nameidata *new_nd); void security_sb_post_pivotroot(struct nameidata *old_nd, struct nameidata *new_nd); -int security_sb_get_mnt_opts(const struct super_block *sb, char ***mount_options, - int **flags, int *num_opts); -int security_sb_set_mnt_opts(struct super_block *sb, char **mount_options, - int *flags, int num_opts); +int security_sb_get_mnt_opts(const struct super_block *sb, + struct security_mnt_opts *opts); +int security_sb_set_mnt_opts(struct super_block *sb, struct security_mnt_opts *opts); void security_sb_clone_mnt_opts(const struct super_block *oldsb, struct super_block *newsb); +int security_sb_parse_opts_str(char *options, struct security_mnt_opts *opts); int security_inode_alloc(struct inode *inode); void security_inode_free(struct inode *inode); @@ -1635,6 +1654,16 @@ int security_secctx_to_secid(char *secdata, u32 seclen, u32 *secid); void security_release_secctx(char *secdata, u32 seclen); #else /* CONFIG_SECURITY */ +struct security_mnt_opts { +}; + +static inline void security_init_mnt_opts(struct security_mnt_opts *opts) +{ +} + +static inline void security_free_mnt_opts(struct security_mnt_opts *opts) +{ +} /* * This is the default capabilities functionality. Most of these functions @@ -1762,8 +1791,7 @@ static inline int security_sb_alloc (struct super_block *sb) static inline void security_sb_free (struct super_block *sb) { } -static inline int security_sb_copy_data (struct file_system_type *type, - void *orig, void *copy) +static inline int security_sb_copy_data (char *orig, char *copy) { return 0; } @@ -1819,6 +1847,27 @@ static inline int security_sb_pivotroot (struct nameidata *old_nd, static inline void security_sb_post_pivotroot (struct nameidata *old_nd, struct nameidata *new_nd) { } +static inline int security_sb_get_mnt_opts(const struct super_block *sb, + struct security_mnt_opts *opts) +{ + security_init_mnt_opts(opts); + return 0; +} + +static inline int security_sb_set_mnt_opts(struct super_block *sb, + struct security_mnt_opts *opts) +{ + return 0; +} + +static inline void security_sb_clone_mnt_opts(const struct super_block *oldsb, + struct super_block *newsb) +{ } + +static inline int security_sb_parse_opts_str(char *options, struct security_mnt_opts *opts) +{ + return 0; +} static inline int security_inode_alloc (struct inode *inode) { diff --git a/include/asm-sh/sci.h b/include/linux/serial_sci.h similarity index 73% rename from include/asm-sh/sci.h rename to include/linux/serial_sci.h index 52e73660c1298ed6f2378cb84ade382c0903fb8b..893cc53486bc676a99ed2712fd220c66623f0814 100644 --- a/include/asm-sh/sci.h +++ b/include/linux/serial_sci.h @@ -1,12 +1,10 @@ -#ifndef __ASM_SH_SCI_H -#define __ASM_SH_SCI_H +#ifndef __LINUX_SERIAL_SCI_H +#define __LINUX_SERIAL_SCI_H #include /* - * Generic header for SuperH SCI(F) - * - * Do not place SH-specific parts in here, sh64 and h8300 depend on this too. + * Generic header for SuperH SCI(F) (used by sh/sh64/h8300 and related parts) */ /* Offsets into the sci_port->irqs array */ @@ -31,4 +29,4 @@ struct plat_sci_port { int early_sci_setup(struct uart_port *port); -#endif /* __ASM_SH_SCI_H */ +#endif /* __LINUX_SERIAL_SCI_H */ diff --git a/include/linux/slab_def.h b/include/linux/slab_def.h index fcc48096ee6406be0200c19ea7d6b1a64609dda5..39c3a5eb8ebe677851fedd8c8ff6a70730d17c0b 100644 --- a/include/linux/slab_def.h +++ b/include/linux/slab_def.h @@ -41,7 +41,7 @@ static inline void *kmalloc(size_t size, gfp_t flags) goto found; \ else \ i++; -#include "kmalloc_sizes.h" +#include #undef CACHE { extern void __you_cannot_kmalloc_that_much(void); @@ -75,7 +75,7 @@ static inline void *kmalloc_node(size_t size, gfp_t flags, int node) goto found; \ else \ i++; -#include "kmalloc_sizes.h" +#include #undef CACHE { extern void __you_cannot_kmalloc_that_much(void); diff --git a/include/linux/slub_def.h b/include/linux/slub_def.h index 57deecc79d52787800aa98b72d0cefe9e556e495..b00c1c73eb0a7a3108f2fcc76d4c6fd4ee54fbb8 100644 --- a/include/linux/slub_def.h +++ b/include/linux/slub_def.h @@ -61,7 +61,7 @@ struct kmem_cache { int size; /* The size of an object including meta data */ int objsize; /* The size of an object without meta data */ int offset; /* Free pointer offset. */ - int order; + int order; /* Current preferred allocation order */ /* * Avoid an extra cache line for UP, SMP and for the node local to @@ -138,11 +138,11 @@ static __always_inline int kmalloc_index(size_t size) if (size <= 512) return 9; if (size <= 1024) return 10; if (size <= 2 * 1024) return 11; + if (size <= 4 * 1024) return 12; /* * The following is only needed to support architectures with a larger page * size than 4k. */ - if (size <= 4 * 1024) return 12; if (size <= 8 * 1024) return 13; if (size <= 16 * 1024) return 14; if (size <= 32 * 1024) return 15; diff --git a/include/linux/sm501-regs.h b/include/linux/sm501-regs.h index 64236b73c724e2bb4a8b357d8f8c50539377a9ca..d53642d2d8992d33e234d4f24f7dbe366d86cab7 100644 --- a/include/linux/sm501-regs.h +++ b/include/linux/sm501-regs.h @@ -129,11 +129,14 @@ #define SM501_DEVICEID_SM501 (0x05010000) #define SM501_DEVICEID_IDMASK (0xffff0000) +#define SM501_DEVICEID_REVMASK (0x000000ff) #define SM501_PLLCLOCK_COUNT (0x000064) #define SM501_MISC_TIMING (0x000068) #define SM501_CURRENT_SDRAM_CLOCK (0x00006C) +#define SM501_PROGRAMMABLE_PLL_CONTROL (0x000074) + /* GPIO base */ #define SM501_GPIO (0x010000) #define SM501_GPIO_DATA_LOW (0x00) diff --git a/include/linux/sm501.h b/include/linux/sm501.h index 932a9efee8a5c7c9508b6c6a4f1caf565069825e..bca13454470025684a946cc63a59026dced33967 100644 --- a/include/linux/sm501.h +++ b/include/linux/sm501.h @@ -24,7 +24,8 @@ extern int sm501_unit_power(struct device *dev, extern unsigned long sm501_set_clock(struct device *dev, int clksrc, unsigned long freq); -extern unsigned long sm501_find_clock(int clksrc, unsigned long req_freq); +extern unsigned long sm501_find_clock(struct device *dev, + int clksrc, unsigned long req_freq); /* sm501_misc_control * diff --git a/include/linux/tifm.h b/include/linux/tifm.h index da76ed85f5958fb941cbb837a7f824b0981fd575..848c0f3925419a7743e5bc998d02a8893f91d36d 100644 --- a/include/linux/tifm.h +++ b/include/linux/tifm.h @@ -70,9 +70,9 @@ enum { #define TIFM_FIFO_ENABLE 0x00000001 #define TIFM_FIFO_READY 0x00000001 +#define TIFM_FIFO_MORE 0x00000008 #define TIFM_FIFO_INT_SETALL 0x0000ffff #define TIFM_FIFO_INTMASK 0x00000005 -#define TIFM_FIFO_SIZE 0x00000200 #define TIFM_DMA_RESET 0x00000002 #define TIFM_DMA_TX 0x00008000 diff --git a/include/linux/time.h b/include/linux/time.h index 2091a19f1655aab8e5130256f83af4103efa9e3f..d32ef0ad4c0aaf8964d94abe215c5dbf4dde8aaf 100644 --- a/include/linux/time.h +++ b/include/linux/time.h @@ -174,6 +174,10 @@ static inline void timespec_add_ns(struct timespec *a, u64 ns) { ns += a->tv_nsec; while(unlikely(ns >= NSEC_PER_SEC)) { + /* The following asm() prevents the compiler from + * optimising this loop into a modulo operation. */ + asm("" : "+r"(ns)); + ns -= NSEC_PER_SEC; a->tv_sec++; } diff --git a/include/linux/timex.h b/include/linux/timex.h index c3f374786a4358e59eb6ce72e3b436e6a2556449..8ea3e71ba7fa8ff17d8de5587f482450c349ef36 100644 --- a/include/linux/timex.h +++ b/include/linux/timex.h @@ -232,14 +232,7 @@ static inline int ntp_synced(void) #else #define NTP_INTERVAL_FREQ (HZ) #endif - -#define CLOCK_TICK_OVERFLOW (LATCH * HZ - CLOCK_TICK_RATE) -#define CLOCK_TICK_ADJUST (((s64)CLOCK_TICK_OVERFLOW * NSEC_PER_SEC) / \ - (s64)CLOCK_TICK_RATE) - -/* Because using NSEC_PER_SEC would be too easy */ -#define NTP_INTERVAL_LENGTH ((((s64)TICK_USEC * NSEC_PER_USEC * USER_HZ) + \ - CLOCK_TICK_ADJUST) / NTP_INTERVAL_FREQ) +#define NTP_INTERVAL_LENGTH (NSEC_PER_SEC/NTP_INTERVAL_FREQ) /* Returns how long ticks are at present, in ns / 2^(SHIFT_SCALE-10). */ extern u64 current_tick_length(void); diff --git a/include/linux/usb.h b/include/linux/usb.h index 2372e2e6b5271addb820c2c30f0f2549fe340134..583e0481dfa028cfe137156d74dd342dc5a03f9c 100644 --- a/include/linux/usb.h +++ b/include/linux/usb.h @@ -94,10 +94,9 @@ enum usb_interface_condition { * @altsetting: array of interface structures, one for each alternate * setting that may be selected. Each one includes a set of * endpoint configurations. They will be in no particular order. - * @num_altsetting: number of altsettings defined. * @cur_altsetting: the current altsetting. + * @num_altsetting: number of altsettings defined. * @intf_assoc: interface association descriptor - * @driver: the USB driver that is bound to this interface. * @minor: the minor number assigned to this interface, if this * interface is bound to a driver that uses the USB major number. * If this interface does not use the USB major, this field should @@ -781,8 +780,7 @@ static inline int usb_endpoint_is_isoc_out( .idVendor = (vend), \ .idProduct = (prod) /** - * USB_DEVICE_VER - macro used to describe a specific usb device with a - * version range + * USB_DEVICE_VER - describe a specific usb device with a version range * @vend: the 16 bit USB Vendor ID * @prod: the 16 bit USB Product ID * @lo: the bcdDevice_lo value @@ -799,8 +797,7 @@ static inline int usb_endpoint_is_isoc_out( .bcdDevice_hi = (hi) /** - * USB_DEVICE_INTERFACE_PROTOCOL - macro used to describe a usb - * device with a specific interface protocol + * USB_DEVICE_INTERFACE_PROTOCOL - describe a usb device with a specific interface protocol * @vend: the 16 bit USB Vendor ID * @prod: the 16 bit USB Product ID * @pr: bInterfaceProtocol value @@ -846,8 +843,7 @@ static inline int usb_endpoint_is_isoc_out( .bInterfaceProtocol = (pr) /** - * USB_DEVICE_AND_INTERFACE_INFO - macro used to describe a specific usb device - * with a class of usb interfaces + * USB_DEVICE_AND_INTERFACE_INFO - describe a specific usb device with a class of usb interfaces * @vend: the 16 bit USB Vendor ID * @prod: the 16 bit USB Product ID * @cl: bInterfaceClass value diff --git a/include/linux/usb/Kbuild b/include/linux/usb/Kbuild index b8cba1dcb2c63008a60f17926c40b3a5b728cc9c..42e84fc315e30f3a71396c29bc52375744fa49c7 100644 --- a/include/linux/usb/Kbuild +++ b/include/linux/usb/Kbuild @@ -3,5 +3,5 @@ header-y += cdc.h header-y += ch9.h header-y += gadgetfs.h header-y += midi.h -unifdef-y += g_printer.h +header-y += g_printer.h diff --git a/include/linux/usb/gadget.h b/include/linux/usb/gadget.h index aa3047ff00d13076e8ce29bd805b6a214b931945..f3295296b4353a5305ca3ee947d80b7ac3e0932b 100644 --- a/include/linux/usb/gadget.h +++ b/include/linux/usb/gadget.h @@ -15,8 +15,6 @@ #ifndef __LINUX_USB_GADGET_H #define __LINUX_USB_GADGET_H -#ifdef __KERNEL__ - struct usb_ep; /** @@ -848,6 +846,4 @@ extern struct usb_ep *usb_ep_autoconfig(struct usb_gadget *, extern void usb_ep_autoconfig_reset(struct usb_gadget *) __devinit; -#endif /* __KERNEL__ */ - #endif /* __LINUX_USB_GADGET_H */ diff --git a/include/linux/virtio.h b/include/linux/virtio.h index 260d1fcf29a4222c011ab39176b1e2e4d46a98a3..12c18ac1b973caf7fc33f44db0ee7fa759fc361f 100644 --- a/include/linux/virtio.h +++ b/include/linux/virtio.h @@ -43,8 +43,9 @@ struct virtqueue * vq: the struct virtqueue we're talking about. * @enable_cb: restart callbacks after disable_cb. * vq: the struct virtqueue we're talking about. - * This returns "false" (and doesn't re-enable) if there are pending - * buffers in the queue, to avoid a race. + * This re-enables callbacks; it returns "false" if there are pending + * buffers in the queue, to detect a possible race between the driver + * checking for more work, and enabling callbacks. * * Locking rules are straightforward: the driver is responsible for * locking. No two operations may be invoked simultaneously. diff --git a/include/linux/vmstat.h b/include/linux/vmstat.h index 75370ec0923e40760e5616c9864e34e272703832..9f1b4b46151ebbebe40413a3368c18afa850704c 100644 --- a/include/linux/vmstat.h +++ b/include/linux/vmstat.h @@ -246,8 +246,7 @@ static inline void __dec_zone_state(struct zone *zone, enum zone_stat_item item) static inline void __dec_zone_page_state(struct page *page, enum zone_stat_item item) { - atomic_long_dec(&page_zone(page)->vm_stat[item]); - atomic_long_dec(&vm_stat[item]); + __dec_zone_state(page_zone(page), item); } /* diff --git a/include/net/bluetooth/bluetooth.h b/include/net/bluetooth/bluetooth.h index 771d17783c1889d7d89d7875bdfb28a350e9d4e7..750648df13f4785cee631985648966a602daf58b 100644 --- a/include/net/bluetooth/bluetooth.h +++ b/include/net/bluetooth/bluetooth.h @@ -170,7 +170,7 @@ static inline int skb_frags_no(struct sk_buff *skb) int bt_err(__u16 code); extern int hci_sock_init(void); -extern int hci_sock_cleanup(void); +extern void hci_sock_cleanup(void); extern int bt_sysfs_init(void); extern void bt_sysfs_cleanup(void); diff --git a/include/net/dst.h b/include/net/dst.h index e3ac7d0fc4e1807e62d1246b74aefa5d9ae9f23a..ae13370e8484528a8501b0dbf4a8091ff5dd7e95 100644 --- a/include/net/dst.h +++ b/include/net/dst.h @@ -52,15 +52,10 @@ struct dst_entry unsigned short header_len; /* more space at head required */ unsigned short trailer_len; /* space to reserve at tail */ - u32 metrics[RTAX_MAX]; - struct dst_entry *path; - - unsigned long rate_last; /* rate limiting for ICMP */ unsigned int rate_tokens; + unsigned long rate_last; /* rate limiting for ICMP */ -#ifdef CONFIG_NET_CLS_ROUTE - __u32 tclassid; -#endif + struct dst_entry *path; struct neighbour *neighbour; struct hh_cache *hh; @@ -70,10 +65,20 @@ struct dst_entry int (*output)(struct sk_buff*); struct dst_ops *ops; - - unsigned long lastuse; + + u32 metrics[RTAX_MAX]; + +#ifdef CONFIG_NET_CLS_ROUTE + __u32 tclassid; +#endif + + /* + * __refcnt wants to be on a different cache line from + * input/output/ops or performance tanks badly + */ atomic_t __refcnt; /* client references */ int __use; + unsigned long lastuse; union { struct dst_entry *next; struct rtable *rt_next; diff --git a/include/net/irda/irttp.h b/include/net/irda/irttp.h index 32c385dd9e06a94ab6cf77988537d02cc47835ad..0788c23d2828e222408050e7a2c84342d6a984cc 100644 --- a/include/net/irda/irttp.h +++ b/include/net/irda/irttp.h @@ -169,17 +169,17 @@ int irttp_disconnect_request(struct tsap_cb *self, struct sk_buff *skb, void irttp_flow_request(struct tsap_cb *self, LOCAL_FLOW flow); struct tsap_cb *irttp_dup(struct tsap_cb *self, void *instance); -static __inline __u32 irttp_get_saddr(struct tsap_cb *self) +static inline __u32 irttp_get_saddr(struct tsap_cb *self) { return irlmp_get_saddr(self->lsap); } -static __inline __u32 irttp_get_daddr(struct tsap_cb *self) +static inline __u32 irttp_get_daddr(struct tsap_cb *self) { return irlmp_get_daddr(self->lsap); } -static __inline __u32 irttp_get_max_seg_size(struct tsap_cb *self) +static inline __u32 irttp_get_max_seg_size(struct tsap_cb *self) { return self->max_seg_size; } diff --git a/include/net/net_namespace.h b/include/net/net_namespace.h index 28738b7d53eb2a0748cecad1076a9726da8d936f..923f2b8b909600b3962035f714308ddc5e8acf9d 100644 --- a/include/net/net_namespace.h +++ b/include/net/net_namespace.h @@ -31,7 +31,6 @@ struct net { struct proc_dir_entry *proc_net; struct proc_dir_entry *proc_net_stat; - struct proc_dir_entry *proc_net_root; struct list_head sysctl_table_headers; diff --git a/include/net/netfilter/nf_conntrack_extend.h b/include/net/netfilter/nf_conntrack_extend.h index 49aac6323fbeaf7c4dacbb16c8194d91246977bf..f736e842977f07ce8469bf832fcf2905af36ded1 100644 --- a/include/net/netfilter/nf_conntrack_extend.h +++ b/include/net/netfilter/nf_conntrack_extend.h @@ -17,7 +17,6 @@ enum nf_ct_ext_id struct nf_ct_ext { u8 offset[NF_CT_EXT_NUM]; u8 len; - u8 real_len; char data[0]; }; diff --git a/include/net/xfrm.h b/include/net/xfrm.h index 9b6205665190c6a050265ec26d7f2321804d83d0..c435620dbb377c0807497a206c7e923b86b1560c 100644 --- a/include/net/xfrm.h +++ b/include/net/xfrm.h @@ -278,7 +278,7 @@ extern int __xfrm_state_delete(struct xfrm_state *x); struct xfrm_state_afinfo { unsigned int family; unsigned int proto; - unsigned int eth_proto; + __be16 eth_proto; struct module *owner; const struct xfrm_type *type_map[IPPROTO_MAX]; struct xfrm_mode *mode_map[XFRM_MODE_MAX]; diff --git a/include/scsi/libsas.h b/include/scsi/libsas.h index 3ffd6b582a97144cb37009ef6ef47d1ff4cd8feb..39e1cac24bb751503fdef353a764292326b32037 100644 --- a/include/scsi/libsas.h +++ b/include/scsi/libsas.h @@ -675,5 +675,6 @@ extern int sas_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy, extern void sas_ssp_task_response(struct device *dev, struct sas_task *task, struct ssp_response_iu *iu); +struct sas_phy *sas_find_local_phy(struct domain_device *dev); #endif /* _SASLIB_H_ */ diff --git a/include/scsi/scsi_transport_iscsi.h b/include/scsi/scsi_transport_iscsi.h index dbc96ef4cc72020b827e6e04e4dfe0d125091e38..aab1eae2ec4c4a6d310ab79cc214d6e627ec79ea 100644 --- a/include/scsi/scsi_transport_iscsi.h +++ b/include/scsi/scsi_transport_iscsi.h @@ -177,6 +177,8 @@ struct iscsi_cls_session { struct list_head host_list; struct iscsi_transport *transport; spinlock_t lock; + struct work_struct block_work; + struct work_struct unblock_work; struct work_struct scan_work; struct work_struct unbind_work; diff --git a/init/Kconfig b/init/Kconfig index f698a5af500791ae7158457f16c9f00df503cbbb..a97924bc5b8dcfa87079ee2f9f70ce9988d4bf40 100644 --- a/init/Kconfig +++ b/init/Kconfig @@ -366,10 +366,29 @@ config RESOURCE_COUNTERS infrastructure that works with cgroups depends on CGROUPS +config CGROUP_MEM_RES_CTLR + bool "Memory Resource Controller for Control Groups" + depends on CGROUPS && RESOURCE_COUNTERS + help + Provides a memory resource controller that manages both page cache and + RSS memory. + + Note that setting this option increases fixed memory overhead + associated with each page of memory in the system by 4/8 bytes + and also increases cache misses because struct page on many 64bit + systems will not fit into a single cache line anymore. + + Only enable when you're ok with these trade offs and really + sure you need the memory resource controller. + config SYSFS_DEPRECATED + bool + +config SYSFS_DEPRECATED_V2 bool "Create deprecated sysfs files" depends on SYSFS default y + select SYSFS_DEPRECATED help This option creates deprecated symlinks such as the "device"-link, the :-link, and the @@ -382,25 +401,11 @@ config SYSFS_DEPRECATED If enabled, this option will also move any device structures that belong to a class, back into the /sys/class hierarchy, in - order to support older versions of udev. - - If you are using a distro that was released in 2006 or later, - it should be safe to say N here. - -config CGROUP_MEM_CONT - bool "Memory controller for cgroups" - depends on CGROUPS && RESOURCE_COUNTERS - help - Provides a memory controller that manages both page cache and - RSS memory. + order to support older versions of udev and some userspace + programs. - Note that setting this option increases fixed memory overhead - associated with each page of memory in the system by 4/8 bytes - and also increases cache misses because struct page on many 64bit - systems will not fit into a single cache line anymore. - - Only enable when you're ok with these trade offs and really - sure you need the memory controller. + If you are using a distro with the most recent userspace + packages, it should be safe to say N here. config PROC_PID_CPUSET bool "Include legacy /proc//cpuset file" @@ -860,38 +865,10 @@ source "block/Kconfig" config PREEMPT_NOTIFIERS bool -choice - prompt "RCU implementation type:" - default CLASSIC_RCU - help - This allows you to choose either the classic RCU implementation - that is designed for best read-side performance on non-realtime - systems, or the preemptible RCU implementation for best latency - on realtime systems. Note that some kernel preemption modes - will restrict your choice. - - Select the default if you are unsure. - config CLASSIC_RCU - bool "Classic RCU" + def_bool !PREEMPT_RCU help This option selects the classic RCU implementation that is designed for best read-side performance on non-realtime - systems. - - Say Y if you are unsure. - -config PREEMPT_RCU - bool "Preemptible RCU" - depends on PREEMPT - help - This option reduces the latency of the kernel by making certain - RCU sections preemptible. Normally RCU code is non-preemptible, if - this option is selected then read-only RCU sections become - preemptible. This helps latency, but may expose bugs due to - now-naive assumptions about each RCU read-side critical section - remaining on a given CPU through its execution. - - Say N if you are unsure. - -endchoice + systems. Classic RCU is the default. Note that the + PREEMPT_RCU symbol is used to select/deselect this option. diff --git a/init/initramfs.c b/init/initramfs.c index c0b1e0533d80d32080c8d44acf2ab9f9d90bcbb7..d53fee8d8604a5514889bfcd93acee4dd882fae0 100644 --- a/init/initramfs.c +++ b/init/initramfs.c @@ -538,7 +538,7 @@ skip: initrd_end = 0; } -int __init populate_rootfs(void) +static int __init populate_rootfs(void) { char *err = unpack_to_rootfs(__initramfs_start, __initramfs_end - __initramfs_start, 0); @@ -577,10 +577,4 @@ int __init populate_rootfs(void) } return 0; } -#ifndef CONFIG_ACPI_CUSTOM_DSDT_INITRD -/* - * if this option is enabled, populate_rootfs() is called _earlier_ in the - * boot sequence. This insures that the ACPI initialisation can find the file. - */ rootfs_initcall(populate_rootfs); -#endif diff --git a/init/main.c b/init/main.c index 8b1982082ad8ada65bbd1ff4a1c565c2a77feba6..99ce94930b09302f7af89f75c07d7daa6a7ef668 100644 --- a/init/main.c +++ b/init/main.c @@ -102,12 +102,6 @@ static inline void mark_rodata_ro(void) { } extern void tc_init(void); #endif -#ifdef CONFIG_ACPI_CUSTOM_DSDT_INITRD -extern int populate_rootfs(void); -#else -static inline void populate_rootfs(void) {} -#endif - enum system_states system_state; EXPORT_SYMBOL(system_state); @@ -254,7 +248,7 @@ early_param("quiet", quiet_kernel); static int __init loglevel(char *str) { get_option(&str, &console_loglevel); - return 1; + return 0; } early_param("loglevel", loglevel); @@ -650,7 +644,6 @@ asmlinkage void __init start_kernel(void) check_bugs(); - populate_rootfs(); /* For DSDT override from initramfs */ acpi_early_init(); /* before LAPIC and SMP init */ /* Do the rest non-__init'ed, we're now alive */ diff --git a/ipc/shm.c b/ipc/shm.c index c47e87278a92d87acf6bdfefbb16ab73186c24b2..cc63fae02f064d298689279a46599a8159b01df1 100644 --- a/ipc/shm.c +++ b/ipc/shm.c @@ -271,9 +271,10 @@ static struct mempolicy *shm_get_policy(struct vm_area_struct *vma, if (sfd->vm_ops->get_policy) pol = sfd->vm_ops->get_policy(vma, addr); - else if (vma->vm_policy) + else if (vma->vm_policy) { pol = vma->vm_policy; - else + mpol_get(pol); /* get_vma_policy() expects this */ + } else pol = current->mempolicy; return pol; } diff --git a/kernel/Kconfig.preempt b/kernel/Kconfig.preempt index 0669b70fa6a3af35c4c67599575a8c2a12154fa4..9fdba03dc1fcd119c31274fb3590480aa1db9f05 100644 --- a/kernel/Kconfig.preempt +++ b/kernel/Kconfig.preempt @@ -52,8 +52,23 @@ config PREEMPT endchoice +config PREEMPT_RCU + bool "Preemptible RCU" + depends on PREEMPT + default n + help + This option reduces the latency of the kernel by making certain + RCU sections preemptible. Normally RCU code is non-preemptible, if + this option is selected then read-only RCU sections become + preemptible. This helps latency, but may expose bugs due to + now-naive assumptions about each RCU read-side critical section + remaining on a given CPU through its execution. + + Say N if you are unsure. + config RCU_TRACE bool "Enable tracing for RCU - currently stats in debugfs" + depends on PREEMPT_RCU select DEBUG_FS default y help diff --git a/kernel/audit.c b/kernel/audit.c index 2eeea9a142408a156f0897a75c81343a5619c07c..10c4930c2bbfbe0e98a5b56ff61a953fd4017367 100644 --- a/kernel/audit.c +++ b/kernel/audit.c @@ -170,7 +170,9 @@ void audit_panic(const char *message) printk(KERN_ERR "audit: %s\n", message); break; case AUDIT_FAIL_PANIC: - panic("audit: %s\n", message); + /* test audit_pid since printk is always losey, why bother? */ + if (audit_pid) + panic("audit: %s\n", message); break; } } @@ -352,6 +354,7 @@ static int kauditd_thread(void *dummy) if (err < 0) { BUG_ON(err != -ECONNREFUSED); /* Shoudn't happen */ printk(KERN_ERR "audit: *NO* daemon at audit_pid=%d\n", audit_pid); + audit_log_lost("auditd dissapeared\n"); audit_pid = 0; } } else { @@ -1350,17 +1353,19 @@ void audit_log_end(struct audit_buffer *ab) if (!audit_rate_check()) { audit_log_lost("rate limit exceeded"); } else { + struct nlmsghdr *nlh = nlmsg_hdr(ab->skb); if (audit_pid) { - struct nlmsghdr *nlh = nlmsg_hdr(ab->skb); nlh->nlmsg_len = ab->skb->len - NLMSG_SPACE(0); skb_queue_tail(&audit_skb_queue, ab->skb); ab->skb = NULL; wake_up_interruptible(&kauditd_wait); - } else if (printk_ratelimit()) { - struct nlmsghdr *nlh = nlmsg_hdr(ab->skb); - printk(KERN_NOTICE "type=%d %s\n", nlh->nlmsg_type, ab->skb->data + NLMSG_SPACE(0)); - } else { - audit_log_lost("printk limit exceeded\n"); + } else if (nlh->nlmsg_type != AUDIT_EOE) { + if (printk_ratelimit()) { + printk(KERN_NOTICE "type=%d %s\n", + nlh->nlmsg_type, + ab->skb->data + NLMSG_SPACE(0)); + } else + audit_log_lost("printk limit exceeded\n"); } } audit_buffer_free(ab); diff --git a/kernel/auditsc.c b/kernel/auditsc.c index 2087d6de67ea4b6ce90b347d0f43a56dbdbad9d3..782262e4107d42822b1a8cf756016ce47720456d 100644 --- a/kernel/auditsc.c +++ b/kernel/auditsc.c @@ -1070,7 +1070,7 @@ static int audit_log_single_execve_arg(struct audit_context *context, * so we can be sure nothing was lost. */ if ((i == 0) && (too_long)) - audit_log_format(*ab, "a%d_len=%ld ", arg_num, + audit_log_format(*ab, "a%d_len=%zu ", arg_num, has_cntl ? 2*len : len); /* diff --git a/kernel/cgroup.c b/kernel/cgroup.c index d8abe996e009702663d9769714f6428f88aac641..e9c2fb01e89bf9e0943c3e7a1230098af3df6243 100644 --- a/kernel/cgroup.c +++ b/kernel/cgroup.c @@ -2232,7 +2232,6 @@ static long cgroup_create(struct cgroup *parent, struct dentry *dentry, mutex_lock(&cgroup_mutex); - cgrp->flags = 0; INIT_LIST_HEAD(&cgrp->sibling); INIT_LIST_HEAD(&cgrp->children); INIT_LIST_HEAD(&cgrp->css_sets); @@ -2242,6 +2241,9 @@ static long cgroup_create(struct cgroup *parent, struct dentry *dentry, cgrp->root = parent->root; cgrp->top_cgroup = parent->top_cgroup; + if (notify_on_release(parent)) + set_bit(CGRP_NOTIFY_ON_RELEASE, &cgrp->flags); + for_each_subsys(root, ss) { struct cgroup_subsys_state *css = ss->create(ss, cgrp); if (IS_ERR(css)) { diff --git a/kernel/cpuset.c b/kernel/cpuset.c index 3e296ed81d4da76aefa913e7deed8f76f2032087..a1b61f414228ea031cc40ea9ea17ab95e264ceaf 100644 --- a/kernel/cpuset.c +++ b/kernel/cpuset.c @@ -322,8 +322,8 @@ static void guarantee_online_mems(const struct cpuset *cs, nodemask_t *pmask) * Call without callback_mutex or task_lock() held. May be * called with or without cgroup_mutex held. Thanks in part to * 'the_top_cpuset_hack', the task's cpuset pointer will never - * be NULL. This routine also might acquire callback_mutex and - * current->mm->mmap_sem during call. + * be NULL. This routine also might acquire callback_mutex during + * call. * * Reading current->cpuset->mems_generation doesn't need task_lock * to guard the current->cpuset derefence, because it is guarded diff --git a/kernel/exit.c b/kernel/exit.c index 506a957b665a69bbf84794e233b8032f2d98b280..53872bf993fa79d46b6e252db4f393c6a3e6828f 100644 --- a/kernel/exit.c +++ b/kernel/exit.c @@ -214,20 +214,19 @@ struct pid *session_of_pgrp(struct pid *pgrp) static int will_become_orphaned_pgrp(struct pid *pgrp, struct task_struct *ignored_task) { struct task_struct *p; - int ret = 1; do_each_pid_task(pgrp, PIDTYPE_PGID, p) { - if (p == ignored_task - || p->exit_state - || is_global_init(p->real_parent)) + if ((p == ignored_task) || + (p->exit_state && thread_group_empty(p)) || + is_global_init(p->real_parent)) continue; + if (task_pgrp(p->real_parent) != pgrp && - task_session(p->real_parent) == task_session(p)) { - ret = 0; - break; - } + task_session(p->real_parent) == task_session(p)) + return 0; } while_each_pid_task(pgrp, PIDTYPE_PGID, p); - return ret; /* (sighing) "Often!" */ + + return 1; } int is_current_pgrp_orphaned(void) @@ -255,6 +254,37 @@ static int has_stopped_jobs(struct pid *pgrp) return retval; } +/* + * Check to see if any process groups have become orphaned as + * a result of our exiting, and if they have any stopped jobs, + * send them a SIGHUP and then a SIGCONT. (POSIX 3.2.2.2) + */ +static void +kill_orphaned_pgrp(struct task_struct *tsk, struct task_struct *parent) +{ + struct pid *pgrp = task_pgrp(tsk); + struct task_struct *ignored_task = tsk; + + if (!parent) + /* exit: our father is in a different pgrp than + * we are and we were the only connection outside. + */ + parent = tsk->real_parent; + else + /* reparent: our child is in a different pgrp than + * we are, and it was the only connection outside. + */ + ignored_task = NULL; + + if (task_pgrp(parent) != pgrp && + task_session(parent) == task_session(tsk) && + will_become_orphaned_pgrp(pgrp, ignored_task) && + has_stopped_jobs(pgrp)) { + __kill_pgrp_info(SIGHUP, SEND_SIG_PRIV, pgrp); + __kill_pgrp_info(SIGCONT, SEND_SIG_PRIV, pgrp); + } +} + /** * reparent_to_kthreadd - Reparent the calling kernel thread to kthreadd * @@ -635,22 +665,7 @@ reparent_thread(struct task_struct *p, struct task_struct *father, int traced) p->exit_signal != -1 && thread_group_empty(p)) do_notify_parent(p, p->exit_signal); - /* - * process group orphan check - * Case ii: Our child is in a different pgrp - * than we are, and it was the only connection - * outside, so the child pgrp is now orphaned. - */ - if ((task_pgrp(p) != task_pgrp(father)) && - (task_session(p) == task_session(father))) { - struct pid *pgrp = task_pgrp(p); - - if (will_become_orphaned_pgrp(pgrp, NULL) && - has_stopped_jobs(pgrp)) { - __kill_pgrp_info(SIGHUP, SEND_SIG_PRIV, pgrp); - __kill_pgrp_info(SIGCONT, SEND_SIG_PRIV, pgrp); - } - } + kill_orphaned_pgrp(p, father); } /* @@ -735,11 +750,9 @@ static void forget_original_parent(struct task_struct *father) * Send signals to all our closest relatives so that they know * to properly mourn us.. */ -static void exit_notify(struct task_struct *tsk) +static void exit_notify(struct task_struct *tsk, int group_dead) { int state; - struct task_struct *t; - struct pid *pgrp; /* * This does two things: @@ -753,25 +766,8 @@ static void exit_notify(struct task_struct *tsk) exit_task_namespaces(tsk); write_lock_irq(&tasklist_lock); - /* - * Check to see if any process groups have become orphaned - * as a result of our exiting, and if they have any stopped - * jobs, send them a SIGHUP and then a SIGCONT. (POSIX 3.2.2.2) - * - * Case i: Our father is in a different pgrp than we are - * and we were the only connection outside, so our pgrp - * is about to become orphaned. - */ - t = tsk->real_parent; - - pgrp = task_pgrp(tsk); - if ((task_pgrp(t) != pgrp) && - (task_session(t) == task_session(tsk)) && - will_become_orphaned_pgrp(pgrp, tsk) && - has_stopped_jobs(pgrp)) { - __kill_pgrp_info(SIGHUP, SEND_SIG_PRIV, pgrp); - __kill_pgrp_info(SIGCONT, SEND_SIG_PRIV, pgrp); - } + if (group_dead) + kill_orphaned_pgrp(tsk->group_leader, NULL); /* Let father know we died * @@ -788,8 +784,8 @@ static void exit_notify(struct task_struct *tsk) * the same after a fork. */ if (tsk->exit_signal != SIGCHLD && tsk->exit_signal != -1 && - ( tsk->parent_exec_id != t->self_exec_id || - tsk->self_exec_id != tsk->parent_exec_id) + (tsk->parent_exec_id != tsk->real_parent->self_exec_id || + tsk->self_exec_id != tsk->parent_exec_id) && !capable(CAP_KILL)) tsk->exit_signal = SIGCHLD; @@ -986,7 +982,7 @@ NORET_TYPE void do_exit(long code) module_put(tsk->binfmt->module); proc_exit_connector(tsk); - exit_notify(tsk); + exit_notify(tsk, group_dead); #ifdef CONFIG_NUMA mpol_free(tsk->mempolicy); tsk->mempolicy = NULL; @@ -1382,7 +1378,7 @@ unlock_sig: if (!retval && infop) retval = put_user(0, &infop->si_errno); if (!retval && infop) - retval = put_user(why, &infop->si_code); + retval = put_user((short)why, &infop->si_code); if (!retval && infop) retval = put_user(exit_code, &infop->si_status); if (!retval && infop) diff --git a/kernel/kprobes.c b/kernel/kprobes.c index 7a86e64323385785bda6e838f01c9637e192844a..fcfb580c3afc847e60fc9fa4f682b33c25650963 100644 --- a/kernel/kprobes.c +++ b/kernel/kprobes.c @@ -498,27 +498,36 @@ static int __kprobes in_kprobes_functions(unsigned long addr) return 0; } +/* + * If we have a symbol_name argument, look it up and add the offset field + * to it. This way, we can specify a relative address to a symbol. + */ +static kprobe_opcode_t __kprobes *kprobe_addr(struct kprobe *p) +{ + kprobe_opcode_t *addr = p->addr; + if (p->symbol_name) { + if (addr) + return NULL; + kprobe_lookup_name(p->symbol_name, addr); + } + + if (!addr) + return NULL; + return (kprobe_opcode_t *)(((char *)addr) + p->offset); +} + static int __kprobes __register_kprobe(struct kprobe *p, unsigned long called_from) { int ret = 0; struct kprobe *old_p; struct module *probed_mod; + kprobe_opcode_t *addr; - /* - * If we have a symbol_name argument look it up, - * and add it to the address. That way the addr - * field can either be global or relative to a symbol. - */ - if (p->symbol_name) { - if (p->addr) - return -EINVAL; - kprobe_lookup_name(p->symbol_name, p->addr); - } - - if (!p->addr) + addr = kprobe_addr(p); + if (!addr) return -EINVAL; - p->addr = (kprobe_opcode_t *)(((char *)p->addr)+ p->offset); + p->addr = addr; if (!kernel_text_address((unsigned long) p->addr) || in_kprobes_functions((unsigned long) p->addr)) @@ -678,8 +687,7 @@ void __kprobes unregister_jprobe(struct jprobe *jp) unregister_kprobe(&jp->kp); } -#ifdef ARCH_SUPPORTS_KRETPROBES - +#ifdef CONFIG_KRETPROBES /* * This kprobe pre_handler is registered with every kretprobe. When probe * hits it will set up the return probe. @@ -722,12 +730,12 @@ int __kprobes register_kretprobe(struct kretprobe *rp) int ret = 0; struct kretprobe_instance *inst; int i; - void *addr = rp->kp.addr; + void *addr; if (kretprobe_blacklist_size) { - if (addr == NULL) - kprobe_lookup_name(rp->kp.symbol_name, addr); - addr += rp->kp.offset; + addr = kprobe_addr(&rp->kp); + if (!addr) + return -EINVAL; for (i = 0; kretprobe_blacklist[i].name != NULL; i++) { if (kretprobe_blacklist[i].addr == addr) @@ -769,8 +777,7 @@ int __kprobes register_kretprobe(struct kretprobe *rp) return ret; } -#else /* ARCH_SUPPORTS_KRETPROBES */ - +#else /* CONFIG_KRETPROBES */ int __kprobes register_kretprobe(struct kretprobe *rp) { return -ENOSYS; @@ -781,8 +788,7 @@ static int __kprobes pre_handler_kretprobe(struct kprobe *p, { return 0; } - -#endif /* ARCH_SUPPORTS_KRETPROBES */ +#endif /* CONFIG_KRETPROBES */ void __kprobes unregister_kretprobe(struct kretprobe *rp) { diff --git a/kernel/lockdep.c b/kernel/lockdep.c index 3574379f4d62d2d04c9431c0c2172dc044d0ca66..81a4e4a3f087adfc650eb6baf2c05147f209e062 100644 --- a/kernel/lockdep.c +++ b/kernel/lockdep.c @@ -779,6 +779,10 @@ register_lock_class(struct lockdep_map *lock, unsigned int subclass, int force) * parallel walking of the hash-list safe: */ list_add_tail_rcu(&class->hash_entry, hash_head); + /* + * Add it to the global list of classes: + */ + list_add_tail_rcu(&class->lock_entry, &all_lock_classes); if (verbose(class)) { graph_unlock(); @@ -2282,10 +2286,6 @@ static int mark_lock(struct task_struct *curr, struct held_lock *this, return 0; break; case LOCK_USED: - /* - * Add it to the global list of classes: - */ - list_add_tail_rcu(&this->class->lock_entry, &all_lock_classes); debug_atomic_dec(&nr_unused_locks); break; default: diff --git a/kernel/marker.c b/kernel/marker.c index 50effc01d9a2e094217c0c920eb0f64677424fcc..48a4ea5afffde0b758a627fb63046f8a65976ff5 100644 --- a/kernel/marker.c +++ b/kernel/marker.c @@ -698,14 +698,12 @@ int marker_probe_unregister(const char *name, { struct marker_entry *entry; struct marker_probe_closure *old; - int ret = 0; + int ret = -ENOENT; mutex_lock(&markers_mutex); entry = get_marker(name); - if (!entry) { - ret = -ENOENT; + if (!entry) goto end; - } if (entry->rcu_pending) rcu_barrier(); old = marker_entry_remove_probe(entry, probe, probe_private); @@ -713,12 +711,15 @@ int marker_probe_unregister(const char *name, marker_update_probes(); /* may update entry */ mutex_lock(&markers_mutex); entry = get_marker(name); + if (!entry) + goto end; entry->oldptr = old; entry->rcu_pending = 1; /* write rcu_pending before calling the RCU callback */ smp_wmb(); call_rcu(&entry->rcu, free_old_closure); remove_marker(name); /* Ignore busy error message */ + ret = 0; end: mutex_unlock(&markers_mutex); return ret; diff --git a/kernel/module.c b/kernel/module.c index 901cd6ac2f11d9d4b54d3bff34e10495e86f01a2..5d437bffd8dc7a4219fe471eab6a8699ed08e3df 100644 --- a/kernel/module.c +++ b/kernel/module.c @@ -1933,8 +1933,15 @@ static struct module *load_module(void __user *umod, /* Set up license info based on the info section */ set_license(mod, get_modinfo(sechdrs, infoindex, "license")); + /* + * ndiswrapper is under GPL by itself, but loads proprietary modules. + * Don't use add_taint_module(), as it would prevent ndiswrapper from + * using GPL-only symbols it needs. + */ if (strcmp(mod->name, "ndiswrapper") == 0) - add_taint_module(mod, TAINT_PROPRIETARY_MODULE); + add_taint(TAINT_PROPRIETARY_MODULE); + + /* driverloader was caught wrongly pretending to be under GPL */ if (strcmp(mod->name, "driverloader") == 0) add_taint_module(mod, TAINT_PROPRIETARY_MODULE); @@ -2171,10 +2178,20 @@ sys_init_module(void __user *umod, wake_up(&module_wq); return ret; } + if (ret > 0) { + printk(KERN_WARNING "%s: '%s'->init suspiciously returned %d, " + "it should follow 0/-E convention\n" + KERN_WARNING "%s: loading module anyway...\n", + __func__, mod->name, ret, + __func__); + dump_stack(); + } - /* Now it's a first class citizen! */ - mutex_lock(&module_mutex); + /* Now it's a first class citizen! Wake up anyone waiting for it. */ mod->state = MODULE_STATE_LIVE; + wake_up(&module_wq); + + mutex_lock(&module_mutex); /* Drop initial reference. */ module_put(mod); unwind_remove_table(mod->unwind_info, 1); @@ -2183,7 +2200,6 @@ sys_init_module(void __user *umod, mod->init_size = 0; mod->init_text_size = 0; mutex_unlock(&module_mutex); - wake_up(&module_wq); return 0; } diff --git a/kernel/power/Kconfig b/kernel/power/Kconfig index 79833170bb9cddf4aad9b6bde7806628856ffde5..6233f3b4ae6628c0676c73f09a2937f5039fcd5c 100644 --- a/kernel/power/Kconfig +++ b/kernel/power/Kconfig @@ -190,7 +190,7 @@ config APM_EMULATION notification of APM "events" (e.g. battery status change). In order to use APM, you will need supporting software. For location - and more information, read and the + and more information, read and the Battery Powered Linux mini-HOWTO, available from . diff --git a/kernel/power/process.c b/kernel/power/process.c index 7c2118f9597f3139cfef277233a739d5d717b159..f1d0b345c9ba86a24ac48ee29cc4cb6f800b1c94 100644 --- a/kernel/power/process.c +++ b/kernel/power/process.c @@ -75,22 +75,15 @@ void refrigerator(void) __set_current_state(save); } -static void fake_signal_wake_up(struct task_struct *p, int resume) +static void fake_signal_wake_up(struct task_struct *p) { unsigned long flags; spin_lock_irqsave(&p->sighand->siglock, flags); - signal_wake_up(p, resume); + signal_wake_up(p, 0); spin_unlock_irqrestore(&p->sighand->siglock, flags); } -static void send_fake_signal(struct task_struct *p) -{ - if (task_is_stopped(p)) - force_sig_specific(SIGSTOP, p); - fake_signal_wake_up(p, task_is_stopped(p)); -} - static int has_mm(struct task_struct *p) { return (p->mm && !(p->flags & PF_BORROWED_MM)); @@ -121,7 +114,7 @@ static int freeze_task(struct task_struct *p, int with_mm_only) if (freezing(p)) { if (has_mm(p)) { if (!signal_pending(p)) - fake_signal_wake_up(p, 0); + fake_signal_wake_up(p); } else { if (with_mm_only) ret = 0; @@ -135,7 +128,7 @@ static int freeze_task(struct task_struct *p, int with_mm_only) } else { if (has_mm(p)) { set_freeze_flag(p); - send_fake_signal(p); + fake_signal_wake_up(p); } else { if (with_mm_only) { ret = 0; @@ -182,15 +175,17 @@ static int try_to_freeze_tasks(int freeze_user_space) if (frozen(p) || !freezeable(p)) continue; - if (task_is_traced(p) && frozen(p->parent)) { - cancel_freezing(p); - continue; - } - if (!freeze_task(p, freeze_user_space)) continue; - if (!freezer_should_skip(p)) + /* + * Now that we've done set_freeze_flag, don't + * perturb a task in TASK_STOPPED or TASK_TRACED. + * It is "frozen enough". If the task does wake + * up, it will immediately call try_to_freeze. + */ + if (!task_is_stopped_or_traced(p) && + !freezer_should_skip(p)) todo++; } while_each_thread(g, p); read_unlock(&tasklist_lock); diff --git a/kernel/power/snapshot.c b/kernel/power/snapshot.c index 72a020cabb4c5238f395c1aa6420a630dc8b49dc..5f91a07c4eac7e104f3fc9c333a481be11ead921 100644 --- a/kernel/power/snapshot.c +++ b/kernel/power/snapshot.c @@ -447,7 +447,7 @@ static void memory_bm_free(struct memory_bitmap *bm, int clear_nosave_free) * of @bm->cur_zone_bm are updated. */ -static void memory_bm_find_bit(struct memory_bitmap *bm, unsigned long pfn, +static int memory_bm_find_bit(struct memory_bitmap *bm, unsigned long pfn, void **addr, unsigned int *bit_nr) { struct zone_bitmap *zone_bm; @@ -461,7 +461,8 @@ static void memory_bm_find_bit(struct memory_bitmap *bm, unsigned long pfn, while (pfn < zone_bm->start_pfn || pfn >= zone_bm->end_pfn) { zone_bm = zone_bm->next; - BUG_ON(!zone_bm); + if (!zone_bm) + return -EFAULT; } bm->cur.zone_bm = zone_bm; } @@ -479,23 +480,40 @@ static void memory_bm_find_bit(struct memory_bitmap *bm, unsigned long pfn, pfn -= bb->start_pfn; *bit_nr = pfn % BM_BITS_PER_CHUNK; *addr = bb->data + pfn / BM_BITS_PER_CHUNK; + return 0; } static void memory_bm_set_bit(struct memory_bitmap *bm, unsigned long pfn) { void *addr; unsigned int bit; + int error; - memory_bm_find_bit(bm, pfn, &addr, &bit); + error = memory_bm_find_bit(bm, pfn, &addr, &bit); + BUG_ON(error); set_bit(bit, addr); } +static int mem_bm_set_bit_check(struct memory_bitmap *bm, unsigned long pfn) +{ + void *addr; + unsigned int bit; + int error; + + error = memory_bm_find_bit(bm, pfn, &addr, &bit); + if (!error) + set_bit(bit, addr); + return error; +} + static void memory_bm_clear_bit(struct memory_bitmap *bm, unsigned long pfn) { void *addr; unsigned int bit; + int error; - memory_bm_find_bit(bm, pfn, &addr, &bit); + error = memory_bm_find_bit(bm, pfn, &addr, &bit); + BUG_ON(error); clear_bit(bit, addr); } @@ -503,8 +521,10 @@ static int memory_bm_test_bit(struct memory_bitmap *bm, unsigned long pfn) { void *addr; unsigned int bit; + int error; - memory_bm_find_bit(bm, pfn, &addr, &bit); + error = memory_bm_find_bit(bm, pfn, &addr, &bit); + BUG_ON(error); return test_bit(bit, addr); } @@ -709,8 +729,15 @@ static void mark_nosave_pages(struct memory_bitmap *bm) region->end_pfn << PAGE_SHIFT); for (pfn = region->start_pfn; pfn < region->end_pfn; pfn++) - if (pfn_valid(pfn)) - memory_bm_set_bit(bm, pfn); + if (pfn_valid(pfn)) { + /* + * It is safe to ignore the result of + * mem_bm_set_bit_check() here, since we won't + * touch the PFNs for which the error is + * returned anyway. + */ + mem_bm_set_bit_check(bm, pfn); + } } } diff --git a/kernel/printk.c b/kernel/printk.c index bee36100f110ab75617ad4dce16beac9e1434f76..9adc2a473e6e0f59bbc41350422d415e8f17a7ec 100644 --- a/kernel/printk.c +++ b/kernel/printk.c @@ -666,7 +666,7 @@ asmlinkage int vprintk(const char *fmt, va_list args) } /* Emit the output into the temporary buffer */ printed_len += vscnprintf(printk_buf + printed_len, - sizeof(printk_buf), fmt, args); + sizeof(printk_buf) - printed_len, fmt, args); /* * Copy the output into log_buf. If the caller didn't provide diff --git a/kernel/rcupreempt.c b/kernel/rcupreempt.c index 987cfb7ade8977225baf5a88695f2c9ba110b549..e9517014b57c100af5926165d2131992f0589401 100644 --- a/kernel/rcupreempt.c +++ b/kernel/rcupreempt.c @@ -23,6 +23,10 @@ * to Suparna Bhattacharya for pushing me completely away * from atomic instructions on the read side. * + * - Added handling of Dynamic Ticks + * Copyright 2007 - Paul E. Mckenney + * - Steven Rostedt + * * Papers: http://www.rdrop.com/users/paulmck/RCU * * Design Document: http://lwn.net/Articles/253651/ @@ -409,6 +413,212 @@ static void __rcu_advance_callbacks(struct rcu_data *rdp) } } +#ifdef CONFIG_NO_HZ + +DEFINE_PER_CPU(long, dynticks_progress_counter) = 1; +static DEFINE_PER_CPU(long, rcu_dyntick_snapshot); +static DEFINE_PER_CPU(int, rcu_update_flag); + +/** + * rcu_irq_enter - Called from Hard irq handlers and NMI/SMI. + * + * If the CPU was idle with dynamic ticks active, this updates the + * dynticks_progress_counter to let the RCU handling know that the + * CPU is active. + */ +void rcu_irq_enter(void) +{ + int cpu = smp_processor_id(); + + if (per_cpu(rcu_update_flag, cpu)) + per_cpu(rcu_update_flag, cpu)++; + + /* + * Only update if we are coming from a stopped ticks mode + * (dynticks_progress_counter is even). + */ + if (!in_interrupt() && + (per_cpu(dynticks_progress_counter, cpu) & 0x1) == 0) { + /* + * The following might seem like we could have a race + * with NMI/SMIs. But this really isn't a problem. + * Here we do a read/modify/write, and the race happens + * when an NMI/SMI comes in after the read and before + * the write. But NMI/SMIs will increment this counter + * twice before returning, so the zero bit will not + * be corrupted by the NMI/SMI which is the most important + * part. + * + * The only thing is that we would bring back the counter + * to a postion that it was in during the NMI/SMI. + * But the zero bit would be set, so the rest of the + * counter would again be ignored. + * + * On return from the IRQ, the counter may have the zero + * bit be 0 and the counter the same as the return from + * the NMI/SMI. If the state machine was so unlucky to + * see that, it still doesn't matter, since all + * RCU read-side critical sections on this CPU would + * have already completed. + */ + per_cpu(dynticks_progress_counter, cpu)++; + /* + * The following memory barrier ensures that any + * rcu_read_lock() primitives in the irq handler + * are seen by other CPUs to follow the above + * increment to dynticks_progress_counter. This is + * required in order for other CPUs to correctly + * determine when it is safe to advance the RCU + * grace-period state machine. + */ + smp_mb(); /* see above block comment. */ + /* + * Since we can't determine the dynamic tick mode from + * the dynticks_progress_counter after this routine, + * we use a second flag to acknowledge that we came + * from an idle state with ticks stopped. + */ + per_cpu(rcu_update_flag, cpu)++; + /* + * If we take an NMI/SMI now, they will also increment + * the rcu_update_flag, and will not update the + * dynticks_progress_counter on exit. That is for + * this IRQ to do. + */ + } +} + +/** + * rcu_irq_exit - Called from exiting Hard irq context. + * + * If the CPU was idle with dynamic ticks active, update the + * dynticks_progress_counter to put let the RCU handling be + * aware that the CPU is going back to idle with no ticks. + */ +void rcu_irq_exit(void) +{ + int cpu = smp_processor_id(); + + /* + * rcu_update_flag is set if we interrupted the CPU + * when it was idle with ticks stopped. + * Once this occurs, we keep track of interrupt nesting + * because a NMI/SMI could also come in, and we still + * only want the IRQ that started the increment of the + * dynticks_progress_counter to be the one that modifies + * it on exit. + */ + if (per_cpu(rcu_update_flag, cpu)) { + if (--per_cpu(rcu_update_flag, cpu)) + return; + + /* This must match the interrupt nesting */ + WARN_ON(in_interrupt()); + + /* + * If an NMI/SMI happens now we are still + * protected by the dynticks_progress_counter being odd. + */ + + /* + * The following memory barrier ensures that any + * rcu_read_unlock() primitives in the irq handler + * are seen by other CPUs to preceed the following + * increment to dynticks_progress_counter. This + * is required in order for other CPUs to determine + * when it is safe to advance the RCU grace-period + * state machine. + */ + smp_mb(); /* see above block comment. */ + per_cpu(dynticks_progress_counter, cpu)++; + WARN_ON(per_cpu(dynticks_progress_counter, cpu) & 0x1); + } +} + +static void dyntick_save_progress_counter(int cpu) +{ + per_cpu(rcu_dyntick_snapshot, cpu) = + per_cpu(dynticks_progress_counter, cpu); +} + +static inline int +rcu_try_flip_waitack_needed(int cpu) +{ + long curr; + long snap; + + curr = per_cpu(dynticks_progress_counter, cpu); + snap = per_cpu(rcu_dyntick_snapshot, cpu); + smp_mb(); /* force ordering with cpu entering/leaving dynticks. */ + + /* + * If the CPU remained in dynticks mode for the entire time + * and didn't take any interrupts, NMIs, SMIs, or whatever, + * then it cannot be in the middle of an rcu_read_lock(), so + * the next rcu_read_lock() it executes must use the new value + * of the counter. So we can safely pretend that this CPU + * already acknowledged the counter. + */ + + if ((curr == snap) && ((curr & 0x1) == 0)) + return 0; + + /* + * If the CPU passed through or entered a dynticks idle phase with + * no active irq handlers, then, as above, we can safely pretend + * that this CPU already acknowledged the counter. + */ + + if ((curr - snap) > 2 || (snap & 0x1) == 0) + return 0; + + /* We need this CPU to explicitly acknowledge the counter flip. */ + + return 1; +} + +static inline int +rcu_try_flip_waitmb_needed(int cpu) +{ + long curr; + long snap; + + curr = per_cpu(dynticks_progress_counter, cpu); + snap = per_cpu(rcu_dyntick_snapshot, cpu); + smp_mb(); /* force ordering with cpu entering/leaving dynticks. */ + + /* + * If the CPU remained in dynticks mode for the entire time + * and didn't take any interrupts, NMIs, SMIs, or whatever, + * then it cannot have executed an RCU read-side critical section + * during that time, so there is no need for it to execute a + * memory barrier. + */ + + if ((curr == snap) && ((curr & 0x1) == 0)) + return 0; + + /* + * If the CPU either entered or exited an outermost interrupt, + * SMI, NMI, or whatever handler, then we know that it executed + * a memory barrier when doing so. So we don't need another one. + */ + if (curr != snap) + return 0; + + /* We need the CPU to execute a memory barrier. */ + + return 1; +} + +#else /* !CONFIG_NO_HZ */ + +# define dyntick_save_progress_counter(cpu) do { } while (0) +# define rcu_try_flip_waitack_needed(cpu) (1) +# define rcu_try_flip_waitmb_needed(cpu) (1) + +#endif /* CONFIG_NO_HZ */ + /* * Get here when RCU is idle. Decide whether we need to * move out of idle state, and return non-zero if so. @@ -447,8 +657,10 @@ rcu_try_flip_idle(void) /* Now ask each CPU for acknowledgement of the flip. */ - for_each_cpu_mask(cpu, rcu_cpu_online_map) + for_each_cpu_mask(cpu, rcu_cpu_online_map) { per_cpu(rcu_flip_flag, cpu) = rcu_flipped; + dyntick_save_progress_counter(cpu); + } return 1; } @@ -464,7 +676,8 @@ rcu_try_flip_waitack(void) RCU_TRACE_ME(rcupreempt_trace_try_flip_a1); for_each_cpu_mask(cpu, rcu_cpu_online_map) - if (per_cpu(rcu_flip_flag, cpu) != rcu_flip_seen) { + if (rcu_try_flip_waitack_needed(cpu) && + per_cpu(rcu_flip_flag, cpu) != rcu_flip_seen) { RCU_TRACE_ME(rcupreempt_trace_try_flip_ae1); return 0; } @@ -509,8 +722,10 @@ rcu_try_flip_waitzero(void) smp_mb(); /* ^^^^^^^^^^^^ */ /* Call for a memory barrier from each CPU. */ - for_each_cpu_mask(cpu, rcu_cpu_online_map) + for_each_cpu_mask(cpu, rcu_cpu_online_map) { per_cpu(rcu_mb_flag, cpu) = rcu_mb_needed; + dyntick_save_progress_counter(cpu); + } RCU_TRACE_ME(rcupreempt_trace_try_flip_z2); return 1; @@ -528,7 +743,8 @@ rcu_try_flip_waitmb(void) RCU_TRACE_ME(rcupreempt_trace_try_flip_m1); for_each_cpu_mask(cpu, rcu_cpu_online_map) - if (per_cpu(rcu_mb_flag, cpu) != rcu_mb_done) { + if (rcu_try_flip_waitmb_needed(cpu) && + per_cpu(rcu_mb_flag, cpu) != rcu_mb_done) { RCU_TRACE_ME(rcupreempt_trace_try_flip_me1); return 0; } @@ -702,8 +918,9 @@ void rcu_offline_cpu(int cpu) * fix. */ + local_irq_save(flags); rdp = RCU_DATA_ME(); - spin_lock_irqsave(&rdp->lock, flags); + spin_lock(&rdp->lock); *rdp->nexttail = list; if (list) rdp->nexttail = tail; @@ -735,9 +952,11 @@ static void rcu_process_callbacks(struct softirq_action *unused) { unsigned long flags; struct rcu_head *next, *list; - struct rcu_data *rdp = RCU_DATA_ME(); + struct rcu_data *rdp; - spin_lock_irqsave(&rdp->lock, flags); + local_irq_save(flags); + rdp = RCU_DATA_ME(); + spin_lock(&rdp->lock); list = rdp->donelist; if (list == NULL) { spin_unlock_irqrestore(&rdp->lock, flags); diff --git a/kernel/res_counter.c b/kernel/res_counter.c index 16cbec2d5d60514e67c14907e6d11f91cfecafd1..efbfc0fc232f33c49b5b918704b4e13ae5d0f2cc 100644 --- a/kernel/res_counter.c +++ b/kernel/res_counter.c @@ -113,6 +113,7 @@ ssize_t res_counter_write(struct res_counter *counter, int member, ret = -EINVAL; + strstrip(buf); if (write_strategy) { if (write_strategy(buf, &tmp)) { goto out_free; diff --git a/kernel/sched.c b/kernel/sched.c index b387a8de26a5f9ca8b6e2e9d3ad33f66fbf65882..d1ad69b270ca7abc418871ce3160cc4bfbc04135 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -174,41 +174,6 @@ struct task_group { struct sched_entity **se; /* runqueue "owned" by this group on each cpu */ struct cfs_rq **cfs_rq; - - /* - * shares assigned to a task group governs how much of cpu bandwidth - * is allocated to the group. The more shares a group has, the more is - * the cpu bandwidth allocated to it. - * - * For ex, lets say that there are three task groups, A, B and C which - * have been assigned shares 1000, 2000 and 3000 respectively. Then, - * cpu bandwidth allocated by the scheduler to task groups A, B and C - * should be: - * - * Bw(A) = 1000/(1000+2000+3000) * 100 = 16.66% - * Bw(B) = 2000/(1000+2000+3000) * 100 = 33.33% - * Bw(C) = 3000/(1000+2000+3000) * 100 = 50% - * - * The weight assigned to a task group's schedulable entities on every - * cpu (task_group.se[a_cpu]->load.weight) is derived from the task - * group's shares. For ex: lets say that task group A has been - * assigned shares of 1000 and there are two CPUs in a system. Then, - * - * tg_A->se[0]->load.weight = tg_A->se[1]->load.weight = 1000; - * - * Note: It's not necessary that each of a task's group schedulable - * entity have the same weight on all CPUs. If the group - * has 2 of its tasks on CPU0 and 1 task on CPU1, then a - * better distribution of weight could be: - * - * tg_A->se[0]->load.weight = 2/3 * 2000 = 1333 - * tg_A->se[1]->load.weight = 1/2 * 2000 = 667 - * - * rebalance_shares() is responsible for distributing the shares of a - * task groups like this among the group's schedulable entities across - * cpus. - * - */ unsigned long shares; #endif @@ -250,22 +215,12 @@ static DEFINE_SPINLOCK(task_group_lock); static DEFINE_MUTEX(doms_cur_mutex); #ifdef CONFIG_FAIR_GROUP_SCHED -#ifdef CONFIG_SMP -/* kernel thread that runs rebalance_shares() periodically */ -static struct task_struct *lb_monitor_task; -static int load_balance_monitor(void *unused); -#endif - -static void set_se_shares(struct sched_entity *se, unsigned long shares); - #ifdef CONFIG_USER_SCHED # define INIT_TASK_GROUP_LOAD (2*NICE_0_LOAD) #else # define INIT_TASK_GROUP_LOAD NICE_0_LOAD #endif -#define MIN_GROUP_SHARES 2 - static int init_task_group_load = INIT_TASK_GROUP_LOAD; #endif @@ -346,7 +301,7 @@ struct cfs_rq { /* 'curr' points to currently running entity on this cfs_rq. * It is set to NULL otherwise (i.e when none are currently running). */ - struct sched_entity *curr; + struct sched_entity *curr, *next; unsigned long nr_spread_over; @@ -668,6 +623,8 @@ const_debug unsigned int sysctl_sched_nr_migrate = 32; */ unsigned int sysctl_sched_rt_period = 1000000; +static __read_mostly int scheduler_running; + /* * part of the period that we allow rt tasks to run in us. * default: 0.95s @@ -689,14 +646,16 @@ unsigned long long cpu_clock(int cpu) unsigned long flags; struct rq *rq; - local_irq_save(flags); - rq = cpu_rq(cpu); /* * Only call sched_clock() if the scheduler has already been * initialized (some code might call cpu_clock() very early): */ - if (rq->idle) - update_rq_clock(rq); + if (unlikely(!scheduler_running)) + return 0; + + local_irq_save(flags); + rq = cpu_rq(cpu); + update_rq_clock(rq); now = rq->clock; local_irq_restore(flags); @@ -1125,7 +1084,7 @@ calc_delta_mine(unsigned long delta_exec, unsigned long weight, u64 tmp; if (unlikely(!lw->inv_weight)) - lw->inv_weight = (WMULT_CONST - lw->weight/2) / lw->weight + 1; + lw->inv_weight = (WMULT_CONST-lw->weight/2) / (lw->weight+1); tmp = (u64)delta_exec * weight; /* @@ -1149,11 +1108,13 @@ calc_delta_fair(unsigned long delta_exec, struct load_weight *lw) static inline void update_load_add(struct load_weight *lw, unsigned long inc) { lw->weight += inc; + lw->inv_weight = 0; } static inline void update_load_sub(struct load_weight *lw, unsigned long dec) { lw->weight -= dec; + lw->inv_weight = 0; } /* @@ -1241,16 +1202,6 @@ static void cpuacct_charge(struct task_struct *tsk, u64 cputime); static inline void cpuacct_charge(struct task_struct *tsk, u64 cputime) {} #endif -static inline void inc_cpu_load(struct rq *rq, unsigned long load) -{ - update_load_add(&rq->load, load); -} - -static inline void dec_cpu_load(struct rq *rq, unsigned long load) -{ - update_load_sub(&rq->load, load); -} - #ifdef CONFIG_SMP static unsigned long source_load(int cpu, int type); static unsigned long target_load(int cpu, int type); @@ -1268,14 +1219,26 @@ static int task_hot(struct task_struct *p, u64 now, struct sched_domain *sd); #define sched_class_highest (&rt_sched_class) -static void inc_nr_running(struct rq *rq) +static inline void inc_load(struct rq *rq, const struct task_struct *p) +{ + update_load_add(&rq->load, p->se.load.weight); +} + +static inline void dec_load(struct rq *rq, const struct task_struct *p) +{ + update_load_sub(&rq->load, p->se.load.weight); +} + +static void inc_nr_running(struct task_struct *p, struct rq *rq) { rq->nr_running++; + inc_load(rq, p); } -static void dec_nr_running(struct rq *rq) +static void dec_nr_running(struct task_struct *p, struct rq *rq) { rq->nr_running--; + dec_load(rq, p); } static void set_load_weight(struct task_struct *p) @@ -1367,7 +1330,7 @@ static void activate_task(struct rq *rq, struct task_struct *p, int wakeup) rq->nr_uninterruptible--; enqueue_task(rq, p, wakeup); - inc_nr_running(rq); + inc_nr_running(p, rq); } /* @@ -1379,7 +1342,7 @@ static void deactivate_task(struct rq *rq, struct task_struct *p, int sleep) rq->nr_uninterruptible++; dequeue_task(rq, p, sleep); - dec_nr_running(rq); + dec_nr_running(p, rq); } /** @@ -2019,7 +1982,7 @@ void wake_up_new_task(struct task_struct *p, unsigned long clone_flags) * management (if any): */ p->sched_class->task_new(rq, p); - inc_nr_running(rq); + inc_nr_running(p, rq); } check_preempt_curr(rq, p); #ifdef CONFIG_SMP @@ -3885,7 +3848,7 @@ pick_next_task(struct rq *rq, struct task_struct *prev) asmlinkage void __sched schedule(void) { struct task_struct *prev, *next; - long *switch_count; + unsigned long *switch_count; struct rq *rq; int cpu; @@ -4307,11 +4270,10 @@ void rt_mutex_setprio(struct task_struct *p, int prio) oldprio = p->prio; on_rq = p->se.on_rq; running = task_current(rq, p); - if (on_rq) { + if (on_rq) dequeue_task(rq, p, 0); - if (running) - p->sched_class->put_prev_task(rq, p); - } + if (running) + p->sched_class->put_prev_task(rq, p); if (rt_prio(prio)) p->sched_class = &rt_sched_class; @@ -4320,10 +4282,9 @@ void rt_mutex_setprio(struct task_struct *p, int prio) p->prio = prio; + if (running) + p->sched_class->set_curr_task(rq); if (on_rq) { - if (running) - p->sched_class->set_curr_task(rq); - enqueue_task(rq, p, 0); check_class_changed(rq, p, prev_class, oldprio, running); @@ -4358,8 +4319,10 @@ void set_user_nice(struct task_struct *p, long nice) goto out_unlock; } on_rq = p->se.on_rq; - if (on_rq) + if (on_rq) { dequeue_task(rq, p, 0); + dec_load(rq, p); + } p->static_prio = NICE_TO_PRIO(nice); set_load_weight(p); @@ -4369,6 +4332,7 @@ void set_user_nice(struct task_struct *p, long nice) if (on_rq) { enqueue_task(rq, p, 0); + inc_load(rq, p); /* * If the task increased its priority or is running and * lowered its priority, then reschedule its CPU: @@ -4458,7 +4422,7 @@ int task_nice(const struct task_struct *p) { return TASK_NICE(p); } -EXPORT_SYMBOL_GPL(task_nice); +EXPORT_SYMBOL(task_nice); /** * idle_cpu - is a given cpu idle currently? @@ -4617,19 +4581,17 @@ recheck: update_rq_clock(rq); on_rq = p->se.on_rq; running = task_current(rq, p); - if (on_rq) { + if (on_rq) deactivate_task(rq, p, 0); - if (running) - p->sched_class->put_prev_task(rq, p); - } + if (running) + p->sched_class->put_prev_task(rq, p); oldprio = p->prio; __setscheduler(rq, p, policy, param->sched_priority); + if (running) + p->sched_class->set_curr_task(rq); if (on_rq) { - if (running) - p->sched_class->set_curr_task(rq); - activate_task(rq, p, 0); check_class_changed(rq, p, prev_class, oldprio, running); @@ -5136,7 +5098,7 @@ long sys_sched_rr_get_interval(pid_t pid, struct timespec __user *interval) time_slice = 0; if (p->policy == SCHED_RR) { time_slice = DEF_TIMESLICE; - } else { + } else if (p->policy != SCHED_FIFO) { struct sched_entity *se = &p->se; unsigned long flags; struct rq *rq; @@ -5917,7 +5879,8 @@ migration_call(struct notifier_block *nfb, unsigned long action, void *hcpu) spin_unlock_irq(&rq->lock); break; - case CPU_DOWN_PREPARE: + case CPU_DYING: + case CPU_DYING_FROZEN: /* Update our root-domain */ rq = cpu_rq(cpu); spin_lock_irqsave(&rq->lock, flags); @@ -7083,21 +7046,6 @@ void __init sched_init_smp(void) if (set_cpus_allowed(current, non_isolated_cpus) < 0) BUG(); sched_init_granularity(); - -#ifdef CONFIG_FAIR_GROUP_SCHED - if (nr_cpu_ids == 1) - return; - - lb_monitor_task = kthread_create(load_balance_monitor, NULL, - "group_balance"); - if (!IS_ERR(lb_monitor_task)) { - lb_monitor_task->flags |= PF_NOFREEZE; - wake_up_process(lb_monitor_task); - } else { - printk(KERN_ERR "Could not create load balance monitor thread" - "(error = %ld) \n", PTR_ERR(lb_monitor_task)); - } -#endif } #else void __init sched_init_smp(void) @@ -7284,6 +7232,8 @@ void __init sched_init(void) * During early bootup we pretend to be a normal task: */ current->sched_class = &fair_sched_class; + + scheduler_running = 1; } #ifdef CONFIG_DEBUG_SPINLOCK_SLEEP @@ -7418,157 +7368,6 @@ void set_curr_task(int cpu, struct task_struct *p) #ifdef CONFIG_GROUP_SCHED -#if defined CONFIG_FAIR_GROUP_SCHED && defined CONFIG_SMP -/* - * distribute shares of all task groups among their schedulable entities, - * to reflect load distribution across cpus. - */ -static int rebalance_shares(struct sched_domain *sd, int this_cpu) -{ - struct cfs_rq *cfs_rq; - struct rq *rq = cpu_rq(this_cpu); - cpumask_t sdspan = sd->span; - int balanced = 1; - - /* Walk thr' all the task groups that we have */ - for_each_leaf_cfs_rq(rq, cfs_rq) { - int i; - unsigned long total_load = 0, total_shares; - struct task_group *tg = cfs_rq->tg; - - /* Gather total task load of this group across cpus */ - for_each_cpu_mask(i, sdspan) - total_load += tg->cfs_rq[i]->load.weight; - - /* Nothing to do if this group has no load */ - if (!total_load) - continue; - - /* - * tg->shares represents the number of cpu shares the task group - * is eligible to hold on a single cpu. On N cpus, it is - * eligible to hold (N * tg->shares) number of cpu shares. - */ - total_shares = tg->shares * cpus_weight(sdspan); - - /* - * redistribute total_shares across cpus as per the task load - * distribution. - */ - for_each_cpu_mask(i, sdspan) { - unsigned long local_load, local_shares; - - local_load = tg->cfs_rq[i]->load.weight; - local_shares = (local_load * total_shares) / total_load; - if (!local_shares) - local_shares = MIN_GROUP_SHARES; - if (local_shares == tg->se[i]->load.weight) - continue; - - spin_lock_irq(&cpu_rq(i)->lock); - set_se_shares(tg->se[i], local_shares); - spin_unlock_irq(&cpu_rq(i)->lock); - balanced = 0; - } - } - - return balanced; -} - -/* - * How frequently should we rebalance_shares() across cpus? - * - * The more frequently we rebalance shares, the more accurate is the fairness - * of cpu bandwidth distribution between task groups. However higher frequency - * also implies increased scheduling overhead. - * - * sysctl_sched_min_bal_int_shares represents the minimum interval between - * consecutive calls to rebalance_shares() in the same sched domain. - * - * sysctl_sched_max_bal_int_shares represents the maximum interval between - * consecutive calls to rebalance_shares() in the same sched domain. - * - * These settings allows for the appropriate trade-off between accuracy of - * fairness and the associated overhead. - * - */ - -/* default: 8ms, units: milliseconds */ -const_debug unsigned int sysctl_sched_min_bal_int_shares = 8; - -/* default: 128ms, units: milliseconds */ -const_debug unsigned int sysctl_sched_max_bal_int_shares = 128; - -/* kernel thread that runs rebalance_shares() periodically */ -static int load_balance_monitor(void *unused) -{ - unsigned int timeout = sysctl_sched_min_bal_int_shares; - struct sched_param schedparm; - int ret; - - /* - * We don't want this thread's execution to be limited by the shares - * assigned to default group (init_task_group). Hence make it run - * as a SCHED_RR RT task at the lowest priority. - */ - schedparm.sched_priority = 1; - ret = sched_setscheduler(current, SCHED_RR, &schedparm); - if (ret) - printk(KERN_ERR "Couldn't set SCHED_RR policy for load balance" - " monitor thread (error = %d) \n", ret); - - while (!kthread_should_stop()) { - int i, cpu, balanced = 1; - - /* Prevent cpus going down or coming up */ - get_online_cpus(); - /* lockout changes to doms_cur[] array */ - lock_doms_cur(); - /* - * Enter a rcu read-side critical section to safely walk rq->sd - * chain on various cpus and to walk task group list - * (rq->leaf_cfs_rq_list) in rebalance_shares(). - */ - rcu_read_lock(); - - for (i = 0; i < ndoms_cur; i++) { - cpumask_t cpumap = doms_cur[i]; - struct sched_domain *sd = NULL, *sd_prev = NULL; - - cpu = first_cpu(cpumap); - - /* Find the highest domain at which to balance shares */ - for_each_domain(cpu, sd) { - if (!(sd->flags & SD_LOAD_BALANCE)) - continue; - sd_prev = sd; - } - - sd = sd_prev; - /* sd == NULL? No load balance reqd in this domain */ - if (!sd) - continue; - - balanced &= rebalance_shares(sd, cpu); - } - - rcu_read_unlock(); - - unlock_doms_cur(); - put_online_cpus(); - - if (!balanced) - timeout = sysctl_sched_min_bal_int_shares; - else if (timeout < sysctl_sched_max_bal_int_shares) - timeout *= 2; - - msleep_interruptible(timeout); - } - - return 0; -} -#endif /* CONFIG_SMP */ - #ifdef CONFIG_FAIR_GROUP_SCHED static void free_fair_sched_group(struct task_group *tg) { @@ -7817,47 +7616,46 @@ void sched_move_task(struct task_struct *tsk) running = task_current(rq, tsk); on_rq = tsk->se.on_rq; - if (on_rq) { + if (on_rq) dequeue_task(rq, tsk, 0); - if (unlikely(running)) - tsk->sched_class->put_prev_task(rq, tsk); - } + if (unlikely(running)) + tsk->sched_class->put_prev_task(rq, tsk); set_task_rq(tsk, task_cpu(tsk)); - if (on_rq) { - if (unlikely(running)) - tsk->sched_class->set_curr_task(rq); +#ifdef CONFIG_FAIR_GROUP_SCHED + if (tsk->sched_class->moved_group) + tsk->sched_class->moved_group(tsk); +#endif + + if (unlikely(running)) + tsk->sched_class->set_curr_task(rq); + if (on_rq) enqueue_task(rq, tsk, 0); - } task_rq_unlock(rq, &flags); } #ifdef CONFIG_FAIR_GROUP_SCHED -/* rq->lock to be locked by caller */ static void set_se_shares(struct sched_entity *se, unsigned long shares) { struct cfs_rq *cfs_rq = se->cfs_rq; struct rq *rq = cfs_rq->rq; int on_rq; - if (!shares) - shares = MIN_GROUP_SHARES; + spin_lock_irq(&rq->lock); on_rq = se->on_rq; - if (on_rq) { + if (on_rq) dequeue_entity(cfs_rq, se, 0); - dec_cpu_load(rq, se->load.weight); - } se->load.weight = shares; se->load.inv_weight = div64_64((1ULL<<32), shares); - if (on_rq) { + if (on_rq) enqueue_entity(cfs_rq, se, 0); - inc_cpu_load(rq, se->load.weight); - } + + spin_unlock_irq(&rq->lock); } static DEFINE_MUTEX(shares_mutex); @@ -7867,18 +7665,18 @@ int sched_group_set_shares(struct task_group *tg, unsigned long shares) int i; unsigned long flags; + /* + * A weight of 0 or 1 can cause arithmetics problems. + * (The default weight is 1024 - so there's no practical + * limitation from this.) + */ + if (shares < 2) + shares = 2; + mutex_lock(&shares_mutex); if (tg->shares == shares) goto done; - if (shares < MIN_GROUP_SHARES) - shares = MIN_GROUP_SHARES; - - /* - * Prevent any load balance activity (rebalance_shares, - * load_balance_fair) from referring to this group first, - * by taking it off the rq->leaf_cfs_rq_list on each cpu. - */ spin_lock_irqsave(&task_group_lock, flags); for_each_possible_cpu(i) unregister_fair_sched_group(tg, i); @@ -7892,11 +7690,8 @@ int sched_group_set_shares(struct task_group *tg, unsigned long shares) * w/o tripping rebalance_share or load_balance_fair. */ tg->shares = shares; - for_each_possible_cpu(i) { - spin_lock_irq(&cpu_rq(i)->lock); + for_each_possible_cpu(i) set_se_shares(tg->se[i], shares); - spin_unlock_irq(&cpu_rq(i)->lock); - } /* * Enable load balance activity on this group, by inserting it back on @@ -7928,9 +7723,7 @@ static unsigned long to_ratio(u64 period, u64 runtime) if (runtime == RUNTIME_INF) return 1ULL << 16; - runtime *= (1ULL << 16); - div64_64(runtime, period); - return runtime; + return div64_64(runtime << 16, period); } static int __rt_schedulable(struct task_group *tg, u64 period, u64 runtime) @@ -7954,25 +7747,40 @@ static int __rt_schedulable(struct task_group *tg, u64 period, u64 runtime) return total + to_ratio(period, runtime) < global_ratio; } +/* Must be called with tasklist_lock held */ +static inline int tg_has_rt_tasks(struct task_group *tg) +{ + struct task_struct *g, *p; + do_each_thread(g, p) { + if (rt_task(p) && rt_rq_of_se(&p->rt)->tg == tg) + return 1; + } while_each_thread(g, p); + return 0; +} + int sched_group_set_rt_runtime(struct task_group *tg, long rt_runtime_us) { u64 rt_runtime, rt_period; int err = 0; - rt_period = sysctl_sched_rt_period * NSEC_PER_USEC; + rt_period = (u64)sysctl_sched_rt_period * NSEC_PER_USEC; rt_runtime = (u64)rt_runtime_us * NSEC_PER_USEC; if (rt_runtime_us == -1) - rt_runtime = rt_period; + rt_runtime = RUNTIME_INF; mutex_lock(&rt_constraints_mutex); + read_lock(&tasklist_lock); + if (rt_runtime_us == 0 && tg_has_rt_tasks(tg)) { + err = -EBUSY; + goto unlock; + } if (!__rt_schedulable(tg, rt_period, rt_runtime)) { err = -EINVAL; goto unlock; } - if (rt_runtime_us == -1) - rt_runtime = RUNTIME_INF; tg->rt_runtime = rt_runtime; unlock: + read_unlock(&tasklist_lock); mutex_unlock(&rt_constraints_mutex); return err; diff --git a/kernel/sched_fair.c b/kernel/sched_fair.c index 6c091d6e159d01fb23c0dd786495c533cb005c5b..f2cc59080efa4f9ae1e12aa30afe2e3fe08a86f9 100644 --- a/kernel/sched_fair.c +++ b/kernel/sched_fair.c @@ -175,8 +175,15 @@ static void __enqueue_entity(struct cfs_rq *cfs_rq, struct sched_entity *se) * Maintain a cache of leftmost tree entries (it is frequently * used): */ - if (leftmost) + if (leftmost) { cfs_rq->rb_leftmost = &se->run_node; + /* + * maintain cfs_rq->min_vruntime to be a monotonic increasing + * value tracking the leftmost vruntime in the tree. + */ + cfs_rq->min_vruntime = + max_vruntime(cfs_rq->min_vruntime, se->vruntime); + } rb_link_node(&se->run_node, parent, link); rb_insert_color(&se->run_node, &cfs_rq->tasks_timeline); @@ -184,8 +191,24 @@ static void __enqueue_entity(struct cfs_rq *cfs_rq, struct sched_entity *se) static void __dequeue_entity(struct cfs_rq *cfs_rq, struct sched_entity *se) { - if (cfs_rq->rb_leftmost == &se->run_node) - cfs_rq->rb_leftmost = rb_next(&se->run_node); + if (cfs_rq->rb_leftmost == &se->run_node) { + struct rb_node *next_node; + struct sched_entity *next; + + next_node = rb_next(&se->run_node); + cfs_rq->rb_leftmost = next_node; + + if (next_node) { + next = rb_entry(next_node, + struct sched_entity, run_node); + cfs_rq->min_vruntime = + max_vruntime(cfs_rq->min_vruntime, + next->vruntime); + } + } + + if (cfs_rq->next == se) + cfs_rq->next = NULL; rb_erase(&se->run_node, &cfs_rq->tasks_timeline); } @@ -202,17 +225,12 @@ static struct sched_entity *__pick_next_entity(struct cfs_rq *cfs_rq) static inline struct sched_entity *__pick_last_entity(struct cfs_rq *cfs_rq) { - struct rb_node **link = &cfs_rq->tasks_timeline.rb_node; - struct sched_entity *se = NULL; - struct rb_node *parent; + struct rb_node *last = rb_last(&cfs_rq->tasks_timeline); - while (*link) { - parent = *link; - se = rb_entry(parent, struct sched_entity, run_node); - link = &parent->rb_right; - } + if (!last) + return NULL; - return se; + return rb_entry(last, struct sched_entity, run_node); } /************************************************************** @@ -265,12 +283,8 @@ static u64 __sched_period(unsigned long nr_running) */ static u64 sched_slice(struct cfs_rq *cfs_rq, struct sched_entity *se) { - u64 slice = __sched_period(cfs_rq->nr_running); - - slice *= se->load.weight; - do_div(slice, cfs_rq->load.weight); - - return slice; + return calc_delta_mine(__sched_period(cfs_rq->nr_running), + se->load.weight, &cfs_rq->load); } /* @@ -308,7 +322,6 @@ __update_curr(struct cfs_rq *cfs_rq, struct sched_entity *curr, unsigned long delta_exec) { unsigned long delta_exec_weighted; - u64 vruntime; schedstat_set(curr->exec_max, max((u64)delta_exec, curr->exec_max)); @@ -320,19 +333,6 @@ __update_curr(struct cfs_rq *cfs_rq, struct sched_entity *curr, &curr->load); } curr->vruntime += delta_exec_weighted; - - /* - * maintain cfs_rq->min_vruntime to be a monotonic increasing - * value tracking the leftmost vruntime in the tree. - */ - if (first_fair(cfs_rq)) { - vruntime = min_vruntime(curr->vruntime, - __pick_next_entity(cfs_rq)->vruntime); - } else - vruntime = curr->vruntime; - - cfs_rq->min_vruntime = - max_vruntime(cfs_rq->min_vruntime, vruntime); } static void update_curr(struct cfs_rq *cfs_rq) @@ -498,7 +498,11 @@ place_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, int initial) { u64 vruntime; - vruntime = cfs_rq->min_vruntime; + if (first_fair(cfs_rq)) { + vruntime = min_vruntime(cfs_rq->min_vruntime, + __pick_next_entity(cfs_rq)->vruntime); + } else + vruntime = cfs_rq->min_vruntime; if (sched_feat(TREE_AVG)) { struct sched_entity *last = __pick_last_entity(cfs_rq); @@ -520,8 +524,10 @@ place_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, int initial) if (!initial) { /* sleeps upto a single latency don't count. */ - if (sched_feat(NEW_FAIR_SLEEPERS)) - vruntime -= sysctl_sched_latency; + if (sched_feat(NEW_FAIR_SLEEPERS)) { + vruntime -= calc_delta_fair(sysctl_sched_latency, + &cfs_rq->load); + } /* ensure we never gain time by being placed backwards. */ vruntime = max_vruntime(se->vruntime, vruntime); @@ -621,12 +627,32 @@ set_next_entity(struct cfs_rq *cfs_rq, struct sched_entity *se) se->prev_sum_exec_runtime = se->sum_exec_runtime; } +static struct sched_entity * +pick_next(struct cfs_rq *cfs_rq, struct sched_entity *se) +{ + s64 diff, gran; + + if (!cfs_rq->next) + return se; + + diff = cfs_rq->next->vruntime - se->vruntime; + if (diff < 0) + return se; + + gran = calc_delta_fair(sysctl_sched_wakeup_granularity, &cfs_rq->load); + if (diff > gran) + return se; + + return cfs_rq->next; +} + static struct sched_entity *pick_next_entity(struct cfs_rq *cfs_rq) { struct sched_entity *se = NULL; if (first_fair(cfs_rq)) { se = __pick_next_entity(cfs_rq); + se = pick_next(cfs_rq, se); set_next_entity(cfs_rq, se); } @@ -732,8 +758,6 @@ static inline struct sched_entity *parent_entity(struct sched_entity *se) return se->parent; } -#define GROUP_IMBALANCE_PCT 20 - #else /* CONFIG_FAIR_GROUP_SCHED */ #define for_each_sched_entity(se) \ @@ -824,26 +848,15 @@ hrtick_start_fair(struct rq *rq, struct task_struct *p) static void enqueue_task_fair(struct rq *rq, struct task_struct *p, int wakeup) { struct cfs_rq *cfs_rq; - struct sched_entity *se = &p->se, - *topse = NULL; /* Highest schedulable entity */ - int incload = 1; + struct sched_entity *se = &p->se; for_each_sched_entity(se) { - topse = se; - if (se->on_rq) { - incload = 0; + if (se->on_rq) break; - } cfs_rq = cfs_rq_of(se); enqueue_entity(cfs_rq, se, wakeup); wakeup = 1; } - /* Increment cpu load if we just enqueued the first task of a group on - * 'rq->cpu'. 'topse' represents the group to which task 'p' belongs - * at the highest grouping level. - */ - if (incload) - inc_cpu_load(rq, topse->load.weight); hrtick_start_fair(rq, rq->curr); } @@ -856,28 +869,16 @@ static void enqueue_task_fair(struct rq *rq, struct task_struct *p, int wakeup) static void dequeue_task_fair(struct rq *rq, struct task_struct *p, int sleep) { struct cfs_rq *cfs_rq; - struct sched_entity *se = &p->se, - *topse = NULL; /* Highest schedulable entity */ - int decload = 1; + struct sched_entity *se = &p->se; for_each_sched_entity(se) { - topse = se; cfs_rq = cfs_rq_of(se); dequeue_entity(cfs_rq, se, sleep); /* Don't dequeue parent if it has other entities besides us */ - if (cfs_rq->load.weight) { - if (parent_entity(se)) - decload = 0; + if (cfs_rq->load.weight) break; - } sleep = 1; } - /* Decrement cpu load if we just dequeued the last task of a group on - * 'rq->cpu'. 'topse' represents the group to which task 'p' belongs - * at the highest grouping level. - */ - if (decload) - dec_cpu_load(rq, topse->load.weight); hrtick_start_fair(rq, rq->curr); } @@ -1090,6 +1091,9 @@ static void check_preempt_wakeup(struct rq *rq, struct task_struct *p) resched_task(curr); return; } + + cfs_rq_of(pse)->next = pse; + /* * Batch tasks do not preempt (their preemption is driven by * the tick): @@ -1191,6 +1195,25 @@ static struct task_struct *load_balance_next_fair(void *arg) return __load_balance_iterator(cfs_rq, cfs_rq->rb_load_balance_curr); } +#ifdef CONFIG_FAIR_GROUP_SCHED +static int cfs_rq_best_prio(struct cfs_rq *cfs_rq) +{ + struct sched_entity *curr; + struct task_struct *p; + + if (!cfs_rq->nr_running || !first_fair(cfs_rq)) + return MAX_PRIO; + + curr = cfs_rq->curr; + if (!curr) + curr = __pick_next_entity(cfs_rq); + + p = task_of(curr); + + return p->prio; +} +#endif + static unsigned long load_balance_fair(struct rq *this_rq, int this_cpu, struct rq *busiest, unsigned long max_load_move, @@ -1200,45 +1223,28 @@ load_balance_fair(struct rq *this_rq, int this_cpu, struct rq *busiest, struct cfs_rq *busy_cfs_rq; long rem_load_move = max_load_move; struct rq_iterator cfs_rq_iterator; - unsigned long load_moved; cfs_rq_iterator.start = load_balance_start_fair; cfs_rq_iterator.next = load_balance_next_fair; for_each_leaf_cfs_rq(busiest, busy_cfs_rq) { #ifdef CONFIG_FAIR_GROUP_SCHED - struct cfs_rq *this_cfs_rq = busy_cfs_rq->tg->cfs_rq[this_cpu]; - unsigned long maxload, task_load, group_weight; - unsigned long thisload, per_task_load; - struct sched_entity *se = busy_cfs_rq->tg->se[busiest->cpu]; + struct cfs_rq *this_cfs_rq; + long imbalance; + unsigned long maxload; - task_load = busy_cfs_rq->load.weight; - group_weight = se->load.weight; + this_cfs_rq = cpu_cfs_rq(busy_cfs_rq, this_cpu); - /* - * 'group_weight' is contributed by tasks of total weight - * 'task_load'. To move 'rem_load_move' worth of weight only, - * we need to move a maximum task load of: - * - * maxload = (remload / group_weight) * task_load; - */ - maxload = (rem_load_move * task_load) / group_weight; - - if (!maxload || !task_load) + imbalance = busy_cfs_rq->load.weight - this_cfs_rq->load.weight; + /* Don't pull if this_cfs_rq has more load than busy_cfs_rq */ + if (imbalance <= 0) continue; - per_task_load = task_load / busy_cfs_rq->nr_running; - /* - * balance_tasks will try to forcibly move atleast one task if - * possible (because of SCHED_LOAD_SCALE_FUZZ). Avoid that if - * maxload is less than GROUP_IMBALANCE_FUZZ% the per_task_load. - */ - if (100 * maxload < GROUP_IMBALANCE_PCT * per_task_load) - continue; + /* Don't pull more than imbalance/2 */ + imbalance /= 2; + maxload = min(rem_load_move, imbalance); - /* Disable priority-based load balance */ - *this_best_prio = 0; - thisload = this_cfs_rq->load.weight; + *this_best_prio = cfs_rq_best_prio(this_cfs_rq); #else # define maxload rem_load_move #endif @@ -1247,33 +1253,11 @@ load_balance_fair(struct rq *this_rq, int this_cpu, struct rq *busiest, * load_balance_[start|next]_fair iterators */ cfs_rq_iterator.arg = busy_cfs_rq; - load_moved = balance_tasks(this_rq, this_cpu, busiest, + rem_load_move -= balance_tasks(this_rq, this_cpu, busiest, maxload, sd, idle, all_pinned, this_best_prio, &cfs_rq_iterator); -#ifdef CONFIG_FAIR_GROUP_SCHED - /* - * load_moved holds the task load that was moved. The - * effective (group) weight moved would be: - * load_moved_eff = load_moved/task_load * group_weight; - */ - load_moved = (group_weight * load_moved) / task_load; - - /* Adjust shares on both cpus to reflect load_moved */ - group_weight -= load_moved; - set_se_shares(se, group_weight); - - se = busy_cfs_rq->tg->se[this_cpu]; - if (!thisload) - group_weight = load_moved; - else - group_weight = se->load.weight + load_moved; - set_se_shares(se, group_weight); -#endif - - rem_load_move -= load_moved; - if (rem_load_move <= 0) break; } @@ -1403,6 +1387,16 @@ static void set_curr_task_fair(struct rq *rq) set_next_entity(cfs_rq_of(se), se); } +#ifdef CONFIG_FAIR_GROUP_SCHED +static void moved_group_fair(struct task_struct *p) +{ + struct cfs_rq *cfs_rq = task_cfs_rq(p); + + update_curr(cfs_rq); + place_entity(cfs_rq, &p->se, 1); +} +#endif + /* * All the scheduling class methods: */ @@ -1431,6 +1425,10 @@ static const struct sched_class fair_sched_class = { .prio_changed = prio_changed_fair, .switched_to = switched_to_fair, + +#ifdef CONFIG_FAIR_GROUP_SCHED + .moved_group = moved_group_fair, +#endif }; #ifdef CONFIG_SCHED_DEBUG diff --git a/kernel/sched_rt.c b/kernel/sched_rt.c index f54792b175b26a331df3e133a8b7f854122eefdf..0a6d2e516420516cb1d0c35a5345db1f356f71ab 100644 --- a/kernel/sched_rt.c +++ b/kernel/sched_rt.c @@ -393,8 +393,6 @@ static void enqueue_task_rt(struct rq *rq, struct task_struct *p, int wakeup) */ for_each_sched_rt_entity(rt_se) enqueue_rt_entity(rt_se); - - inc_cpu_load(rq, p->se.load.weight); } static void dequeue_task_rt(struct rq *rq, struct task_struct *p, int sleep) @@ -414,8 +412,6 @@ static void dequeue_task_rt(struct rq *rq, struct task_struct *p, int sleep) if (rt_rq && rt_rq->rt_nr_running) enqueue_rt_entity(rt_se); } - - dec_cpu_load(rq, p->se.load.weight); } /* @@ -1111,9 +1107,11 @@ static void prio_changed_rt(struct rq *rq, struct task_struct *p, pull_rt_task(rq); /* * If there's a higher priority task waiting to run - * then reschedule. + * then reschedule. Note, the above pull_rt_task + * can release the rq lock and p could migrate. + * Only reschedule if p is still on the same runqueue. */ - if (p->prio > rq->rt.highest_prio) + if (p->prio > rq->rt.highest_prio && rq->curr == p) resched_task(p); #else /* For UP simply resched on drop of prio */ diff --git a/kernel/signal.c b/kernel/signal.c index 84917fe507f77b8ff949af7f958e11ac2ed423b7..6af1210092c39a45db3552ecc9199728f8938410 100644 --- a/kernel/signal.c +++ b/kernel/signal.c @@ -1623,7 +1623,6 @@ static void ptrace_stop(int exit_code, int clear_code, siginfo_t *info) /* Let the debugger run. */ __set_current_state(TASK_TRACED); spin_unlock_irq(¤t->sighand->siglock); - try_to_freeze(); read_lock(&tasklist_lock); if (!unlikely(killed) && may_ptrace_stop()) { do_notify_parent_cldstop(current, CLD_TRAPPED); @@ -1640,6 +1639,13 @@ static void ptrace_stop(int exit_code, int clear_code, siginfo_t *info) read_unlock(&tasklist_lock); } + /* + * While in TASK_TRACED, we were considered "frozen enough". + * Now that we woke up, it's crucial if we're supposed to be + * frozen that we freeze now before running anything substantial. + */ + try_to_freeze(); + /* * We are back. Now reacquire the siglock before touching * last_siginfo, so that we are sure to have synchronized with @@ -1757,9 +1763,15 @@ int get_signal_to_deliver(siginfo_t *info, struct k_sigaction *return_ka, sigset_t *mask = ¤t->blocked; int signr = 0; +relock: + /* + * We'll jump back here after any time we were stopped in TASK_STOPPED. + * While in TASK_STOPPED, we were considered "frozen enough". + * Now that we woke up, it's crucial if we're supposed to be + * frozen that we freeze now before running anything substantial. + */ try_to_freeze(); -relock: spin_lock_irq(¤t->sighand->siglock); for (;;) { struct k_sigaction *ka; diff --git a/kernel/softirq.c b/kernel/softirq.c index 5b3aea5f471e06a2bac64ad232dce64e60650ea4..31e9f2a4792847388b524d313bc389bd8cd4cf20 100644 --- a/kernel/softirq.c +++ b/kernel/softirq.c @@ -313,6 +313,7 @@ void irq_exit(void) /* Make sure that timer wheel updates are propagated */ if (!in_interrupt() && idle_cpu(smp_processor_id()) && !need_resched()) tick_nohz_stop_sched_tick(); + rcu_irq_exit(); #endif preempt_enable_no_resched(); } diff --git a/kernel/softlockup.c b/kernel/softlockup.c index 7c2da88db4eddf6539673357b01d94b543aac52c..01b6522fd92bc0b28f7df00eb66876a389b34908 100644 --- a/kernel/softlockup.c +++ b/kernel/softlockup.c @@ -216,26 +216,27 @@ static int watchdog(void *__bind_cpu) /* initialize timestamp */ touch_softlockup_watchdog(); + set_current_state(TASK_INTERRUPTIBLE); /* * Run briefly once per second to reset the softlockup timestamp. * If this gets delayed for more than 60 seconds then the * debug-printout triggers in softlockup_tick(). */ while (!kthread_should_stop()) { - set_current_state(TASK_INTERRUPTIBLE); touch_softlockup_watchdog(); schedule(); if (kthread_should_stop()) break; - if (this_cpu != check_cpu) - continue; - - if (sysctl_hung_task_timeout_secs) - check_hung_uninterruptible_tasks(this_cpu); + if (this_cpu == check_cpu) { + if (sysctl_hung_task_timeout_secs) + check_hung_uninterruptible_tasks(this_cpu); + } + set_current_state(TASK_INTERRUPTIBLE); } + __set_current_state(TASK_RUNNING); return 0; } diff --git a/kernel/sysctl.c b/kernel/sysctl.c index 8b7e95411795793724f036594e1446e32f1e444b..b2a2d6889babc898794e7c7fb7907ef59a3b487b 100644 --- a/kernel/sysctl.c +++ b/kernel/sysctl.c @@ -311,24 +311,6 @@ static struct ctl_table kern_table[] = { .mode = 0644, .proc_handler = &proc_dointvec, }, -#if defined(CONFIG_FAIR_GROUP_SCHED) && defined(CONFIG_SMP) - { - .ctl_name = CTL_UNNUMBERED, - .procname = "sched_min_bal_int_shares", - .data = &sysctl_sched_min_bal_int_shares, - .maxlen = sizeof(unsigned int), - .mode = 0644, - .proc_handler = &proc_dointvec, - }, - { - .ctl_name = CTL_UNNUMBERED, - .procname = "sched_max_bal_int_shares", - .data = &sysctl_sched_max_bal_int_shares, - .maxlen = sizeof(unsigned int), - .mode = 0644, - .proc_handler = &proc_dointvec, - }, -#endif #endif { .ctl_name = CTL_UNNUMBERED, diff --git a/kernel/time/ntp.c b/kernel/time/ntp.c index c88b5910e7abb9c630106fcbf21b6b7a0d363faf..5fd9b946977038cbdc192dc5a11146696ad53947 100644 --- a/kernel/time/ntp.c +++ b/kernel/time/ntp.c @@ -42,12 +42,13 @@ long time_esterror = NTP_PHASE_LIMIT; /* estimated error (us) */ long time_freq; /* frequency offset (scaled ppm)*/ static long time_reftime; /* time at last adjustment (s) */ long time_adjust; +static long ntp_tick_adj; static void ntp_update_frequency(void) { u64 second_length = (u64)(tick_usec * NSEC_PER_USEC * USER_HZ) << TICK_LENGTH_SHIFT; - second_length += (s64)CLOCK_TICK_ADJUST << TICK_LENGTH_SHIFT; + second_length += (s64)ntp_tick_adj << TICK_LENGTH_SHIFT; second_length += (s64)time_freq << (TICK_LENGTH_SHIFT - SHIFT_NSEC); tick_length_base = second_length; @@ -342,14 +343,16 @@ int do_adjtimex(struct timex *txc) freq_adj = shift_right(freq_adj, time_constant * 2 + (SHIFT_PLL + 2) * 2 - SHIFT_NSEC); if (mtemp >= MINSEC && (time_status & STA_FLL || mtemp > MAXSEC)) { + u64 utemp64; temp64 = time_offset << (SHIFT_NSEC - SHIFT_FLL); if (time_offset < 0) { - temp64 = -temp64; - do_div(temp64, mtemp); - freq_adj -= temp64; + utemp64 = -temp64; + do_div(utemp64, mtemp); + freq_adj -= utemp64; } else { - do_div(temp64, mtemp); - freq_adj += temp64; + utemp64 = temp64; + do_div(utemp64, mtemp); + freq_adj += utemp64; } } freq_adj += time_freq; @@ -400,3 +403,11 @@ leave: if ((time_status & (STA_UNSYNC|STA_CLOCKERR)) != 0) notify_cmos_timer(); return(result); } + +static int __init ntp_tick_adj_setup(char *str) +{ + ntp_tick_adj = simple_strtol(str, NULL, 0); + return 1; +} + +__setup("ntp_tick_adj=", ntp_tick_adj_setup); diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c index fa9bb73dbdb41c4678ca0ad1da01ebcaf5e46cc1..686da821d376b01dd21d379bfd8baf39d6b106f1 100644 --- a/kernel/time/tick-sched.c +++ b/kernel/time/tick-sched.c @@ -282,6 +282,7 @@ void tick_nohz_stop_sched_tick(void) ts->idle_tick = ts->sched_timer.expires; ts->tick_stopped = 1; ts->idle_jiffies = last_jiffies; + rcu_enter_nohz(); } /* @@ -375,6 +376,8 @@ void tick_nohz_restart_sched_tick(void) return; } + rcu_exit_nohz(); + /* Update jiffies first */ select_nohz_load_balancer(0); now = ktime_get(); @@ -637,7 +640,7 @@ void tick_cancel_sched_timer(int cpu) if (ts->sched_timer.base) hrtimer_cancel(&ts->sched_timer); - ts->tick_stopped = 0; + ts->nohz_mode = NOHZ_MODE_INACTIVE; } #endif /* HIGH_RES_TIMERS */ diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c index 1af9fb050fe28b1e77ae9f43c3005e16972b2d65..671af612b7684ed27578ae3db8445f71f3499059 100644 --- a/kernel/time/timekeeping.c +++ b/kernel/time/timekeeping.c @@ -187,8 +187,7 @@ static void change_clocksource(void) clock->error = 0; clock->xtime_nsec = 0; - clocksource_calculate_interval(clock, - (unsigned long)(current_tick_length()>>TICK_LENGTH_SHIFT)); + clocksource_calculate_interval(clock, NTP_INTERVAL_LENGTH); tick_clock_notify(); @@ -245,8 +244,7 @@ void __init timekeeping_init(void) ntp_clear(); clock = clocksource_get_next(); - clocksource_calculate_interval(clock, - (unsigned long)(current_tick_length()>>TICK_LENGTH_SHIFT)); + clocksource_calculate_interval(clock, NTP_INTERVAL_LENGTH); clock->cycle_last = clocksource_read(clock); xtime.tv_sec = sec; diff --git a/lib/devres.c b/lib/devres.c index b1d336ce7f3d0c34f694844c8bd7dfd0f1dc687d..edc27a5d1b735aba4855d33e9756ab375d9569ce 100644 --- a/lib/devres.c +++ b/lib/devres.c @@ -297,6 +297,31 @@ int pcim_iomap_regions(struct pci_dev *pdev, u16 mask, const char *name) } EXPORT_SYMBOL(pcim_iomap_regions); +/** + * pcim_iomap_regions_request_all - Request all BARs and iomap specified ones + * @pdev: PCI device to map IO resources for + * @mask: Mask of BARs to iomap + * @name: Name used when requesting regions + * + * Request all PCI BARs and iomap regions specified by @mask. + */ +int pcim_iomap_regions_request_all(struct pci_dev *pdev, u16 mask, + const char *name) +{ + int request_mask = ((1 << 6) - 1) & ~mask; + int rc; + + rc = pci_request_selected_regions(pdev, request_mask, name); + if (rc) + return rc; + + rc = pcim_iomap_regions(pdev, mask, name); + if (rc) + pci_release_selected_regions(pdev, request_mask); + return rc; +} +EXPORT_SYMBOL(pcim_iomap_regions_request_all); + /** * pcim_iounmap_regions - Unmap and release PCI BARs * @pdev: PCI device to map IO resources for diff --git a/lib/iommu-helper.c b/lib/iommu-helper.c index 495575a59ca643f752a2314b44e5e0e77a2963f5..a3b8d4c3f77a5e7e466bd8f5e5591f3dcaa2c3bd 100644 --- a/lib/iommu-helper.c +++ b/lib/iommu-helper.c @@ -40,10 +40,12 @@ static inline void set_bit_area(unsigned long *map, unsigned long i, } } -static inline int is_span_boundary(unsigned int index, unsigned int nr, - unsigned long shift, - unsigned long boundary_size) +int iommu_is_span_boundary(unsigned int index, unsigned int nr, + unsigned long shift, + unsigned long boundary_size) { + BUG_ON(!is_power_of_2(boundary_size)); + shift = (shift + index) & (boundary_size - 1); return shift + nr > boundary_size; } @@ -57,7 +59,7 @@ unsigned long iommu_area_alloc(unsigned long *map, unsigned long size, again: index = find_next_zero_area(map, size, start, nr, align_mask); if (index != -1) { - if (is_span_boundary(index, nr, shift, boundary_size)) { + if (iommu_is_span_boundary(index, nr, shift, boundary_size)) { /* we could do more effectively */ start = index + 1; goto again; diff --git a/lib/kobject.c b/lib/kobject.c index d784daeb8571692e0fed288f17df60651a04366c..0d03252f87a8535db2a9fe00632560c6fa337f24 100644 --- a/lib/kobject.c +++ b/lib/kobject.c @@ -153,6 +153,10 @@ static void kobject_init_internal(struct kobject *kobj) return; kref_init(&kobj->kref); INIT_LIST_HEAD(&kobj->entry); + kobj->state_in_sysfs = 0; + kobj->state_add_uevent_sent = 0; + kobj->state_remove_uevent_sent = 0; + kobj->state_initialized = 1; } @@ -289,13 +293,8 @@ void kobject_init(struct kobject *kobj, struct kobj_type *ktype) dump_stack(); } - kref_init(&kobj->kref); - INIT_LIST_HEAD(&kobj->entry); + kobject_init_internal(kobj); kobj->ktype = ktype; - kobj->state_in_sysfs = 0; - kobj->state_add_uevent_sent = 0; - kobj->state_remove_uevent_sent = 0; - kobj->state_initialized = 1; return; error: diff --git a/lib/swiotlb.c b/lib/swiotlb.c index 4bb5a11e18a289e6bcf3a89ca41b0a13fb0b40cc..025922807e6e648bb7dc4eda61bfd8fa609a221c 100644 --- a/lib/swiotlb.c +++ b/lib/swiotlb.c @@ -310,7 +310,9 @@ map_single(struct device *hwdev, char *buffer, size_t size, int dir) start_dma_addr = virt_to_bus(io_tlb_start) & mask; offset_slots = ALIGN(start_dma_addr, 1 << IO_TLB_SHIFT) >> IO_TLB_SHIFT; - max_slots = ALIGN(mask + 1, 1 << IO_TLB_SHIFT) >> IO_TLB_SHIFT; + max_slots = mask + 1 + ? ALIGN(mask + 1, 1 << IO_TLB_SHIFT) >> IO_TLB_SHIFT + : 1UL << (BITS_PER_LONG - IO_TLB_SHIFT); /* * For mappings greater than a page, we limit the stride (and @@ -333,16 +335,18 @@ map_single(struct device *hwdev, char *buffer, size_t size, int dir) index = ALIGN(io_tlb_index, stride); if (index >= io_tlb_nslabs) index = 0; - - while (is_span_boundary(index, nslots, offset_slots, - max_slots)) { - index += stride; - if (index >= io_tlb_nslabs) - index = 0; - } wrap = index; do { + while (is_span_boundary(index, nslots, offset_slots, + max_slots)) { + index += stride; + if (index >= io_tlb_nslabs) + index = 0; + if (index == wrap) + goto not_found; + } + /* * If we find a slot that indicates we have 'nslots' * number of contiguous buffers, we allocate the @@ -367,14 +371,12 @@ map_single(struct device *hwdev, char *buffer, size_t size, int dir) goto found; } - do { - index += stride; - if (index >= io_tlb_nslabs) - index = 0; - } while (is_span_boundary(index, nslots, offset_slots, - max_slots)); + index += stride; + if (index >= io_tlb_nslabs) + index = 0; } while (index != wrap); + not_found: spin_unlock_irqrestore(&io_tlb_lock, flags); return NULL; } diff --git a/mm/Makefile b/mm/Makefile index 9f117bab5322e59b49cba45146b0e54176d206ca..a5b0dd93427a7266d7a26dcc7fd1266c602725fb 100644 --- a/mm/Makefile +++ b/mm/Makefile @@ -32,5 +32,5 @@ obj-$(CONFIG_FS_XIP) += filemap_xip.o obj-$(CONFIG_MIGRATION) += migrate.o obj-$(CONFIG_SMP) += allocpercpu.o obj-$(CONFIG_QUICKLIST) += quicklist.o -obj-$(CONFIG_CGROUP_MEM_CONT) += memcontrol.o +obj-$(CONFIG_CGROUP_MEM_RES_CTLR) += memcontrol.o diff --git a/mm/allocpercpu.c b/mm/allocpercpu.c index 7e58322b7134ff1d04e40269e030bdd53e1c87f6..b0012e27fea8796da01cfb2172d1d5930c60d22f 100644 --- a/mm/allocpercpu.c +++ b/mm/allocpercpu.c @@ -6,6 +6,10 @@ #include #include +#ifndef cache_line_size +#define cache_line_size() L1_CACHE_BYTES +#endif + /** * percpu_depopulate - depopulate per-cpu data for given cpu * @__pdata: per-cpu data to depopulate @@ -52,6 +56,11 @@ void *percpu_populate(void *__pdata, size_t size, gfp_t gfp, int cpu) struct percpu_data *pdata = __percpu_disguise(__pdata); int node = cpu_to_node(cpu); + /* + * We should make sure each CPU gets private memory. + */ + size = roundup(size, cache_line_size()); + BUG_ON(pdata->ptrs[cpu]); if (node_online(node)) pdata->ptrs[cpu] = kmalloc_node(size, gfp|__GFP_ZERO, node); @@ -98,7 +107,11 @@ EXPORT_SYMBOL_GPL(__percpu_populate_mask); */ void *__percpu_alloc_mask(size_t size, gfp_t gfp, cpumask_t *mask) { - void *pdata = kzalloc(nr_cpu_ids * sizeof(void *), gfp); + /* + * We allocate whole cache lines to avoid false sharing + */ + size_t sz = roundup(nr_cpu_ids * sizeof(void *), cache_line_size()); + void *pdata = kzalloc(sz, gfp); void *__pdata = __percpu_disguise(pdata); if (unlikely(!pdata)) diff --git a/mm/filemap.c b/mm/filemap.c index 5c74b68935acde87e1b9a91152b399a408509cf7..df343d1e6345ffb33ef3fa4eacf6c784c0ef8178 100644 --- a/mm/filemap.c +++ b/mm/filemap.c @@ -28,7 +28,6 @@ #include #include #include -#include #include #include #include @@ -1743,21 +1742,27 @@ size_t iov_iter_copy_from_user(struct page *page, } EXPORT_SYMBOL(iov_iter_copy_from_user); -static void __iov_iter_advance_iov(struct iov_iter *i, size_t bytes) +void iov_iter_advance(struct iov_iter *i, size_t bytes) { + BUG_ON(i->count < bytes); + if (likely(i->nr_segs == 1)) { i->iov_offset += bytes; + i->count -= bytes; } else { const struct iovec *iov = i->iov; size_t base = i->iov_offset; /* * The !iov->iov_len check ensures we skip over unlikely - * zero-length segments. + * zero-length segments (without overruning the iovec). */ - while (bytes || !iov->iov_len) { - int copy = min(bytes, iov->iov_len - base); + while (bytes || unlikely(!iov->iov_len && i->count)) { + int copy; + copy = min(bytes, iov->iov_len - base); + BUG_ON(!i->count || i->count < copy); + i->count -= copy; bytes -= copy; base += copy; if (iov->iov_len == base) { @@ -1769,14 +1774,6 @@ static void __iov_iter_advance_iov(struct iov_iter *i, size_t bytes) i->iov_offset = base; } } - -void iov_iter_advance(struct iov_iter *i, size_t bytes) -{ - BUG_ON(i->count < bytes); - - __iov_iter_advance_iov(i, bytes); - i->count -= bytes; -} EXPORT_SYMBOL(iov_iter_advance); /* diff --git a/mm/hugetlb.c b/mm/hugetlb.c index 89e6286a7f57823e0427b7eeb84e6e39340764e1..74c1b6b0b37b82dce75e06533c989ab73001afeb 100644 --- a/mm/hugetlb.c +++ b/mm/hugetlb.c @@ -71,7 +71,25 @@ static void enqueue_huge_page(struct page *page) free_huge_pages_node[nid]++; } -static struct page *dequeue_huge_page(struct vm_area_struct *vma, +static struct page *dequeue_huge_page(void) +{ + int nid; + struct page *page = NULL; + + for (nid = 0; nid < MAX_NUMNODES; ++nid) { + if (!list_empty(&hugepage_freelists[nid])) { + page = list_entry(hugepage_freelists[nid].next, + struct page, lru); + list_del(&page->lru); + free_huge_pages--; + free_huge_pages_node[nid]--; + break; + } + } + return page; +} + +static struct page *dequeue_huge_page_vma(struct vm_area_struct *vma, unsigned long address) { int nid; @@ -268,6 +286,12 @@ static struct page *alloc_buddy_huge_page(struct vm_area_struct *vma, spin_lock(&hugetlb_lock); if (page) { + /* + * This page is now managed by the hugetlb allocator and has + * no users -- drop the buddy allocator's reference. + */ + put_page_testzero(page); + VM_BUG_ON(page_count(page)); nid = page_to_nid(page); set_compound_page_dtor(page, free_huge_page); /* @@ -296,8 +320,10 @@ static int gather_surplus_pages(int delta) int needed, allocated; needed = (resv_huge_pages + delta) - free_huge_pages; - if (needed <= 0) + if (needed <= 0) { + resv_huge_pages += delta; return 0; + } allocated = 0; INIT_LIST_HEAD(&surplus_list); @@ -335,9 +361,12 @@ retry: * The surplus_list now contains _at_least_ the number of extra pages * needed to accomodate the reservation. Add the appropriate number * of pages to the hugetlb pool and free the extras back to the buddy - * allocator. + * allocator. Commit the entire reservation here to prevent another + * process from stealing the pages as they are added to the pool but + * before they are reserved. */ needed += allocated; + resv_huge_pages += delta; ret = 0; free: list_for_each_entry_safe(page, tmp, &surplus_list, lru) { @@ -346,13 +375,14 @@ free: enqueue_huge_page(page); else { /* - * Decrement the refcount and free the page using its - * destructor. This must be done with hugetlb_lock + * The page has a reference count of zero already, so + * call free_huge_page directly instead of using + * put_page. This must be done with hugetlb_lock * unlocked which is safe because free_huge_page takes * hugetlb_lock before deciding how to free the page. */ spin_unlock(&hugetlb_lock); - put_page(page); + free_huge_page(page); spin_lock(&hugetlb_lock); } } @@ -371,6 +401,9 @@ static void return_unused_surplus_pages(unsigned long unused_resv_pages) struct page *page; unsigned long nr_pages; + /* Uncommit the reservation */ + resv_huge_pages -= unused_resv_pages; + nr_pages = min(unused_resv_pages, surplus_huge_pages); while (nr_pages) { @@ -402,7 +435,7 @@ static struct page *alloc_huge_page_shared(struct vm_area_struct *vma, struct page *page; spin_lock(&hugetlb_lock); - page = dequeue_huge_page(vma, addr); + page = dequeue_huge_page_vma(vma, addr); spin_unlock(&hugetlb_lock); return page ? page : ERR_PTR(-VM_FAULT_OOM); } @@ -417,7 +450,7 @@ static struct page *alloc_huge_page_private(struct vm_area_struct *vma, spin_lock(&hugetlb_lock); if (free_huge_pages > resv_huge_pages) - page = dequeue_huge_page(vma, addr); + page = dequeue_huge_page_vma(vma, addr); spin_unlock(&hugetlb_lock); if (!page) { page = alloc_buddy_huge_page(vma, addr); @@ -570,7 +603,7 @@ static unsigned long set_max_huge_pages(unsigned long count) min_count = max(count, min_count); try_to_free_low(min_count); while (min_count < persistent_huge_pages) { - struct page *page = dequeue_huge_page(NULL, 0); + struct page *page = dequeue_huge_page(); if (!page) break; update_and_free_page(page); @@ -1205,12 +1238,13 @@ static int hugetlb_acct_memory(long delta) if (gather_surplus_pages(delta) < 0) goto out; - if (delta > cpuset_mems_nr(free_huge_pages_node)) + if (delta > cpuset_mems_nr(free_huge_pages_node)) { + return_unused_surplus_pages(delta); goto out; + } } ret = 0; - resv_huge_pages += delta; if (delta < 0) return_unused_surplus_pages((unsigned long) -delta); diff --git a/mm/memcontrol.c b/mm/memcontrol.c index 631002d085d1374dfdfe734f761aaf3e6a65dde3..8b9f6cae938e98090a8850ba31a8aaf24cc1a1c7 100644 --- a/mm/memcontrol.c +++ b/mm/memcontrol.c @@ -137,14 +137,21 @@ struct mem_cgroup { */ struct mem_cgroup_stat stat; }; +static struct mem_cgroup init_mem_cgroup; /* * We use the lower bit of the page->page_cgroup pointer as a bit spin - * lock. We need to ensure that page->page_cgroup is atleast two - * byte aligned (based on comments from Nick Piggin) + * lock. We need to ensure that page->page_cgroup is at least two + * byte aligned (based on comments from Nick Piggin). But since + * bit_spin_lock doesn't actually set that lock bit in a non-debug + * uniprocessor kernel, we should avoid setting it here too. */ #define PAGE_CGROUP_LOCK_BIT 0x0 -#define PAGE_CGROUP_LOCK (1 << PAGE_CGROUP_LOCK_BIT) +#if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK) +#define PAGE_CGROUP_LOCK (1 << PAGE_CGROUP_LOCK_BIT) +#else +#define PAGE_CGROUP_LOCK 0x0 +#endif /* * A page_cgroup page is associated with every page descriptor. The @@ -154,37 +161,27 @@ struct page_cgroup { struct list_head lru; /* per cgroup LRU list */ struct page *page; struct mem_cgroup *mem_cgroup; - atomic_t ref_cnt; /* Helpful when pages move b/w */ - /* mapped and cached states */ - int flags; + int ref_cnt; /* cached, mapped, migrating */ + int flags; }; #define PAGE_CGROUP_FLAG_CACHE (0x1) /* charged as cache */ #define PAGE_CGROUP_FLAG_ACTIVE (0x2) /* page is active in this cgroup */ -static inline int page_cgroup_nid(struct page_cgroup *pc) +static int page_cgroup_nid(struct page_cgroup *pc) { return page_to_nid(pc->page); } -static inline enum zone_type page_cgroup_zid(struct page_cgroup *pc) +static enum zone_type page_cgroup_zid(struct page_cgroup *pc) { return page_zonenum(pc->page); } -enum { - MEM_CGROUP_TYPE_UNSPEC = 0, - MEM_CGROUP_TYPE_MAPPED, - MEM_CGROUP_TYPE_CACHED, - MEM_CGROUP_TYPE_ALL, - MEM_CGROUP_TYPE_MAX, -}; - enum charge_type { MEM_CGROUP_CHARGE_TYPE_CACHE = 0, MEM_CGROUP_CHARGE_TYPE_MAPPED, }; - /* * Always modified under lru lock. Then, not necessary to preempt_disable() */ @@ -193,23 +190,21 @@ static void mem_cgroup_charge_statistics(struct mem_cgroup *mem, int flags, { int val = (charge)? 1 : -1; struct mem_cgroup_stat *stat = &mem->stat; - VM_BUG_ON(!irqs_disabled()); + VM_BUG_ON(!irqs_disabled()); if (flags & PAGE_CGROUP_FLAG_CACHE) - __mem_cgroup_stat_add_safe(stat, - MEM_CGROUP_STAT_CACHE, val); + __mem_cgroup_stat_add_safe(stat, MEM_CGROUP_STAT_CACHE, val); else __mem_cgroup_stat_add_safe(stat, MEM_CGROUP_STAT_RSS, val); } -static inline struct mem_cgroup_per_zone * +static struct mem_cgroup_per_zone * mem_cgroup_zoneinfo(struct mem_cgroup *mem, int nid, int zid) { - BUG_ON(!mem->info.nodeinfo[nid]); return &mem->info.nodeinfo[nid]->zoneinfo[zid]; } -static inline struct mem_cgroup_per_zone * +static struct mem_cgroup_per_zone * page_cgroup_zoneinfo(struct page_cgroup *pc) { struct mem_cgroup *mem = pc->mem_cgroup; @@ -234,18 +229,14 @@ static unsigned long mem_cgroup_get_all_zonestat(struct mem_cgroup *mem, return total; } -static struct mem_cgroup init_mem_cgroup; - -static inline -struct mem_cgroup *mem_cgroup_from_cont(struct cgroup *cont) +static struct mem_cgroup *mem_cgroup_from_cont(struct cgroup *cont) { return container_of(cgroup_subsys_state(cont, mem_cgroup_subsys_id), struct mem_cgroup, css); } -static inline -struct mem_cgroup *mem_cgroup_from_task(struct task_struct *p) +static struct mem_cgroup *mem_cgroup_from_task(struct task_struct *p) { return container_of(task_subsys_state(p, mem_cgroup_subsys_id), struct mem_cgroup, css); @@ -267,81 +258,33 @@ void mm_free_cgroup(struct mm_struct *mm) static inline int page_cgroup_locked(struct page *page) { - return bit_spin_is_locked(PAGE_CGROUP_LOCK_BIT, - &page->page_cgroup); + return bit_spin_is_locked(PAGE_CGROUP_LOCK_BIT, &page->page_cgroup); } -void page_assign_page_cgroup(struct page *page, struct page_cgroup *pc) +static void page_assign_page_cgroup(struct page *page, struct page_cgroup *pc) { - int locked; - - /* - * While resetting the page_cgroup we might not hold the - * page_cgroup lock. free_hot_cold_page() is an example - * of such a scenario - */ - if (pc) - VM_BUG_ON(!page_cgroup_locked(page)); - locked = (page->page_cgroup & PAGE_CGROUP_LOCK); - page->page_cgroup = ((unsigned long)pc | locked); + VM_BUG_ON(!page_cgroup_locked(page)); + page->page_cgroup = ((unsigned long)pc | PAGE_CGROUP_LOCK); } struct page_cgroup *page_get_page_cgroup(struct page *page) { - return (struct page_cgroup *) - (page->page_cgroup & ~PAGE_CGROUP_LOCK); + return (struct page_cgroup *) (page->page_cgroup & ~PAGE_CGROUP_LOCK); } -static void __always_inline lock_page_cgroup(struct page *page) +static void lock_page_cgroup(struct page *page) { bit_spin_lock(PAGE_CGROUP_LOCK_BIT, &page->page_cgroup); - VM_BUG_ON(!page_cgroup_locked(page)); -} - -static void __always_inline unlock_page_cgroup(struct page *page) -{ - bit_spin_unlock(PAGE_CGROUP_LOCK_BIT, &page->page_cgroup); } -/* - * Tie new page_cgroup to struct page under lock_page_cgroup() - * This can fail if the page has been tied to a page_cgroup. - * If success, returns 0. - */ -static int page_cgroup_assign_new_page_cgroup(struct page *page, - struct page_cgroup *pc) +static int try_lock_page_cgroup(struct page *page) { - int ret = 0; - - lock_page_cgroup(page); - if (!page_get_page_cgroup(page)) - page_assign_page_cgroup(page, pc); - else /* A page is tied to other pc. */ - ret = 1; - unlock_page_cgroup(page); - return ret; + return bit_spin_trylock(PAGE_CGROUP_LOCK_BIT, &page->page_cgroup); } -/* - * Clear page->page_cgroup member under lock_page_cgroup(). - * If given "pc" value is different from one page->page_cgroup, - * page->cgroup is not cleared. - * Returns a value of page->page_cgroup at lock taken. - * A can can detect failure of clearing by following - * clear_page_cgroup(page, pc) == pc - */ - -static struct page_cgroup *clear_page_cgroup(struct page *page, - struct page_cgroup *pc) +static void unlock_page_cgroup(struct page *page) { - struct page_cgroup *ret; - /* lock and clear */ - lock_page_cgroup(page); - ret = page_get_page_cgroup(page); - if (likely(ret == pc)) - page_assign_page_cgroup(page, NULL); - unlock_page_cgroup(page); - return ret; + bit_spin_unlock(PAGE_CGROUP_LOCK_BIT, &page->page_cgroup); } static void __mem_cgroup_remove_list(struct page_cgroup *pc) @@ -399,7 +342,7 @@ int task_in_mem_cgroup(struct task_struct *task, const struct mem_cgroup *mem) int ret; task_lock(task); - ret = task->mm && vm_match_cgroup(task->mm, mem); + ret = task->mm && mm_match_cgroup(task->mm, mem); task_unlock(task); return ret; } @@ -407,18 +350,30 @@ int task_in_mem_cgroup(struct task_struct *task, const struct mem_cgroup *mem) /* * This routine assumes that the appropriate zone's lru lock is already held */ -void mem_cgroup_move_lists(struct page_cgroup *pc, bool active) +void mem_cgroup_move_lists(struct page *page, bool active) { + struct page_cgroup *pc; struct mem_cgroup_per_zone *mz; unsigned long flags; - if (!pc) + /* + * We cannot lock_page_cgroup while holding zone's lru_lock, + * because other holders of lock_page_cgroup can be interrupted + * with an attempt to rotate_reclaimable_page. But we cannot + * safely get to page_cgroup without it, so just try_lock it: + * mem_cgroup_isolate_pages allows for page left on wrong list. + */ + if (!try_lock_page_cgroup(page)) return; - mz = page_cgroup_zoneinfo(pc); - spin_lock_irqsave(&mz->lru_lock, flags); - __mem_cgroup_move_lists(pc, active); - spin_unlock_irqrestore(&mz->lru_lock, flags); + pc = page_get_page_cgroup(page); + if (pc) { + mz = page_cgroup_zoneinfo(pc); + spin_lock_irqsave(&mz->lru_lock, flags); + __mem_cgroup_move_lists(pc, active); + spin_unlock_irqrestore(&mz->lru_lock, flags); + } + unlock_page_cgroup(page); } /* @@ -437,6 +392,7 @@ int mem_cgroup_calc_mapped_ratio(struct mem_cgroup *mem) rss = (long)mem_cgroup_read_stat(&mem->stat, MEM_CGROUP_STAT_RSS); return (int)((rss * 100L) / total); } + /* * This function is called from vmscan.c. In page reclaiming loop. balance * between active and inactive list is calculated. For memory controller @@ -500,7 +456,6 @@ long mem_cgroup_calc_reclaim_inactive(struct mem_cgroup *mem, struct mem_cgroup_per_zone *mz = mem_cgroup_zoneinfo(mem, nid, zid); nr_inactive = MEM_CGROUP_ZSTAT(mz, MEM_CGROUP_ZSTAT_INACTIVE); - return (nr_inactive >> priority); } @@ -586,26 +541,21 @@ static int mem_cgroup_charge_common(struct page *page, struct mm_struct *mm, * with it */ retry: - if (page) { - lock_page_cgroup(page); - pc = page_get_page_cgroup(page); - /* - * The page_cgroup exists and - * the page has already been accounted. - */ - if (pc) { - if (unlikely(!atomic_inc_not_zero(&pc->ref_cnt))) { - /* this page is under being uncharged ? */ - unlock_page_cgroup(page); - cpu_relax(); - goto retry; - } else { - unlock_page_cgroup(page); - goto done; - } - } + lock_page_cgroup(page); + pc = page_get_page_cgroup(page); + /* + * The page_cgroup exists and + * the page has already been accounted. + */ + if (pc) { + VM_BUG_ON(pc->page != page); + VM_BUG_ON(pc->ref_cnt <= 0); + + pc->ref_cnt++; unlock_page_cgroup(page); + goto done; } + unlock_page_cgroup(page); pc = kzalloc(sizeof(struct page_cgroup), gfp_mask); if (pc == NULL) @@ -623,16 +573,11 @@ retry: rcu_read_lock(); mem = rcu_dereference(mm->mem_cgroup); /* - * For every charge from the cgroup, increment reference - * count + * For every charge from the cgroup, increment reference count */ css_get(&mem->css); rcu_read_unlock(); - /* - * If we created the page_cgroup, we should free it on exceeding - * the cgroup limit. - */ while (res_counter_charge(&mem->res, PAGE_SIZE)) { if (!(gfp_mask & __GFP_WAIT)) goto out; @@ -641,12 +586,12 @@ retry: continue; /* - * try_to_free_mem_cgroup_pages() might not give us a full - * picture of reclaim. Some pages are reclaimed and might be - * moved to swap cache or just unmapped from the cgroup. - * Check the limit again to see if the reclaim reduced the - * current usage of the cgroup before giving up - */ + * try_to_free_mem_cgroup_pages() might not give us a full + * picture of reclaim. Some pages are reclaimed and might be + * moved to swap cache or just unmapped from the cgroup. + * Check the limit again to see if the reclaim reduced the + * current usage of the cgroup before giving up + */ if (res_counter_check_under_limit(&mem->res)) continue; @@ -657,14 +602,16 @@ retry: congestion_wait(WRITE, HZ/10); } - atomic_set(&pc->ref_cnt, 1); + pc->ref_cnt = 1; pc->mem_cgroup = mem; pc->page = page; pc->flags = PAGE_CGROUP_FLAG_ACTIVE; if (ctype == MEM_CGROUP_CHARGE_TYPE_CACHE) pc->flags |= PAGE_CGROUP_FLAG_CACHE; - if (!page || page_cgroup_assign_new_page_cgroup(page, pc)) { + lock_page_cgroup(page); + if (page_get_page_cgroup(page)) { + unlock_page_cgroup(page); /* * Another charge has been added to this page already. * We take lock_page_cgroup(page) again and read @@ -673,17 +620,16 @@ retry: res_counter_uncharge(&mem->res, PAGE_SIZE); css_put(&mem->css); kfree(pc); - if (!page) - goto done; goto retry; } + page_assign_page_cgroup(page, pc); mz = page_cgroup_zoneinfo(pc); spin_lock_irqsave(&mz->lru_lock, flags); - /* Update statistics vector */ __mem_cgroup_add_list(pc); spin_unlock_irqrestore(&mz->lru_lock, flags); + unlock_page_cgroup(page); done: return 0; out: @@ -693,70 +639,61 @@ err: return -ENOMEM; } -int mem_cgroup_charge(struct page *page, struct mm_struct *mm, - gfp_t gfp_mask) +int mem_cgroup_charge(struct page *page, struct mm_struct *mm, gfp_t gfp_mask) { return mem_cgroup_charge_common(page, mm, gfp_mask, - MEM_CGROUP_CHARGE_TYPE_MAPPED); + MEM_CGROUP_CHARGE_TYPE_MAPPED); } -/* - * See if the cached pages should be charged at all? - */ int mem_cgroup_cache_charge(struct page *page, struct mm_struct *mm, gfp_t gfp_mask) { - int ret = 0; if (!mm) mm = &init_mm; - - ret = mem_cgroup_charge_common(page, mm, gfp_mask, + return mem_cgroup_charge_common(page, mm, gfp_mask, MEM_CGROUP_CHARGE_TYPE_CACHE); - return ret; } /* * Uncharging is always a welcome operation, we never complain, simply - * uncharge. This routine should be called with lock_page_cgroup held + * uncharge. */ -void mem_cgroup_uncharge(struct page_cgroup *pc) +void mem_cgroup_uncharge_page(struct page *page) { + struct page_cgroup *pc; struct mem_cgroup *mem; struct mem_cgroup_per_zone *mz; - struct page *page; unsigned long flags; /* * Check if our page_cgroup is valid */ + lock_page_cgroup(page); + pc = page_get_page_cgroup(page); if (!pc) - return; + goto unlock; - if (atomic_dec_and_test(&pc->ref_cnt)) { - page = pc->page; + VM_BUG_ON(pc->page != page); + VM_BUG_ON(pc->ref_cnt <= 0); + + if (--(pc->ref_cnt) == 0) { mz = page_cgroup_zoneinfo(pc); - /* - * get page->cgroup and clear it under lock. - * force_empty can drop page->cgroup without checking refcnt. - */ + spin_lock_irqsave(&mz->lru_lock, flags); + __mem_cgroup_remove_list(pc); + spin_unlock_irqrestore(&mz->lru_lock, flags); + + page_assign_page_cgroup(page, NULL); unlock_page_cgroup(page); - if (clear_page_cgroup(page, pc) == pc) { - mem = pc->mem_cgroup; - css_put(&mem->css); - res_counter_uncharge(&mem->res, PAGE_SIZE); - spin_lock_irqsave(&mz->lru_lock, flags); - __mem_cgroup_remove_list(pc); - spin_unlock_irqrestore(&mz->lru_lock, flags); - kfree(pc); - } - lock_page_cgroup(page); + + mem = pc->mem_cgroup; + res_counter_uncharge(&mem->res, PAGE_SIZE); + css_put(&mem->css); + + kfree(pc); + return; } -} -void mem_cgroup_uncharge_page(struct page *page) -{ - lock_page_cgroup(page); - mem_cgroup_uncharge(page_get_page_cgroup(page)); +unlock: unlock_page_cgroup(page); } @@ -764,63 +701,59 @@ void mem_cgroup_uncharge_page(struct page *page) * Returns non-zero if a page (under migration) has valid page_cgroup member. * Refcnt of page_cgroup is incremented. */ - int mem_cgroup_prepare_migration(struct page *page) { struct page_cgroup *pc; - int ret = 0; + lock_page_cgroup(page); pc = page_get_page_cgroup(page); - if (pc && atomic_inc_not_zero(&pc->ref_cnt)) - ret = 1; + if (pc) + pc->ref_cnt++; unlock_page_cgroup(page); - return ret; + return pc != NULL; } void mem_cgroup_end_migration(struct page *page) { - struct page_cgroup *pc; - - lock_page_cgroup(page); - pc = page_get_page_cgroup(page); - mem_cgroup_uncharge(pc); - unlock_page_cgroup(page); + mem_cgroup_uncharge_page(page); } + /* - * We know both *page* and *newpage* are now not-on-LRU and Pg_locked. + * We know both *page* and *newpage* are now not-on-LRU and PG_locked. * And no race with uncharge() routines because page_cgroup for *page* * has extra one reference by mem_cgroup_prepare_migration. */ - void mem_cgroup_page_migration(struct page *page, struct page *newpage) { struct page_cgroup *pc; - struct mem_cgroup *mem; - unsigned long flags; struct mem_cgroup_per_zone *mz; -retry: + unsigned long flags; + + lock_page_cgroup(page); pc = page_get_page_cgroup(page); - if (!pc) + if (!pc) { + unlock_page_cgroup(page); return; - mem = pc->mem_cgroup; + } + mz = page_cgroup_zoneinfo(pc); - if (clear_page_cgroup(page, pc) != pc) - goto retry; spin_lock_irqsave(&mz->lru_lock, flags); - __mem_cgroup_remove_list(pc); spin_unlock_irqrestore(&mz->lru_lock, flags); + page_assign_page_cgroup(page, NULL); + unlock_page_cgroup(page); + pc->page = newpage; lock_page_cgroup(newpage); page_assign_page_cgroup(newpage, pc); - unlock_page_cgroup(newpage); mz = page_cgroup_zoneinfo(pc); spin_lock_irqsave(&mz->lru_lock, flags); __mem_cgroup_add_list(pc); spin_unlock_irqrestore(&mz->lru_lock, flags); - return; + + unlock_page_cgroup(newpage); } /* @@ -829,14 +762,13 @@ retry: * *And* this routine doesn't reclaim page itself, just removes page_cgroup. */ #define FORCE_UNCHARGE_BATCH (128) -static void -mem_cgroup_force_empty_list(struct mem_cgroup *mem, +static void mem_cgroup_force_empty_list(struct mem_cgroup *mem, struct mem_cgroup_per_zone *mz, int active) { struct page_cgroup *pc; struct page *page; - int count; + int count = FORCE_UNCHARGE_BATCH; unsigned long flags; struct list_head *list; @@ -845,46 +777,36 @@ mem_cgroup_force_empty_list(struct mem_cgroup *mem, else list = &mz->inactive_list; - if (list_empty(list)) - return; -retry: - count = FORCE_UNCHARGE_BATCH; spin_lock_irqsave(&mz->lru_lock, flags); - - while (--count && !list_empty(list)) { + while (!list_empty(list)) { pc = list_entry(list->prev, struct page_cgroup, lru); page = pc->page; - /* Avoid race with charge */ - atomic_set(&pc->ref_cnt, 0); - if (clear_page_cgroup(page, pc) == pc) { - css_put(&mem->css); - res_counter_uncharge(&mem->res, PAGE_SIZE); - __mem_cgroup_remove_list(pc); - kfree(pc); - } else /* being uncharged ? ...do relax */ - break; + get_page(page); + spin_unlock_irqrestore(&mz->lru_lock, flags); + mem_cgroup_uncharge_page(page); + put_page(page); + if (--count <= 0) { + count = FORCE_UNCHARGE_BATCH; + cond_resched(); + } + spin_lock_irqsave(&mz->lru_lock, flags); } spin_unlock_irqrestore(&mz->lru_lock, flags); - if (!list_empty(list)) { - cond_resched(); - goto retry; - } - return; } /* * make mem_cgroup's charge to be 0 if there is no task. * This enables deleting this mem_cgroup. */ - -int mem_cgroup_force_empty(struct mem_cgroup *mem) +static int mem_cgroup_force_empty(struct mem_cgroup *mem) { int ret = -EBUSY; int node, zid; + css_get(&mem->css); /* * page reclaim code (kswapd etc..) will move pages between -` * active_list <-> inactive_list while we don't take a lock. + * active_list <-> inactive_list while we don't take a lock. * So, we have to do loop here until all lists are empty. */ while (mem->res.usage > 0) { @@ -906,9 +828,7 @@ out: return ret; } - - -int mem_cgroup_write_strategy(char *buf, unsigned long long *tmp) +static int mem_cgroup_write_strategy(char *buf, unsigned long long *tmp) { *tmp = memparse(buf, &buf); if (*buf != '\0') @@ -945,8 +865,7 @@ static ssize_t mem_force_empty_write(struct cgroup *cont, size_t nbytes, loff_t *ppos) { struct mem_cgroup *mem = mem_cgroup_from_cont(cont); - int ret; - ret = mem_cgroup_force_empty(mem); + int ret = mem_cgroup_force_empty(mem); if (!ret) ret = nbytes; return ret; @@ -955,7 +874,6 @@ static ssize_t mem_force_empty_write(struct cgroup *cont, /* * Note: This should be removed if cgroup supports write-only file. */ - static ssize_t mem_force_empty_read(struct cgroup *cont, struct cftype *cft, struct file *file, char __user *userbuf, @@ -964,7 +882,6 @@ static ssize_t mem_force_empty_read(struct cgroup *cont, return -EINVAL; } - static const struct mem_cgroup_stat_desc { const char *msg; u64 unit; @@ -1017,8 +934,6 @@ static int mem_control_stat_open(struct inode *unused, struct file *file) return single_open(file, mem_control_stat_show, cont); } - - static struct cftype mem_cgroup_files[] = { { .name = "usage_in_bytes", @@ -1084,9 +999,6 @@ static void free_mem_cgroup_per_zone_info(struct mem_cgroup *mem, int node) kfree(mem->info.nodeinfo[node]); } - -static struct mem_cgroup init_mem_cgroup; - static struct cgroup_subsys_state * mem_cgroup_create(struct cgroup_subsys *ss, struct cgroup *cont) { @@ -1176,7 +1088,6 @@ static void mem_cgroup_move_task(struct cgroup_subsys *ss, out: mmput(mm); - return; } struct cgroup_subsys mem_cgroup_subsys = { diff --git a/mm/memory.c b/mm/memory.c index ce3c9e4492d803b011f50ea8641e477056116ddd..0d14d1e58a5fa78e6b6a01369cc1e0869c77dfe9 100644 --- a/mm/memory.c +++ b/mm/memory.c @@ -1711,7 +1711,7 @@ unlock: } return ret; oom_free_new: - __free_page(new_page); + page_cache_release(new_page); oom: if (old_page) page_cache_release(old_page); @@ -2093,12 +2093,9 @@ static int do_swap_page(struct mm_struct *mm, struct vm_area_struct *vma, unlock_page(page); if (write_access) { - /* XXX: We could OR the do_wp_page code with this one? */ - if (do_wp_page(mm, vma, address, - page_table, pmd, ptl, pte) & VM_FAULT_OOM) { - mem_cgroup_uncharge_page(page); - ret = VM_FAULT_OOM; - } + ret |= do_wp_page(mm, vma, address, page_table, pmd, ptl, pte); + if (ret & VM_FAULT_ERROR) + ret &= VM_FAULT_ERROR; goto out; } @@ -2163,7 +2160,7 @@ release: page_cache_release(page); goto unlock; oom_free_page: - __free_page(page); + page_cache_release(page); oom: return VM_FAULT_OOM; } diff --git a/mm/mempolicy.c b/mm/mempolicy.c index 6c7ba1a63d23b05931003d97b8932c39ca983060..3c3601121509d8a3c1d3ab2a8cf4a35953a9aa4e 100644 --- a/mm/mempolicy.c +++ b/mm/mempolicy.c @@ -1296,7 +1296,9 @@ struct zonelist *huge_zonelist(struct vm_area_struct *vma, unsigned long addr, unsigned nid; nid = interleave_nid(pol, vma, addr, HPAGE_SHIFT); - __mpol_free(pol); /* finished with pol */ + if (unlikely(pol != &default_policy && + pol != current->mempolicy)) + __mpol_free(pol); /* finished with pol */ return NODE_DATA(nid)->node_zonelists + gfp_zone(gfp_flags); } @@ -1360,6 +1362,9 @@ alloc_page_vma(gfp_t gfp, struct vm_area_struct *vma, unsigned long addr) unsigned nid; nid = interleave_nid(pol, vma, addr, PAGE_SHIFT); + if (unlikely(pol != &default_policy && + pol != current->mempolicy)) + __mpol_free(pol); /* finished with pol */ return alloc_page_interleave(gfp, 0, nid); } zl = zonelist_policy(gfp, pol); diff --git a/mm/migrate.c b/mm/migrate.c index a73504ff5ab982007b2e0355e49f0dedcac65899..4e0eccca5e265ac19bc507a171a2f720d27f8c21 100644 --- a/mm/migrate.c +++ b/mm/migrate.c @@ -153,11 +153,6 @@ static void remove_migration_pte(struct vm_area_struct *vma, return; } - if (mem_cgroup_charge(new, mm, GFP_KERNEL)) { - pte_unmap(ptep); - return; - } - ptl = pte_lockptr(mm, pmd); spin_lock(ptl); pte = *ptep; @@ -169,6 +164,20 @@ static void remove_migration_pte(struct vm_area_struct *vma, if (!is_migration_entry(entry) || migration_entry_to_page(entry) != old) goto out; + /* + * Yes, ignore the return value from a GFP_ATOMIC mem_cgroup_charge. + * Failure is not an option here: we're now expected to remove every + * migration pte, and will cause crashes otherwise. Normally this + * is not an issue: mem_cgroup_prepare_migration bumped up the old + * page_cgroup count for safety, that's now attached to the new page, + * so this charge should just be another incrementation of the count, + * to keep in balance with rmap.c's mem_cgroup_uncharging. But if + * there's been a force_empty, those reference counts may no longer + * be reliable, and this charge can actually fail: oh well, we don't + * make the situation any worse by proceeding as if it had succeeded. + */ + mem_cgroup_charge(new, mm, GFP_ATOMIC); + get_page(new); pte = pte_mkold(mk_pte(new, vma->vm_page_prot)); if (is_write_migration_entry(entry)) diff --git a/mm/oom_kill.c b/mm/oom_kill.c index 4194b9db0104d54dea5ea871e0e111695fa49cba..44b2da11bf43f75a3714761ab09217339579977d 100644 --- a/mm/oom_kill.c +++ b/mm/oom_kill.c @@ -412,7 +412,7 @@ static int oom_kill_process(struct task_struct *p, gfp_t gfp_mask, int order, return oom_kill_task(p); } -#ifdef CONFIG_CGROUP_MEM_CONT +#ifdef CONFIG_CGROUP_MEM_RES_CTLR void mem_cgroup_out_of_memory(struct mem_cgroup *mem, gfp_t gfp_mask) { unsigned long points = 0; diff --git a/mm/page_alloc.c b/mm/page_alloc.c index 8896e874a67dae2c558034dbbf27491b231c2b2a..402a504f12283f23cb510ec9ebfce4d0d52eea29 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -221,13 +222,19 @@ static inline int bad_range(struct zone *zone, struct page *page) static void bad_page(struct page *page) { - printk(KERN_EMERG "Bad page state in process '%s'\n" - KERN_EMERG "page:%p flags:0x%0*lx mapping:%p mapcount:%d count:%d\n" - KERN_EMERG "Trying to fix it up, but a reboot is needed\n" - KERN_EMERG "Backtrace:\n", + void *pc = page_get_page_cgroup(page); + + printk(KERN_EMERG "Bad page state in process '%s'\n" KERN_EMERG + "page:%p flags:0x%0*lx mapping:%p mapcount:%d count:%d\n", current->comm, page, (int)(2*sizeof(unsigned long)), (unsigned long)page->flags, page->mapping, page_mapcount(page), page_count(page)); + if (pc) { + printk(KERN_EMERG "cgroup:%p\n", pc); + page_reset_bad_cgroup(page); + } + printk(KERN_EMERG "Trying to fix it up, but a reboot is needed\n" + KERN_EMERG "Backtrace:\n"); dump_stack(); page->flags &= ~(1 << PG_lru | 1 << PG_private | @@ -453,6 +460,7 @@ static inline int free_pages_check(struct page *page) { if (unlikely(page_mapcount(page) | (page->mapping != NULL) | + (page_get_page_cgroup(page) != NULL) | (page_count(page) != 0) | (page->flags & ( 1 << PG_lru | @@ -602,6 +610,7 @@ static int prep_new_page(struct page *page, int order, gfp_t gfp_flags) { if (unlikely(page_mapcount(page) | (page->mapping != NULL) | + (page_get_page_cgroup(page) != NULL) | (page_count(page) != 0) | (page->flags & ( 1 << PG_lru | @@ -988,7 +997,6 @@ static void free_hot_cold_page(struct page *page, int cold) if (!PageHighMem(page)) debug_check_no_locks_freed(page_address(page), PAGE_SIZE); - VM_BUG_ON(page_get_page_cgroup(page)); arch_free_page(page, 0); kernel_map_pages(page, 1, 0); @@ -1276,7 +1284,7 @@ static nodemask_t *zlc_setup(struct zonelist *zonelist, int alloc_flags) if (!zlc) return NULL; - if (jiffies - zlc->last_full_zap > 1 * HZ) { + if (time_after(jiffies, zlc->last_full_zap + HZ)) { bitmap_zero(zlc->fullzones, MAX_ZONES_PER_ZONELIST); zlc->last_full_zap = jiffies; } @@ -2527,7 +2535,6 @@ void __meminit memmap_init_zone(unsigned long size, int nid, unsigned long zone, set_page_links(page, zone, nid, pfn); init_page_count(page); reset_page_mapcount(page); - page_assign_page_cgroup(page, NULL); SetPageReserved(page); /* diff --git a/mm/rmap.c b/mm/rmap.c index 8fd527c4e2bff8e45c929c42f01c60834c573ef9..0c9a2df06c39cc3733f0e5b6975d82d4b82807ae 100644 --- a/mm/rmap.c +++ b/mm/rmap.c @@ -321,7 +321,7 @@ static int page_referenced_anon(struct page *page, * counting on behalf of references from different * cgroups */ - if (mem_cont && !vm_match_cgroup(vma->vm_mm, mem_cont)) + if (mem_cont && !mm_match_cgroup(vma->vm_mm, mem_cont)) continue; referenced += page_referenced_one(page, vma, &mapcount); if (!mapcount) @@ -382,7 +382,7 @@ static int page_referenced_file(struct page *page, * counting on behalf of references from different * cgroups */ - if (mem_cont && !vm_match_cgroup(vma->vm_mm, mem_cont)) + if (mem_cont && !mm_match_cgroup(vma->vm_mm, mem_cont)) continue; if ((vma->vm_flags & (VM_LOCKED|VM_MAYSHARE)) == (VM_LOCKED|VM_MAYSHARE)) { diff --git a/mm/shmem.c b/mm/shmem.c index 90b576cbc06e40fb0f43d06f37f5ef24deee9f13..3372bc579e896f474ef24cffa929b69228ff9445 100644 --- a/mm/shmem.c +++ b/mm/shmem.c @@ -1370,14 +1370,17 @@ repeat: shmem_swp_unmap(entry); spin_unlock(&info->lock); unlock_page(swappage); - page_cache_release(swappage); if (error == -ENOMEM) { /* allow reclaim from this memory cgroup */ - error = mem_cgroup_cache_charge(NULL, + error = mem_cgroup_cache_charge(swappage, current->mm, gfp & ~__GFP_HIGHMEM); - if (error) + if (error) { + page_cache_release(swappage); goto failed; + } + mem_cgroup_uncharge_page(swappage); } + page_cache_release(swappage); goto repeat; } } else if (sgp == SGP_READ && !filepage) { diff --git a/mm/slab.c b/mm/slab.c index 473e6c2eaefbcafbba74b7e37a658422027e968e..e6c698f55674c9599de52137f2597e0f59b631ce 100644 --- a/mm/slab.c +++ b/mm/slab.c @@ -333,7 +333,7 @@ static __always_inline int index_of(const size_t size) return i; \ else \ i++; -#include "linux/kmalloc_sizes.h" +#include #undef CACHE __bad_size(); } else @@ -2964,11 +2964,10 @@ static void *cache_alloc_refill(struct kmem_cache *cachep, gfp_t flags) struct array_cache *ac; int node; - node = numa_node_id(); - +retry: check_irq_off(); + node = numa_node_id(); ac = cpu_cache_get(cachep); -retry: batchcount = ac->batchcount; if (!ac->touched && batchcount > BATCHREFILL_LIMIT) { /* @@ -3280,7 +3279,7 @@ retry: if (local_flags & __GFP_WAIT) local_irq_enable(); kmem_flagcheck(cache, flags); - obj = kmem_getpages(cache, flags, -1); + obj = kmem_getpages(cache, local_flags, -1); if (local_flags & __GFP_WAIT) local_irq_disable(); if (obj) { diff --git a/mm/slub.c b/mm/slub.c index 74c65af0a54f4c112e6f2bc223018deb74771d25..96d63eb3ab179528efd1ea8c64cbc6358212a967 100644 --- a/mm/slub.c +++ b/mm/slub.c @@ -291,32 +291,16 @@ static inline struct kmem_cache_cpu *get_cpu_slab(struct kmem_cache *s, int cpu) #endif } -/* - * The end pointer in a slab is special. It points to the first object in the - * slab but has bit 0 set to mark it. - * - * Note that SLUB relies on page_mapping returning NULL for pages with bit 0 - * in the mapping set. - */ -static inline int is_end(void *addr) -{ - return (unsigned long)addr & PAGE_MAPPING_ANON; -} - -static void *slab_address(struct page *page) -{ - return page->end - PAGE_MAPPING_ANON; -} - +/* Verify that a pointer has an address that is valid within a slab page */ static inline int check_valid_pointer(struct kmem_cache *s, struct page *page, const void *object) { void *base; - if (object == page->end) + if (!object) return 1; - base = slab_address(page); + base = page_address(page); if (object < base || object >= base + s->objects * s->size || (object - base) % s->size) { return 0; @@ -349,8 +333,7 @@ static inline void set_freepointer(struct kmem_cache *s, void *object, void *fp) /* Scan freelist */ #define for_each_free_object(__p, __s, __free) \ - for (__p = (__free); (__p) != page->end; __p = get_freepointer((__s),\ - __p)) + for (__p = (__free); __p; __p = get_freepointer((__s), __p)) /* Determine object index from a given position */ static inline int slab_index(void *p, struct kmem_cache *s, void *addr) @@ -502,7 +485,7 @@ static void slab_fix(struct kmem_cache *s, char *fmt, ...) static void print_trailer(struct kmem_cache *s, struct page *page, u8 *p) { unsigned int off; /* Offset of last byte */ - u8 *addr = slab_address(page); + u8 *addr = page_address(page); print_tracking(s, p); @@ -637,7 +620,7 @@ static int check_bytes_and_report(struct kmem_cache *s, struct page *page, * A. Free pointer (if we cannot overwrite object on free) * B. Tracking data for SLAB_STORE_USER * C. Padding to reach required alignment boundary or at mininum - * one word if debuggin is on to be able to detect writes + * one word if debugging is on to be able to detect writes * before the word boundary. * * Padding is done using 0x5a (POISON_INUSE) @@ -680,7 +663,7 @@ static int slab_pad_check(struct kmem_cache *s, struct page *page) if (!(s->flags & SLAB_POISON)) return 1; - start = slab_address(page); + start = page_address(page); end = start + (PAGE_SIZE << s->order); length = s->objects * s->size; remainder = end - (start + length); @@ -748,7 +731,7 @@ static int check_object(struct kmem_cache *s, struct page *page, * of the free objects in this slab. May cause * another error because the object count is now wrong. */ - set_freepointer(s, p, page->end); + set_freepointer(s, p, NULL); return 0; } return 1; @@ -782,18 +765,18 @@ static int on_freelist(struct kmem_cache *s, struct page *page, void *search) void *fp = page->freelist; void *object = NULL; - while (fp != page->end && nr <= s->objects) { + while (fp && nr <= s->objects) { if (fp == search) return 1; if (!check_valid_pointer(s, page, fp)) { if (object) { object_err(s, page, object, "Freechain corrupt"); - set_freepointer(s, object, page->end); + set_freepointer(s, object, NULL); break; } else { slab_err(s, page, "Freepointer corrupt"); - page->freelist = page->end; + page->freelist = NULL; page->inuse = s->objects; slab_fix(s, "Freelist cleared"); return 0; @@ -870,7 +853,7 @@ static int alloc_debug_processing(struct kmem_cache *s, struct page *page, if (!check_slab(s, page)) goto bad; - if (object && !on_freelist(s, page, object)) { + if (!on_freelist(s, page, object)) { object_err(s, page, object, "Object already allocated"); goto bad; } @@ -880,7 +863,7 @@ static int alloc_debug_processing(struct kmem_cache *s, struct page *page, goto bad; } - if (object && !check_object(s, page, object, 0)) + if (!check_object(s, page, object, 0)) goto bad; /* Success perform special debug activities for allocs */ @@ -899,7 +882,7 @@ bad: */ slab_fix(s, "Marking all objects used"); page->inuse = s->objects; - page->freelist = page->end; + page->freelist = NULL; } return 0; } @@ -939,7 +922,7 @@ static int free_debug_processing(struct kmem_cache *s, struct page *page, } /* Special debug activities for freeing objects */ - if (!SlabFrozen(page) && page->freelist == page->end) + if (!SlabFrozen(page) && !page->freelist) remove_full(s, page); if (s->flags & SLAB_STORE_USER) set_track(s, object, TRACK_FREE, addr); @@ -1015,30 +998,11 @@ static unsigned long kmem_cache_flags(unsigned long objsize, void (*ctor)(struct kmem_cache *, void *)) { /* - * The page->offset field is only 16 bit wide. This is an offset - * in units of words from the beginning of an object. If the slab - * size is bigger then we cannot move the free pointer behind the - * object anymore. - * - * On 32 bit platforms the limit is 256k. On 64bit platforms - * the limit is 512k. - * - * Debugging or ctor may create a need to move the free - * pointer. Fail if this happens. + * Enable debugging if selected on the kernel commandline. */ - if (objsize >= 65535 * sizeof(void *)) { - BUG_ON(flags & (SLAB_RED_ZONE | SLAB_POISON | - SLAB_STORE_USER | SLAB_DESTROY_BY_RCU)); - BUG_ON(ctor); - } else { - /* - * Enable debugging if selected on the kernel commandline. - */ - if (slub_debug && (!slub_debug_slabs || - strncmp(slub_debug_slabs, name, - strlen(slub_debug_slabs)) == 0)) - flags |= slub_debug; - } + if (slub_debug && (!slub_debug_slabs || + strncmp(slub_debug_slabs, name, strlen(slub_debug_slabs)) == 0)) + flags |= slub_debug; return flags; } @@ -1124,7 +1088,6 @@ static struct page *new_slab(struct kmem_cache *s, gfp_t flags, int node) SetSlabDebug(page); start = page_address(page); - page->end = start + 1; if (unlikely(s->flags & SLAB_POISON)) memset(start, POISON_INUSE, PAGE_SIZE << s->order); @@ -1136,7 +1099,7 @@ static struct page *new_slab(struct kmem_cache *s, gfp_t flags, int node) last = p; } setup_object(s, page, last); - set_freepointer(s, last, page->end); + set_freepointer(s, last, NULL); page->freelist = start; page->inuse = 0; @@ -1152,7 +1115,7 @@ static void __free_slab(struct kmem_cache *s, struct page *page) void *p; slab_pad_check(s, page); - for_each_object(p, s, slab_address(page)) + for_each_object(p, s, page_address(page)) check_object(s, page, p, 0); ClearSlabDebug(page); } @@ -1162,7 +1125,6 @@ static void __free_slab(struct kmem_cache *s, struct page *page) NR_SLAB_RECLAIMABLE : NR_SLAB_UNRECLAIMABLE, -pages); - page->mapping = NULL; __free_pages(page, s->order); } @@ -1307,7 +1269,7 @@ static struct page *get_any_partial(struct kmem_cache *s, gfp_t flags) * may return off node objects because partial slabs are obtained * from other nodes and filled up. * - * If /sys/slab/xx/defrag_ratio is set to 100 (which makes + * If /sys/kernel/slab/xx/defrag_ratio is set to 100 (which makes * defrag_ratio = 1000) then every (well almost) allocation will * first attempt to defrag slab caches on other nodes. This means * scanning over all nodes to look for partial slabs which may be @@ -1366,7 +1328,7 @@ static void unfreeze_slab(struct kmem_cache *s, struct page *page, int tail) ClearSlabFrozen(page); if (page->inuse) { - if (page->freelist != page->end) { + if (page->freelist) { add_partial(n, page, tail); stat(c, tail ? DEACTIVATE_TO_TAIL : DEACTIVATE_TO_HEAD); } else { @@ -1382,9 +1344,11 @@ static void unfreeze_slab(struct kmem_cache *s, struct page *page, int tail) * Adding an empty slab to the partial slabs in order * to avoid page allocator overhead. This slab needs * to come after the other slabs with objects in - * order to fill them up. That way the size of the - * partial list stays small. kmem_cache_shrink can - * reclaim empty slabs from the partial list. + * so that the others get filled first. That way the + * size of the partial list stays small. + * + * kmem_cache_shrink can reclaim any empty slabs from the + * partial list. */ add_partial(n, page, 1); slab_unlock(page); @@ -1404,18 +1368,14 @@ static void deactivate_slab(struct kmem_cache *s, struct kmem_cache_cpu *c) struct page *page = c->page; int tail = 1; - if (c->freelist) + if (page->freelist) stat(c, DEACTIVATE_REMOTE_FREES); /* - * Merge cpu freelist into freelist. Typically we get here + * Merge cpu freelist into slab freelist. Typically we get here * because both freelists are empty. So this is unlikely * to occur. - * - * We need to use _is_end here because deactivate slab may - * be called for a debug slab. Then c->freelist may contain - * a dummy pointer. */ - while (unlikely(!is_end(c->freelist))) { + while (unlikely(c->freelist)) { void **object; tail = 0; /* Hot objects. Put the slab first */ @@ -1442,6 +1402,7 @@ static inline void flush_slab(struct kmem_cache *s, struct kmem_cache_cpu *c) /* * Flush cpu slab. + * * Called from IPI handler with interrupts disabled. */ static inline void __flush_cpu_slab(struct kmem_cache *s, int cpu) @@ -1500,7 +1461,8 @@ static inline int node_match(struct kmem_cache_cpu *c, int node) * rest of the freelist to the lockless freelist. * * And if we were unable to get a new slab from the partial slab lists then - * we need to allocate a new slab. This is slowest path since we may sleep. + * we need to allocate a new slab. This is the slowest path since it involves + * a call to the page allocator and the setup of a new slab. */ static void *__slab_alloc(struct kmem_cache *s, gfp_t gfpflags, int node, void *addr, struct kmem_cache_cpu *c) @@ -1514,18 +1476,19 @@ static void *__slab_alloc(struct kmem_cache *s, slab_lock(c->page); if (unlikely(!node_match(c, node))) goto another_slab; + stat(c, ALLOC_REFILL); + load_freelist: object = c->page->freelist; - if (unlikely(object == c->page->end)) + if (unlikely(!object)) goto another_slab; if (unlikely(SlabDebug(c->page))) goto debug; - object = c->page->freelist; c->freelist = object[c->offset]; c->page->inuse = s->objects; - c->page->freelist = c->page->end; + c->page->freelist = NULL; c->node = page_to_nid(c->page); unlock_out: slab_unlock(c->page); @@ -1578,7 +1541,6 @@ new_slab: return NULL; debug: - object = c->page->freelist; if (!alloc_debug_processing(s, c->page, object, addr)) goto another_slab; @@ -1607,7 +1569,7 @@ static __always_inline void *slab_alloc(struct kmem_cache *s, local_irq_save(flags); c = get_cpu_slab(s, smp_processor_id()); - if (unlikely(is_end(c->freelist) || !node_match(c, node))) + if (unlikely(!c->freelist || !node_match(c, node))) object = __slab_alloc(s, gfpflags, node, addr, c); @@ -1659,6 +1621,7 @@ static void __slab_free(struct kmem_cache *s, struct page *page, if (unlikely(SlabDebug(page))) goto debug; + checks_ok: prior = object[offset] = page->freelist; page->freelist = object; @@ -1673,11 +1636,10 @@ checks_ok: goto slab_empty; /* - * Objects left in the slab. If it - * was not on the partial list before + * Objects left in the slab. If it was not on the partial list before * then add it. */ - if (unlikely(prior == page->end)) { + if (unlikely(!prior)) { add_partial(get_node(s, page_to_nid(page)), page, 1); stat(c, FREE_ADD_PARTIAL); } @@ -1687,7 +1649,7 @@ out_unlock: return; slab_empty: - if (prior != page->end) { + if (prior) { /* * Slab still on the partial list. */ @@ -1724,8 +1686,8 @@ static __always_inline void slab_free(struct kmem_cache *s, unsigned long flags; local_irq_save(flags); - debug_check_no_locks_freed(object, s->objsize); c = get_cpu_slab(s, smp_processor_id()); + debug_check_no_locks_freed(object, c->objsize); if (likely(page == c->page && c->node >= 0)) { object[c->offset] = c->freelist; c->freelist = object; @@ -1888,20 +1850,21 @@ static unsigned long calculate_alignment(unsigned long flags, unsigned long align, unsigned long size) { /* - * If the user wants hardware cache aligned objects then - * follow that suggestion if the object is sufficiently - * large. + * If the user wants hardware cache aligned objects then follow that + * suggestion if the object is sufficiently large. * - * The hardware cache alignment cannot override the - * specified alignment though. If that is greater - * then use it. + * The hardware cache alignment cannot override the specified + * alignment though. If that is greater then use it. */ - if ((flags & SLAB_HWCACHE_ALIGN) && - size > cache_line_size() / 2) - return max_t(unsigned long, align, cache_line_size()); + if (flags & SLAB_HWCACHE_ALIGN) { + unsigned long ralign = cache_line_size(); + while (size <= ralign / 2) + ralign /= 2; + align = max(align, ralign); + } if (align < ARCH_SLAB_MINALIGN) - return ARCH_SLAB_MINALIGN; + align = ARCH_SLAB_MINALIGN; return ALIGN(align, sizeof(void *)); } @@ -1910,7 +1873,7 @@ static void init_kmem_cache_cpu(struct kmem_cache *s, struct kmem_cache_cpu *c) { c->page = NULL; - c->freelist = (void *)PAGE_MAPPING_ANON; + c->freelist = NULL; c->node = 0; c->offset = s->offset / sizeof(void *); c->objsize = s->objsize; @@ -2092,6 +2055,7 @@ static struct kmem_cache_node *early_kmem_cache_node_alloc(gfp_t gfpflags, #endif init_kmem_cache_node(n); atomic_long_inc(&n->nr_slabs); + /* * lockdep requires consistent irq usage for each lock * so even though there cannot be a race this early in @@ -2172,6 +2136,14 @@ static int calculate_sizes(struct kmem_cache *s) unsigned long size = s->objsize; unsigned long align = s->align; + /* + * Round up object size to the next word boundary. We can only + * place the free pointer at word boundaries and this determines + * the possible location of the free pointer. + */ + size = ALIGN(size, sizeof(void *)); + +#ifdef CONFIG_SLUB_DEBUG /* * Determine if we can poison the object itself. If the user of * the slab may touch the object after free or before allocation @@ -2183,14 +2155,7 @@ static int calculate_sizes(struct kmem_cache *s) else s->flags &= ~__OBJECT_POISON; - /* - * Round up object size to the next word boundary. We can only - * place the free pointer at word boundaries and this determines - * the possible location of the free pointer. - */ - size = ALIGN(size, sizeof(void *)); -#ifdef CONFIG_SLUB_DEBUG /* * If we are Redzoning then check if there is some space between the * end of the object and the free pointer. If not then add an @@ -2343,7 +2308,7 @@ int kmem_ptr_validate(struct kmem_cache *s, const void *object) /* * We could also check if the object is on the slabs freelist. * But this would be too expensive and it seems that the main - * purpose of kmem_ptr_valid is to check if the object belongs + * purpose of kmem_ptr_valid() is to check if the object belongs * to a certain slab. */ return 1; @@ -2630,13 +2595,24 @@ void *__kmalloc(size_t size, gfp_t flags) } EXPORT_SYMBOL(__kmalloc); +static void *kmalloc_large_node(size_t size, gfp_t flags, int node) +{ + struct page *page = alloc_pages_node(node, flags | __GFP_COMP, + get_order(size)); + + if (page) + return page_address(page); + else + return NULL; +} + #ifdef CONFIG_NUMA void *__kmalloc_node(size_t size, gfp_t flags, int node) { struct kmem_cache *s; if (unlikely(size > PAGE_SIZE)) - return kmalloc_large(size, flags); + return kmalloc_large_node(size, flags, node); s = get_slab(size, flags); @@ -2653,19 +2629,17 @@ size_t ksize(const void *object) struct page *page; struct kmem_cache *s; - BUG_ON(!object); if (unlikely(object == ZERO_SIZE_PTR)) return 0; page = virt_to_head_page(object); - BUG_ON(!page); if (unlikely(!PageSlab(page))) return PAGE_SIZE << compound_order(page); s = page->slab; - BUG_ON(!s); +#ifdef CONFIG_SLUB_DEBUG /* * Debugging requires use of the padding between object * and whatever may come after it. @@ -2673,6 +2647,7 @@ size_t ksize(const void *object) if (s->flags & (SLAB_RED_ZONE | SLAB_POISON)) return s->objsize; +#endif /* * If we have the need to store the freelist pointer * back there or track user information then we can @@ -2680,7 +2655,6 @@ size_t ksize(const void *object) */ if (s->flags & (SLAB_DESTROY_BY_RCU | SLAB_STORE_USER)) return s->inuse; - /* * Else we can use all the padding etc for the allocation */ @@ -2957,7 +2931,7 @@ void __init kmem_cache_init(void) /* * Patch up the size_index table if we have strange large alignment * requirements for the kmalloc array. This is only the case for - * mips it seems. The standard arches will not generate any code here. + * MIPS it seems. The standard arches will not generate any code here. * * Largest permitted alignment is 256 bytes due to the way we * handle the index determination for the smaller caches. @@ -2986,7 +2960,6 @@ void __init kmem_cache_init(void) kmem_size = sizeof(struct kmem_cache); #endif - printk(KERN_INFO "SLUB: Genslabs=%d, HWalign=%d, Order=%d-%d, MinObjects=%d," " CPUs=%d, Nodes=%d\n", @@ -3083,12 +3056,15 @@ struct kmem_cache *kmem_cache_create(const char *name, size_t size, */ for_each_online_cpu(cpu) get_cpu_slab(s, cpu)->objsize = s->objsize; + s->inuse = max_t(int, s->inuse, ALIGN(size, sizeof(void *))); up_write(&slub_lock); + if (sysfs_slab_alias(s, name)) goto err; return s; } + s = kmalloc(kmem_size, GFP_KERNEL); if (s) { if (kmem_cache_open(s, GFP_KERNEL, name, @@ -3184,7 +3160,7 @@ void *__kmalloc_node_track_caller(size_t size, gfp_t gfpflags, struct kmem_cache *s; if (unlikely(size > PAGE_SIZE)) - return kmalloc_large(size, gfpflags); + return kmalloc_large_node(size, gfpflags, node); s = get_slab(size, gfpflags); @@ -3199,7 +3175,7 @@ static int validate_slab(struct kmem_cache *s, struct page *page, unsigned long *map) { void *p; - void *addr = slab_address(page); + void *addr = page_address(page); if (!check_slab(s, page) || !on_freelist(s, page, NULL)) @@ -3482,7 +3458,7 @@ static int add_location(struct loc_track *t, struct kmem_cache *s, static void process_slab(struct loc_track *t, struct kmem_cache *s, struct page *page, enum track_item alloc) { - void *addr = slab_address(page); + void *addr = page_address(page); DECLARE_BITMAP(map, s->objects); void *p; @@ -3591,8 +3567,8 @@ enum slab_stat_type { #define SO_CPU (1 << SL_CPU) #define SO_OBJECTS (1 << SL_OBJECTS) -static unsigned long slab_objects(struct kmem_cache *s, - char *buf, unsigned long flags) +static ssize_t show_slab_objects(struct kmem_cache *s, + char *buf, unsigned long flags) { unsigned long total = 0; int cpu; @@ -3602,6 +3578,8 @@ static unsigned long slab_objects(struct kmem_cache *s, unsigned long *per_cpu; nodes = kzalloc(2 * sizeof(unsigned long) * nr_node_ids, GFP_KERNEL); + if (!nodes) + return -ENOMEM; per_cpu = nodes + nr_node_ids; for_each_possible_cpu(cpu) { @@ -3754,25 +3732,25 @@ SLAB_ATTR_RO(aliases); static ssize_t slabs_show(struct kmem_cache *s, char *buf) { - return slab_objects(s, buf, SO_FULL|SO_PARTIAL|SO_CPU); + return show_slab_objects(s, buf, SO_FULL|SO_PARTIAL|SO_CPU); } SLAB_ATTR_RO(slabs); static ssize_t partial_show(struct kmem_cache *s, char *buf) { - return slab_objects(s, buf, SO_PARTIAL); + return show_slab_objects(s, buf, SO_PARTIAL); } SLAB_ATTR_RO(partial); static ssize_t cpu_slabs_show(struct kmem_cache *s, char *buf) { - return slab_objects(s, buf, SO_CPU); + return show_slab_objects(s, buf, SO_CPU); } SLAB_ATTR_RO(cpu_slabs); static ssize_t objects_show(struct kmem_cache *s, char *buf) { - return slab_objects(s, buf, SO_FULL|SO_PARTIAL|SO_CPU|SO_OBJECTS); + return show_slab_objects(s, buf, SO_FULL|SO_PARTIAL|SO_CPU|SO_OBJECTS); } SLAB_ATTR_RO(objects); @@ -3971,7 +3949,6 @@ SLAB_ATTR(remote_node_defrag_ratio); #endif #ifdef CONFIG_SLUB_STATS - static int show_stat(struct kmem_cache *s, char *buf, enum stat_item si) { unsigned long sum = 0; @@ -4155,8 +4132,8 @@ static struct kset *slab_kset; #define ID_STR_LENGTH 64 /* Create a unique string id for a slab cache: - * format - * :[flags-]size:[memory address of kmemcache] + * + * Format :[flags-]size */ static char *create_unique_id(struct kmem_cache *s) { diff --git a/mm/swap.c b/mm/swap.c index 710a20bb9749cc9c9397e85bb59643dc38c27698..d4ec59aa5c4632962f8adf1aad5cef68afbe5701 100644 --- a/mm/swap.c +++ b/mm/swap.c @@ -176,7 +176,7 @@ void activate_page(struct page *page) SetPageActive(page); add_page_to_active_list(zone, page); __count_vm_event(PGACTIVATE); - mem_cgroup_move_lists(page_get_page_cgroup(page), true); + mem_cgroup_move_lists(page, true); } spin_unlock_irq(&zone->lru_lock); } diff --git a/mm/truncate.c b/mm/truncate.c index c35c49e54fb6527eae91cb02177fc2b05a00abad..7d20ce41ecf52c2cd4027207558734f835124992 100644 --- a/mm/truncate.c +++ b/mm/truncate.c @@ -134,8 +134,7 @@ invalidate_complete_page(struct address_space *mapping, struct page *page) } /** - * truncate_inode_pages - truncate range of pages specified by start and - * end byte offsets + * truncate_inode_pages - truncate range of pages specified by start & end byte offsets * @mapping: mapping to truncate * @lstart: offset from which to truncate * @lend: offset to which to truncate diff --git a/mm/vmscan.c b/mm/vmscan.c index a26dabd62fed40c8ec7832dc4656feaf7d3909f9..45711585684ec74c01f7b93ae28a8d8b4f62bfb9 100644 --- a/mm/vmscan.c +++ b/mm/vmscan.c @@ -126,7 +126,7 @@ long vm_total_pages; /* The total number of pages which the VM controls */ static LIST_HEAD(shrinker_list); static DECLARE_RWSEM(shrinker_rwsem); -#ifdef CONFIG_CGROUP_MEM_CONT +#ifdef CONFIG_CGROUP_MEM_RES_CTLR #define scan_global_lru(sc) (!(sc)->mem_cgroup) #else #define scan_global_lru(sc) (1) @@ -1128,7 +1128,7 @@ static void shrink_active_list(unsigned long nr_pages, struct zone *zone, ClearPageActive(page); list_move(&page->lru, &zone->inactive_list); - mem_cgroup_move_lists(page_get_page_cgroup(page), false); + mem_cgroup_move_lists(page, false); pgmoved++; if (!pagevec_add(&pvec, page)) { __mod_zone_page_state(zone, NR_INACTIVE, pgmoved); @@ -1156,8 +1156,9 @@ static void shrink_active_list(unsigned long nr_pages, struct zone *zone, VM_BUG_ON(PageLRU(page)); SetPageLRU(page); VM_BUG_ON(!PageActive(page)); + list_move(&page->lru, &zone->active_list); - mem_cgroup_move_lists(page_get_page_cgroup(page), true); + mem_cgroup_move_lists(page, true); pgmoved++; if (!pagevec_add(&pvec, page)) { __mod_zone_page_state(zone, NR_ACTIVE, pgmoved); @@ -1427,7 +1428,7 @@ unsigned long try_to_free_pages(struct zone **zones, int order, gfp_t gfp_mask) return do_try_to_free_pages(zones, gfp_mask, &sc); } -#ifdef CONFIG_CGROUP_MEM_CONT +#ifdef CONFIG_CGROUP_MEM_RES_CTLR unsigned long try_to_free_mem_cgroup_pages(struct mem_cgroup *mem_cont, gfp_t gfp_mask) diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c index 556b2893b56b7e3295f6dd71aa00e5581a7e5e8c..1e5c9904571d27a78a90761aeb3882f1bf3bfa57 100644 --- a/net/8021q/vlan_dev.c +++ b/net/8021q/vlan_dev.c @@ -382,7 +382,7 @@ static int vlan_dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) vlan_dev_info(dev)->cnt_encap_on_xmit++; pr_debug("%s: proto to encap: 0x%hx\n", - __func__, htons(veth->h_vlan_proto)); + __func__, ntohs(veth->h_vlan_proto)); /* Construct the second two bytes. This field looks something * like: * usr_priority: 3 bits (high bits) diff --git a/net/bluetooth/bnep/bnep.h b/net/bluetooth/bnep/bnep.h index a2992280c3d1ee3a5b908faf793a18b6b4f16e5c..e69244dd8de850ceb4197aa8157a91011511f332 100644 --- a/net/bluetooth/bnep/bnep.h +++ b/net/bluetooth/bnep/bnep.h @@ -174,7 +174,7 @@ struct bnep_session { void bnep_net_setup(struct net_device *dev); int bnep_sock_init(void); -int bnep_sock_cleanup(void); +void bnep_sock_cleanup(void); static inline int bnep_mc_hash(__u8 *addr) { diff --git a/net/bluetooth/bnep/sock.c b/net/bluetooth/bnep/sock.c index 81065e548a1f50d4c4a37dd9c4c54f52726d7fdd..201e5b1ce473cd2066d2607a2d5af6f8555c2d6f 100644 --- a/net/bluetooth/bnep/sock.c +++ b/net/bluetooth/bnep/sock.c @@ -257,12 +257,10 @@ error: return err; } -int __exit bnep_sock_cleanup(void) +void __exit bnep_sock_cleanup(void) { if (bt_sock_unregister(BTPROTO_BNEP) < 0) BT_ERR("Can't unregister BNEP socket"); proto_unregister(&bnep_proto); - - return 0; } diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index 930b58e7149a77b4af84e4dd4674437b0bf31378..aec6929f5c166fd362df7e38faebb19f91f8a445 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c @@ -902,8 +902,6 @@ int hci_unregister_dev(struct hci_dev *hdev) BT_DBG("%p name %s type %d", hdev, hdev->name, hdev->type); - hci_unregister_sysfs(hdev); - write_lock_bh(&hci_dev_list_lock); list_del(&hdev->list); write_unlock_bh(&hci_dev_list_lock); @@ -915,6 +913,8 @@ int hci_unregister_dev(struct hci_dev *hdev) hci_notify(hdev, HCI_DEV_UNREG); + hci_unregister_sysfs(hdev); + __hci_dev_put(hdev); return 0; diff --git a/net/bluetooth/hci_sock.c b/net/bluetooth/hci_sock.c index 14991323c273a15793823107e25d79af5403f58e..b5d4019d3572c59eefe328a22085645d6132b136 100644 --- a/net/bluetooth/hci_sock.c +++ b/net/bluetooth/hci_sock.c @@ -734,7 +734,7 @@ error: return err; } -int __exit hci_sock_cleanup(void) +void __exit hci_sock_cleanup(void) { if (bt_sock_unregister(BTPROTO_HCI) < 0) BT_ERR("HCI socket unregistration failed"); @@ -742,6 +742,4 @@ int __exit hci_sock_cleanup(void) hci_unregister_notifier(&hci_sock_nblock); proto_unregister(&hci_sk_proto); - - return 0; } diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c index 4cb8a1385539e3a82123f4c6c3e32a852570f312..44f5ce1fbfa4849c6c00941b978d799b56a121df 100644 --- a/net/ipv4/af_inet.c +++ b/net/ipv4/af_inet.c @@ -458,7 +458,7 @@ int inet_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) err = -EADDRNOTAVAIL; if (!sysctl_ip_nonlocal_bind && !inet->freebind && - addr->sin_addr.s_addr != INADDR_ANY && + addr->sin_addr.s_addr != htonl(INADDR_ANY) && chk_addr_ret != RTN_LOCAL && chk_addr_ret != RTN_MULTICAST && chk_addr_ret != RTN_BROADCAST) diff --git a/net/ipv4/esp4.c b/net/ipv4/esp4.c index 091e6709f83109dc1e229f24bfe3cad71d5be13a..f3ceca31aa45c15e361f3d8557d4a5c13f726905 100644 --- a/net/ipv4/esp4.c +++ b/net/ipv4/esp4.c @@ -168,7 +168,7 @@ static int esp_output(struct xfrm_state *x, struct sk_buff *skb) struct xfrm_encap_tmpl *encap = x->encap; struct udphdr *uh; __be32 *udpdata32; - unsigned int sport, dport; + __be16 sport, dport; int encap_type; spin_lock_bh(&x->lock); diff --git a/net/ipv4/ip_sockglue.c b/net/ipv4/ip_sockglue.c index e7c9e4e72327e7649f6ffe9b567eaa4bc69dff5c..bb3cbe5ec36ddeae6b825df339a75ba68adfd452 100644 --- a/net/ipv4/ip_sockglue.c +++ b/net/ipv4/ip_sockglue.c @@ -583,7 +583,7 @@ static int do_ip_setsockopt(struct sock *sk, int level, } if (!mreq.imr_ifindex) { - if (mreq.imr_address.s_addr == INADDR_ANY) { + if (mreq.imr_address.s_addr == htonl(INADDR_ANY)) { inet->mc_index = 0; inet->mc_addr = 0; err = 0; diff --git a/net/ipv4/ipconfig.c b/net/ipv4/ipconfig.c index 4afce057280600379a5e1960b57686213daf5632..96138b128de89f5133c7bf15ec699fc522e8f2ca 100644 --- a/net/ipv4/ipconfig.c +++ b/net/ipv4/ipconfig.c @@ -103,6 +103,7 @@ - '3' from resolv.h */ #define NONE __constant_htonl(INADDR_NONE) +#define ANY __constant_htonl(INADDR_ANY) /* * Public IP configuration @@ -1476,19 +1477,19 @@ static int __init ip_auto_config_setup(char *addrs) DBG(("IP-Config: Parameter #%d: `%s'\n", num, ip)); switch (num) { case 0: - if ((ic_myaddr = in_aton(ip)) == INADDR_ANY) + if ((ic_myaddr = in_aton(ip)) == ANY) ic_myaddr = NONE; break; case 1: - if ((ic_servaddr = in_aton(ip)) == INADDR_ANY) + if ((ic_servaddr = in_aton(ip)) == ANY) ic_servaddr = NONE; break; case 2: - if ((ic_gateway = in_aton(ip)) == INADDR_ANY) + if ((ic_gateway = in_aton(ip)) == ANY) ic_gateway = NONE; break; case 3: - if ((ic_netmask = in_aton(ip)) == INADDR_ANY) + if ((ic_netmask = in_aton(ip)) == ANY) ic_netmask = NONE; break; case 4: diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index cbfef8b1f5e83c4153cb4e52286c7d0c007345a9..67f84f5035c43d275d84fd1bccc3a15f48b1ccb5 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c @@ -1035,6 +1035,13 @@ static void tcp_cwnd_validate(struct sock *sk) * introducing MSS oddities to segment boundaries. In rare cases where * mss_now != mss_cache, we will request caller to create a small skb * per input skb which could be mostly avoided here (if desired). + * + * We explicitly want to create a request for splitting write queue tail + * to a small skb for Nagle purposes while avoiding unnecessary modulos, + * thus all the complexity (cwnd_len is always MSS multiple which we + * return whenever allowed by the other factors). Basically we need the + * modulo only when the receiver window alone is the limiting factor or + * when we would be allowed to send the split-due-to-Nagle skb fully. */ static unsigned int tcp_mss_split_point(struct sock *sk, struct sk_buff *skb, unsigned int mss_now, unsigned int cwnd) @@ -1048,10 +1055,11 @@ static unsigned int tcp_mss_split_point(struct sock *sk, struct sk_buff *skb, if (likely(cwnd_len <= window && skb != tcp_write_queue_tail(sk))) return cwnd_len; - if (skb == tcp_write_queue_tail(sk) && cwnd_len <= skb->len) + needed = min(skb->len, window); + + if (skb == tcp_write_queue_tail(sk) && cwnd_len <= needed) return cwnd_len; - needed = min(skb->len, window); return needed - needed % mss_now; } diff --git a/net/netfilter/nf_conntrack_expect.c b/net/netfilter/nf_conntrack_expect.c index e06bf0028bb18eaea80e40fb633d4aac495a038f..684ec9c1ad38b7545502fd08213360bd2c7a9b0c 100644 --- a/net/netfilter/nf_conntrack_expect.c +++ b/net/netfilter/nf_conntrack_expect.c @@ -381,7 +381,7 @@ int nf_ct_expect_related(struct nf_conntrack_expect *expect) if (nf_ct_expect_count >= nf_ct_expect_max) { if (net_ratelimit()) printk(KERN_WARNING - "nf_conntrack: expectation table full"); + "nf_conntrack: expectation table full\n"); ret = -EMFILE; goto out; } diff --git a/net/netfilter/nf_conntrack_extend.c b/net/netfilter/nf_conntrack_extend.c index 8b9be1e978cda3dc00c01050d69e495ac8c610ad..2bd9963b5b3ea4cf26d4abde679a72e8b28421a7 100644 --- a/net/netfilter/nf_conntrack_extend.c +++ b/net/netfilter/nf_conntrack_extend.c @@ -19,14 +19,6 @@ static struct nf_ct_ext_type *nf_ct_ext_types[NF_CT_EXT_NUM]; static DEFINE_MUTEX(nf_ct_ext_type_mutex); -/* Horrible trick to figure out smallest amount worth kmallocing. */ -#define CACHE(x) (x) + 0 * -enum { - NF_CT_EXT_MIN_SIZE = -#include - 1 }; -#undef CACHE - void __nf_ct_ext_destroy(struct nf_conn *ct) { unsigned int i; @@ -53,7 +45,7 @@ EXPORT_SYMBOL(__nf_ct_ext_destroy); static void * nf_ct_ext_create(struct nf_ct_ext **ext, enum nf_ct_ext_id id, gfp_t gfp) { - unsigned int off, len, real_len; + unsigned int off, len; struct nf_ct_ext_type *t; rcu_read_lock(); @@ -61,16 +53,14 @@ nf_ct_ext_create(struct nf_ct_ext **ext, enum nf_ct_ext_id id, gfp_t gfp) BUG_ON(t == NULL); off = ALIGN(sizeof(struct nf_ct_ext), t->align); len = off + t->len; - real_len = t->alloc_size; rcu_read_unlock(); - *ext = kzalloc(real_len, gfp); + *ext = kzalloc(t->alloc_size, gfp); if (!*ext) return NULL; (*ext)->offset[id] = off; (*ext)->len = len; - (*ext)->real_len = real_len; return (void *)(*ext) + off; } @@ -95,7 +85,7 @@ void *__nf_ct_ext_add(struct nf_conn *ct, enum nf_ct_ext_id id, gfp_t gfp) newlen = newoff + t->len; rcu_read_unlock(); - if (newlen >= ct->ext->real_len) { + if (newlen >= ksize(ct->ext)) { new = kmalloc(newlen, gfp); if (!new) return NULL; @@ -114,7 +104,6 @@ void *__nf_ct_ext_add(struct nf_conn *ct, enum nf_ct_ext_id id, gfp_t gfp) rcu_read_unlock(); } kfree(ct->ext); - new->real_len = newlen; ct->ext = new; } @@ -156,8 +145,6 @@ static void update_alloc_size(struct nf_ct_ext_type *type) t1->alloc_size = ALIGN(t1->alloc_size, t2->align) + t2->len; } - if (t1->alloc_size < NF_CT_EXT_MIN_SIZE) - t1->alloc_size = NF_CT_EXT_MIN_SIZE; } } diff --git a/net/netfilter/nf_queue.c b/net/netfilter/nf_queue.c index bfc2928c19120f4c5994ae616066b1f030ba2a01..ddc80ea114cda13509f5828b2c8f5590a6d7f3e3 100644 --- a/net/netfilter/nf_queue.c +++ b/net/netfilter/nf_queue.c @@ -51,7 +51,7 @@ int nf_unregister_queue_handler(int pf, const struct nf_queue_handler *qh) return -EINVAL; mutex_lock(&queue_handler_mutex); - if (queue_handler[pf] != qh) { + if (queue_handler[pf] && queue_handler[pf] != qh) { mutex_unlock(&queue_handler_mutex); return -EINVAL; } diff --git a/net/netfilter/nfnetlink_log.c b/net/netfilter/nfnetlink_log.c index 7efa40d47393727447fd1bdbf88d579914e5cfc4..bf3f19b21fe49eb0399ac66b09940bd085fb17ca 100644 --- a/net/netfilter/nfnetlink_log.c +++ b/net/netfilter/nfnetlink_log.c @@ -556,7 +556,7 @@ nfulnl_log_packet(unsigned int pf, /* FIXME: do we want to make the size calculation conditional based on * what is actually present? way more branches and checks, but more * memory efficient... */ - size = NLMSG_ALIGN(sizeof(struct nfgenmsg)) + size = NLMSG_SPACE(sizeof(struct nfgenmsg)) + nla_total_size(sizeof(struct nfulnl_msg_packet_hdr)) + nla_total_size(sizeof(u_int32_t)) /* ifindex */ + nla_total_size(sizeof(u_int32_t)) /* ifindex */ @@ -702,20 +702,30 @@ nfulnl_recv_config(struct sock *ctnl, struct sk_buff *skb, struct nfgenmsg *nfmsg = NLMSG_DATA(nlh); u_int16_t group_num = ntohs(nfmsg->res_id); struct nfulnl_instance *inst; + struct nfulnl_msg_config_cmd *cmd = NULL; int ret = 0; + if (nfula[NFULA_CFG_CMD]) { + u_int8_t pf = nfmsg->nfgen_family; + cmd = nla_data(nfula[NFULA_CFG_CMD]); + + /* Commands without queue context */ + switch (cmd->command) { + case NFULNL_CFG_CMD_PF_BIND: + return nf_log_register(pf, &nfulnl_logger); + case NFULNL_CFG_CMD_PF_UNBIND: + nf_log_unregister_pf(pf); + return 0; + } + } + inst = instance_lookup_get(group_num); if (inst && inst->peer_pid != NETLINK_CB(skb).pid) { ret = -EPERM; goto out_put; } - if (nfula[NFULA_CFG_CMD]) { - u_int8_t pf = nfmsg->nfgen_family; - struct nfulnl_msg_config_cmd *cmd; - - cmd = nla_data(nfula[NFULA_CFG_CMD]); - + if (cmd != NULL) { switch (cmd->command) { case NFULNL_CFG_CMD_BIND: if (inst) { @@ -738,14 +748,6 @@ nfulnl_recv_config(struct sock *ctnl, struct sk_buff *skb, instance_destroy(inst); goto out; - case NFULNL_CFG_CMD_PF_BIND: - ret = nf_log_register(pf, &nfulnl_logger); - break; - case NFULNL_CFG_CMD_PF_UNBIND: - /* This is a bug and a feature. We cannot unregister - * other handlers, like nfnetlink_inst can */ - nf_log_unregister_pf(pf); - break; default: ret = -ENOTSUPP; break; diff --git a/net/netfilter/nfnetlink_queue.c b/net/netfilter/nfnetlink_queue.c index 0043d3a9f87eb5bbb477c96f64d99a60d6320e6a..012cb69108202c6ac1060847a7050a874e12931c 100644 --- a/net/netfilter/nfnetlink_queue.c +++ b/net/netfilter/nfnetlink_queue.c @@ -224,7 +224,7 @@ nfqnl_build_packet_message(struct nfqnl_instance *queue, struct net_device *indev; struct net_device *outdev; - size = NLMSG_ALIGN(sizeof(struct nfgenmsg)) + size = NLMSG_SPACE(sizeof(struct nfgenmsg)) + nla_total_size(sizeof(struct nfqnl_msg_packet_hdr)) + nla_total_size(sizeof(u_int32_t)) /* ifindex */ + nla_total_size(sizeof(u_int32_t)) /* ifindex */ @@ -703,19 +703,12 @@ nfqnl_recv_config(struct sock *ctnl, struct sk_buff *skb, /* Commands without queue context - might sleep */ switch (cmd->command) { case NFQNL_CFG_CMD_PF_BIND: - ret = nf_register_queue_handler(ntohs(cmd->pf), - &nfqh); - break; + return nf_register_queue_handler(ntohs(cmd->pf), + &nfqh); case NFQNL_CFG_CMD_PF_UNBIND: - ret = nf_unregister_queue_handler(ntohs(cmd->pf), - &nfqh); - break; - default: - break; + return nf_unregister_queue_handler(ntohs(cmd->pf), + &nfqh); } - - if (ret < 0) - return ret; } rcu_read_lock(); diff --git a/net/netfilter/xt_time.c b/net/netfilter/xt_time.c index e9a8794bc3ab6020c27cb6b73c24efd2b79201d1..9fa2e0824708f1acf62ab9c803a38eb4b4b2e408 100644 --- a/net/netfilter/xt_time.c +++ b/net/netfilter/xt_time.c @@ -95,8 +95,11 @@ static inline void localtime_2(struct xtm *r, time_t time) */ r->dse = time / 86400; - /* 1970-01-01 (w=0) was a Thursday (4). */ - r->weekday = (4 + r->dse) % 7; + /* + * 1970-01-01 (w=0) was a Thursday (4). + * -1 and +1 map Sunday properly onto 7. + */ + r->weekday = (4 + r->dse - 1) % 7 + 1; } static void localtime_3(struct xtm *r, time_t time) diff --git a/net/rxrpc/ar-recvmsg.c b/net/rxrpc/ar-recvmsg.c index f19121d4795b25cbb687459741e318ce76091989..a39bf97f8830703cf1a6c5e23367727532e26efb 100644 --- a/net/rxrpc/ar-recvmsg.c +++ b/net/rxrpc/ar-recvmsg.c @@ -143,7 +143,8 @@ int rxrpc_recvmsg(struct kiocb *iocb, struct socket *sock, /* copy the peer address and timestamp */ if (!continue_call) { if (msg->msg_name && msg->msg_namelen > 0) - memcpy(&msg->msg_name, &call->conn->trans->peer->srx, + memcpy(msg->msg_name, + &call->conn->trans->peer->srx, sizeof(call->conn->trans->peer->srx)); sock_recv_timestamp(msg, &rx->sk, skb); } diff --git a/net/sched/cls_u32.c b/net/sched/cls_u32.c index b18fa95ef248e78f8a898248fa3466970b9f820d..c5c16b4b6e98d5e96eb7ee68ec4fd5e5f2d011e6 100644 --- a/net/sched/cls_u32.c +++ b/net/sched/cls_u32.c @@ -89,7 +89,7 @@ static const struct tcf_ext_map u32_ext_map = { static struct tc_u_common *u32_list; -static __inline__ unsigned u32_hash_fold(u32 key, struct tc_u32_sel *sel, u8 fshift) +static __inline__ unsigned u32_hash_fold(__be32 key, struct tc_u32_sel *sel, u8 fshift) { unsigned h = ntohl(key & sel->hmask)>>fshift; @@ -137,7 +137,7 @@ next_knode: for (i = n->sel.nkeys; i>0; i--, key++) { - if ((*(u32*)(ptr+key->off+(off2&key->offmask))^key->val)&key->mask) { + if ((*(__be32*)(ptr+key->off+(off2&key->offmask))^key->val)&key->mask) { n = n->next; goto next_knode; } @@ -182,7 +182,7 @@ check_terminal: ht = n->ht_down; sel = 0; if (ht->divisor) - sel = ht->divisor&u32_hash_fold(*(u32*)(ptr+n->sel.hoff), &n->sel,n->fshift); + sel = ht->divisor&u32_hash_fold(*(__be32*)(ptr+n->sel.hoff), &n->sel,n->fshift); if (!(n->sel.flags&(TC_U32_VAROFFSET|TC_U32_OFFSET|TC_U32_EAT))) goto next_ht; @@ -190,7 +190,7 @@ check_terminal: if (n->sel.flags&(TC_U32_OFFSET|TC_U32_VAROFFSET)) { off2 = n->sel.off + 3; if (n->sel.flags&TC_U32_VAROFFSET) - off2 += ntohs(n->sel.offmask & *(u16*)(ptr+n->sel.offoff)) >>n->sel.offshift; + off2 += ntohs(n->sel.offmask & *(__be16*)(ptr+n->sel.offoff)) >>n->sel.offshift; off2 &= ~3; } if (n->sel.flags&TC_U32_EAT) { diff --git a/net/sched/em_u32.c b/net/sched/em_u32.c index 112796e4a7c469d7147328ec54d507bd4e468c9f..953f1479f7da2d4af4015440fc708ffda9d81670 100644 --- a/net/sched/em_u32.c +++ b/net/sched/em_u32.c @@ -35,7 +35,7 @@ static int em_u32_match(struct sk_buff *skb, struct tcf_ematch *em, if (!tcf_valid_offset(skb, ptr, sizeof(u32))) return 0; - return !(((*(u32*) ptr) ^ key->val) & key->mask); + return !(((*(__be32*) ptr) ^ key->val) & key->mask); } static struct tcf_ematch_ops em_u32_ops = { diff --git a/net/sctp/bind_addr.c b/net/sctp/bind_addr.c index a27511ebc4cb6ae80749a41c6b85239021749fee..ceefda025e2d3d31fbeb64e0b31d7866222c407f 100644 --- a/net/sctp/bind_addr.c +++ b/net/sctp/bind_addr.c @@ -209,6 +209,7 @@ int sctp_add_bind_addr(struct sctp_bind_addr *bp, union sctp_addr *new, int sctp_del_bind_addr(struct sctp_bind_addr *bp, union sctp_addr *del_addr) { struct sctp_sockaddr_entry *addr, *temp; + int found = 0; /* We hold the socket lock when calling this function, * and that acts as a writer synchronizing lock. @@ -216,13 +217,14 @@ int sctp_del_bind_addr(struct sctp_bind_addr *bp, union sctp_addr *del_addr) list_for_each_entry_safe(addr, temp, &bp->address_list, list) { if (sctp_cmp_addr_exact(&addr->a, del_addr)) { /* Found the exact match. */ + found = 1; addr->valid = 0; list_del_rcu(&addr->list); break; } } - if (addr && !addr->valid) { + if (found) { call_rcu(&addr->rcu, sctp_local_addr_free); SCTP_DBG_OBJCNT_DEC(addr); return 0; diff --git a/net/sctp/input.c b/net/sctp/input.c index 4db5a75e01ce99a72cc53014767facc71ca6500e..c1d7e3b5c4b409ae636dfc9a5593a1673f01ecc3 100644 --- a/net/sctp/input.c +++ b/net/sctp/input.c @@ -944,7 +944,7 @@ static struct sctp_association *__sctp_rcv_init_lookup(struct sk_buff *skb, static struct sctp_association *__sctp_rcv_asconf_lookup( sctp_chunkhdr_t *ch, const union sctp_addr *laddr, - __be32 peer_port, + __be16 peer_port, struct sctp_transport **transportp) { sctp_addip_chunk_t *asconf = (struct sctp_addip_chunk *)ch; diff --git a/net/sctp/ipv6.c b/net/sctp/ipv6.c index 2622215cd3576e1a3d3a1b57ffa450a40ab0e36b..1937be583cd7f98c7470a8aa6b1cebb546cf108b 100644 --- a/net/sctp/ipv6.c +++ b/net/sctp/ipv6.c @@ -89,6 +89,7 @@ static int sctp_inet6addr_event(struct notifier_block *this, unsigned long ev, struct inet6_ifaddr *ifa = (struct inet6_ifaddr *)ptr; struct sctp_sockaddr_entry *addr = NULL; struct sctp_sockaddr_entry *temp; + int found = 0; switch (ev) { case NETDEV_UP: @@ -111,13 +112,14 @@ static int sctp_inet6addr_event(struct notifier_block *this, unsigned long ev, &sctp_local_addr_list, list) { if (ipv6_addr_equal(&addr->a.v6.sin6_addr, &ifa->addr)) { + found = 1; addr->valid = 0; list_del_rcu(&addr->list); break; } } spin_unlock_bh(&sctp_local_addr_lock); - if (addr && !addr->valid) + if (found) call_rcu(&addr->rcu, sctp_local_addr_free); break; } diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c index 87512f14cf719ead1a20c97dfe32a4b4503043d9..25be8f04de6e6dd0ee2cfcaffa3b076603800d05 100644 --- a/net/sctp/protocol.c +++ b/net/sctp/protocol.c @@ -337,14 +337,14 @@ static int sctp_v4_cmp_addr(const union sctp_addr *addr1, static void sctp_v4_inaddr_any(union sctp_addr *addr, __be16 port) { addr->v4.sin_family = AF_INET; - addr->v4.sin_addr.s_addr = INADDR_ANY; + addr->v4.sin_addr.s_addr = htonl(INADDR_ANY); addr->v4.sin_port = port; } /* Is this a wildcard address? */ static int sctp_v4_is_any(const union sctp_addr *addr) { - return INADDR_ANY == addr->v4.sin_addr.s_addr; + return htonl(INADDR_ANY) == addr->v4.sin_addr.s_addr; } /* This function checks if the address is a valid address to be used for @@ -375,7 +375,7 @@ static int sctp_v4_available(union sctp_addr *addr, struct sctp_sock *sp) int ret = inet_addr_type(&init_net, addr->v4.sin_addr.s_addr); - if (addr->v4.sin_addr.s_addr != INADDR_ANY && + if (addr->v4.sin_addr.s_addr != htonl(INADDR_ANY) && ret != RTN_LOCAL && !sp->inet.freebind && !sysctl_ip_nonlocal_bind) @@ -628,6 +628,7 @@ static int sctp_inetaddr_event(struct notifier_block *this, unsigned long ev, struct in_ifaddr *ifa = (struct in_ifaddr *)ptr; struct sctp_sockaddr_entry *addr = NULL; struct sctp_sockaddr_entry *temp; + int found = 0; if (ifa->ifa_dev->dev->nd_net != &init_net) return NOTIFY_DONE; @@ -650,13 +651,14 @@ static int sctp_inetaddr_event(struct notifier_block *this, unsigned long ev, list_for_each_entry_safe(addr, temp, &sctp_local_addr_list, list) { if (addr->a.v4.sin_addr.s_addr == ifa->ifa_local) { + found = 1; addr->valid = 0; list_del_rcu(&addr->list); break; } } spin_unlock_bh(&sctp_local_addr_lock); - if (addr && !addr->valid) + if (found) call_rcu(&addr->rcu, sctp_local_addr_free); break; } @@ -786,8 +788,8 @@ static int sctp_inet_cmp_addr(const union sctp_addr *addr1, /* PF_INET only supports AF_INET addresses. */ if (addr1->sa.sa_family != addr2->sa.sa_family) return 0; - if (INADDR_ANY == addr1->v4.sin_addr.s_addr || - INADDR_ANY == addr2->v4.sin_addr.s_addr) + if (htonl(INADDR_ANY) == addr1->v4.sin_addr.s_addr || + htonl(INADDR_ANY) == addr2->v4.sin_addr.s_addr) return 1; if (addr1->v4.sin_addr.s_addr == addr2->v4.sin_addr.s_addr) return 1; diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c index e45be4e3f80d733c8f3eb27773651ad1a4d44add..578630e8e00d321a93565ee96c3a43b0d85acefa 100644 --- a/net/sctp/sm_make_chunk.c +++ b/net/sctp/sm_make_chunk.c @@ -2375,6 +2375,14 @@ static int sctp_process_param(struct sctp_association *asoc, asoc->peer.ipv4_address = 0; asoc->peer.ipv6_address = 0; + /* Assume that peer supports the address family + * by which it sends a packet. + */ + if (peer_addr->sa.sa_family == AF_INET6) + asoc->peer.ipv6_address = 1; + else if (peer_addr->sa.sa_family == AF_INET) + asoc->peer.ipv4_address = 1; + /* Cycle through address types; avoid divide by 0. */ sat = ntohs(param.p->length) - sizeof(sctp_paramhdr_t); if (sat) diff --git a/net/sctp/socket.c b/net/sctp/socket.c index 1316694d0a21ee77fe4473565f4d820ca7d2abbd..a3138a0fe2c50a5ef1904f243d3d6b0ceba68868 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c @@ -2933,17 +2933,39 @@ static int sctp_setsockopt_maxburst(struct sock *sk, char __user *optval, int optlen) { + struct sctp_assoc_value params; + struct sctp_sock *sp; + struct sctp_association *asoc; int val; + int assoc_id = 0; - if (optlen != sizeof(int)) + if (optlen < sizeof(int)) return -EINVAL; - if (get_user(val, (int __user *)optval)) - return -EFAULT; - if (val < 0) + if (optlen == sizeof(int)) { + printk(KERN_WARNING + "SCTP: Use of int in max_burst socket option deprecated\n"); + printk(KERN_WARNING + "SCTP: Use struct sctp_assoc_value instead\n"); + if (copy_from_user(&val, optval, optlen)) + return -EFAULT; + } else if (optlen == sizeof(struct sctp_assoc_value)) { + if (copy_from_user(¶ms, optval, optlen)) + return -EFAULT; + val = params.assoc_value; + assoc_id = params.assoc_id; + } else return -EINVAL; - sctp_sk(sk)->max_burst = val; + sp = sctp_sk(sk); + + if (assoc_id != 0) { + asoc = sctp_id2assoc(sk, assoc_id); + if (!asoc) + return -EINVAL; + asoc->max_burst = val; + } else + sp->max_burst = val; return 0; } @@ -5005,20 +5027,45 @@ static int sctp_getsockopt_maxburst(struct sock *sk, int len, char __user *optval, int __user *optlen) { - int val; + struct sctp_assoc_value params; + struct sctp_sock *sp; + struct sctp_association *asoc; if (len < sizeof(int)) return -EINVAL; - len = sizeof(int); + if (len == sizeof(int)) { + printk(KERN_WARNING + "SCTP: Use of int in max_burst socket option deprecated\n"); + printk(KERN_WARNING + "SCTP: Use struct sctp_assoc_value instead\n"); + params.assoc_id = 0; + } else if (len == sizeof (struct sctp_assoc_value)) { + if (copy_from_user(¶ms, optval, len)) + return -EFAULT; + } else + return -EINVAL; - val = sctp_sk(sk)->max_burst; - if (put_user(len, optlen)) - return -EFAULT; - if (copy_to_user(optval, &val, len)) - return -EFAULT; + sp = sctp_sk(sk); + + if (params.assoc_id != 0) { + asoc = sctp_id2assoc(sk, params.assoc_id); + if (!asoc) + return -EINVAL; + params.assoc_value = asoc->max_burst; + } else + params.assoc_value = sp->max_burst; + + if (len == sizeof(int)) { + if (copy_to_user(optval, ¶ms.assoc_value, len)) + return -EFAULT; + } else { + if (copy_to_user(optval, ¶ms, len)) + return -EFAULT; + } + + return 0; - return -ENOTSUPP; } static int sctp_getsockopt_hmac_ident(struct sock *sk, int len, diff --git a/net/sunrpc/auth_gss/gss_mech_switch.c b/net/sunrpc/auth_gss/gss_mech_switch.c index 61801a069ff02c69d91313ea75df3d542ffff0e2..bce9d527af08187c5ff5c590acc43464483fe90a 100644 --- a/net/sunrpc/auth_gss/gss_mech_switch.c +++ b/net/sunrpc/auth_gss/gss_mech_switch.c @@ -317,7 +317,7 @@ gss_delete_sec_context(struct gss_ctx **context_handle) if (!*context_handle) return(GSS_S_NO_CONTEXT); - if ((*context_handle)->internal_ctx_id != 0) + if ((*context_handle)->internal_ctx_id) (*context_handle)->mech_type->gm_ops ->gss_delete_sec_context((*context_handle) ->internal_ctx_id); diff --git a/net/sunrpc/svc_xprt.c b/net/sunrpc/svc_xprt.c index ea377e06afae0d1a56812e9b6771a3c055c7a410..332eb47539e16a18a5dd7313dfaf76525078976b 100644 --- a/net/sunrpc/svc_xprt.c +++ b/net/sunrpc/svc_xprt.c @@ -185,7 +185,7 @@ int svc_create_xprt(struct svc_serv *serv, char *xprt_name, unsigned short port, struct svc_xprt_class *xcl; struct sockaddr_in sin = { .sin_family = AF_INET, - .sin_addr.s_addr = INADDR_ANY, + .sin_addr.s_addr = htonl(INADDR_ANY), .sin_port = htons(port), }; dprintk("svc: creating transport %s[%d]\n", xprt_name, port); diff --git a/net/sunrpc/xprtrdma/svc_rdma_sendto.c b/net/sunrpc/xprtrdma/svc_rdma_sendto.c index 0598b229c11d326720a6c56b9bce66cfaa66e6b7..981f190c1b398278b496300a69b733fe2469c922 100644 --- a/net/sunrpc/xprtrdma/svc_rdma_sendto.c +++ b/net/sunrpc/xprtrdma/svc_rdma_sendto.c @@ -156,7 +156,7 @@ static int send_write(struct svcxprt_rdma *xprt, struct svc_rqst *rqstp, struct svc_rdma_op_ctxt *ctxt; int ret = 0; - BUG_ON(sge_count >= 32); + BUG_ON(sge_count > RPCSVC_MAXPAGES); dprintk("svcrdma: RDMA_WRITE rmr=%x, to=%llx, xdr_off=%d, " "write_len=%d, xdr_sge=%p, sge_count=%d\n", rmr, (unsigned long long)to, xdr_off, diff --git a/net/sunrpc/xprtrdma/svc_rdma_transport.c b/net/sunrpc/xprtrdma/svc_rdma_transport.c index f09444c451bc232540baf771fa69499531ffca35..16fd3f6718ff55746168c732ec3f367ef9b61f9a 100644 --- a/net/sunrpc/xprtrdma/svc_rdma_transport.c +++ b/net/sunrpc/xprtrdma/svc_rdma_transport.c @@ -54,7 +54,6 @@ static struct svc_xprt *svc_rdma_create(struct svc_serv *serv, int flags); static struct svc_xprt *svc_rdma_accept(struct svc_xprt *xprt); static void svc_rdma_release_rqst(struct svc_rqst *); -static void rdma_destroy_xprt(struct svcxprt_rdma *xprt); static void dto_tasklet_func(unsigned long data); static void svc_rdma_detach(struct svc_xprt *xprt); static void svc_rdma_free(struct svc_xprt *xprt); @@ -247,6 +246,7 @@ static void dto_tasklet_func(unsigned long data) sq_cq_reap(xprt); } + svc_xprt_put(&xprt->sc_xprt); spin_lock_irqsave(&dto_lock, flags); } spin_unlock_irqrestore(&dto_lock, flags); @@ -275,8 +275,10 @@ static void rq_comp_handler(struct ib_cq *cq, void *cq_context) * add it */ spin_lock_irqsave(&dto_lock, flags); - if (list_empty(&xprt->sc_dto_q)) + if (list_empty(&xprt->sc_dto_q)) { + svc_xprt_get(&xprt->sc_xprt); list_add_tail(&xprt->sc_dto_q, &dto_xprt_q); + } spin_unlock_irqrestore(&dto_lock, flags); /* Tasklet does all the work to avoid irqsave locks. */ @@ -386,8 +388,10 @@ static void sq_comp_handler(struct ib_cq *cq, void *cq_context) * add it */ spin_lock_irqsave(&dto_lock, flags); - if (list_empty(&xprt->sc_dto_q)) + if (list_empty(&xprt->sc_dto_q)) { + svc_xprt_get(&xprt->sc_xprt); list_add_tail(&xprt->sc_dto_q, &dto_xprt_q); + } spin_unlock_irqrestore(&dto_lock, flags); /* Tasklet does all the work to avoid irqsave locks. */ @@ -611,6 +615,7 @@ static int rdma_cma_handler(struct rdma_cm_id *cma_id, switch (event->event) { case RDMA_CM_EVENT_ESTABLISHED: /* Accept complete */ + svc_xprt_get(xprt); dprintk("svcrdma: Connection completed on DTO xprt=%p, " "cm_id=%p\n", xprt, cma_id); clear_bit(RDMAXPRT_CONN_PENDING, &rdma->sc_flags); @@ -661,15 +666,15 @@ static struct svc_xprt *svc_rdma_create(struct svc_serv *serv, listen_id = rdma_create_id(rdma_listen_handler, cma_xprt, RDMA_PS_TCP); if (IS_ERR(listen_id)) { - rdma_destroy_xprt(cma_xprt); + svc_xprt_put(&cma_xprt->sc_xprt); dprintk("svcrdma: rdma_create_id failed = %ld\n", PTR_ERR(listen_id)); return (void *)listen_id; } ret = rdma_bind_addr(listen_id, sa); if (ret) { - rdma_destroy_xprt(cma_xprt); rdma_destroy_id(listen_id); + svc_xprt_put(&cma_xprt->sc_xprt); dprintk("svcrdma: rdma_bind_addr failed = %d\n", ret); return ERR_PTR(ret); } @@ -678,8 +683,9 @@ static struct svc_xprt *svc_rdma_create(struct svc_serv *serv, ret = rdma_listen(listen_id, RPCRDMA_LISTEN_BACKLOG); if (ret) { rdma_destroy_id(listen_id); - rdma_destroy_xprt(cma_xprt); + svc_xprt_put(&cma_xprt->sc_xprt); dprintk("svcrdma: rdma_listen failed = %d\n", ret); + return ERR_PTR(ret); } /* @@ -820,6 +826,7 @@ static struct svc_xprt *svc_rdma_accept(struct svc_xprt *xprt) newxprt->sc_sq_depth = qp_attr.cap.max_send_wr; newxprt->sc_max_requests = qp_attr.cap.max_recv_wr; } + svc_xprt_get(&newxprt->sc_xprt); newxprt->sc_qp = newxprt->sc_cm_id->qp; /* Register all of physical memory */ @@ -891,8 +898,15 @@ static struct svc_xprt *svc_rdma_accept(struct svc_xprt *xprt) errout: dprintk("svcrdma: failure accepting new connection rc=%d.\n", ret); + /* Take a reference in case the DTO handler runs */ + svc_xprt_get(&newxprt->sc_xprt); + if (newxprt->sc_qp && !IS_ERR(newxprt->sc_qp)) { + ib_destroy_qp(newxprt->sc_qp); + svc_xprt_put(&newxprt->sc_xprt); + } rdma_destroy_id(newxprt->sc_cm_id); - rdma_destroy_xprt(newxprt); + /* This call to put will destroy the transport */ + svc_xprt_put(&newxprt->sc_xprt); return NULL; } @@ -919,54 +933,60 @@ static void svc_rdma_release_rqst(struct svc_rqst *rqstp) rqstp->rq_xprt_ctxt = NULL; } -/* Disable data ready events for this connection */ +/* + * When connected, an svc_xprt has at least three references: + * + * - A reference held by the QP. We still hold that here because this + * code deletes the QP and puts the reference. + * + * - A reference held by the cm_id between the ESTABLISHED and + * DISCONNECTED events. If the remote peer disconnected first, this + * reference could be gone. + * + * - A reference held by the svc_recv code that called this function + * as part of close processing. + * + * At a minimum two references should still be held. + */ static void svc_rdma_detach(struct svc_xprt *xprt) { struct svcxprt_rdma *rdma = container_of(xprt, struct svcxprt_rdma, sc_xprt); - unsigned long flags; - dprintk("svc: svc_rdma_detach(%p)\n", xprt); - /* - * Shutdown the connection. This will ensure we don't get any - * more events from the provider. - */ + + /* Disconnect and flush posted WQE */ rdma_disconnect(rdma->sc_cm_id); - rdma_destroy_id(rdma->sc_cm_id); - /* We may already be on the DTO list */ - spin_lock_irqsave(&dto_lock, flags); - if (!list_empty(&rdma->sc_dto_q)) - list_del_init(&rdma->sc_dto_q); - spin_unlock_irqrestore(&dto_lock, flags); + /* Destroy the QP if present (not a listener) */ + if (rdma->sc_qp && !IS_ERR(rdma->sc_qp)) { + ib_destroy_qp(rdma->sc_qp); + svc_xprt_put(xprt); + } + + /* Destroy the CM ID */ + rdma_destroy_id(rdma->sc_cm_id); } static void svc_rdma_free(struct svc_xprt *xprt) { struct svcxprt_rdma *rdma = (struct svcxprt_rdma *)xprt; dprintk("svcrdma: svc_rdma_free(%p)\n", rdma); - rdma_destroy_xprt(rdma); - kfree(rdma); -} - -static void rdma_destroy_xprt(struct svcxprt_rdma *xprt) -{ - if (xprt->sc_qp && !IS_ERR(xprt->sc_qp)) - ib_destroy_qp(xprt->sc_qp); - - if (xprt->sc_sq_cq && !IS_ERR(xprt->sc_sq_cq)) - ib_destroy_cq(xprt->sc_sq_cq); + /* We should only be called from kref_put */ + BUG_ON(atomic_read(&xprt->xpt_ref.refcount) != 0); + if (rdma->sc_sq_cq && !IS_ERR(rdma->sc_sq_cq)) + ib_destroy_cq(rdma->sc_sq_cq); - if (xprt->sc_rq_cq && !IS_ERR(xprt->sc_rq_cq)) - ib_destroy_cq(xprt->sc_rq_cq); + if (rdma->sc_rq_cq && !IS_ERR(rdma->sc_rq_cq)) + ib_destroy_cq(rdma->sc_rq_cq); - if (xprt->sc_phys_mr && !IS_ERR(xprt->sc_phys_mr)) - ib_dereg_mr(xprt->sc_phys_mr); + if (rdma->sc_phys_mr && !IS_ERR(rdma->sc_phys_mr)) + ib_dereg_mr(rdma->sc_phys_mr); - if (xprt->sc_pd && !IS_ERR(xprt->sc_pd)) - ib_dealloc_pd(xprt->sc_pd); + if (rdma->sc_pd && !IS_ERR(rdma->sc_pd)) + ib_dealloc_pd(rdma->sc_pd); - destroy_context_cache(xprt->sc_ctxt_head); + destroy_context_cache(rdma->sc_ctxt_head); + kfree(rdma); } static int svc_rdma_has_wspace(struct svc_xprt *xprt) diff --git a/net/sunrpc/xprtrdma/transport.c b/net/sunrpc/xprtrdma/transport.c index 02c522c17de599f5ea4d776038ff1e0e5d268642..a564c1a39ec5f833b3a5dd9f369269615a047940 100644 --- a/net/sunrpc/xprtrdma/transport.c +++ b/net/sunrpc/xprtrdma/transport.c @@ -614,7 +614,11 @@ xprt_rdma_free(void *buffer) return; req = container_of(buffer, struct rpcrdma_req, rl_xdr_buf[0]); - r_xprt = container_of(req->rl_buffer, struct rpcrdma_xprt, rx_buf); + if (req->rl_iov.length == 0) { /* see allocate above */ + r_xprt = container_of(((struct rpcrdma_req *) req->rl_buffer)->rl_buffer, + struct rpcrdma_xprt, rx_buf); + } else + r_xprt = container_of(req->rl_buffer, struct rpcrdma_xprt, rx_buf); rep = req->rl_reply; dprintk("RPC: %s: called on 0x%p%s\n", diff --git a/samples/Kconfig b/samples/Kconfig index 74d97cc247872216fc179bf5fdce5b0b9c2cd671..e1fb471cc50182e5e907bef3caa566f8ede7e6d4 100644 --- a/samples/Kconfig +++ b/samples/Kconfig @@ -22,5 +22,16 @@ config SAMPLE_KOBJECT If in doubt, say "N" here. +config SAMPLE_KPROBES + tristate "Build kprobes examples -- loadable modules only" + depends on KPROBES && m + help + This build several kprobes example modules. + +config SAMPLE_KRETPROBES + tristate "Build kretprobes example -- loadable modules only" + default m + depends on SAMPLE_KPROBES && KRETPROBES + endif # SAMPLES diff --git a/samples/Makefile b/samples/Makefile index 8652d0f268ad0fb25e24c65375828ec932df2e96..2e02575f779441bf1babe686f50f0b7fb1d3e03e 100644 --- a/samples/Makefile +++ b/samples/Makefile @@ -1,3 +1,3 @@ # Makefile for Linux samples code -obj-$(CONFIG_SAMPLES) += markers/ kobject/ +obj-$(CONFIG_SAMPLES) += markers/ kobject/ kprobes/ diff --git a/samples/kprobes/Makefile b/samples/kprobes/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..68739bc4fc6a64f61df13004b0ed2d7963255279 --- /dev/null +++ b/samples/kprobes/Makefile @@ -0,0 +1,5 @@ +# builds the kprobes example kernel modules; +# then to use one (as root): insmod + +obj-$(CONFIG_SAMPLE_KPROBES) += kprobe_example.o jprobe_example.o +obj-$(CONFIG_SAMPLE_KRETPROBES) += kretprobe_example.o diff --git a/samples/kprobes/jprobe_example.c b/samples/kprobes/jprobe_example.c new file mode 100644 index 0000000000000000000000000000000000000000..b7541355b92bd547c27faa21ac6a01a2b96cbc85 --- /dev/null +++ b/samples/kprobes/jprobe_example.c @@ -0,0 +1,68 @@ +/* + * Here's a sample kernel module showing the use of jprobes to dump + * the arguments of do_fork(). + * + * For more information on theory of operation of jprobes, see + * Documentation/kprobes.txt + * + * Build and insert the kernel module as done in the kprobe example. + * You will see the trace data in /var/log/messages and on the + * console whenever do_fork() is invoked to create a new process. + * (Some messages may be suppressed if syslogd is configured to + * eliminate duplicate messages.) + */ + +#include +#include +#include + +/* + * Jumper probe for do_fork. + * Mirror principle enables access to arguments of the probed routine + * from the probe handler. + */ + +/* Proxy routine having the same arguments as actual do_fork() routine */ +static long jdo_fork(unsigned long clone_flags, unsigned long stack_start, + struct pt_regs *regs, unsigned long stack_size, + int __user *parent_tidptr, int __user *child_tidptr) +{ + printk(KERN_INFO "jprobe: clone_flags = 0x%lx, stack_size = 0x%lx," + " regs = 0x%p\n", + clone_flags, stack_size, regs); + + /* Always end with a call to jprobe_return(). */ + jprobe_return(); + return 0; +} + +static struct jprobe my_jprobe = { + .entry = jdo_fork, + .kp = { + .symbol_name = "do_fork", + }, +}; + +static int __init jprobe_init(void) +{ + int ret; + + ret = register_jprobe(&my_jprobe); + if (ret < 0) { + printk(KERN_INFO "register_jprobe failed, returned %d\n", ret); + return -1; + } + printk(KERN_INFO "Planted jprobe at %p, handler addr %p\n", + my_jprobe.kp.addr, my_jprobe.entry); + return 0; +} + +static void __exit jprobe_exit(void) +{ + unregister_jprobe(&my_jprobe); + printk(KERN_INFO "jprobe at %p unregistered\n", my_jprobe.kp.addr); +} + +module_init(jprobe_init) +module_exit(jprobe_exit) +MODULE_LICENSE("GPL"); diff --git a/samples/kprobes/kprobe_example.c b/samples/kprobes/kprobe_example.c new file mode 100644 index 0000000000000000000000000000000000000000..a681998a871cae548eb05f741ed6533daa17d238 --- /dev/null +++ b/samples/kprobes/kprobe_example.c @@ -0,0 +1,91 @@ +/* + * NOTE: This example is works on x86 and powerpc. + * Here's a sample kernel module showing the use of kprobes to dump a + * stack trace and selected registers when do_fork() is called. + * + * For more information on theory of operation of kprobes, see + * Documentation/kprobes.txt + * + * You will see the trace data in /var/log/messages and on the console + * whenever do_fork() is invoked to create a new process. + */ + +#include +#include +#include + +/* For each probe you need to allocate a kprobe structure */ +static struct kprobe kp = { + .symbol_name = "do_fork", +}; + +/* kprobe pre_handler: called just before the probed instruction is executed */ +static int handler_pre(struct kprobe *p, struct pt_regs *regs) +{ +#ifdef CONFIG_X86 + printk(KERN_INFO "pre_handler: p->addr = 0x%p, ip = %lx," + " flags = 0x%lx\n", + p->addr, regs->ip, regs->flags); +#endif +#ifdef CONFIG_PPC + printk(KERN_INFO "pre_handler: p->addr = 0x%p, nip = 0x%lx," + " msr = 0x%lx\n", + p->addr, regs->nip, regs->msr); +#endif + + /* A dump_stack() here will give a stack backtrace */ + return 0; +} + +/* kprobe post_handler: called after the probed instruction is executed */ +static void handler_post(struct kprobe *p, struct pt_regs *regs, + unsigned long flags) +{ +#ifdef CONFIG_X86 + printk(KERN_INFO "post_handler: p->addr = 0x%p, flags = 0x%lx\n", + p->addr, regs->flags); +#endif +#ifdef CONFIG_PPC + printk(KERN_INFO "post_handler: p->addr = 0x%p, msr = 0x%lx\n", + p->addr, regs->msr); +#endif +} + +/* + * fault_handler: this is called if an exception is generated for any + * instruction within the pre- or post-handler, or when Kprobes + * single-steps the probed instruction. + */ +static int handler_fault(struct kprobe *p, struct pt_regs *regs, int trapnr) +{ + printk(KERN_INFO "fault_handler: p->addr = 0x%p, trap #%dn", + p->addr, trapnr); + /* Return 0 because we don't handle the fault. */ + return 0; +} + +static int __init kprobe_init(void) +{ + int ret; + kp.pre_handler = handler_pre; + kp.post_handler = handler_post; + kp.fault_handler = handler_fault; + + ret = register_kprobe(&kp); + if (ret < 0) { + printk(KERN_INFO "register_kprobe failed, returned %d\n", ret); + return ret; + } + printk(KERN_INFO "Planted kprobe at %p\n", kp.addr); + return 0; +} + +static void __exit kprobe_exit(void) +{ + unregister_kprobe(&kp); + printk(KERN_INFO "kprobe at %p unregistered\n", kp.addr); +} + +module_init(kprobe_init) +module_exit(kprobe_exit) +MODULE_LICENSE("GPL"); diff --git a/samples/kprobes/kretprobe_example.c b/samples/kprobes/kretprobe_example.c new file mode 100644 index 0000000000000000000000000000000000000000..4e764b317d6124c803439f02754e2339a538db12 --- /dev/null +++ b/samples/kprobes/kretprobe_example.c @@ -0,0 +1,106 @@ +/* + * kretprobe_example.c + * + * Here's a sample kernel module showing the use of return probes to + * report the return value and total time taken for probed function + * to run. + * + * usage: insmod kretprobe_example.ko func= + * + * If no func_name is specified, do_fork is instrumented + * + * For more information on theory of operation of kretprobes, see + * Documentation/kprobes.txt + * + * Build and insert the kernel module as done in the kprobe example. + * You will see the trace data in /var/log/messages and on the console + * whenever the probed function returns. (Some messages may be suppressed + * if syslogd is configured to eliminate duplicate messages.) + */ + +#include +#include +#include +#include +#include + +static char func_name[NAME_MAX] = "do_fork"; +module_param_string(func, func_name, NAME_MAX, S_IRUGO); +MODULE_PARM_DESC(func, "Function to kretprobe; this module will report the" + " function's execution time"); + +/* per-instance private data */ +struct my_data { + ktime_t entry_stamp; +}; + +/* Here we use the entry_hanlder to timestamp function entry */ +static int entry_handler(struct kretprobe_instance *ri, struct pt_regs *regs) +{ + struct my_data *data; + + if (!current->mm) + return 1; /* Skip kernel threads */ + + data = (struct my_data *)ri->data; + data->entry_stamp = ktime_get(); + return 0; +} + +/* + * Return-probe handler: Log the return value and duration. Duration may turn + * out to be zero consistently, depending upon the granularity of time + * accounting on the platform. + */ +static int ret_handler(struct kretprobe_instance *ri, struct pt_regs *regs) +{ + int retval = regs_return_value(regs); + struct my_data *data = (struct my_data *)ri->data; + s64 delta; + ktime_t now; + + now = ktime_get(); + delta = ktime_to_ns(ktime_sub(now, data->entry_stamp)); + printk(KERN_INFO "%s returned %d and took %lld ns to execute\n", + func_name, retval, (long long)delta); + return 0; +} + +static struct kretprobe my_kretprobe = { + .handler = ret_handler, + .entry_handler = entry_handler, + .data_size = sizeof(struct my_data), + /* Probe up to 20 instances concurrently. */ + .maxactive = 20, +}; + +static int __init kretprobe_init(void) +{ + int ret; + + my_kretprobe.kp.symbol_name = func_name; + ret = register_kretprobe(&my_kretprobe); + if (ret < 0) { + printk(KERN_INFO "register_kretprobe failed, returned %d\n", + ret); + return -1; + } + printk(KERN_INFO "Planted return probe at %s: %p\n", + my_kretprobe.kp.symbol_name, my_kretprobe.kp.addr); + return 0; +} + +static void __exit kretprobe_exit(void) +{ + unregister_kretprobe(&my_kretprobe); + printk(KERN_INFO "kretprobe at %p unregistered\n", + my_kretprobe.kp.addr); + + /* nmissed > 0 suggests that maxactive was set too low. */ + printk(KERN_INFO "Missed probing %d instances of %s\n", + my_kretprobe.nmissed, my_kretprobe.kp.symbol_name); +} + +module_init(kretprobe_init) +module_exit(kretprobe_exit) +MODULE_LICENSE("GPL"); diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index 2086a856400a9c7258958b96fe0f3d53d3d70ff8..2a7cef9726e4892b3454e7198dca4c529aeed891 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -9,7 +9,7 @@ use strict; my $P = $0; $P =~ s@.*/@@g; -my $V = '0.14'; +my $V = '0.15'; use Getopt::Long qw(:config no_auto_abbrev); @@ -105,8 +105,7 @@ our $Sparse = qr{ __iomem| __must_check| __init_refok| - __kprobes| - fastcall + __kprobes }x; our $Attribute = qr{ const| @@ -158,7 +157,10 @@ sub build_types { \b (?:const\s+)? (?:unsigned\s+)? - $all + (?: + $all| + (?:typeof|__typeof__)\s*\(\s*\**\s*$Ident\s*\) + ) (?:\s+$Sparse|\s+const)* \b }x; @@ -362,6 +364,7 @@ sub ctx_statement_block { my $type = ''; my $level = 0; + my $p; my $c; my $len = 0; @@ -386,6 +389,7 @@ sub ctx_statement_block { last; } } + $p = $c; $c = substr($blk, $off, 1); $remainder = substr($blk, $off); @@ -397,8 +401,9 @@ sub ctx_statement_block { } # An else is really a conditional as long as its not else if - if ($level == 0 && $remainder =~ /(\s+else)(?:\s|{)/ && - $remainder !~ /\s+else\s+if\b/) { + if ($level == 0 && (!defined($p) || $p =~ /(?:\s|\})/) && + $remainder =~ /(else)(?:\s|{)/ && + $remainder !~ /else\s+if\b/) { $coff = $off + length($1); } @@ -445,21 +450,73 @@ sub ctx_statement_block { $line, $remain + 1, $off - $loff + 1, $level); } +sub statement_lines { + my ($stmt) = @_; + + # Strip the diff line prefixes and rip blank lines at start and end. + $stmt =~ s/(^|\n)./$1/g; + $stmt =~ s/^\s*//; + $stmt =~ s/\s*$//; + + my @stmt_lines = ($stmt =~ /\n/g); + + return $#stmt_lines + 2; +} + +sub statement_rawlines { + my ($stmt) = @_; + + my @stmt_lines = ($stmt =~ /\n/g); + + return $#stmt_lines + 2; +} + +sub statement_block_size { + my ($stmt) = @_; + + $stmt =~ s/(^|\n)./$1/g; + $stmt =~ s/^\s*{//; + $stmt =~ s/}\s*$//; + $stmt =~ s/^\s*//; + $stmt =~ s/\s*$//; + + my @stmt_lines = ($stmt =~ /\n/g); + my @stmt_statements = ($stmt =~ /;/g); + + my $stmt_lines = $#stmt_lines + 2; + my $stmt_statements = $#stmt_statements + 1; + + if ($stmt_lines > $stmt_statements) { + return $stmt_lines; + } else { + return $stmt_statements; + } +} + sub ctx_statement_full { my ($linenr, $remain, $off) = @_; my ($statement, $condition, $level); my (@chunks); + # Grab the first conditional/block pair. ($statement, $condition, $linenr, $remain, $off, $level) = ctx_statement_block($linenr, $remain, $off); #print "F: c<$condition> s<$statement>\n"; + push(@chunks, [ $condition, $statement ]); + if (!($remain > 0 && $condition =~ /^\s*(?:\n[+-])?\s*(?:if|else|do)\b/s)) { + return ($level, $linenr, @chunks); + } + + # Pull in the following conditional/block pairs and see if they + # could continue the statement. for (;;) { - push(@chunks, [ $condition, $statement ]); - last if (!($remain > 0 && $condition =~ /^.\s*(?:if|else|do)/)); ($statement, $condition, $linenr, $remain, $off, $level) = ctx_statement_block($linenr, $remain, $off); - #print "C: c<$condition> s<$statement>\n"; + #print "C: c<$condition> s<$statement> remain<$remain>\n"; + last if (!($remain > 0 && $condition =~ /^\s*(?:\n[+-])?\s*(?:else|do)\b/s)); + #print "C: push\n"; + push(@chunks, [ $condition, $statement ]); } return ($level, $linenr, @chunks); @@ -593,13 +650,13 @@ sub cat_vet { } my $av_preprocessor = 0; -my $av_paren = 0; +my $av_pending; my @av_paren_type; sub annotate_reset { $av_preprocessor = 0; - $av_paren = 0; - @av_paren_type = (); + $av_pending = '_'; + @av_paren_type = ('E'); } sub annotate_values { @@ -611,12 +668,13 @@ sub annotate_values { print "$stream\n" if ($dbg_values > 1); while (length($cur)) { - print " <$type> " if ($dbg_values > 1); + print " <" . join('', @av_paren_type) . + "> <$type> " if ($dbg_values > 1); if ($cur =~ /^(\s+)/o) { print "WS($1)\n" if ($dbg_values > 1); if ($1 =~ /\n/ && $av_preprocessor) { + $type = pop(@av_paren_type); $av_preprocessor = 0; - $type = 'N'; } } elsif ($cur =~ /^($Type)/) { @@ -626,11 +684,33 @@ sub annotate_values { } elsif ($cur =~ /^(#\s*define\s*$Ident)(\(?)/o) { print "DEFINE($1)\n" if ($dbg_values > 1); $av_preprocessor = 1; - $av_paren_type[$av_paren] = 'N'; + $av_pending = 'N'; - } elsif ($cur =~ /^(#\s*(?:ifdef|ifndef|if|else|elif|endif))/o) { - print "PRE($1)\n" if ($dbg_values > 1); + } elsif ($cur =~ /^(#\s*(?:ifdef|ifndef|if))/o) { + print "PRE_START($1)\n" if ($dbg_values > 1); $av_preprocessor = 1; + + push(@av_paren_type, $type); + push(@av_paren_type, $type); + $type = 'N'; + + } elsif ($cur =~ /^(#\s*(?:else|elif))/o) { + print "PRE_RESTART($1)\n" if ($dbg_values > 1); + $av_preprocessor = 1; + + push(@av_paren_type, $av_paren_type[$#av_paren_type]); + + $type = 'N'; + + } elsif ($cur =~ /^(#\s*(?:endif))/o) { + print "PRE_END($1)\n" if ($dbg_values > 1); + + $av_preprocessor = 1; + + # Assume all arms of the conditional end as this + # one does, and continue as if the #endif was not here. + pop(@av_paren_type); + push(@av_paren_type, $type); $type = 'N'; } elsif ($cur =~ /^(\\\n)/o) { @@ -639,13 +719,13 @@ sub annotate_values { } elsif ($cur =~ /^(sizeof)\s*(\()?/o) { print "SIZEOF($1)\n" if ($dbg_values > 1); if (defined $2) { - $av_paren_type[$av_paren] = 'V'; + $av_pending = 'V'; } $type = 'N'; } elsif ($cur =~ /^(if|while|typeof|__typeof__|for)\b/o) { print "COND($1)\n" if ($dbg_values > 1); - $av_paren_type[$av_paren] = 'N'; + $av_pending = 'N'; $type = 'N'; } elsif ($cur =~/^(return|case|else)/o) { @@ -654,14 +734,14 @@ sub annotate_values { } elsif ($cur =~ /^(\()/o) { print "PAREN('$1')\n" if ($dbg_values > 1); - $av_paren++; + push(@av_paren_type, $av_pending); + $av_pending = '_'; $type = 'N'; } elsif ($cur =~ /^(\))/o) { - $av_paren-- if ($av_paren > 0); - if (defined $av_paren_type[$av_paren]) { - $type = $av_paren_type[$av_paren]; - undef $av_paren_type[$av_paren]; + my $new_type = pop(@av_paren_type); + if ($new_type ne '_') { + $type = $new_type; print "PAREN('$1') -> $type\n" if ($dbg_values > 1); } else { @@ -670,7 +750,7 @@ sub annotate_values { } elsif ($cur =~ /^($Ident)\(/o) { print "FUNC($1)\n" if ($dbg_values > 1); - $av_paren_type[$av_paren] = 'V'; + $av_pending = 'V'; } elsif ($cur =~ /^($Ident|$Constant)/o) { print "IDENT($1)\n" if ($dbg_values > 1); @@ -680,11 +760,11 @@ sub annotate_values { print "ASSIGN($1)\n" if ($dbg_values > 1); $type = 'N'; - } elsif ($cur =~/^(;)/) { + } elsif ($cur =~/^(;|{|})/) { print "END($1)\n" if ($dbg_values > 1); $type = 'E'; - } elsif ($cur =~ /^(;|{|}|\?|:|\[)/o) { + } elsif ($cur =~ /^(;|\?|:|\[)/o) { print "CLOSE($1)\n" if ($dbg_values > 1); $type = 'N'; @@ -988,7 +1068,7 @@ sub process { } # check for RCS/CVS revision markers - if ($rawline =~ /\$(Revision|Log|Id)(?:\$|)/) { + if ($rawline =~ /^\+.*\$(Revision|Log|Id)(?:\$|)/) { WARN("CVS style keyword markers, these will _not_ be updated\n". $herecurr); } @@ -999,41 +1079,44 @@ sub process { # Check for potential 'bare' types if ($realcnt) { + my ($s, $c) = ctx_statement_block($linenr, $realcnt, 0); + $s =~ s/\n./ /g; + $s =~ s/{.*$//; + # Ignore goto labels. - if ($line =~ /$Ident:\*$/) { + if ($s =~ /$Ident:\*$/) { # Ignore functions being called - } elsif ($line =~ /^.\s*$Ident\s*\(/) { + } elsif ($s =~ /^.\s*$Ident\s*\(/) { # definitions in global scope can only start with types - } elsif ($line =~ /^.(?:$Storage\s+)?(?:$Inline\s+)?(?:const\s+)?($Ident)\b/) { - possible($1, $line); + } elsif ($s =~ /^.(?:$Storage\s+)?(?:$Inline\s+)?(?:const\s+)?($Ident)\b/) { + possible($1, $s); # declarations always start with types - } elsif ($prev_values eq 'E' && $line =~ /^.\s*(?:$Storage\s+)?(?:const\s+)?($Ident)\b(:?\s+$Sparse)?\s*\**\s*$Ident\s*(?:;|=|,)/) { - possible($1); + } elsif ($prev_values eq 'E' && $s =~ /^.\s*(?:$Storage\s+)?(?:const\s+)?($Ident)\b(:?\s+$Sparse)?\s*\**\s*$Ident\s*(?:;|=|,)/) { + possible($1, $s); } # any (foo ... *) is a pointer cast, and foo is a type - while ($line =~ /\(($Ident)(?:\s+$Sparse)*\s*\*+\s*\)/g) { - possible($1, $line); + while ($s =~ /\(($Ident)(?:\s+$Sparse)*\s*\*+\s*\)/g) { + possible($1, $s); } # Check for any sort of function declaration. # int foo(something bar, other baz); # void (*store_gdt)(x86_descr_ptr *); - if ($prev_values eq 'E' && $line =~ /^(.(?:typedef\s*)?(?:(?:$Storage|$Inline)\s*)*\s*$Type\s*(?:\b$Ident|\(\*\s*$Ident\))\s*)\(/) { + if ($prev_values eq 'E' && $s =~ /^(.(?:typedef\s*)?(?:(?:$Storage|$Inline)\s*)*\s*$Type\s*(?:\b$Ident|\(\*\s*$Ident\))\s*)\(/) { my ($name_len) = length($1); - my ($level, @ctx) = ctx_statement_level($linenr, $realcnt, $name_len); - my $ctx = join("\n", @ctx); - $ctx =~ s/\n.//; + my $ctx = $s; substr($ctx, 0, $name_len + 1) = ''; $ctx =~ s/\)[^\)]*$//; + for my $arg (split(/\s*,\s*/, $ctx)) { if ($arg =~ /^(?:const\s+)?($Ident)(?:\s+$Sparse)*\s*\**\s*(:?\b$Ident)?$/ || $arg =~ /^($Ident)$/) { - possible($1, $line); + possible($1, $s); } } } @@ -1100,8 +1183,8 @@ sub process { $curr_values = $prev_values . $curr_values; if ($dbg_values) { my $outline = $opline; $outline =~ s/\t/ /g; - warn "--> .$outline\n"; - warn "--> $curr_values\n"; + print "$linenr > .$outline\n"; + print "$linenr > $curr_values\n"; } $prev_values = substr($curr_values, -1); @@ -1148,7 +1231,9 @@ sub process { if (($prevline !~ /^}/) && ($prevline !~ /^\+}/) && ($prevline !~ /^ }/) && - ($prevline !~ /\b\Q$name\E(?:\s+$Attribute)?\s*(?:;|=)/)) { + ($prevline !~ /^.DECLARE_$Ident\(\Q$name\E\)/) && + ($prevline !~ /^.LIST_HEAD\(\Q$name\E\)/) && + ($prevline !~ /\b\Q$name\E(?:\s+$Attribute)?\s*(?:;|=|\[)/)) { WARN("EXPORT_SYMBOL(foo); should immediately follow its function/variable\n" . $herecurr); } } @@ -1266,7 +1351,7 @@ sub process { =>|->|<<|>>|<|>|=|!|~| &&|\|\||,|\^|\+\+|--|&|\||\+|-|\*|\/|% }x; - my @elements = split(/($;+|$ops|;)/, $opline); + my @elements = split(/($ops|;)/, $opline); my $off = 0; my $blank = copy_spacing($opline); @@ -1277,6 +1362,7 @@ sub process { my $a = ''; $a = 'V' if ($elements[$n] ne ''); $a = 'W' if ($elements[$n] =~ /\s$/); + $a = 'C' if ($elements[$n] =~ /$;$/); $a = 'B' if ($elements[$n] =~ /(\[|\()$/); $a = 'O' if ($elements[$n] eq ''); $a = 'E' if ($elements[$n] eq '' && $n == 0); @@ -1287,6 +1373,7 @@ sub process { if (defined $elements[$n + 2]) { $c = 'V' if ($elements[$n + 2] ne ''); $c = 'W' if ($elements[$n + 2] =~ /^\s/); + $c = 'C' if ($elements[$n + 2] =~ /^$;/); $c = 'B' if ($elements[$n + 2] =~ /^(\)|\]|;)/); $c = 'O' if ($elements[$n + 2] eq ''); $c = 'E' if ($elements[$n + 2] =~ /\s*\\$/); @@ -1330,13 +1417,13 @@ sub process { if ($op_type ne 'V' && $ca =~ /\s$/ && $cc =~ /^\s*,/) { - # Ignore comments - } elsif ($op =~ /^$;+$/) { +# # Ignore comments +# } elsif ($op =~ /^$;+$/) { # ; should have either the end of line or a space or \ after it } elsif ($op eq ';') { - if ($ctx !~ /.x[WEB]/ && $cc !~ /^\\/ && - $cc !~ /^;/) { + if ($ctx !~ /.x[WEBC]/ && + $cc !~ /^\\/ && $cc !~ /^;/) { ERROR("need space after that '$op' $at\n" . $hereptr); } @@ -1351,7 +1438,7 @@ sub process { # , must have a space on the right. } elsif ($op eq ',') { - if ($ctx !~ /.xW|.xE/ && $cc !~ /^}/) { + if ($ctx !~ /.x[WEC]/ && $cc !~ /^}/) { ERROR("need space after that '$op' $at\n" . $hereptr); } @@ -1364,7 +1451,7 @@ sub process { # unary operator, or a cast } elsif ($op eq '!' || $op eq '~' || ($is_unary && ($op eq '*' || $op eq '-' || $op eq '&'))) { - if ($ctx !~ /[WEB]x./ && $ca !~ /(?:\)|!|~|\*|-|\&|\||\+\+|\-\-|\{)$/) { + if ($ctx !~ /[WEBC]x./ && $ca !~ /(?:\)|!|~|\*|-|\&|\||\+\+|\-\-|\{)$/) { ERROR("need space before that '$op' $at\n" . $hereptr); } if ($ctx =~ /.xW/) { @@ -1373,7 +1460,7 @@ sub process { # unary ++ and unary -- are allowed no space on one side. } elsif ($op eq '++' or $op eq '--') { - if ($ctx !~ /[WOB]x[^W]/ && $ctx !~ /[^W]x[WOBE]/) { + if ($ctx !~ /[WOBC]x[^W]/ && $ctx !~ /[^W]x[WOBEC]/) { ERROR("need space one side of that '$op' $at\n" . $hereptr); } if ($ctx =~ /WxB/ || ($ctx =~ /Wx./ && $cc =~ /^;/)) { @@ -1387,13 +1474,13 @@ sub process { $op eq '*' or $op eq '/' or $op eq '%') { - if ($ctx !~ /VxV|WxW|VxE|WxE|VxO/) { + if ($ctx !~ /VxV|WxW|VxE|WxE|VxO|Cx.|.xC/) { ERROR("need consistent spacing around '$op' $at\n" . $hereptr); } # All the others need spaces both sides. - } elsif ($ctx !~ /[EW]x[WE]/) { + } elsif ($ctx !~ /[EWC]x[CWE]/) { # Ignore email addresses if (!($op eq '<' && $cb =~ /$;\S+\@\S+>/) && !($op eq '>' && $cb =~ /<\S+\@\S+$;/)) { @@ -1551,7 +1638,7 @@ sub process { # multi-statement macros should be enclosed in a do while loop, grab the # first statement and ensure its the whole macro if its not enclosed -# in a known goot container +# in a known good container if ($prevline =~ /\#define.*\\/ && $prevline !~/(?:do\s+{|\(\{|\{)/ && $line !~ /(?:do\s+{|\(\{|\{)/ && @@ -1599,84 +1686,95 @@ sub process { # check for redundant bracing round if etc if ($line =~ /(^.*)\bif\b/ && $1 !~ /else\s*$/) { my ($level, $endln, @chunks) = - ctx_statement_full($linenr, $realcnt, 0); + ctx_statement_full($linenr, $realcnt, 1); #print "chunks<$#chunks> linenr<$linenr> endln<$endln> level<$level>\n"; - if ($#chunks > 1 && $level == 0) { + #print "APW: <<$chunks[1][0]>><<$chunks[1][1]>>\n"; + if ($#chunks > 0 && $level == 0) { my $allowed = 0; my $seen = 0; + my $herectx = $here . "\n";; + my $ln = $linenr - 1; for my $chunk (@chunks) { my ($cond, $block) = @{$chunk}; + $herectx .= "$rawlines[$ln]\n[...]\n"; + $ln += statement_rawlines($block) - 1; + substr($block, 0, length($cond)) = ''; $seen++ if ($block =~ /^\s*{/); - $block =~ s/(^|\n)./$1/g; - $block =~ s/^\s*{//; - $block =~ s/}\s*$//; - $block =~ s/^\s*//; - $block =~ s/\s*$//; - - my @lines = ($block =~ /\n/g); - my @statements = ($block =~ /;/g); - - #print "cond<$cond> block<$block> lines<" . scalar(@lines) . "> statements<" . scalar(@statements) . "> seen<$seen> allowed<$allowed>\n"; - if (scalar(@lines) != 0) { + #print "cond<$cond> block<$block> allowed<$allowed>\n"; + if (statement_lines($cond) > 1) { + #print "APW: ALLOWED: cond<$cond>\n"; $allowed = 1; } if ($block =~/\b(?:if|for|while)\b/) { + #print "APW: ALLOWED: block<$block>\n"; $allowed = 1; } - if (scalar(@statements) > 1) { + if (statement_block_size($block) > 1) { + #print "APW: ALLOWED: lines block<$block>\n"; $allowed = 1; } } if ($seen && !$allowed) { - WARN("braces {} are not necessary for any arm of this statement\n" . $herecurr); - $suppress_ifbraces = $endln; + WARN("braces {} are not necessary for any arm of this statement\n" . $herectx); } + # Either way we have looked over this whole + # statement and said what needs to be said. + $suppress_ifbraces = $endln; } } if ($linenr > $suppress_ifbraces && $line =~ /\b(if|while|for|else)\b/) { - # Locate the end of the opening statement. - my @control = ctx_statement($linenr, $realcnt, 0); - my $nr = $linenr + (scalar(@control) - 1); - my $cnt = $realcnt - (scalar(@control) - 1); - - my $off = $realcnt - $cnt; - #print "$off: line<$line>end<" . $lines[$nr - 1] . ">\n"; - - # If this is is a braced statement group check it - if ($lines[$nr - 1] =~ /{\s*$/) { - my ($lvl, @block) = ctx_block_level($nr, $cnt); - - my $stmt = join("\n", @block); - # Drop the diff line leader. - $stmt =~ s/\n./\n/g; - # Drop the code outside the block. - $stmt =~ s/(^[^{]*){\s*//; - my $before = $1; - $stmt =~ s/\s*}([^}]*$)//; - my $after = $1; - - #print "block<" . join(' ', @block) . "><" . scalar(@block) . ">\n"; - #print "before<$before> stmt<$stmt> after<$after>\n\n"; - - # Count the newlines, if there is only one - # then the block should not have {}'s. - my @lines = ($stmt =~ /\n/g); - my @statements = ($stmt =~ /;/g); - #print "lines<" . scalar(@lines) . ">\n"; - #print "statements<" . scalar(@statements) . ">\n"; - if ($lvl == 0 && scalar(@lines) == 0 && - scalar(@statements) < 2 && - $stmt !~ /{/ && $stmt !~ /\bif\b/ && - $before !~ /}/ && $after !~ /{/) { - my $herectx = "$here\n" . join("\n", @control, @block[1 .. $#block]) . "\n"; - shift(@block); - WARN("braces {} are not necessary for single statement blocks\n" . $herectx); + my ($level, $endln, @chunks) = + ctx_statement_full($linenr, $realcnt, $-[0]); + + my $allowed = 0; + + # Check the pre-context. + if (substr($line, 0, $-[0]) =~ /(\}\s*)$/) { + #print "APW: ALLOWED: pre<$1>\n"; + $allowed = 1; + } + # Check the condition. + my ($cond, $block) = @{$chunks[0]}; + if (defined $cond) { + substr($block, 0, length($cond)) = ''; + } + if (statement_lines($cond) > 1) { + #print "APW: ALLOWED: cond<$cond>\n"; + $allowed = 1; + } + if ($block =~/\b(?:if|for|while)\b/) { + #print "APW: ALLOWED: block<$block>\n"; + $allowed = 1; + } + if (statement_block_size($block) > 1) { + #print "APW: ALLOWED: lines block<$block>\n"; + $allowed = 1; + } + # Check the post-context. + if (defined $chunks[1]) { + my ($cond, $block) = @{$chunks[1]}; + if (defined $cond) { + substr($block, 0, length($cond)) = ''; + } + if ($block =~ /^\s*\{/) { + #print "APW: ALLOWED: chunk-1 block<$block>\n"; + $allowed = 1; + } + } + if ($level == 0 && $block =~ /^\s*\{/ && !$allowed) { + my $herectx = $here . "\n";; + my $end = $linenr + statement_rawlines($block) - 1; + + for (my $ln = $linenr - 1; $ln < $end; $ln++) { + $herectx .= $rawlines[$ln] . "\n";; } + + WARN("braces {} are not necessary for single statement blocks\n" . $herectx); } } @@ -1828,15 +1926,6 @@ sub process { print "are false positives report them to the maintainer, see\n"; print "CHECKPATCH in MAINTAINERS.\n"; } - print <num_mnt_opts)) return -EOPNOTSUPP; return 0; } @@ -268,6 +265,11 @@ static void dummy_sb_clone_mnt_opts(const struct super_block *oldsb, return; } +static int dummy_sb_parse_opts_str(char *options, struct security_mnt_opts *opts) +{ + return 0; +} + static int dummy_inode_alloc_security (struct inode *inode) { return 0; @@ -1028,6 +1030,7 @@ void security_fixup_ops (struct security_operations *ops) set_to_dummy_if_null(ops, sb_get_mnt_opts); set_to_dummy_if_null(ops, sb_set_mnt_opts); set_to_dummy_if_null(ops, sb_clone_mnt_opts); + set_to_dummy_if_null(ops, sb_parse_opts_str); set_to_dummy_if_null(ops, inode_alloc_security); set_to_dummy_if_null(ops, inode_free_security); set_to_dummy_if_null(ops, inode_init_security); diff --git a/security/security.c b/security/security.c index d15e56cbaadeea25c550cfc985de2dbbfbf410fa..b1387a6b416da9f85a8a8fa3114d386abc1d8757 100644 --- a/security/security.c +++ b/security/security.c @@ -244,10 +244,11 @@ void security_sb_free(struct super_block *sb) security_ops->sb_free_security(sb); } -int security_sb_copy_data(struct file_system_type *type, void *orig, void *copy) +int security_sb_copy_data(char *orig, char *copy) { - return security_ops->sb_copy_data(type, orig, copy); + return security_ops->sb_copy_data(orig, copy); } +EXPORT_SYMBOL(security_sb_copy_data); int security_sb_kern_mount(struct super_block *sb, void *data) { @@ -306,24 +307,30 @@ void security_sb_post_pivotroot(struct nameidata *old_nd, struct nameidata *new_ } int security_sb_get_mnt_opts(const struct super_block *sb, - char ***mount_options, - int **flags, int *num_opts) + struct security_mnt_opts *opts) { - return security_ops->sb_get_mnt_opts(sb, mount_options, flags, num_opts); + return security_ops->sb_get_mnt_opts(sb, opts); } int security_sb_set_mnt_opts(struct super_block *sb, - char **mount_options, - int *flags, int num_opts) + struct security_mnt_opts *opts) { - return security_ops->sb_set_mnt_opts(sb, mount_options, flags, num_opts); + return security_ops->sb_set_mnt_opts(sb, opts); } +EXPORT_SYMBOL(security_sb_set_mnt_opts); void security_sb_clone_mnt_opts(const struct super_block *oldsb, struct super_block *newsb) { security_ops->sb_clone_mnt_opts(oldsb, newsb); } +EXPORT_SYMBOL(security_sb_clone_mnt_opts); + +int security_sb_parse_opts_str(char *options, struct security_mnt_opts *opts) +{ + return security_ops->sb_parse_opts_str(options, opts); +} +EXPORT_SYMBOL(security_sb_parse_opts_str); int security_inode_alloc(struct inode *inode) { diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 75c2e99bfb813a0653350bf18572d1359878dde5..4bf4807f2d44351f9a46084a21e26567e8602448 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -443,8 +443,7 @@ out: * mount options, or whatever. */ static int selinux_get_mnt_opts(const struct super_block *sb, - char ***mount_options, int **mnt_opts_flags, - int *num_opts) + struct security_mnt_opts *opts) { int rc = 0, i; struct superblock_security_struct *sbsec = sb->s_security; @@ -452,9 +451,7 @@ static int selinux_get_mnt_opts(const struct super_block *sb, u32 len; char tmp; - *num_opts = 0; - *mount_options = NULL; - *mnt_opts_flags = NULL; + security_init_mnt_opts(opts); if (!sbsec->initialized) return -EINVAL; @@ -470,18 +467,18 @@ static int selinux_get_mnt_opts(const struct super_block *sb, /* count the number of mount options for this sb */ for (i = 0; i < 8; i++) { if (tmp & 0x01) - (*num_opts)++; + opts->num_mnt_opts++; tmp >>= 1; } - *mount_options = kcalloc(*num_opts, sizeof(char *), GFP_ATOMIC); - if (!*mount_options) { + opts->mnt_opts = kcalloc(opts->num_mnt_opts, sizeof(char *), GFP_ATOMIC); + if (!opts->mnt_opts) { rc = -ENOMEM; goto out_free; } - *mnt_opts_flags = kcalloc(*num_opts, sizeof(int), GFP_ATOMIC); - if (!*mnt_opts_flags) { + opts->mnt_opts_flags = kcalloc(opts->num_mnt_opts, sizeof(int), GFP_ATOMIC); + if (!opts->mnt_opts_flags) { rc = -ENOMEM; goto out_free; } @@ -491,22 +488,22 @@ static int selinux_get_mnt_opts(const struct super_block *sb, rc = security_sid_to_context(sbsec->sid, &context, &len); if (rc) goto out_free; - (*mount_options)[i] = context; - (*mnt_opts_flags)[i++] = FSCONTEXT_MNT; + opts->mnt_opts[i] = context; + opts->mnt_opts_flags[i++] = FSCONTEXT_MNT; } if (sbsec->flags & CONTEXT_MNT) { rc = security_sid_to_context(sbsec->mntpoint_sid, &context, &len); if (rc) goto out_free; - (*mount_options)[i] = context; - (*mnt_opts_flags)[i++] = CONTEXT_MNT; + opts->mnt_opts[i] = context; + opts->mnt_opts_flags[i++] = CONTEXT_MNT; } if (sbsec->flags & DEFCONTEXT_MNT) { rc = security_sid_to_context(sbsec->def_sid, &context, &len); if (rc) goto out_free; - (*mount_options)[i] = context; - (*mnt_opts_flags)[i++] = DEFCONTEXT_MNT; + opts->mnt_opts[i] = context; + opts->mnt_opts_flags[i++] = DEFCONTEXT_MNT; } if (sbsec->flags & ROOTCONTEXT_MNT) { struct inode *root = sbsec->sb->s_root->d_inode; @@ -515,24 +512,16 @@ static int selinux_get_mnt_opts(const struct super_block *sb, rc = security_sid_to_context(isec->sid, &context, &len); if (rc) goto out_free; - (*mount_options)[i] = context; - (*mnt_opts_flags)[i++] = ROOTCONTEXT_MNT; + opts->mnt_opts[i] = context; + opts->mnt_opts_flags[i++] = ROOTCONTEXT_MNT; } - BUG_ON(i != *num_opts); + BUG_ON(i != opts->num_mnt_opts); return 0; out_free: - /* don't leak context string if security_sid_to_context had an error */ - if (*mount_options && i) - for (; i > 0; i--) - kfree((*mount_options)[i-1]); - kfree(*mount_options); - *mount_options = NULL; - kfree(*mnt_opts_flags); - *mnt_opts_flags = NULL; - *num_opts = 0; + security_free_mnt_opts(opts); return rc; } @@ -553,12 +542,13 @@ static int bad_option(struct superblock_security_struct *sbsec, char flag, return 1; return 0; } + /* * Allow filesystems with binary mount data to explicitly set mount point * labeling information. */ -static int selinux_set_mnt_opts(struct super_block *sb, char **mount_options, - int *flags, int num_opts) +static int selinux_set_mnt_opts(struct super_block *sb, + struct security_mnt_opts *opts) { int rc = 0, i; struct task_security_struct *tsec = current->security; @@ -568,6 +558,9 @@ static int selinux_set_mnt_opts(struct super_block *sb, char **mount_options, struct inode_security_struct *root_isec = inode->i_security; u32 fscontext_sid = 0, context_sid = 0, rootcontext_sid = 0; u32 defcontext_sid = 0; + char **mount_options = opts->mnt_opts; + int *flags = opts->mnt_opts_flags; + int num_opts = opts->num_mnt_opts; mutex_lock(&sbsec->lock); @@ -588,6 +581,21 @@ static int selinux_set_mnt_opts(struct super_block *sb, char **mount_options, goto out; } + /* + * Binary mount data FS will come through this function twice. Once + * from an explicit call and once from the generic calls from the vfs. + * Since the generic VFS calls will not contain any security mount data + * we need to skip the double mount verification. + * + * This does open a hole in which we will not notice if the first + * mount using this sb set explict options and a second mount using + * this sb does not set any security options. (The first options + * will be used for both mounts) + */ + if (sbsec->initialized && (sb->s_type->fs_flags & FS_BINARY_MOUNTDATA) + && (num_opts == 0)) + goto out; + /* * parse the mount options, check if they are valid sids. * also check if someone is trying to mount the same sb more @@ -792,43 +800,14 @@ static void selinux_sb_clone_mnt_opts(const struct super_block *oldsb, mutex_unlock(&newsbsec->lock); } -/* - * string mount options parsing and call set the sbsec - */ -static int superblock_doinit(struct super_block *sb, void *data) +int selinux_parse_opts_str(char *options, struct security_mnt_opts *opts) { + char *p; char *context = NULL, *defcontext = NULL; char *fscontext = NULL, *rootcontext = NULL; - int rc = 0; - char *p, *options = data; - /* selinux only know about a fixed number of mount options */ - char *mnt_opts[NUM_SEL_MNT_OPTS]; - int mnt_opts_flags[NUM_SEL_MNT_OPTS], num_mnt_opts = 0; - - if (!data) - goto out; + int rc, num_mnt_opts = 0; - /* with the nfs patch this will become a goto out; */ - if (sb->s_type->fs_flags & FS_BINARY_MOUNTDATA) { - const char *name = sb->s_type->name; - /* NFS we understand. */ - if (!strcmp(name, "nfs")) { - struct nfs_mount_data *d = data; - - if (d->version != NFS_MOUNT_VERSION) - goto out; - - if (d->context[0]) { - context = kstrdup(d->context, GFP_KERNEL); - if (!context) { - rc = -ENOMEM; - goto out; - } - } - goto build_flags; - } else - goto out; - } + opts->num_mnt_opts = 0; /* Standard string-based options. */ while ((p = strsep(&options, "|")) != NULL) { @@ -901,26 +880,37 @@ static int superblock_doinit(struct super_block *sb, void *data) } } -build_flags: + rc = -ENOMEM; + opts->mnt_opts = kcalloc(NUM_SEL_MNT_OPTS, sizeof(char *), GFP_ATOMIC); + if (!opts->mnt_opts) + goto out_err; + + opts->mnt_opts_flags = kcalloc(NUM_SEL_MNT_OPTS, sizeof(int), GFP_ATOMIC); + if (!opts->mnt_opts_flags) { + kfree(opts->mnt_opts); + goto out_err; + } + if (fscontext) { - mnt_opts[num_mnt_opts] = fscontext; - mnt_opts_flags[num_mnt_opts++] = FSCONTEXT_MNT; + opts->mnt_opts[num_mnt_opts] = fscontext; + opts->mnt_opts_flags[num_mnt_opts++] = FSCONTEXT_MNT; } if (context) { - mnt_opts[num_mnt_opts] = context; - mnt_opts_flags[num_mnt_opts++] = CONTEXT_MNT; + opts->mnt_opts[num_mnt_opts] = context; + opts->mnt_opts_flags[num_mnt_opts++] = CONTEXT_MNT; } if (rootcontext) { - mnt_opts[num_mnt_opts] = rootcontext; - mnt_opts_flags[num_mnt_opts++] = ROOTCONTEXT_MNT; + opts->mnt_opts[num_mnt_opts] = rootcontext; + opts->mnt_opts_flags[num_mnt_opts++] = ROOTCONTEXT_MNT; } if (defcontext) { - mnt_opts[num_mnt_opts] = defcontext; - mnt_opts_flags[num_mnt_opts++] = DEFCONTEXT_MNT; + opts->mnt_opts[num_mnt_opts] = defcontext; + opts->mnt_opts_flags[num_mnt_opts++] = DEFCONTEXT_MNT; } -out: - rc = selinux_set_mnt_opts(sb, mnt_opts, mnt_opts_flags, num_mnt_opts); + opts->num_mnt_opts = num_mnt_opts; + return 0; + out_err: kfree(context); kfree(defcontext); @@ -928,6 +918,33 @@ out_err: kfree(rootcontext); return rc; } +/* + * string mount options parsing and call set the sbsec + */ +static int superblock_doinit(struct super_block *sb, void *data) +{ + int rc = 0; + char *options = data; + struct security_mnt_opts opts; + + security_init_mnt_opts(&opts); + + if (!data) + goto out; + + BUG_ON(sb->s_type->fs_flags & FS_BINARY_MOUNTDATA); + + rc = selinux_parse_opts_str(options, &opts); + if (rc) + goto out_err; + +out: + rc = selinux_set_mnt_opts(sb, &opts); + +out_err: + security_free_mnt_opts(&opts); + return rc; +} static inline u16 inode_mode_to_security_class(umode_t mode) { @@ -2253,7 +2270,7 @@ static inline void take_selinux_option(char **to, char *from, int *first, } } -static int selinux_sb_copy_data(struct file_system_type *type, void *orig, void *copy) +static int selinux_sb_copy_data(char *orig, char *copy) { int fnosec, fsec, rc = 0; char *in_save, *in_curr, *in_end; @@ -2263,12 +2280,6 @@ static int selinux_sb_copy_data(struct file_system_type *type, void *orig, void in_curr = orig; sec_curr = copy; - /* Binary mount data: just copy */ - if (type->fs_flags & FS_BINARY_MOUNTDATA) { - copy_page(sec_curr, in_curr); - goto out; - } - nosec = (char *)get_zeroed_page(GFP_KERNEL); if (!nosec) { rc = -ENOMEM; @@ -5251,6 +5262,8 @@ static struct security_operations selinux_ops = { .sb_get_mnt_opts = selinux_get_mnt_opts, .sb_set_mnt_opts = selinux_set_mnt_opts, .sb_clone_mnt_opts = selinux_sb_clone_mnt_opts, + .sb_parse_opts_str = selinux_parse_opts_str, + .inode_alloc_security = selinux_inode_alloc_security, .inode_free_security = selinux_inode_free_security, diff --git a/security/selinux/include/security.h b/security/selinux/include/security.h index 837ce420d2f64ff810c4e96b7b7ce9a1ca695328..f7d2f03781f29b650d7e9bfa82822bb680b2a82d 100644 --- a/security/selinux/include/security.h +++ b/security/selinux/include/security.h @@ -35,6 +35,11 @@ #define POLICYDB_VERSION_MAX POLICYDB_VERSION_POLCAP #endif +#define CONTEXT_MNT 0x01 +#define FSCONTEXT_MNT 0x02 +#define ROOTCONTEXT_MNT 0x04 +#define DEFCONTEXT_MNT 0x08 + struct netlbl_lsm_secattr; extern int selinux_enabled; diff --git a/security/smack/smack.h b/security/smack/smack.h index a21a0e907ab34092017e6a67243a1ad93b3be171..62c1e982849d9b1ab83c38c1bc6bc9df68749e77 100644 --- a/security/smack/smack.h +++ b/security/smack/smack.h @@ -26,14 +26,6 @@ #define SMK_MAXLEN 23 #define SMK_LABELLEN (SMK_MAXLEN+1) -/* - * How many kinds of access are there? - * Here's your answer. - */ -#define SMK_ACCESSDASH '-' -#define SMK_ACCESSLOW "rwxa" -#define SMK_ACCESSKINDS (sizeof(SMK_ACCESSLOW) - 1) - struct superblock_smack { char *smk_root; char *smk_floor; diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c index 770eb067e165f493b1e153cac3cfcec6d66953f7..0241fd359675a947def24347cbc22dd559fe314e 100644 --- a/security/smack/smack_lsm.c +++ b/security/smack/smack_lsm.c @@ -189,17 +189,10 @@ static void smack_sb_free_security(struct super_block *sb) * Copy the Smack specific mount options out of the mount * options list. */ -static int smack_sb_copy_data(struct file_system_type *type, void *orig, - void *smackopts) +static int smack_sb_copy_data(char *orig, char *smackopts) { char *cp, *commap, *otheropts, *dp; - /* Binary mount data: just copy */ - if (type->fs_flags & FS_BINARY_MOUNTDATA) { - copy_page(smackopts, orig); - return 0; - } - otheropts = (char *)get_zeroed_page(GFP_KERNEL); if (otheropts == NULL) return -ENOMEM; diff --git a/security/smack/smackfs.c b/security/smack/smackfs.c index 358c92c1a153df7f943d09fdc3634ffffc47a632..afe7c9b0732ac6c16ae6677bbfe1ca0ca5ecf799 100644 --- a/security/smack/smackfs.c +++ b/security/smack/smackfs.c @@ -81,10 +81,23 @@ static struct semaphore smack_write_sem; /* * Values for parsing cipso rules * SMK_DIGITLEN: Length of a digit field in a rule. - * SMK_CIPSOMEN: Minimum possible cipso rule length. + * SMK_CIPSOMIN: Minimum possible cipso rule length. + * SMK_CIPSOMAX: Maximum possible cipso rule length. */ #define SMK_DIGITLEN 4 -#define SMK_CIPSOMIN (SMK_MAXLEN + 2 * SMK_DIGITLEN) +#define SMK_CIPSOMIN (SMK_LABELLEN + 2 * SMK_DIGITLEN) +#define SMK_CIPSOMAX (SMK_CIPSOMIN + SMACK_CIPSO_MAXCATNUM * SMK_DIGITLEN) + +/* + * Values for parsing MAC rules + * SMK_ACCESS: Maximum possible combination of access permissions + * SMK_ACCESSLEN: Maximum length for a rule access field + * SMK_LOADLEN: Smack rule length + */ +#define SMK_ACCESS "rwxa" +#define SMK_ACCESSLEN (sizeof(SMK_ACCESS) - 1) +#define SMK_LOADLEN (SMK_LABELLEN + SMK_LABELLEN + SMK_ACCESSLEN) + /* * Seq_file read operations for /smack/load @@ -229,14 +242,10 @@ static void smk_set_access(struct smack_rule *srp) * The format is exactly: * char subject[SMK_LABELLEN] * char object[SMK_LABELLEN] - * char access[SMK_ACCESSKINDS] - * - * Anything following is commentary and ignored. + * char access[SMK_ACCESSLEN] * - * writes must be SMK_LABELLEN+SMK_LABELLEN+4 bytes. + * writes must be SMK_LABELLEN+SMK_LABELLEN+SMK_ACCESSLEN bytes. */ -#define MINIMUM_LOAD (SMK_LABELLEN + SMK_LABELLEN + SMK_ACCESSKINDS) - static ssize_t smk_write_load(struct file *file, const char __user *buf, size_t count, loff_t *ppos) { @@ -253,7 +262,7 @@ static ssize_t smk_write_load(struct file *file, const char __user *buf, return -EPERM; if (*ppos != 0) return -EINVAL; - if (count < MINIMUM_LOAD) + if (count != SMK_LOADLEN) return -EINVAL; data = kzalloc(count, GFP_KERNEL); @@ -513,7 +522,7 @@ static ssize_t smk_write_cipso(struct file *file, const char __user *buf, return -EPERM; if (*ppos != 0) return -EINVAL; - if (count <= SMK_CIPSOMIN) + if (count < SMK_CIPSOMIN || count > SMK_CIPSOMAX) return -EINVAL; data = kzalloc(count + 1, GFP_KERNEL); @@ -547,7 +556,7 @@ static ssize_t smk_write_cipso(struct file *file, const char __user *buf, if (ret != 1 || catlen > SMACK_CIPSO_MAXCATNUM) goto out; - if (count <= (SMK_CIPSOMIN + catlen * SMK_DIGITLEN)) + if (count != (SMK_CIPSOMIN + catlen * SMK_DIGITLEN)) goto out; memset(mapcatset, 0, sizeof(mapcatset)); diff --git a/sound/isa/sb/sb8_main.c b/sound/isa/sb/sb8_main.c index 6304c3a89ba0650b5a644c555f81dfded2cd2620..fe03bb820532beed11afd25dbfe8c67959ead1fa 100644 --- a/sound/isa/sb/sb8_main.c +++ b/sound/isa/sb/sb8_main.c @@ -277,7 +277,7 @@ static int snd_sb8_capture_prepare(struct snd_pcm_substream *substream) } else { snd_sbdsp_command(chip, 256 - runtime->rate_den); } - if (chip->capture_format != SB_DSP_OUTPUT) { + if (chip->capture_format != SB_DSP_INPUT) { count--; snd_sbdsp_command(chip, SB_DSP_BLOCK_SIZE); snd_sbdsp_command(chip, count & 0xff); diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c index 19f08846d6fcaa84a800a7fcf932b0b52858172c..c8649282c2cfec54b191468f52b98bc18b82e385 100644 --- a/sound/pci/hda/patch_analog.c +++ b/sound/pci/hda/patch_analog.c @@ -1778,9 +1778,9 @@ static hda_nid_t ad1988_capsrc_nids[3] = { static struct hda_input_mux ad1988_6stack_capture_source = { .num_items = 5, .items = { - { "Front Mic", 0x0 }, - { "Line", 0x1 }, - { "Mic", 0x4 }, + { "Front Mic", 0x1 }, /* port-B */ + { "Line", 0x2 }, /* port-C */ + { "Mic", 0x4 }, /* port-E */ { "CD", 0x5 }, { "Mix", 0x9 }, }, @@ -1789,7 +1789,7 @@ static struct hda_input_mux ad1988_6stack_capture_source = { static struct hda_input_mux ad1988_laptop_capture_source = { .num_items = 3, .items = { - { "Mic/Line", 0x0 }, + { "Mic/Line", 0x1 }, /* port-B */ { "CD", 0x5 }, { "Mix", 0x9 }, }, diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c index f7cd3a804b11b5faa9283646cf0817efce8069e1..7206b30cbf9454c30e19f0c2c49e9dbe9684df2f 100644 --- a/sound/pci/hda/patch_conexant.c +++ b/sound/pci/hda/patch_conexant.c @@ -1230,6 +1230,11 @@ static struct hda_verb cxt5047_toshiba_init_verbs[] = { static struct hda_verb cxt5047_hp_init_verbs[] = { /* pin sensing on HP jack */ {0x13, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_HP_EVENT}, + /* 0x13 is actually shared by both HP and speaker; + * setting the connection to 0 (=0x19) makes the master volume control + * working mysteriouslly... + */ + {0x13, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Record selector: Ext Mic */ {0x12, AC_VERB_SET_CONNECT_SEL,0x03}, {0x19, AC_VERB_SET_AMP_GAIN_MUTE, diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 777f8c01ca7a6c804d0050d785aaa163f0f42780..33282f9c01c7f9a586038243ea50695a3572a982 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -3973,8 +3973,8 @@ static struct snd_kcontrol_new alc260_fujitsu_mixer[] = { ALC_PIN_MODE("Mic/Line Jack Mode", 0x12, ALC_PIN_DIR_IN), HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT), HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT), - HDA_CODEC_VOLUME("Internal Speaker Playback Volume", 0x09, 0x0, HDA_OUTPUT), - HDA_BIND_MUTE("Internal Speaker Playback Switch", 0x09, 2, HDA_INPUT), + HDA_CODEC_VOLUME("Speaker Playback Volume", 0x09, 0x0, HDA_OUTPUT), + HDA_BIND_MUTE("Speaker Playback Switch", 0x09, 2, HDA_INPUT), { } /* end */ }; @@ -4005,9 +4005,9 @@ static struct snd_kcontrol_new alc260_acer_mixer[] = { HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT), HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT), ALC_PIN_MODE("Headphone Jack Mode", 0x0f, ALC_PIN_DIR_INOUT), - HDA_CODEC_VOLUME_MONO("Mono Speaker Playback Volume", 0x0a, 1, 0x0, + HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT), - HDA_BIND_MUTE_MONO("Mono Speaker Playback Switch", 0x0a, 1, 2, + HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2, HDA_INPUT), HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT), HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT), @@ -7639,6 +7639,7 @@ static struct snd_pci_quirk alc883_cfg_tbl[] = { SND_PCI_QUIRK(0x17aa, 0x3bfc, "Lenovo NB0763", ALC883_LENOVO_NB0763), SND_PCI_QUIRK(0x17aa, 0x3bfd, "Lenovo NB0763", ALC883_LENOVO_NB0763), SND_PCI_QUIRK(0x17c0, 0x4071, "MEDION MD2", ALC883_MEDION_MD2), + SND_PCI_QUIRK(0x17f2, 0x5000, "Albatron KI690-AM2", ALC883_6ST_DIG), SND_PCI_QUIRK(0x1991, 0x5625, "Haier W66", ALC883_HAIER_W66), SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC883_3ST_6ch), {} @@ -8102,7 +8103,7 @@ static struct snd_kcontrol_new alc262_base_mixer[] = { HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), /* HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT), - HDA_CODEC_MUTE("PC Beelp Playback Switch", 0x0b, 0x05, HDA_INPUT), */ + HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT), */ HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT), HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), @@ -8124,7 +8125,7 @@ static struct snd_kcontrol_new alc262_hippo1_mixer[] = { HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), /* HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT), - HDA_CODEC_MUTE("PC Beelp Playback Switch", 0x0b, 0x05, HDA_INPUT), */ + HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT), */ /*HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),*/ HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), { } /* end */ @@ -9238,6 +9239,7 @@ static struct snd_pci_quirk alc262_cfg_tbl[] = { SND_PCI_QUIRK(0x104d, 0x900e, "Sony ASSAMD", ALC262_SONY_ASSAMD), SND_PCI_QUIRK(0x104d, 0x9015, "Sony 0x9015", ALC262_SONY_ASSAMD), SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FUJITSU), + SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FUJITSU), SND_PCI_QUIRK(0x144d, 0xc032, "Samsung Q1 Ultra", ALC262_ULTRA), SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_BENQ_ED8), SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_BENQ_T31), @@ -12993,8 +12995,8 @@ static struct snd_kcontrol_new alc662_lenovo_101e_mixer[] = { static struct snd_kcontrol_new alc662_eeepc_p701_mixer[] = { HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), - HDA_CODEC_VOLUME("LineOut Playback Volume", 0x02, 0x0, HDA_OUTPUT), - HDA_CODEC_MUTE("LineOut Playback Switch", 0x1b, 0x0, HDA_OUTPUT), + HDA_CODEC_VOLUME("Line-Out Playback Volume", 0x02, 0x0, HDA_OUTPUT), + HDA_CODEC_MUTE("Line-Out Playback Switch", 0x1b, 0x0, HDA_OUTPUT), HDA_CODEC_VOLUME("e-Mic Boost", 0x18, 0, HDA_INPUT), HDA_CODEC_VOLUME("e-Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), @@ -13007,8 +13009,8 @@ static struct snd_kcontrol_new alc662_eeepc_p701_mixer[] = { }; static struct snd_kcontrol_new alc662_eeepc_ep20_mixer[] = { - HDA_CODEC_VOLUME("LineOut Playback Volume", 0x02, 0x0, HDA_OUTPUT), - HDA_CODEC_MUTE("LineOut Playback Switch", 0x14, 0x0, HDA_OUTPUT), + HDA_CODEC_VOLUME("Line-Out Playback Volume", 0x02, 0x0, HDA_OUTPUT), + HDA_CODEC_MUTE("Line-Out Playback Switch", 0x14, 0x0, HDA_OUTPUT), HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT), HDA_BIND_MUTE("Surround Playback Switch", 0x03, 2, HDA_INPUT), HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT), diff --git a/sound/pci/ice1712/phase.c b/sound/pci/ice1712/phase.c index 9ab4a9f383cbb19b69834a7b27be19e759ea80db..5a158b73dcaa2050211bf55291d3de67b0621ebd 100644 --- a/sound/pci/ice1712/phase.c +++ b/sound/pci/ice1712/phase.c @@ -51,7 +51,7 @@ struct phase28_spec { unsigned short master[2]; unsigned short vol[8]; -} phase28; +}; /* WM8770 registers */ #define WM_DAC_ATTEN 0x00 /* DAC1-8 analog attenuation */ diff --git a/sound/pci/ice1712/revo.c b/sound/pci/ice1712/revo.c index ddd5fc8d4fe12e9bbd3e61db39e95b8e07381826..301bf929acd9018310fe96b94c1c37ce521f05e2 100644 --- a/sound/pci/ice1712/revo.c +++ b/sound/pci/ice1712/revo.c @@ -36,7 +36,7 @@ struct revo51_spec { struct snd_i2c_device *dev; struct snd_pt2258 *pt2258; -} revo51; +}; static void revo_i2s_mclk_changed(struct snd_ice1712 *ice) { diff --git a/sound/pci/intel8x0.c b/sound/pci/intel8x0.c index 061072c7db034722398571b253cfba6eb50be8e3..c52abd0bf22e3026b03274851f71c15d1fbf947b 100644 --- a/sound/pci/intel8x0.c +++ b/sound/pci/intel8x0.c @@ -1708,6 +1708,12 @@ static struct ac97_pcm ac97_pcm_defs[] __devinitdata = { }; static struct ac97_quirk ac97_quirks[] __devinitdata = { + { + .subvendor = 0x0e11, + .subdevice = 0x000e, + .name = "Compaq Deskpro EN", /* AD1885 */ + .type = AC97_TUNE_HP_ONLY + }, { .subvendor = 0x0e11, .subdevice = 0x008a, @@ -1738,6 +1744,12 @@ static struct ac97_quirk ac97_quirks[] __devinitdata = { .name = "IBM NetVista A30p", /* AD1981B */ .type = AC97_TUNE_HP_ONLY }, + { + .subvendor = 0x1025, + .subdevice = 0x0082, + .name = "Acer Travelmate 2310", + .type = AC97_TUNE_HP_ONLY + }, { .subvendor = 0x1025, .subdevice = 0x0083, diff --git a/sound/pci/oxygen/hifier.c b/sound/pci/oxygen/hifier.c index 3ea1f05228a18f04b090ff4b07fb0f804b8bfa84..666f69a3312e9a3c08cd90ac91008105f482fa3d 100644 --- a/sound/pci/oxygen/hifier.c +++ b/sound/pci/oxygen/hifier.c @@ -150,6 +150,7 @@ static const struct oxygen_model model_hifier = { .shortname = "C-Media CMI8787", .longname = "C-Media Oxygen HD Audio", .chip = "CMI8788", + .owner = THIS_MODULE, .init = hifier_init, .control_filter = hifier_control_filter, .mixer_init = hifier_mixer_init, diff --git a/sound/pci/oxygen/virtuoso.c b/sound/pci/oxygen/virtuoso.c index 40e92f5cd69c760111073cfe8e8a9c60e1f00cce..d163397b85cc3d351cc60b1b3b187d191c0ae549 100644 --- a/sound/pci/oxygen/virtuoso.c +++ b/sound/pci/oxygen/virtuoso.c @@ -389,6 +389,7 @@ static const struct oxygen_model model_xonar = { .shortname = "Asus AV200", .longname = "Asus Virtuoso 200", .chip = "AV200", + .owner = THIS_MODULE, .init = xonar_init, .control_filter = xonar_control_filter, .mixer_init = xonar_mixer_init, diff --git a/sound/soc/codecs/tlv320aic3x.c b/sound/soc/codecs/tlv320aic3x.c index 710e0287ef8c13d2b70f72ef42e58e8a4bd8a9cf..569ecaca0e8b9caf7723d9a393367ab6853242c9 100644 --- a/sound/soc/codecs/tlv320aic3x.c +++ b/sound/soc/codecs/tlv320aic3x.c @@ -681,8 +681,8 @@ static const struct aic3x_rate_divs aic3x_divs[] = { {22579200, 48000, 48000, 0x0, 8, 7075}, {33868800, 48000, 48000, 0x0, 5, 8049}, /* 64k */ - {22579200, 96000, 96000, 0x1, 8, 7075}, - {33868800, 96000, 96000, 0x1, 5, 8049}, + {22579200, 64000, 96000, 0x1, 8, 7075}, + {33868800, 64000, 96000, 0x1, 5, 8049}, /* 88.2k */ {22579200, 88200, 88200, 0x0, 8, 0}, {33868800, 88200, 88200, 0x0, 5, 3333}, diff --git a/sound/soc/codecs/wm9712.c b/sound/soc/codecs/wm9712.c index 590baea3c4c3d9d3a2666025615b27f3c506545c..524f7450804f07cc506547618c17bdff96c925e6 100644 --- a/sound/soc/codecs/wm9712.c +++ b/sound/soc/codecs/wm9712.c @@ -176,7 +176,8 @@ static int wm9712_add_controls(struct snd_soc_codec *codec) * the codec only has a single control that is shared by both channels. * This makes it impossible to determine the audio path. */ -static int mixer_event (struct snd_soc_dapm_widget *w, int event) +static int mixer_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *k, int event) { u16 l, r, beep, line, phone, mic, pcm, aux; diff --git a/sound/soc/pxa/corgi.c b/sound/soc/pxa/corgi.c index 3f34e531bebf7921d210a05e583c937535095de1..1a70a6ac98ced1a2a9a5830e7a5678df8bea7b36 100644 --- a/sound/soc/pxa/corgi.c +++ b/sound/soc/pxa/corgi.c @@ -215,7 +215,8 @@ static int corgi_set_spk(struct snd_kcontrol *kcontrol, return 1; } -static int corgi_amp_event(struct snd_soc_dapm_widget *w, int event) +static int corgi_amp_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *k, int event) { if (SND_SOC_DAPM_EVENT_ON(event)) set_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_APM_ON); @@ -225,7 +226,8 @@ static int corgi_amp_event(struct snd_soc_dapm_widget *w, int event) return 0; } -static int corgi_mic_event(struct snd_soc_dapm_widget *w, int event) +static int corgi_mic_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *k, int event) { if (SND_SOC_DAPM_EVENT_ON(event)) set_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_MIC_BIAS); diff --git a/sound/soc/pxa/poodle.c b/sound/soc/pxa/poodle.c index 5ae59bd309a33863d05b3173c7e879df77a6372a..4fbf8bba9627322cd628fb8d21d545ebe608c658 100644 --- a/sound/soc/pxa/poodle.c +++ b/sound/soc/pxa/poodle.c @@ -196,7 +196,8 @@ static int poodle_set_spk(struct snd_kcontrol *kcontrol, return 1; } -static int poodle_amp_event(struct snd_soc_dapm_widget *w, int event) +static int poodle_amp_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *k, int event) { if (SND_SOC_DAPM_EVENT_ON(event)) locomo_gpio_write(&poodle_locomo_device.dev, diff --git a/sound/soc/pxa/spitz.c b/sound/soc/pxa/spitz.c index d56709e15435e175cd533f7cd2badd558c3aded8..ecca39033fcceff2ae449cec9c48ab3f17f3061f 100644 --- a/sound/soc/pxa/spitz.c +++ b/sound/soc/pxa/spitz.c @@ -215,7 +215,8 @@ static int spitz_set_spk(struct snd_kcontrol *kcontrol, return 1; } -static int spitz_mic_bias(struct snd_soc_dapm_widget *w, int event) +static int spitz_mic_bias(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *k, int event) { if (machine_is_borzoi() || machine_is_spitz()) { if (SND_SOC_DAPM_EVENT_ON(event)) diff --git a/sound/soc/pxa/tosa.c b/sound/soc/pxa/tosa.c index e4d40b528ca47e6b85017ac52529b34fece23c55..7346d7e5d066e71b84669f0fe6c054e77b003ca1 100644 --- a/sound/soc/pxa/tosa.c +++ b/sound/soc/pxa/tosa.c @@ -135,7 +135,8 @@ static int tosa_set_spk(struct snd_kcontrol *kcontrol, } /* tosa dapm event handlers */ -static int tosa_hp_event(struct snd_soc_dapm_widget *w, int event) +static int tosa_hp_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *k, int event) { if (SND_SOC_DAPM_EVENT_ON(event)) set_tc6393_gpio(&tc6393_device.dev,TOSA_TC6393_L_MUTE); diff --git a/sound/usb/usbaudio.c b/sound/usb/usbaudio.c index 8fa93566570272036365009776ec0fa952c1303d..f48838a078cb718c050cb02dd71945be16eaa88c 100644 --- a/sound/usb/usbaudio.c +++ b/sound/usb/usbaudio.c @@ -479,6 +479,33 @@ static int retire_playback_sync_urb_hs(struct snd_usb_substream *subs, return 0; } +/* + * process after E-Mu 0202/0404 high speed playback sync complete + * + * These devices return the number of samples per packet instead of the number + * of samples per microframe. + */ +static int retire_playback_sync_urb_hs_emu(struct snd_usb_substream *subs, + struct snd_pcm_runtime *runtime, + struct urb *urb) +{ + unsigned int f; + unsigned long flags; + + if (urb->iso_frame_desc[0].status == 0 && + urb->iso_frame_desc[0].actual_length == 4) { + f = combine_quad((u8*)urb->transfer_buffer) & 0x0fffffff; + f >>= subs->datainterval; + if (f >= subs->freqn - subs->freqn / 8 && f <= subs->freqmax) { + spin_lock_irqsave(&subs->lock, flags); + subs->freqm = f; + spin_unlock_irqrestore(&subs->lock, flags); + } + } + + return 0; +} + /* determine the number of frames in the next packet */ static int snd_usb_audio_next_packet_size(struct snd_usb_substream *subs) { @@ -1735,6 +1762,8 @@ static int check_hw_params_convention(struct snd_usb_substream *subs) channels = kcalloc(MAX_MASK, sizeof(u32), GFP_KERNEL); rates = kcalloc(MAX_MASK, sizeof(u32), GFP_KERNEL); + if (!channels || !rates) + goto __out; list_for_each(p, &subs->fmt_list) { struct audioformat *f; @@ -2219,10 +2248,17 @@ static void init_substream(struct snd_usb_stream *as, int stream, struct audiofo subs->stream = as; subs->direction = stream; subs->dev = as->chip->dev; - if (snd_usb_get_speed(subs->dev) == USB_SPEED_FULL) + if (snd_usb_get_speed(subs->dev) == USB_SPEED_FULL) { subs->ops = audio_urb_ops[stream]; - else + } else { subs->ops = audio_urb_ops_high_speed[stream]; + switch (as->chip->usb_id) { + case USB_ID(0x041e, 0x3f02): /* E-Mu 0202 USB */ + case USB_ID(0x041e, 0x3f04): /* E-Mu 0404 USB */ + subs->ops.retire_sync = retire_playback_sync_urb_hs_emu; + break; + } + } snd_pcm_set_ops(as->pcm, stream, stream == SNDRV_PCM_STREAM_PLAYBACK ? &snd_usb_playback_ops : &snd_usb_capture_ops); diff --git a/virt/kvm/ioapic.c b/virt/kvm/ioapic.c index 317f8e211cd2a136f6a07c8333731dadd0389cbe..4232fd75dd20b710a4ca16c857b80a83948f2fe9 100644 --- a/virt/kvm/ioapic.c +++ b/virt/kvm/ioapic.c @@ -211,6 +211,10 @@ static void ioapic_deliver(struct kvm_ioapic *ioapic, int irq) case IOAPIC_LOWEST_PRIORITY: vcpu = kvm_get_lowest_prio_vcpu(ioapic->kvm, vector, deliver_bitmask); +#ifdef CONFIG_X86 + if (irq == 0) + vcpu = ioapic->kvm->vcpus[0]; +#endif if (vcpu != NULL) ioapic_inj_irq(ioapic, vcpu, vector, trig_mode, delivery_mode); @@ -220,6 +224,10 @@ static void ioapic_deliver(struct kvm_ioapic *ioapic, int irq) deliver_bitmask, vector, IOAPIC_LOWEST_PRIORITY); break; case IOAPIC_FIXED: +#ifdef CONFIG_X86 + if (irq == 0) + deliver_bitmask = 1; +#endif for (vcpu_id = 0; deliver_bitmask != 0; vcpu_id++) { if (!(deliver_bitmask & (1 << vcpu_id))) continue; diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index 32fbf800696901866b760cef48b880a151c58399..b2e12893e3f4d4b0f39d64ff733333171e3a0dfb 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c @@ -169,6 +169,7 @@ static struct kvm *kvm_create_vm(void) kvm_io_bus_init(&kvm->pio_bus); mutex_init(&kvm->lock); kvm_io_bus_init(&kvm->mmio_bus); + init_rwsem(&kvm->slots_lock); spin_lock(&kvm_lock); list_add(&kvm->vm_list, &vm_list); spin_unlock(&kvm_lock); @@ -339,9 +340,9 @@ int kvm_set_memory_region(struct kvm *kvm, { int r; - down_write(¤t->mm->mmap_sem); + down_write(&kvm->slots_lock); r = __kvm_set_memory_region(kvm, mem, user_alloc); - up_write(¤t->mm->mmap_sem); + up_write(&kvm->slots_lock); return r; } EXPORT_SYMBOL_GPL(kvm_set_memory_region);