Merge branch 'for_paulus' of master.kernel.org:/pub/scm/linux/kernel/git/galak/powerpc
* 'for_paulus' of master.kernel.org:/pub/scm/linux/kernel/git/galak/powerpc:
[POWERPC] Fix Kconfig warning
[PPC] Fix modpost warning
[POWERPC] Fix modpost warning
[POWERPC] Fix Section mismatch warnings
[POWERPC] QE: fix Kconfig 'select' warning with UCC_FAST
[POWERPC] 52xx: unbreak lite5200 dts (_pic vs. -pic)
[PPC] Remove duplicate export of __div64_32.
[PPC] Fix COMMON symbol warnings
diff --git a/Documentation/CodingStyle b/Documentation/CodingStyle
index afc2867..b49b92e 100644
--- a/Documentation/CodingStyle
+++ b/Documentation/CodingStyle
@@ -495,29 +495,40 @@
remember: "indent" is not a fix for bad programming.
- Chapter 10: Configuration-files
+ Chapter 10: Kconfig configuration files
-For configuration options (arch/xxx/Kconfig, and all the Kconfig files),
-somewhat different indentation is used.
+For all of the Kconfig* configuration files throughout the source tree,
+the indentation is somewhat different. Lines under a "config" definition
+are indented with one tab, while help text is indented an additional two
+spaces. Example:
-Help text is indented with 2 spaces.
-
-if CONFIG_EXPERIMENTAL
- tristate CONFIG_BOOM
- default n
+config AUDIT
+ bool "Auditing support"
+ depends on NET
help
- Apply nitroglycerine inside the keyboard (DANGEROUS)
- bool CONFIG_CHEER
- depends on CONFIG_BOOM
- default y
- help
- Output nice messages when you explode
-endif
+ Enable auditing infrastructure that can be used with another
+ kernel subsystem, such as SELinux (which requires this for
+ logging of avc messages output). Does not do system-call
+ auditing without CONFIG_AUDITSYSCALL.
-Generally, CONFIG_EXPERIMENTAL should surround all options not considered
-stable. All options that are known to trash data (experimental write-
-support for file-systems, for instance) should be denoted (DANGEROUS), other
-experimental options should be denoted (EXPERIMENTAL).
+Features that might still be considered unstable should be defined as
+dependent on "EXPERIMENTAL":
+
+config SLUB
+ depends on EXPERIMENTAL && !ARCH_USES_SLAB_PAGE_STRUCT
+ bool "SLUB (Unqueued Allocator)"
+ ...
+
+while seriously dangerous features (such as write support for certain
+filesystems) should advertise this prominently in their prompt string:
+
+config ADFS_FS_RW
+ bool "ADFS write support (DANGEROUS)"
+ depends on ADFS_FS
+ ...
+
+For full documentation on the configuration files, see the file
+Documentation/kbuild/kconfig-language.txt.
Chapter 11: Data structures
diff --git a/Documentation/DocBook/gadget.tmpl b/Documentation/DocBook/gadget.tmpl
index e7fc964..6996d97 100644
--- a/Documentation/DocBook/gadget.tmpl
+++ b/Documentation/DocBook/gadget.tmpl
@@ -52,7 +52,7 @@
<toc></toc>
-<chapter><title>Introduction</title>
+<chapter id="intro"><title>Introduction</title>
<para>This document presents a Linux-USB "Gadget"
kernel mode
diff --git a/Documentation/DocBook/usb.tmpl b/Documentation/DocBook/usb.tmpl
index a2ebd65..af29360 100644
--- a/Documentation/DocBook/usb.tmpl
+++ b/Documentation/DocBook/usb.tmpl
@@ -185,7 +185,7 @@
</chapter>
-<chapter><title>USB-Standard Types</title>
+<chapter id="types"><title>USB-Standard Types</title>
<para>In <filename><linux/usb/ch9.h></filename> you will find
the USB data types defined in chapter 9 of the USB specification.
@@ -197,7 +197,7 @@
</chapter>
-<chapter><title>Host-Side Data Types and Macros</title>
+<chapter id="hostside"><title>Host-Side Data Types and Macros</title>
<para>The host side API exposes several layers to drivers, some of
which are more necessary than others.
@@ -211,7 +211,7 @@
</chapter>
- <chapter><title>USB Core APIs</title>
+ <chapter id="usbcore"><title>USB Core APIs</title>
<para>There are two basic I/O models in the USB API.
The most elemental one is asynchronous: drivers submit requests
@@ -248,7 +248,7 @@
!Edrivers/usb/core/hub.c
</chapter>
- <chapter><title>Host Controller APIs</title>
+ <chapter id="hcd"><title>Host Controller APIs</title>
<para>These APIs are only for use by host controller drivers,
most of which implement standard register interfaces such as
@@ -285,7 +285,7 @@
!Idrivers/usb/core/buffer.c
</chapter>
- <chapter>
+ <chapter id="usbfs">
<title>The USB Filesystem (usbfs)</title>
<para>This chapter presents the Linux <emphasis>usbfs</emphasis>.
@@ -317,7 +317,7 @@
not it has a kernel driver.
</para>
- <sect1>
+ <sect1 id="usbfs-files">
<title>What files are in "usbfs"?</title>
<para>Conventionally mounted at
@@ -356,7 +356,7 @@
</sect1>
- <sect1>
+ <sect1 id="usbfs-fstab">
<title>Mounting and Access Control</title>
<para>There are a number of mount options for usbfs, which will
@@ -439,7 +439,7 @@
</sect1>
- <sect1>
+ <sect1 id="usbfs-devices">
<title>/proc/bus/usb/devices</title>
<para>This file is handy for status viewing tools in user
@@ -473,7 +473,7 @@
</para>
</sect1>
- <sect1>
+ <sect1 id="usbfs-bbbddd">
<title>/proc/bus/usb/BBB/DDD</title>
<para>Use these files in one of these basic ways:
@@ -510,7 +510,7 @@
</sect1>
- <sect1>
+ <sect1 id="usbfs-lifecycle">
<title>Life Cycle of User Mode Drivers</title>
<para>Such a driver first needs to find a device file
@@ -565,7 +565,7 @@
</sect1>
- <sect1><title>The ioctl() Requests</title>
+ <sect1 id="usbfs-ioctl"><title>The ioctl() Requests</title>
<para>To use these ioctls, you need to include the following
headers in your userspace program:
@@ -604,7 +604,7 @@
</para>
- <sect2>
+ <sect2 id="usbfs-mgmt">
<title>Management/Status Requests</title>
<para>A number of usbfs requests don't deal very directly
@@ -736,7 +736,7 @@
</sect2>
- <sect2>
+ <sect2 id="usbfs-sync">
<title>Synchronous I/O Support</title>
<para>Synchronous requests involve the kernel blocking
@@ -865,7 +865,7 @@
</variablelist>
</sect2>
- <sect2>
+ <sect2 id="usbfs-async">
<title>Asynchronous I/O Support</title>
<para>As mentioned above, there are situations where it may be
diff --git a/Documentation/HOWTO b/Documentation/HOWTO
index 48123db..ced9207 100644
--- a/Documentation/HOWTO
+++ b/Documentation/HOWTO
@@ -396,26 +396,6 @@
-Managing bug reports
---------------------
-
-One of the best ways to put into practice your hacking skills is by fixing
-bugs reported by other people. Not only you will help to make the kernel
-more stable, you'll learn to fix real world problems and you will improve
-your skills, and other developers will be aware of your presence. Fixing
-bugs is one of the best ways to get merits among other developers, because
-not many people like wasting time fixing other people's bugs.
-
-To work in the already reported bug reports, go to http://bugzilla.kernel.org.
-If you want to be advised of the future bug reports, you can subscribe to the
-bugme-new mailing list (only new bug reports are mailed here) or to the
-bugme-janitor mailing list (every change in the bugzilla is mailed here)
-
- http://lists.osdl.org/mailman/listinfo/bugme-new
- http://lists.osdl.org/mailman/listinfo/bugme-janitors
-
-
-
Mailing lists
-------------
diff --git a/Documentation/block/capability.txt b/Documentation/block/capability.txt
new file mode 100644
index 0000000..2f17294
--- /dev/null
+++ b/Documentation/block/capability.txt
@@ -0,0 +1,15 @@
+Generic Block Device Capability
+===============================================================================
+This file documents the sysfs file block/<disk>/capability
+
+capability is a hex word indicating which capabilities a specific disk
+supports. For more information on bits not listed here, see
+include/linux/genhd.h
+
+Capability Value
+-------------------------------------------------------------------------------
+GENHD_FL_MEDIA_CHANGE_NOTIFY 4
+ When this bit is set, the disk supports Asynchronous Notification
+ of media change events. These events will be broadcast to user
+ space via kernel uevent.
+
diff --git a/Documentation/dontdiff b/Documentation/dontdiff
index 64e9f6c..595a5ea 100644
--- a/Documentation/dontdiff
+++ b/Documentation/dontdiff
@@ -10,10 +10,12 @@
*.grp
*.gz
*.html
+*.i
*.jpeg
*.ko
*.log
*.lst
+*.moc
*.mod.c
*.o
*.orig
@@ -25,6 +27,9 @@
*.s
*.sgml
*.so
+*.symtypes
+*.tab.c
+*.tab.h
*.tex
*.ver
*.xml
@@ -32,9 +37,13 @@
*_vga16.c
*cscope*
*~
+*.9
+*.9.gz
.*
.cscope
53c700_d.h
+53c7xx_d.h
+53c7xx_u.h
53c8xx_d.h*
BitKeeper
COPYING
@@ -70,9 +79,11 @@
classlist.h*
comp*.log
compile.h*
+conf
config
config-*
config_data.h*
+config_data.gz*
conmakehash
consolemap_deftbl.c*
crc32table.h*
@@ -81,18 +92,23 @@
devlist.h*
docproc
dummy_sym.c*
+elf2ecoff
elfconfig.h*
filelist
fixdep
fore200e_mkfirm
fore200e_pca_fw.c*
+gconf
gen-devlist
gen-kdb_cmds.c*
gen_crc32table
gen_init_cpio
genksyms
gentbl
+*_gray256.c
ikconfig.h*
+initramfs_data.cpio
+initramfs_data.cpio.gz
initramfs_list
kallsyms
kconfig
@@ -100,19 +116,30 @@
keywords.c*
ksym.c*
ksym.h*
+kxgettext
+lkc_defs.h
lex.c*
+lex.*.c
+lk201-map.c
logo_*.c
logo_*_clut224.c
logo_*_mono.c
lxdialog
mach-types
mach-types.h
+machtypes.h
make_times_h
map
maui_boot.h
+mconf
+miboot*
mk_elfconfig
+mkboot
+mkbugboot
mkdep
+mkprep
mktables
+mktree
modpost
modversions.h*
offset.h
@@ -120,18 +147,28 @@
oui.c*
parse.c*
parse.h*
+patches*
+pca200e.bin
+pca200e_ecd.bin2
+piggy.gz
+piggyback
pnmtologo
ppc_defs.h*
promcon_tbl.c*
pss_boot.h
+qconf
raid6altivec*.c
raid6int*.c
raid6tables.c
+relocs
+series
setup
sim710_d.h*
+sImage
sm_tbl*
split-include
tags
+tftpboot.img
times.h*
tkparse
trix_boot.h
@@ -139,8 +176,11 @@
version.h*
vmlinux
vmlinux-*
+vmlinux.aout
vmlinux.lds
vsyscall.lds
wanxlfw.inc
uImage
-zImage
+unifdef
+zImage*
+zconf.hash.c
diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt
index 5c8695a..2d7ea850 100644
--- a/Documentation/feature-removal-schedule.txt
+++ b/Documentation/feature-removal-schedule.txt
@@ -62,7 +62,7 @@
What: old NCR53C9x driver
When: October 2007
Why: Replaced by the much better esp_scsi driver. Actual low-level
- driver can ported over almost trivially.
+ driver can be ported over almost trivially.
Who: David Miller <davem@davemloft.net>
Christoph Hellwig <hch@lst.de>
diff --git a/Documentation/filesystems/directory-locking b/Documentation/filesystems/directory-locking
index d7099a9..ff7b611 100644
--- a/Documentation/filesystems/directory-locking
+++ b/Documentation/filesystems/directory-locking
@@ -1,5 +1,6 @@
Locking scheme used for directory operations is based on two
-kinds of locks - per-inode (->i_sem) and per-filesystem (->s_vfs_rename_sem).
+kinds of locks - per-inode (->i_mutex) and per-filesystem
+(->s_vfs_rename_mutex).
For our purposes all operations fall in 5 classes:
@@ -63,7 +64,7 @@
attempt to acquire some lock and already holds at least one lock. Let's
consider the set of contended locks. First of all, filesystem lock is
not contended, since any process blocked on it is not holding any locks.
-Thus all processes are blocked on ->i_sem.
+Thus all processes are blocked on ->i_mutex.
Non-directory objects are not contended due to (3). Thus link
creation can't be a part of deadlock - it can't be blocked on source
diff --git a/Documentation/filesystems/porting b/Documentation/filesystems/porting
index 5531694..dac45c9 100644
--- a/Documentation/filesystems/porting
+++ b/Documentation/filesystems/porting
@@ -107,7 +107,7 @@
---
[informational]
-->link() callers hold ->i_sem on the object we are linking to. Some of your
+->link() callers hold ->i_mutex on the object we are linking to. Some of your
problems might be over...
---
@@ -130,9 +130,9 @@
---
[mandatory]
-->setattr() is called without BKL now. Caller _always_ holds ->i_sem, so
-watch for ->i_sem-grabbing code that might be used by your ->setattr().
-Callers of notify_change() need ->i_sem now.
+->setattr() is called without BKL now. Caller _always_ holds ->i_mutex, so
+watch for ->i_mutex-grabbing code that might be used by your ->setattr().
+Callers of notify_change() need ->i_mutex now.
---
[recommended]
diff --git a/Documentation/i386/boot.txt b/Documentation/i386/boot.txt
index 66fa67f..35985b3 100644
--- a/Documentation/i386/boot.txt
+++ b/Documentation/i386/boot.txt
@@ -2,7 +2,7 @@
----------------------------
H. Peter Anvin <hpa@zytor.com>
- Last update 2007-05-16
+ Last update 2007-05-23
On the i386 platform, the Linux kernel uses a rather complicated boot
convention. This has evolved partially due to historical aspects, as
@@ -202,6 +202,8 @@
nonstandard address should fill in the fields marked (reloc); other
boot loaders can ignore those fields.
+The byte order of all fields is littleendian (this is x86, after all.)
+
Field name: setup_secs
Type: read
Offset/size: 0x1f1/1
@@ -280,14 +282,16 @@
Offset/size: 0x206/2
Protocol: 2.00+
- Contains the boot protocol version, e.g. 0x0204 for version 2.04.
+ Contains the boot protocol version, in (major << 8)+minor format,
+ e.g. 0x0204 for version 2.04, and 0x0a11 for a hypothetical version
+ 10.17.
Field name: readmode_swtch
Type: modify (optional)
Offset/size: 0x208/4
Protocol: 2.00+
- Boot loader hook (see separate chapter.)
+ Boot loader hook (see ADVANCED BOOT LOADER HOOKS below.)
Field name: start_sys
Type: read
@@ -304,10 +308,17 @@
If set to a nonzero value, contains a pointer to a NUL-terminated
human-readable kernel version number string, less 0x200. This can
be used to display the kernel version to the user. This value
- should be less than (0x200*setup_sects). For example, if this value
- is set to 0x1c00, the kernel version number string can be found at
- offset 0x1e00 in the kernel file. This is a valid value if and only
- if the "setup_sects" field contains the value 14 or higher.
+ should be less than (0x200*setup_sects).
+
+ For example, if this value is set to 0x1c00, the kernel version
+ number string can be found at offset 0x1e00 in the kernel file.
+ This is a valid value if and only if the "setup_sects" field
+ contains the value 15 or higher, as:
+
+ 0x1c00 < 15*0x200 (= 0x1e00) but
+ 0x1c00 >= 14*0x200 (= 0x1c00)
+
+ 0x1c00 >> 9 = 14, so the minimum value for setup_secs is 15.
Field name: type_of_loader
Type: write (obligatory)
@@ -377,7 +388,7 @@
This field can be modified for two purposes:
- 1. as a boot loader hook (see separate chapter.)
+ 1. as a boot loader hook (see ADVANCED BOOT LOADER HOOKS below.)
2. if a bootloader which does not install a hook loads a
relocatable kernel at a nonstandard address it will have to modify
@@ -715,7 +726,7 @@
a demand-loaded module!
-**** ADVANCED BOOT TIME HOOKS
+**** ADVANCED BOOT LOADER HOOKS
If the boot loader runs in a particularly hostile environment (such as
LOADLIN, which runs under DOS) it may be impossible to follow the
@@ -740,4 +751,5 @@
set them up to BOOT_DS (0x18) yourself.
After completing your hook, you should jump to the address
- that was in this field before your boot loader overwrote it.
+ that was in this field before your boot loader overwrote it
+ (relocated, if appropriate.)
diff --git a/Documentation/initrd.txt b/Documentation/initrd.txt
index 15f1b35..d3dc505 100644
--- a/Documentation/initrd.txt
+++ b/Documentation/initrd.txt
@@ -27,16 +27,20 @@
1) the boot loader loads the kernel and the initial RAM disk
2) the kernel converts initrd into a "normal" RAM disk and
frees the memory used by initrd
- 3) initrd is mounted read-write as root
- 4) /linuxrc is executed (this can be any valid executable, including
+ 3) if the root device is not /dev/ram0, the old (deprecated)
+ change_root procedure is followed. see the "Obsolete root change
+ mechanism" section below.
+ 4) root device is mounted. if it is /dev/ram0, the initrd image is
+ then mounted as root
+ 5) /sbin/init is executed (this can be any valid executable, including
shell scripts; it is run with uid 0 and can do basically everything
- init can do)
- 5) linuxrc mounts the "real" root file system
- 6) linuxrc places the root file system at the root directory using the
+ init can do).
+ 6) init mounts the "real" root file system
+ 7) init places the root file system at the root directory using the
pivot_root system call
- 7) the usual boot sequence (e.g. invocation of /sbin/init) is performed
- on the root file system
- 8) the initrd file system is removed
+ 8) init execs the /sbin/init on the new root filesystem, performing
+ the usual boot sequence
+ 9) the initrd file system is removed
Note that changing the root directory does not involve unmounting it.
It is therefore possible to leave processes running on initrd during that
@@ -70,7 +74,7 @@
root=/dev/ram0
initrd is mounted as root, and the normal boot procedure is followed,
- with the RAM disk still mounted as root.
+ with the RAM disk mounted as root.
Compressed cpio images
----------------------
@@ -137,11 +141,11 @@
# mkdir /mnt/dev
# mknod /mnt/dev/console c 5 1
5) copy all the files that are needed to properly use the initrd
- environment. Don't forget the most important file, /linuxrc
- Note that /linuxrc's permissions must include "x" (execute).
+ environment. Don't forget the most important file, /sbin/init
+ Note that /sbin/init's permissions must include "x" (execute).
6) correct operation the initrd environment can frequently be tested
even without rebooting with the command
- # chroot /mnt /linuxrc
+ # chroot /mnt /sbin/init
This is of course limited to initrds that do not interfere with the
general system state (e.g. by reconfiguring network interfaces,
overwriting mounted devices, trying to start already running demons,
@@ -154,7 +158,7 @@
# gzip -9 initrd
For experimenting with initrd, you may want to take a rescue floppy and
-only add a symbolic link from /linuxrc to /bin/sh. Alternatively, you
+only add a symbolic link from /sbin/init to /bin/sh. Alternatively, you
can try the experimental newlib environment [2] to create a small
initrd.
@@ -163,15 +167,14 @@
with an older mechanism, the following boot command line parameters
have to be given:
- root=/dev/ram0 init=/linuxrc rw
+ root=/dev/ram0 rw
(rw is only necessary if writing to the initrd file system.)
With LOADLIN, you simply execute
LOADLIN <kernel> initrd=<disk_image>
-e.g. LOADLIN C:\LINUX\BZIMAGE initrd=C:\LINUX\INITRD.GZ root=/dev/ram0
- init=/linuxrc rw
+e.g. LOADLIN C:\LINUX\BZIMAGE initrd=C:\LINUX\INITRD.GZ root=/dev/ram0 rw
With LILO, you add the option INITRD=<path> to either the global section
or to the section of the respective kernel in /etc/lilo.conf, and pass
@@ -179,7 +182,7 @@
image = /bzImage
initrd = /boot/initrd.gz
- append = "root=/dev/ram0 init=/linuxrc rw"
+ append = "root=/dev/ram0 rw"
and run /sbin/lilo
@@ -191,7 +194,7 @@
Changing the root device
------------------------
-When finished with its duties, linuxrc typically changes the root device
+When finished with its duties, init typically changes the root device
and proceeds with starting the Linux system on the "real" root device.
The procedure involves the following steps:
@@ -217,7 +220,7 @@
# mkdir initrd
# pivot_root . initrd
-Now, the linuxrc process may still access the old root via its
+Now, the init process may still access the old root via its
executable, shared libraries, standard input/output/error, and its
current root directory. All these references are dropped by the
following command:
@@ -249,10 +252,6 @@
It is also possible to use initrd with an NFS-mounted root, see the
pivot_root(8) man page for details.
-Note: if linuxrc or any program exec'ed from it terminates for some
-reason, the old change_root mechanism is invoked (see section "Obsolete
-root change mechanism").
-
Usage scenarios
---------------
@@ -264,15 +263,15 @@
1) system boots from floppy or other media with a minimal kernel
(e.g. support for RAM disks, initrd, a.out, and the Ext2 FS) and
loads initrd
- 2) /linuxrc determines what is needed to (1) mount the "real" root FS
+ 2) /sbin/init determines what is needed to (1) mount the "real" root FS
(i.e. device type, device drivers, file system) and (2) the
distribution media (e.g. CD-ROM, network, tape, ...). This can be
done by asking the user, by auto-probing, or by using a hybrid
approach.
- 3) /linuxrc loads the necessary kernel modules
- 4) /linuxrc creates and populates the root file system (this doesn't
+ 3) /sbin/init loads the necessary kernel modules
+ 4) /sbin/init creates and populates the root file system (this doesn't
have to be a very usable system yet)
- 5) /linuxrc invokes pivot_root to change the root file system and
+ 5) /sbin/init invokes pivot_root to change the root file system and
execs - via chroot - a program that continues the installation
6) the boot loader is installed
7) the boot loader is configured to load an initrd with the set of
@@ -291,7 +290,7 @@
such cases, it is desirable to generate only a small set of kernels
(ideally only one) and to keep the system-specific part of configuration
information as small as possible. In this case, a common initrd could be
-generated with all the necessary modules. Then, only /linuxrc or a file
+generated with all the necessary modules. Then, only /sbin/init or a file
read by it would have to be different.
A third scenario are more convenient recovery disks, because information
@@ -337,6 +336,25 @@
the new, supported mechanism is called "pivot_root".
+Mixed change_root and pivot_root mechanism
+------------------------------------------
+
+In case you did not want to use root=/dev/ram0 to trig the pivot_root mechanism,
+you may create both /linuxrc and /sbin/init in your initrd image.
+
+/linuxrc would contain only the following:
+
+#! /bin/sh
+mount -n -t proc proc /proc
+echo 0x0100 >/proc/sys/kernel/real-root-dev
+umount -n /proc
+
+Once linuxrc exited, the kernel would mount again your initrd as root,
+this time executing /sbin/init. Again, it would be duty of this init
+to build the right environment (maybe using the root= device passed on
+the cmdline) before the final execution of the real /sbin/init.
+
+
Resources
---------
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index 09220a1..aae2282 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -396,6 +396,26 @@
clocksource is not available, it defaults to PIT.
Format: { pit | tsc | cyclone | pmtmr }
+ clocksource= [GENERIC_TIME] Override the default clocksource
+ Format: <string>
+ Override the default clocksource and use the clocksource
+ with the name specified.
+ Some clocksource names to choose from, depending on
+ the platform:
+ [all] jiffies (this is the base, fallback clocksource)
+ [ACPI] acpi_pm
+ [ARM] imx_timer1,OSTS,netx_timer,mpu_timer2,
+ pxa_timer,timer3,32k_counter,timer0_1
+ [AVR32] avr32
+ [IA-32] pit,hpet,tsc,vmi-timer;
+ scx200_hrt on Geode; cyclone on IBM x440
+ [MIPS] MIPS
+ [PARISC] cr16
+ [S390] tod
+ [SH] SuperH
+ [SPARC64] tick
+ [X86-64] hpet,tsc
+
code_bytes [IA32] How many bytes of object code to print in an
oops report.
Range: 0 - 8192
@@ -1807,10 +1827,6 @@
time Show timing data prefixed to each printk message line
- clocksource= [GENERIC_TIME] Override the default clocksource
- Override the default clocksource and use the clocksource
- with the name specified.
-
tipar.timeout= [HW,PPT]
Set communications timeout in tenths of a second
(default 15).
diff --git a/Documentation/memory-barriers.txt b/Documentation/memory-barriers.txt
index 58408dd..650657c 100644
--- a/Documentation/memory-barriers.txt
+++ b/Documentation/memory-barriers.txt
@@ -24,7 +24,7 @@
(*) Explicit kernel barriers.
- Compiler barrier.
- - The CPU memory barriers.
+ - CPU memory barriers.
- MMIO write barrier.
(*) Implicit kernel memory barriers.
@@ -265,7 +265,7 @@
ordering over the memory operations on either side of the barrier.
Such enforcement is important because the CPUs and other devices in a system
-can use a variety of tricks to improve performance - including reordering,
+can use a variety of tricks to improve performance, including reordering,
deferral and combination of memory operations; speculative loads; speculative
branch prediction and various types of caching. Memory barriers are used to
override or suppress these tricks, allowing the code to sanely control the
@@ -457,7 +457,7 @@
(Q == &A) implies (D == 1)
(Q == &B) implies (D == 4)
-But! CPU 2's perception of P may be updated _before_ its perception of B, thus
+But! CPU 2's perception of P may be updated _before_ its perception of B, thus
leading to the following situation:
(Q == &B) and (D == 2) ????
@@ -573,7 +573,7 @@
the "weaker" type.
[!] Note that the stores before the write barrier would normally be expected to
-match the loads after the read barrier or data dependency barrier, and vice
+match the loads after the read barrier or the data dependency barrier, and vice
versa:
CPU 1 CPU 2
@@ -588,7 +588,7 @@
EXAMPLES OF MEMORY BARRIER SEQUENCES
------------------------------------
-Firstly, write barriers act as a partial orderings on store operations.
+Firstly, write barriers act as partial orderings on store operations.
Consider the following sequence of events:
CPU 1
@@ -608,15 +608,15 @@
+-------+ : :
| | +------+
| |------>| C=3 | } /\
- | | : +------+ }----- \ -----> Events perceptible
- | | : | A=1 | } \/ to rest of system
+ | | : +------+ }----- \ -----> Events perceptible to
+ | | : | A=1 | } \/ the rest of the system
| | : +------+ }
| CPU 1 | : | B=2 | }
| | +------+ }
| | wwwwwwwwwwwwwwww } <--- At this point the write barrier
| | +------+ } requires all stores prior to the
| | : | E=5 | } barrier to be committed before
- | | : +------+ } further stores may be take place.
+ | | : +------+ } further stores may take place
| |------>| D=4 | }
| | +------+
+-------+ : :
@@ -626,7 +626,7 @@
V
-Secondly, data dependency barriers act as a partial orderings on data-dependent
+Secondly, data dependency barriers act as partial orderings on data-dependent
loads. Consider the following sequence of events:
CPU 1 CPU 2
@@ -975,7 +975,7 @@
barrier();
-This a general barrier - lesser varieties of compiler barrier do not exist.
+This is a general barrier - lesser varieties of compiler barrier do not exist.
The compiler barrier has no direct effect on the CPU, which may then reorder
things however it wishes.
@@ -997,7 +997,7 @@
All CPU memory barriers unconditionally imply compiler barriers.
SMP memory barriers are reduced to compiler barriers on uniprocessor compiled
-systems because it is assumed that a CPU will be appear to be self-consistent,
+systems because it is assumed that a CPU will appear to be self-consistent,
and will order overlapping accesses correctly with respect to itself.
[!] Note that SMP memory barriers _must_ be used to control the ordering of
@@ -1146,9 +1146,9 @@
Therefore, from (1), (2) and (4) an UNLOCK followed by an unconditional LOCK is
equivalent to a full barrier, but a LOCK followed by an UNLOCK is not.
-[!] Note: one of the consequence of LOCKs and UNLOCKs being only one-way
- barriers is that the effects instructions outside of a critical section may
- seep into the inside of the critical section.
+[!] Note: one of the consequences of LOCKs and UNLOCKs being only one-way
+ barriers is that the effects of instructions outside of a critical section
+ may seep into the inside of the critical section.
A LOCK followed by an UNLOCK may not be assumed to be full memory barrier
because it is possible for an access preceding the LOCK to happen after the
@@ -1239,7 +1239,7 @@
UNLOCK M UNLOCK Q
*D = d; *H = h;
-Then there is no guarantee as to what order CPU #3 will see the accesses to *A
+Then there is no guarantee as to what order CPU 3 will see the accesses to *A
through *H occur in, other than the constraints imposed by the separate locks
on the separate CPUs. It might, for example, see:
@@ -1269,12 +1269,12 @@
UNLOCK M [2]
*H = h;
-CPU #3 might see:
+CPU 3 might see:
*E, LOCK M [1], *C, *B, *A, UNLOCK M [1],
LOCK M [2], *H, *F, *G, UNLOCK M [2], *D
-But assuming CPU #1 gets the lock first, it won't see any of:
+But assuming CPU 1 gets the lock first, CPU 3 won't see any of:
*B, *C, *D, *F, *G or *H preceding LOCK M [1]
*A, *B or *C following UNLOCK M [1]
@@ -1327,12 +1327,12 @@
mmiowb();
spin_unlock(Q);
-this will ensure that the two stores issued on CPU #1 appear at the PCI bridge
-before either of the stores issued on CPU #2.
+this will ensure that the two stores issued on CPU 1 appear at the PCI bridge
+before either of the stores issued on CPU 2.
-Furthermore, following a store by a load to the same device obviates the need
-for an mmiowb(), because the load forces the store to complete before the load
+Furthermore, following a store by a load from the same device obviates the need
+for the mmiowb(), because the load forces the store to complete before the load
is performed:
CPU 1 CPU 2
@@ -1363,7 +1363,7 @@
(*) Atomic operations.
- (*) Accessing devices (I/O).
+ (*) Accessing devices.
(*) Interrupts.
@@ -1399,7 +1399,7 @@
(1) read the next pointer from this waiter's record to know as to where the
next waiter record is;
- (4) read the pointer to the waiter's task structure;
+ (2) read the pointer to the waiter's task structure;
(3) clear the task pointer to tell the waiter it has been given the semaphore;
@@ -1407,7 +1407,7 @@
(5) release the reference held on the waiter's task struct.
-In otherwords, it has to perform this sequence of events:
+In other words, it has to perform this sequence of events:
LOAD waiter->list.next;
LOAD waiter->task;
@@ -1502,7 +1502,7 @@
such the implicit memory barrier effects are necessary.
-The following operation are potential problems as they do _not_ imply memory
+The following operations are potential problems as they do _not_ imply memory
barriers, but might be used for implementing such things as UNLOCK-class
operations:
@@ -1517,7 +1517,7 @@
The following also do _not_ imply memory barriers, and so may require explicit
memory barriers under some circumstances (smp_mb__before_atomic_dec() for
-instance)):
+instance):
atomic_add();
atomic_sub();
@@ -1641,8 +1641,8 @@
indeed have special I/O space access cycles and instructions, but many
CPUs don't have such a concept.
- The PCI bus, amongst others, defines an I/O space concept - which on such
- CPUs as i386 and x86_64 cpus readily maps to the CPU's concept of I/O
+ The PCI bus, amongst others, defines an I/O space concept which - on such
+ CPUs as i386 and x86_64 - readily maps to the CPU's concept of I/O
space. However, it may also be mapped as a virtual I/O space in the CPU's
memory map, particularly on those CPUs that don't support alternate I/O
spaces.
@@ -1664,7 +1664,7 @@
i386 architecture machines, for example, this is controlled by way of the
MTRR registers.
- Ordinarily, these will be guaranteed to be fully ordered and uncombined,,
+ Ordinarily, these will be guaranteed to be fully ordered and uncombined,
provided they're not accessing a prefetchable device.
However, intermediary hardware (such as a PCI bridge) may indulge in
@@ -1689,7 +1689,7 @@
(*) ioreadX(), iowriteX()
- These will perform as appropriate for the type of access they're actually
+ These will perform appropriately for the type of access they're actually
doing, be it inX()/outX() or readX()/writeX().
@@ -1705,7 +1705,7 @@
This means that it must be considered that the CPU will execute its instruction
stream in any order it feels like - or even in parallel - provided that if an
-instruction in the stream depends on the an earlier instruction, then that
+instruction in the stream depends on an earlier instruction, then that
earlier instruction must be sufficiently complete[*] before the later
instruction may proceed; in other words: provided that the appearance of
causality is maintained.
@@ -1795,8 +1795,8 @@
become apparent in the same order on those other CPUs.
-Consider dealing with a system that has pair of CPUs (1 & 2), each of which has
-a pair of parallel data caches (CPU 1 has A/B, and CPU 2 has C/D):
+Consider dealing with a system that has a pair of CPUs (1 & 2), each of which
+has a pair of parallel data caches (CPU 1 has A/B, and CPU 2 has C/D):
:
: +--------+
@@ -1835,7 +1835,7 @@
(*) the coherency queue is not flushed by normal loads to lines already
present in the cache, even though the contents of the queue may
- potentially effect those loads.
+ potentially affect those loads.
Imagine, then, that two writes are made on the first CPU, with a write barrier
between them to guarantee that they will appear to reach that CPU's caches in
@@ -1845,7 +1845,7 @@
=============== =============== =======================================
u == 0, v == 1 and p == &u, q == &u
v = 2;
- smp_wmb(); Make sure change to v visible before
+ smp_wmb(); Make sure change to v is visible before
change to p
<A:modify v=2> v is now in cache A exclusively
p = &v;
@@ -1853,7 +1853,7 @@
The write memory barrier forces the other CPUs in the system to perceive that
the local CPU's caches have apparently been updated in the correct order. But
-now imagine that the second CPU that wants to read those values:
+now imagine that the second CPU wants to read those values:
CPU 1 CPU 2 COMMENT
=============== =============== =======================================
@@ -1861,7 +1861,7 @@
q = p;
x = *q;
-The above pair of reads may then fail to happen in expected order, as the
+The above pair of reads may then fail to happen in the expected order, as the
cacheline holding p may get updated in one of the second CPU's caches whilst
the update to the cacheline holding v is delayed in the other of the second
CPU's caches by some other cache event:
@@ -1916,7 +1916,7 @@
Other CPUs may also have split caches, but must coordinate between the various
cachelets for normal memory accesses. The semantics of the Alpha removes the
-need for coordination in absence of memory barriers.
+need for coordination in the absence of memory barriers.
CACHE COHERENCY VS DMA
@@ -1931,10 +1931,10 @@
In addition, the data DMA'd to RAM by a device may be overwritten by dirty
cache lines being written back to RAM from a CPU's cache after the device has
-installed its own data, or cache lines simply present in a CPUs cache may
-simply obscure the fact that RAM has been updated, until at such time as the
-cacheline is discarded from the CPU's cache and reloaded. To deal with this,
-the appropriate part of the kernel must invalidate the overlapping bits of the
+installed its own data, or cache lines present in the CPU's cache may simply
+obscure the fact that RAM has been updated, until at such time as the cacheline
+is discarded from the CPU's cache and reloaded. To deal with this, the
+appropriate part of the kernel must invalidate the overlapping bits of the
cache on each CPU.
See Documentation/cachetlb.txt for more information on cache management.
@@ -1944,7 +1944,7 @@
-----------------------
Memory mapped I/O usually takes place through memory locations that are part of
-a window in the CPU's memory space that have different properties assigned than
+a window in the CPU's memory space that has different properties assigned than
the usual RAM directed window.
Amongst these properties is usually the fact that such accesses bypass the
@@ -1960,7 +1960,7 @@
=========================
A programmer might take it for granted that the CPU will perform memory
-operations in exactly the order specified, so that if a CPU is, for example,
+operations in exactly the order specified, so that if the CPU is, for example,
given the following piece of code to execute:
a = *A;
@@ -1969,7 +1969,7 @@
d = *D;
*E = e;
-They would then expect that the CPU will complete the memory operation for each
+they would then expect that the CPU will complete the memory operation for each
instruction before moving on to the next one, leading to a definite sequence of
operations as seen by external observers in the system:
@@ -1986,8 +1986,8 @@
(*) loads may be done speculatively, and the result discarded should it prove
to have been unnecessary;
- (*) loads may be done speculatively, leading to the result having being
- fetched at the wrong time in the expected sequence of events;
+ (*) loads may be done speculatively, leading to the result having been fetched
+ at the wrong time in the expected sequence of events;
(*) the order of the memory accesses may be rearranged to promote better use
of the CPU buses and caches;
@@ -2069,12 +2069,12 @@
The DEC Alpha CPU is one of the most relaxed CPUs there is. Not only that,
some versions of the Alpha CPU have a split data cache, permitting them to have
-two semantically related cache lines updating at separate times. This is where
+two semantically-related cache lines updated at separate times. This is where
the data dependency barrier really becomes necessary as this synchronises both
caches with the memory coherence system, thus making it seem like pointer
changes vs new data occur in the right order.
-The Alpha defines the Linux's kernel's memory barrier model.
+The Alpha defines the Linux kernel's memory barrier model.
See the subsection on "Cache Coherency" above.
diff --git a/Documentation/spi/spi-summary b/Documentation/spi/spi-summary
index 795fbb4..76ea6c8 100644
--- a/Documentation/spi/spi-summary
+++ b/Documentation/spi/spi-summary
@@ -1,26 +1,30 @@
Overview of Linux kernel SPI support
====================================
-02-Dec-2005
+21-May-2007
What is SPI?
------------
The "Serial Peripheral Interface" (SPI) is a synchronous four wire serial
link used to connect microcontrollers to sensors, memory, and peripherals.
+It's a simple "de facto" standard, not complicated enough to acquire a
+standardization body. SPI uses a master/slave configuration.
The three signal wires hold a clock (SCK, often on the order of 10 MHz),
and parallel data lines with "Master Out, Slave In" (MOSI) or "Master In,
Slave Out" (MISO) signals. (Other names are also used.) There are four
clocking modes through which data is exchanged; mode-0 and mode-3 are most
commonly used. Each clock cycle shifts data out and data in; the clock
-doesn't cycle except when there is data to shift.
+doesn't cycle except when there is a data bit to shift. Not all data bits
+are used though; not every protocol uses those full duplex capabilities.
-SPI masters may use a "chip select" line to activate a given SPI slave
+SPI masters use a fourth "chip select" line to activate a given SPI slave
device, so those three signal wires may be connected to several chips
-in parallel. All SPI slaves support chipselects. Some devices have
+in parallel. All SPI slaves support chipselects; they are usually active
+low signals, labeled nCSx for slave 'x' (e.g. nCS0). Some devices have
other signals, often including an interrupt to the master.
-Unlike serial busses like USB or SMBUS, even low level protocols for
+Unlike serial busses like USB or SMBus, even low level protocols for
SPI slave functions are usually not interoperable between vendors
(except for commodities like SPI memory chips).
@@ -33,6 +37,11 @@
- Some devices may use eight bit words. Others may different word
lengths, such as streams of 12-bit or 20-bit digital samples.
+ - Words are usually sent with their most significant bit (MSB) first,
+ but sometimes the least significant bit (LSB) goes first instead.
+
+ - Sometimes SPI is used to daisy-chain devices, like shift registers.
+
In the same way, SPI slaves will only rarely support any kind of automatic
discovery/enumeration protocol. The tree of slave devices accessible from
a given SPI master will normally be set up manually, with configuration
@@ -44,6 +53,14 @@
Serial Protocol"), PSP ("Programmable Serial Protocol"), and other
related protocols.
+Some chips eliminate a signal line by combining MOSI and MISO, and
+limiting themselves to half-duplex at the hardware level. In fact
+some SPI chips have this signal mode as a strapping option. These
+can be accessed using the same programming interface as SPI, but of
+course they won't handle full duplex transfers. You may find such
+chips described as using "three wire" signaling: SCK, data, nCSx.
+(That data line is sometimes called MOMI or SISO.)
+
Microcontrollers often support both master and slave sides of the SPI
protocol. This document (and Linux) currently only supports the master
side of SPI interactions.
@@ -74,6 +91,32 @@
cards without needing a special purpose MMC/SD/SDIO controller.
+I'm confused. What are these four SPI "clock modes"?
+-----------------------------------------------------
+It's easy to be confused here, and the vendor documentation you'll
+find isn't necessarily helpful. The four modes combine two mode bits:
+
+ - CPOL indicates the initial clock polarity. CPOL=0 means the
+ clock starts low, so the first (leading) edge is rising, and
+ the second (trailing) edge is falling. CPOL=1 means the clock
+ starts high, so the first (leading) edge is falling.
+
+ - CPHA indicates the clock phase used to sample data; CPHA=0 says
+ sample on the leading edge, CPHA=1 means the trailing edge.
+
+ Since the signal needs to stablize before it's sampled, CPHA=0
+ implies that its data is written half a clock before the first
+ clock edge. The chipselect may have made it become available.
+
+Chip specs won't always say "uses SPI mode X" in as many words,
+but their timing diagrams will make the CPOL and CPHA modes clear.
+
+In the SPI mode number, CPOL is the high order bit and CPHA is the
+low order bit. So when a chip's timing diagram shows the clock
+starting low (CPOL=0) and data stabilized for sampling during the
+trailing clock edge (CPHA=1), that's SPI mode 1.
+
+
How do these driver programming interfaces work?
------------------------------------------------
The <linux/spi/spi.h> header file includes kerneldoc, as does the
diff --git a/MAINTAINERS b/MAINTAINERS
index 22ab401..4cc17b9 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -332,6 +332,9 @@
W: http://www.linux-usb.org/SpeedTouch/
S: Maintained
+ALCHEMY AU1XX0 MMC DRIVER
+S: Orphan
+
ALI1563 I2C DRIVER
P: Rudolf Marek
M: r.marek@assembler.cz
@@ -418,6 +421,12 @@
M: spyro@f2s.com
S: Maintained
+ARM PRIMECELL MMCI PL180/1 DRIVER
+P: Russell King
+M: rmk@arm.linux.org.uk
+L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only)
+S: Maintained
+
ARM/ADI ROADRUNNER MACHINE SUPPORT
P: Lennert Buytenhek
M: kernel@wantstofly.org
@@ -649,6 +658,9 @@
W: http://linux-atm.sourceforge.net
S: Maintained
+ATMEL AT91 MCI DRIVER
+S: Orphan
+
ATMEL MACB ETHERNET DRIVER
P: Haavard Skinnemoen
M: hskinnemoen@atmel.com
@@ -2322,7 +2334,7 @@
MEGARAID SCSI DRIVERS
P: Neela Syam Kolli
-M: Neela.Kolli@engenio.com
+M: megaraidlinux@lsi.com
S: linux-scsi@vger.kernel.org
W: http://megaraid.lsilogic.com
S: Maintained
@@ -2380,6 +2392,13 @@
W: http://popies.net/meye/
S: Maintained
+MOTOROLA IMX MMC/SD HOST CONTROLLER INTERFACE DRIVER
+P: Pavel Pisa
+M: ppisa@pikron.com
+L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only)
+W: http://mmc.drzeus.cx/wiki/Controllers/Freescale/SDHC
+S: Maintained
+
MOUSE AND MISC DEVICES [GENERAL]
P: Alessandro Rubini
M: rubini@ipvvis.unipv.it
@@ -2900,6 +2919,9 @@
L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only)
S: Maintained
+PXA MMCI DRIVER
+S: Orphan
+
QLOGIC QLA2XXX FC-SCSI DRIVER
P: Andrew Vasquez
M: linux-driver@qlogic.com
@@ -3416,6 +3438,13 @@
M: oakad@yahoo.com
S: Maintained
+TI OMAP MMC INTERFACE DRIVER
+P: Carlos Aguiar, Anderson Briglia and Syed Khasim
+M: linux-omap-open-source@linux.omap.com
+W: http://linux.omap.com
+W: http://www.muru.com/linux/omap/
+S: Maintained
+
TI OMAP RANDOM NUMBER GENERATOR SUPPORT
P: Deepak Saxena
M: dsaxena@plexity.net
diff --git a/Makefile b/Makefile
index 34210af..562a909 100644
--- a/Makefile
+++ b/Makefile
@@ -1,8 +1,8 @@
VERSION = 2
PATCHLEVEL = 6
SUBLEVEL = 22
-EXTRAVERSION = -rc2
-NAME = Nocturnal Monster Puppy
+EXTRAVERSION = -rc3
+NAME = Jeff Thinks I Should Change This, But To What?
# *DOCUMENTATION*
# To see a list of typical targets execute "make help"
diff --git a/arch/i386/Kconfig b/arch/i386/Kconfig
index c2d54b8..8770a5d 100644
--- a/arch/i386/Kconfig
+++ b/arch/i386/Kconfig
@@ -891,7 +891,7 @@
Don't change this unless you know what you are doing.
config HOTPLUG_CPU
- bool "Support for hot-pluggable CPUs (EXPERIMENTAL)"
+ bool "Support for suspend on SMP and hot-pluggable CPUs (EXPERIMENTAL)"
depends on SMP && HOTPLUG && EXPERIMENTAL && !X86_VOYAGER
---help---
Say Y here to experiment with turning CPUs off and on, and to
diff --git a/arch/i386/mach-generic/bigsmp.c b/arch/i386/mach-generic/bigsmp.c
index e932d34..58a477b 100644
--- a/arch/i386/mach-generic/bigsmp.c
+++ b/arch/i386/mach-generic/bigsmp.c
@@ -21,7 +21,7 @@
static int dmi_bigsmp; /* can be set by dmi scanners */
-static __init int hp_ht_bigsmp(struct dmi_system_id *d)
+static int hp_ht_bigsmp(struct dmi_system_id *d)
{
#ifdef CONFIG_X86_GENERICARCH
printk(KERN_NOTICE "%s detected: force use of apic=bigsmp\n", d->ident);
@@ -31,7 +31,7 @@
}
-static struct dmi_system_id __initdata bigsmp_dmi_table[] = {
+static struct dmi_system_id bigsmp_dmi_table[] = {
{ hp_ht_bigsmp, "HP ProLiant DL760 G2", {
DMI_MATCH(DMI_BIOS_VENDOR, "HP"),
DMI_MATCH(DMI_BIOS_VERSION, "P44-"),
@@ -45,7 +45,7 @@
};
-static int __init probe_bigsmp(void)
+static int probe_bigsmp(void)
{
if (def_to_bigsmp)
dmi_bigsmp = 1;
diff --git a/arch/ia64/kernel/acpi-processor.c b/arch/ia64/kernel/acpi-processor.c
index 4d4993a..5a216c0 100644
--- a/arch/ia64/kernel/acpi-processor.c
+++ b/arch/ia64/kernel/acpi-processor.c
@@ -44,7 +44,7 @@
buf[0] = ACPI_PDC_REVISION_ID;
buf[1] = 1;
- buf[2] |= ACPI_PDC_EST_CAPABILITY_SMP;
+ buf[2] = ACPI_PDC_EST_CAPABILITY_SMP;
obj->type = ACPI_TYPE_BUFFER;
obj->buffer.length = 12;
diff --git a/arch/ia64/kernel/acpi.c b/arch/ia64/kernel/acpi.c
index c478449..103dd8e 100644
--- a/arch/ia64/kernel/acpi.c
+++ b/arch/ia64/kernel/acpi.c
@@ -67,7 +67,8 @@
unsigned int acpi_cpei_override;
unsigned int acpi_cpei_phys_cpuid;
-const char *acpi_get_sysname(void)
+const char __init *
+acpi_get_sysname(void)
{
#ifdef CONFIG_IA64_GENERIC
unsigned long rsdp_phys;
diff --git a/arch/ia64/kernel/process.c b/arch/ia64/kernel/process.c
index d1c3ed9..af73b8d 100644
--- a/arch/ia64/kernel/process.c
+++ b/arch/ia64/kernel/process.c
@@ -763,6 +763,9 @@
unsigned long ip;
int count = 0;
+ if (!p || p == current || p->state == TASK_RUNNING)
+ return 0;
+
/*
* Note: p may not be a blocked task (it could be current or
* another process running on some other CPU. Rather than
@@ -773,6 +776,8 @@
*/
unw_init_from_blocked_task(&info, p);
do {
+ if (p->state == TASK_RUNNING)
+ return 0;
if (unw_unwind(&info) < 0)
return 0;
unw_get_ip(&info, &ip);
diff --git a/arch/ia64/kernel/smpboot.c b/arch/ia64/kernel/smpboot.c
index 5429580..3c9d8e6 100644
--- a/arch/ia64/kernel/smpboot.c
+++ b/arch/ia64/kernel/smpboot.c
@@ -370,7 +370,7 @@
{
}
-static void __devinit
+static void __cpuinit
smp_callin (void)
{
int cpuid, phys_id, itc_master;
@@ -456,7 +456,7 @@
/*
* Activate a secondary processor. head.S calls this.
*/
-int __devinit
+int __cpuinit
start_secondary (void *unused)
{
/* Early console may use I/O ports */
diff --git a/arch/ia64/kernel/unwind.c b/arch/ia64/kernel/unwind.c
index 7d3dd6c..b0b08b5 100644
--- a/arch/ia64/kernel/unwind.c
+++ b/arch/ia64/kernel/unwind.c
@@ -1860,7 +1860,7 @@
unw_unwind (struct unw_frame_info *info)
{
unsigned long prev_ip, prev_sp, prev_bsp;
- unsigned long ip, pr, num_regs;
+ unsigned long ip, pr, num_regs, rp_loc, pfs_loc;
STAT(unsigned long start, flags;)
int retval;
@@ -1870,14 +1870,16 @@
prev_sp = info->sp;
prev_bsp = info->bsp;
- /* restore the ip */
- if (!info->rp_loc) {
+ /* validate the return IP pointer */
+ rp_loc = (unsigned long) info->rp_loc;
+ if ((rp_loc < info->regstk.limit) || (rp_loc > info->regstk.top)) {
/* 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);
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);
@@ -1885,12 +1887,14 @@
return -1;
}
- /* restore the cfm: */
- if (!info->pfs_loc) {
+ /* validate the previous stack frame pointer */
+ pfs_loc = (unsigned long) info->pfs_loc;
+ if ((pfs_loc < info->regstk.limit) || (pfs_loc > info->regstk.top)) {
UNW_DPRINT(0, "unwind.%s: failed to locate ar.pfs!\n", __FUNCTION__);
STAT(unw.stat.api.unwind_time += ia64_get_itc() - start; local_irq_restore(flags));
return -1;
}
+ /* restore the cfm: */
info->cfm_loc = info->pfs_loc;
/* restore the bsp: */
@@ -1992,13 +1996,16 @@
memset(info, 0, sizeof(*info));
rbslimit = (unsigned long) t + IA64_RBS_OFFSET;
+ stklimit = (unsigned long) t + IA64_STK_OFFSET;
+
rbstop = sw->ar_bspstore;
- if (rbstop - (unsigned long) t >= IA64_STK_OFFSET)
+ if (rbstop > stklimit || rbstop < rbslimit)
rbstop = rbslimit;
- stklimit = (unsigned long) t + IA64_STK_OFFSET;
if (stktop <= rbstop)
stktop = rbstop;
+ if (stktop > stklimit)
+ stktop = stklimit;
info->regstk.limit = rbslimit;
info->regstk.top = rbstop;
diff --git a/arch/ia64/pci/pci.c b/arch/ia64/pci/pci.c
index 3549f3b..73696b4a 100644
--- a/arch/ia64/pci/pci.c
+++ b/arch/ia64/pci/pci.c
@@ -354,10 +354,13 @@
acpi_walk_resources(device->handle, METHOD_NAME__CRS, count_window,
&windows);
- controller->window = kmalloc_node(sizeof(*controller->window) * windows,
- GFP_KERNEL, controller->node);
- if (!controller->window)
- goto out2;
+ if (windows) {
+ controller->window =
+ kmalloc_node(sizeof(*controller->window) * windows,
+ GFP_KERNEL, controller->node);
+ if (!controller->window)
+ goto out2;
+ }
name = kmalloc(16, GFP_KERNEL);
if (!name)
diff --git a/arch/ia64/sn/kernel/setup.c b/arch/ia64/sn/kernel/setup.c
index a574fcd..684b1c9 100644
--- a/arch/ia64/sn/kernel/setup.c
+++ b/arch/ia64/sn/kernel/setup.c
@@ -194,7 +194,7 @@
}
extern int platform_intr_list[];
-static int __initdata shub_1_1_found;
+static int __cpuinitdata shub_1_1_found;
/*
* sn_check_for_wars
diff --git a/arch/mips/sgi-ip32/Makefile b/arch/mips/sgi-ip32/Makefile
index 7e14167..60f0227 100644
--- a/arch/mips/sgi-ip32/Makefile
+++ b/arch/mips/sgi-ip32/Makefile
@@ -3,5 +3,5 @@
# under Linux.
#
-obj-y += ip32-berr.o ip32-irq.o ip32-setup.o ip32-reset.o \
+obj-y += ip32-berr.o ip32-irq.o ip32-platform.o ip32-setup.o ip32-reset.o \
crime.o ip32-memory.o
diff --git a/arch/mips/sgi-ip32/ip32-platform.c b/arch/mips/sgi-ip32/ip32-platform.c
new file mode 100644
index 0000000..120b159
--- /dev/null
+++ b/arch/mips/sgi-ip32/ip32-platform.c
@@ -0,0 +1,20 @@
+#include <linux/init.h>
+#include <linux/platform_device.h>
+
+static __init int meth_devinit(void)
+{
+ struct platform_device *pd;
+ int ret;
+
+ pd = platform_device_alloc("meth", -1);
+ if (!pd)
+ return -ENOMEM;
+
+ ret = platform_device_add(pd);
+ if (ret)
+ platform_device_put(pd);
+
+ return ret;
+}
+
+device_initcall(meth_devinit);
diff --git a/arch/sh/boards/landisk/gio.c b/arch/sh/boards/landisk/gio.c
index 50d38be..a37643d 100644
--- a/arch/sh/boards/landisk/gio.c
+++ b/arch/sh/boards/landisk/gio.c
@@ -69,7 +69,7 @@
}
switch (cmd) {
- case GIODRV_IOCSGIOSETADDR: /* addres set */
+ case GIODRV_IOCSGIOSETADDR: /* address set */
addr = data;
break;
diff --git a/arch/sh/boards/landisk/setup.c b/arch/sh/boards/landisk/setup.c
index 4058b4f..f953c74 100644
--- a/arch/sh/boards/landisk/setup.c
+++ b/arch/sh/boards/landisk/setup.c
@@ -44,8 +44,14 @@
},
};
+static struct platform_device rtc_device = {
+ .name = "rs5c313",
+ .id = -1,
+};
+
static struct platform_device *landisk_devices[] __initdata = {
&cf_ide_device,
+ &rtc_device,
};
static int __init landisk_devices_setup(void)
diff --git a/arch/sh/boards/renesas/r7780rp/Makefile b/arch/sh/boards/renesas/r7780rp/Makefile
index 609e5d5..b1d20af 100644
--- a/arch/sh/boards/renesas/r7780rp/Makefile
+++ b/arch/sh/boards/renesas/r7780rp/Makefile
@@ -3,5 +3,8 @@
#
irqinit-y := irq-r7780rp.o
irqinit-$(CONFIG_SH_R7785RP) := irq-r7785rp.o
+obj-y := setup.o irq.o $(irqinit-y)
+
+ifneq ($(CONFIG_SH_R7785RP),y)
obj-$(CONFIG_PUSH_SWITCH) += psw.o
-obj-y := setup.o irq.o $(irqinit-y)
+endif
diff --git a/arch/sh/boards/snapgear/rtc.c b/arch/sh/boards/snapgear/rtc.c
index 1659fdd..edb3dd9 100644
--- a/arch/sh/boards/snapgear/rtc.c
+++ b/arch/sh/boards/snapgear/rtc.c
@@ -108,7 +108,7 @@
static void ds1302_reset(void)
{
unsigned long flags;
- /* Hardware dependant reset/init */
+ /* Hardware dependent reset/init */
local_irq_save(flags);
set_dirp(get_dirp() | RTC_RESET | RTC_IODATA | RTC_SCLK);
set_dp(get_dp() & ~(RTC_RESET | RTC_IODATA | RTC_SCLK));
diff --git a/arch/sh/boards/superh/microdev/io.c b/arch/sh/boards/superh/microdev/io.c
index 83419bf..b704e20 100644
--- a/arch/sh/boards/superh/microdev/io.c
+++ b/arch/sh/boards/superh/microdev/io.c
@@ -198,12 +198,12 @@
/*
* There is a board feature with the current SH4-202 MicroDev in
* that the 2 byte enables (nBE0 and nBE1) are tied together (and
- * to the Chip Select Line (Ethernet_CS)). Due to this conectivity,
+ * to the Chip Select Line (Ethernet_CS)). Due to this connectivity,
* it is not possible to safely perform 8-bit writes to the
* Ethernet registers, as 16-bits will be consumed from the Data
* lines (corrupting the other byte). Hence, this function is
- * written to impliment 16-bit read/modify/write for all byte-wide
- * acceses.
+ * written to implement 16-bit read/modify/write for all byte-wide
+ * accesses.
*
* Note: there is no problem with byte READS (even or odd).
*
diff --git a/arch/sh/boards/superh/microdev/irq.c b/arch/sh/boards/superh/microdev/irq.c
index 8c64baa..cc1cb04 100644
--- a/arch/sh/boards/superh/microdev/irq.c
+++ b/arch/sh/boards/superh/microdev/irq.c
@@ -100,7 +100,7 @@
fpgaIrq = fpgaIrqTable[irq].fpgaIrq;
- /* disable interupts on the FPGA INTC register */
+ /* disable interrupts on the FPGA INTC register */
ctrl_outl(MICRODEV_FPGA_INTC_MASK(fpgaIrq), MICRODEV_FPGA_INTDSB_REG);
}
@@ -125,7 +125,7 @@
priorities |= MICRODEV_FPGA_INTPRI_LEVEL(fpgaIrq, pri);
ctrl_outl(priorities, priorityReg);
- /* enable interupts on the FPGA INTC register */
+ /* enable interrupts on the FPGA INTC register */
ctrl_outl(MICRODEV_FPGA_INTC_MASK(fpgaIrq), MICRODEV_FPGA_INTENB_REG);
}
@@ -152,7 +152,7 @@
{
int i;
- /* disable interupts on the FPGA INTC register */
+ /* disable interrupts on the FPGA INTC register */
ctrl_outl(~0ul, MICRODEV_FPGA_INTDSB_REG);
for (i = 0; i < NUM_EXTERNAL_IRQS; i++)
diff --git a/arch/sh/boards/superh/microdev/setup.c b/arch/sh/boards/superh/microdev/setup.c
index 031c814..6396cea 100644
--- a/arch/sh/boards/superh/microdev/setup.c
+++ b/arch/sh/boards/superh/microdev/setup.c
@@ -349,7 +349,7 @@
SMSC_WRITE_INDEXED(0x00, 0xc7); /* GP47 = nIOWOP */
SMSC_WRITE_INDEXED(0x08, 0xe8); /* GP20 = nIDE2_OE */
- /* Exit the configuraton state */
+ /* Exit the configuration state */
outb(SMSC_EXIT_CONFIG_KEY, SMSC_CONFIG_PORT_ADDR);
return 0;
diff --git a/arch/sh/boards/unknown/setup.c b/arch/sh/boards/unknown/setup.c
index 1c94137..bee4612 100644
--- a/arch/sh/boards/unknown/setup.c
+++ b/arch/sh/boards/unknown/setup.c
@@ -6,7 +6,7 @@
* May be copied or modified under the terms of the GNU General Public
* License. See linux/COPYING for more information.
*
- * Setup code for an unknown machine (internal peripherials only)
+ * Setup code for an unknown machine (internal peripherals only)
*
* This is the simplest of all boards, and serves only as a quick and dirty
* method to start debugging a new board during bring-up until proper board
diff --git a/arch/sh/drivers/dma/dma-api.c b/arch/sh/drivers/dma/dma-api.c
index e062067..8057a27 100644
--- a/arch/sh/drivers/dma/dma-api.c
+++ b/arch/sh/drivers/dma/dma-api.c
@@ -115,7 +115,7 @@
/**
* request_dma_bycap - Allocate a DMA channel based on its capabilities
* @dmac: List of DMA controllers to search
- * @caps: List of capabilites
+ * @caps: List of capabilities
*
* Search all channels of all DMA controllers to find a channel which
* matches the requested capabilities. The result is the channel
diff --git a/arch/sh/drivers/dma/dma-isa.c b/arch/sh/drivers/dma/dma-isa.c
index 05a74ff..5fb044b 100644
--- a/arch/sh/drivers/dma/dma-isa.c
+++ b/arch/sh/drivers/dma/dma-isa.c
@@ -28,7 +28,7 @@
* NOTE: ops->xfer() is the preferred way of doing things. However, there
* are some users of the ISA DMA API that exist in common code that we
* don't necessarily want to go out of our way to break, so we still
- * allow for some compatability at that level. Any new code is strongly
+ * allow for some compatibility at that level. Any new code is strongly
* advised to run far away from the ISA DMA API and use the SH DMA API
* directly.
*/
diff --git a/arch/sh/drivers/dma/dmabrg.c b/arch/sh/drivers/dma/dmabrg.c
index 9d0a293..5e22689 100644
--- a/arch/sh/drivers/dma/dmabrg.c
+++ b/arch/sh/drivers/dma/dmabrg.c
@@ -33,7 +33,7 @@
* 9 | HAC1/SSI1 | rec | half done | DMABRGI2
*
* all can be enabled/disabled in the DMABRGCR register,
- * as well as checked if they occured.
+ * as well as checked if they occurred.
*
* DMABRGI0 services USB DMA Address errors, but it still must be
* enabled/acked in the DMABRGCR register. USB-DMA complete indicator
diff --git a/arch/sh/drivers/pci/ops-dreamcast.c b/arch/sh/drivers/pci/ops-dreamcast.c
index 381306c..e1284fc 100644
--- a/arch/sh/drivers/pci/ops-dreamcast.c
+++ b/arch/sh/drivers/pci/ops-dreamcast.c
@@ -57,7 +57,7 @@
*
* Also, we could very easily support both Type 0 and Type 1 configurations
* here, but since it doesn't seem that there is any such implementation in
- * existance, we don't bother.
+ * existence, we don't bother.
*
* I suppose if someone actually gets around to ripping the chip out of
* the BBA and hanging some more devices off of it, then this might be
diff --git a/arch/sh/drivers/pci/pci-st40.c b/arch/sh/drivers/pci/pci-st40.c
index d67656a..543417f 100644
--- a/arch/sh/drivers/pci/pci-st40.c
+++ b/arch/sh/drivers/pci/pci-st40.c
@@ -292,7 +292,7 @@
PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER |
PCI_COMMAND_IO);
- /* Accesse to the 0xb0000000 -> 0xb6000000 area will go through to 0x10000000 -> 0x16000000
+ /* Access to the 0xb0000000 -> 0xb6000000 area will go through to 0x10000000 -> 0x16000000
* on the PCI bus. This allows a nice 1-1 bus to phys mapping.
*/
@@ -315,7 +315,7 @@
ST40PCI_WRITE(CSR_MBAR0, 0);
ST40PCI_WRITE(LSR0, 0x0fff0001);
- /* ... and set up the initial incomming window to expose all of RAM */
+ /* ... and set up the initial incoming window to expose all of RAM */
pci_set_rbar_region(7, memStart, memStart, memSize);
/* Maximise timeout values */
@@ -473,7 +473,7 @@
mask = r2p2(regionSize) - 0x10000;
- /* Diable the region (in case currently in use, should never happen) */
+ /* Disable the region (in case currently in use, should never happen) */
ST40PCI_WRITE_INDEXED(RSR, region, 0);
/* Start of local address space to publish */
diff --git a/arch/sh/drivers/pci/pci-st40.h b/arch/sh/drivers/pci/pci-st40.h
index d729e0c..cf0d35b 100644
--- a/arch/sh/drivers/pci/pci-st40.h
+++ b/arch/sh/drivers/pci/pci-st40.h
@@ -4,7 +4,7 @@
* May be copied or modified under the terms of the GNU General Public
* License. See linux/COPYING for more information.
*
- * Defintions for the ST40 PCI hardware.
+ * Definitions for the ST40 PCI hardware.
*/
#ifndef __PCI_ST40_H__
diff --git a/arch/sh/drivers/superhyway/ops-sh4-202.c b/arch/sh/drivers/superhyway/ops-sh4-202.c
index a55c98a..3b14bf8 100644
--- a/arch/sh/drivers/superhyway/ops-sh4-202.c
+++ b/arch/sh/drivers/superhyway/ops-sh4-202.c
@@ -130,7 +130,7 @@
* Some modules (PBR and ePBR for instance) also appear to have
* VCRL/VCRH flipped in the documentation, but on the SH4-202
* itself it appears that these are all consistently mapped with
- * VCRH preceeding VCRL.
+ * VCRH preceding VCRL.
*
* Do not trust the documentation, for it is evil.
*/
diff --git a/arch/sh/kernel/cf-enabler.c b/arch/sh/kernel/cf-enabler.c
index 0758d48..849a9e1 100644
--- a/arch/sh/kernel/cf-enabler.c
+++ b/arch/sh/kernel/cf-enabler.c
@@ -31,7 +31,7 @@
*/
#if defined(CONFIG_CPU_SH4)
/* SH4 can't access PCMCIA interface through P2 area.
- * we must remap it with appropreate attribute bit of the page set.
+ * we must remap it with appropriate attribute bit of the page set.
* this part is based on Greg Banks' hd64465_ss.c implementation - Masahiro Abe */
#if defined(CONFIG_CF_AREA6)
diff --git a/arch/sh/kernel/cpu/clock.c b/arch/sh/kernel/cpu/clock.c
index 014f318..6325154 100644
--- a/arch/sh/kernel/cpu/clock.c
+++ b/arch/sh/kernel/cpu/clock.c
@@ -278,6 +278,11 @@
{
}
+void __init __attribute__ ((weak))
+arch_clk_init(void)
+{
+}
+
static int show_clocks(char *buf, char **start, off_t off,
int len, int *eof, void *data)
{
@@ -314,6 +319,8 @@
ret |= clk_register(clk);
}
+ arch_clk_init();
+
/* Kick the child clocks.. */
propagate_rate(&master_clk);
propagate_rate(&bus_clk);
diff --git a/arch/sh/kernel/cpu/irq/maskreg.c b/arch/sh/kernel/cpu/irq/maskreg.c
index 492db31..978992e 100644
--- a/arch/sh/kernel/cpu/irq/maskreg.c
+++ b/arch/sh/kernel/cpu/irq/maskreg.c
@@ -38,7 +38,7 @@
.end = end_maskreg_irq
};
-/* actual implementatin */
+/* actual implementation */
static unsigned int startup_maskreg_irq(unsigned int irq)
{
enable_maskreg_irq(irq);
diff --git a/arch/sh/kernel/cpu/sh4/fpu.c b/arch/sh/kernel/cpu/sh4/fpu.c
index d61dd59..c5a4fc7 100644
--- a/arch/sh/kernel/cpu/sh4/fpu.c
+++ b/arch/sh/kernel/cpu/sh4/fpu.c
@@ -138,7 +138,7 @@
/*
* Load the FPU with signalling NANS. This bit pattern we're using
* has the property that no matter wether considered as single or as
- * double precission represents signaling NANS.
+ * double precision represents signaling NANS.
*/
static void
diff --git a/arch/sh/kernel/cpu/sh4/setup-sh7750.c b/arch/sh/kernel/cpu/sh4/setup-sh7750.c
index 6f8f458..03b14cf 100644
--- a/arch/sh/kernel/cpu/sh4/setup-sh7750.c
+++ b/arch/sh/kernel/cpu/sh4/setup-sh7750.c
@@ -106,6 +106,7 @@
{ 38, 2, 8, 7 }, /* DMAC DMAE */
};
+#ifdef CONFIG_CPU_SUBTYPE_SH7751
static struct ipr_data sh7751_ipr_map[] = {
{ 44, 2, 8, 7 }, /* DMAC DMTE4 */
{ 45, 2, 8, 7 }, /* DMAC DMTE5 */
@@ -117,6 +118,7 @@
/*{ 72, INTPRI00, 8, ? },*/ /* TMU3 TUNI */
/*{ 76, INTPRI00, 12, ? },*/ /* TMU4 TUNI */
};
+#endif
static unsigned long ipr_offsets[] = {
0xffd00004UL, /* 0: IPRA */
diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7722.c b/arch/sh/kernel/cpu/sh4a/clock-sh7722.c
index 2909003..51b386d 100644
--- a/arch/sh/kernel/cpu/sh4a/clock-sh7722.c
+++ b/arch/sh/kernel/cpu/sh4a/clock-sh7722.c
@@ -17,7 +17,6 @@
#include <asm/clock.h>
#include <asm/freq.h>
-#define SH7722_PLL_FREQ (32000000/8)
#define N (-1)
#define NM (-2)
#define ROUND_NEAREST 0
@@ -141,28 +140,36 @@
*/
static int divisors2[] = { 2, 3, 4, 5, 6, 8, 10, 12, 16, 20, 24, 32, 40 };
-static void master_clk_init(struct clk *clk)
+static void master_clk_recalc(struct clk *clk)
{
- clk_set_rate(clk, clk_get_rate(clk));
+ unsigned frqcr = ctrl_inl(FRQCR);
+
+ clk->rate = CONFIG_SH_PCLK_FREQ * (((frqcr >> 24) & 0x1f) + 1);
}
-static void master_clk_recalc(struct clk *clk)
+static void master_clk_init(struct clk *clk)
+{
+ clk->parent = NULL;
+ clk->flags |= CLK_RATE_PROPAGATES;
+ clk->rate = CONFIG_SH_PCLK_FREQ;
+ master_clk_recalc(clk);
+}
+
+
+static void module_clk_recalc(struct clk *clk)
{
unsigned long frqcr = ctrl_inl(FRQCR);
- clk->rate = CONFIG_SH_PCLK_FREQ * (1 + (frqcr >> 24 & 0xF));
+ clk->rate = clk->parent->rate / (((frqcr >> 24) & 0x1f) + 1);
}
static int master_clk_setrate(struct clk *clk, unsigned long rate, int id)
{
- int div = rate / SH7722_PLL_FREQ;
+ int div = rate / clk->rate;
int master_divs[] = { 2, 3, 4, 6, 8, 16 };
int index;
unsigned long frqcr;
- if (rate < SH7722_PLL_FREQ * 2)
- return -EINVAL;
-
for (index = 1; index < ARRAY_SIZE(master_divs); index++)
if (div >= master_divs[index - 1] && div < master_divs[index])
break;
@@ -185,6 +192,10 @@
.set_rate = master_clk_setrate,
};
+static struct clk_ops sh7722_module_clk_ops = {
+ .recalc = module_clk_recalc,
+};
+
struct frqcr_context {
unsigned mask;
unsigned shift;
@@ -489,7 +500,7 @@
if (siu < 0)
return /* siu */ ;
- BUG_ON(siu > 1);
+ BUG_ON(siu > 2);
r = ctrl_inl(sh7722_siu_regs[siu]);
clk->rate = clk->parent->rate * 2 / divisors2[r & 0xF];
}
@@ -571,7 +582,7 @@
*/
struct clk_ops *onchip_ops[] = {
&sh7722_master_clk_ops,
- &sh7722_frqcr_clk_ops,
+ &sh7722_module_clk_ops,
&sh7722_frqcr_clk_ops,
&sh7722_frqcr_clk_ops,
};
@@ -583,7 +594,7 @@
*ops = onchip_ops[type];
}
-int __init sh7722_clock_init(void)
+int __init arch_clk_init(void)
{
struct clk *master;
int i;
@@ -597,4 +608,3 @@
clk_put(master);
return 0;
}
-arch_initcall(sh7722_clock_init);
diff --git a/arch/sh/kernel/kgdb_stub.c b/arch/sh/kernel/kgdb_stub.c
index a532336..edd1ec2 100644
--- a/arch/sh/kernel/kgdb_stub.c
+++ b/arch/sh/kernel/kgdb_stub.c
@@ -2,7 +2,7 @@
* May be copied or modified under the terms of the GNU General Public
* License. See linux/COPYING for more information.
*
- * Containes extracts from code by Glenn Engel, Jim Kingdon,
+ * Contains extracts from code by Glenn Engel, Jim Kingdon,
* David Grothe <dave@gcom.com>, Tigran Aivazian <tigran@sco.com>,
* Amit S. Kale <akale@veritas.com>, William Gatliff <bgat@open-widgets.com>,
* Ben Lee, Steve Chamberlain and Benoit Miller <fulg@iname.com>.
@@ -85,7 +85,7 @@
*
* Responses can be run-length encoded to save space. A '*' means that
* the next character is an ASCII encoding giving a repeat count which
- * stands for that many repititions of the character preceding the '*'.
+ * stands for that many repetitions of the character preceding the '*'.
* The encoding is n+29, yielding a printable character where n >=3
* (which is where RLE starts to win). Don't use an n > 126.
*
diff --git a/arch/sh/kernel/process.c b/arch/sh/kernel/process.c
index 6b4f574..a11e2aa 100644
--- a/arch/sh/kernel/process.c
+++ b/arch/sh/kernel/process.c
@@ -26,8 +26,6 @@
static int hlt_counter;
int ubc_usercnt = 0;
-#define HARD_IDLE_TIMEOUT (HZ / 3)
-
void (*pm_idle)(void);
void (*pm_power_off)(void);
EXPORT_SYMBOL(pm_power_off);
@@ -44,16 +42,39 @@
}
EXPORT_SYMBOL(enable_hlt);
+static int __init nohlt_setup(char *__unused)
+{
+ hlt_counter = 1;
+ return 1;
+}
+__setup("nohlt", nohlt_setup);
+
+static int __init hlt_setup(char *__unused)
+{
+ hlt_counter = 0;
+ return 1;
+}
+__setup("hlt", hlt_setup);
+
void default_idle(void)
{
- if (!hlt_counter)
- cpu_sleep();
- else
- cpu_relax();
+ if (!hlt_counter) {
+ clear_thread_flag(TIF_POLLING_NRFLAG);
+ smp_mb__after_clear_bit();
+ set_bl_bit();
+ while (!need_resched())
+ cpu_sleep();
+ clear_bl_bit();
+ set_thread_flag(TIF_POLLING_NRFLAG);
+ } else
+ while (!need_resched())
+ cpu_relax();
}
void cpu_idle(void)
{
+ set_thread_flag(TIF_POLLING_NRFLAG);
+
/* endless idle loop with no priority at all */
while (1) {
void (*idle)(void) = pm_idle;
diff --git a/arch/sh/kernel/syscalls.S b/arch/sh/kernel/syscalls.S
index 4357d1a..7db1c2d 100644
--- a/arch/sh/kernel/syscalls.S
+++ b/arch/sh/kernel/syscalls.S
@@ -355,3 +355,6 @@
.long sys_getcpu
.long sys_epoll_pwait
.long sys_utimensat /* 320 */
+ .long sys_signalfd
+ .long sys_timerfd
+ .long sys_eventfd
diff --git a/arch/sh/kernel/traps.c b/arch/sh/kernel/traps.c
index 3a19764..5b75cb6 100644
--- a/arch/sh/kernel/traps.c
+++ b/arch/sh/kernel/traps.c
@@ -21,6 +21,7 @@
#include <linux/bug.h>
#include <linux/debug_locks.h>
#include <linux/kdebug.h>
+#include <linux/kexec.h>
#include <linux/limits.h>
#include <asm/system.h>
#include <asm/uaccess.h>
@@ -101,6 +102,16 @@
bust_spinlocks(0);
spin_unlock_irq(&die_lock);
+
+ if (kexec_should_crash(current))
+ crash_kexec(regs);
+
+ if (in_interrupt())
+ panic("Fatal exception in interrupt");
+
+ if (panic_on_oops)
+ panic("Fatal exception");
+
do_exit(SIGSEGV);
}
@@ -513,7 +524,7 @@
* misaligned data access
* access to >= 0x80000000 is user mode
* Unfortuntaly we can't distinguish between instruction address error
- * and data address errors caused by read acceses.
+ * and data address errors caused by read accesses.
*/
asmlinkage void do_address_error(struct pt_regs *regs,
unsigned long writeaccess,
diff --git a/arch/sh/math-emu/math.c b/arch/sh/math-emu/math.c
index 1efbac1..a38e1ee 100644
--- a/arch/sh/math-emu/math.c
+++ b/arch/sh/math-emu/math.c
@@ -148,7 +148,7 @@
return 0;
}
-// to process fmov's extention (odd n for DR access XD).
+// to process fmov's extension (odd n for DR access XD).
#define FMOV_EXT(x) if(x&1) x+=16-1
static int
diff --git a/arch/sh/mm/copy_page.S b/arch/sh/mm/copy_page.S
index 397c94c..ae039f2 100644
--- a/arch/sh/mm/copy_page.S
+++ b/arch/sh/mm/copy_page.S
@@ -129,6 +129,7 @@
rts
nop
#endif
+ .align 2
.Lpsz: .long PAGE_SIZE
/*
* __kernel_size_t __copy_user(void *to, const void *from, __kernel_size_t n);
diff --git a/arch/sh/mm/fault.c b/arch/sh/mm/fault.c
index 9207da6..c878faa 100644
--- a/arch/sh/mm/fault.c
+++ b/arch/sh/mm/fault.c
@@ -15,43 +15,11 @@
#include <linux/mm.h>
#include <linux/hardirq.h>
#include <linux/kprobes.h>
-#include <linux/kdebug.h>
#include <asm/system.h>
#include <asm/mmu_context.h>
#include <asm/tlbflush.h>
#include <asm/kgdb.h>
-#ifdef CONFIG_KPROBES
-ATOMIC_NOTIFIER_HEAD(notify_page_fault_chain);
-
-/* Hook to register for page fault notifications */
-int register_page_fault_notifier(struct notifier_block *nb)
-{
- return atomic_notifier_chain_register(¬ify_page_fault_chain, nb);
-}
-
-int unregister_page_fault_notifier(struct notifier_block *nb)
-{
- return atomic_notifier_chain_unregister(¬ify_page_fault_chain, nb);
-}
-
-static inline int notify_page_fault(enum die_val val, struct pt_regs *regs,
- int trap, int sig)
-{
- struct die_args args = {
- .regs = regs,
- .trapnr = trap,
- };
- return atomic_notifier_call_chain(¬ify_page_fault_chain, val, &args);
-}
-#else
-static inline int notify_page_fault(enum die_val val, struct pt_regs *regs,
- int trap, int sig)
-{
- return NOTIFY_DONE;
-}
-#endif
-
/*
* This routine handles page faults. It determines the address,
* and the problem, and then passes it off to one of the appropriate
@@ -69,11 +37,6 @@
siginfo_t info;
trace_hardirqs_on();
-
- if (notify_page_fault(DIE_PAGE_FAULT, regs,
- writeaccess, SIGSEGV) == NOTIFY_STOP)
- return;
-
local_irq_enable();
#ifdef CONFIG_SH_KGDB
@@ -285,7 +248,7 @@
pte_t *pte;
pte_t entry;
struct mm_struct *mm = current->mm;
- spinlock_t *ptl;
+ spinlock_t *ptl = NULL;
int ret = 1;
#ifdef CONFIG_SH_KGDB
diff --git a/arch/sh/mm/init.c b/arch/sh/mm/init.c
index 8fe223a..e0e644f 100644
--- a/arch/sh/mm/init.c
+++ b/arch/sh/mm/init.c
@@ -12,6 +12,7 @@
#include <linux/init.h>
#include <linux/bootmem.h>
#include <linux/proc_fs.h>
+#include <linux/pagemap.h>
#include <linux/percpu.h>
#include <linux/io.h>
#include <asm/mmu_context.h>
@@ -112,7 +113,7 @@
* As a performance optimization, other platforms preserve the fixmap mapping
* across a context switch, we don't presently do this, but this could be done
* in a similar fashion as to the wired TLB interface that sh64 uses (by way
- * of the memorry mapped UTLB configuration) -- this unfortunately forces us to
+ * of the memory mapped UTLB configuration) -- this unfortunately forces us to
* give up a TLB entry for each mapping we want to preserve. While this may be
* viable for a small number of fixmaps, it's not particularly useful for
* everything and needs to be carefully evaluated. (ie, we may want this for
diff --git a/arch/sh/mm/pmb.c b/arch/sh/mm/pmb.c
index 02aae06..b6a5a33 100644
--- a/arch/sh/mm/pmb.c
+++ b/arch/sh/mm/pmb.c
@@ -3,7 +3,7 @@
*
* Privileged Space Mapping Buffer (PMB) Support.
*
- * Copyright (C) 2005, 2006 Paul Mundt
+ * Copyright (C) 2005, 2006, 2007 Paul Mundt
*
* P1/P2 Section mapping definitions from map32.h, which was:
*
@@ -68,6 +68,32 @@
return mk_pmb_entry(entry) | PMB_DATA;
}
+static DEFINE_SPINLOCK(pmb_list_lock);
+static struct pmb_entry *pmb_list;
+
+static inline void pmb_list_add(struct pmb_entry *pmbe)
+{
+ struct pmb_entry **p, *tmp;
+
+ p = &pmb_list;
+ while ((tmp = *p) != NULL)
+ p = &tmp->next;
+
+ pmbe->next = tmp;
+ *p = pmbe;
+}
+
+static inline void pmb_list_del(struct pmb_entry *pmbe)
+{
+ struct pmb_entry **p, *tmp;
+
+ for (p = &pmb_list; (tmp = *p); p = &tmp->next)
+ if (tmp == pmbe) {
+ *p = tmp->next;
+ return;
+ }
+}
+
struct pmb_entry *pmb_alloc(unsigned long vpn, unsigned long ppn,
unsigned long flags)
{
@@ -81,11 +107,19 @@
pmbe->ppn = ppn;
pmbe->flags = flags;
+ spin_lock_irq(&pmb_list_lock);
+ pmb_list_add(pmbe);
+ spin_unlock_irq(&pmb_list_lock);
+
return pmbe;
}
void pmb_free(struct pmb_entry *pmbe)
{
+ spin_lock_irq(&pmb_list_lock);
+ pmb_list_del(pmbe);
+ spin_unlock_irq(&pmb_list_lock);
+
kmem_cache_free(pmb_cache, pmbe);
}
@@ -167,31 +201,6 @@
clear_bit(entry, &pmb_map);
}
-static DEFINE_SPINLOCK(pmb_list_lock);
-static struct pmb_entry *pmb_list;
-
-static inline void pmb_list_add(struct pmb_entry *pmbe)
-{
- struct pmb_entry **p, *tmp;
-
- p = &pmb_list;
- while ((tmp = *p) != NULL)
- p = &tmp->next;
-
- pmbe->next = tmp;
- *p = pmbe;
-}
-
-static inline void pmb_list_del(struct pmb_entry *pmbe)
-{
- struct pmb_entry **p, *tmp;
-
- for (p = &pmb_list; (tmp = *p); p = &tmp->next)
- if (tmp == pmbe) {
- *p = tmp->next;
- return;
- }
-}
static struct {
unsigned long size;
@@ -283,25 +292,14 @@
} while (pmbe);
}
-static void pmb_cache_ctor(void *pmb, struct kmem_cache *cachep, unsigned long flags)
+static void pmb_cache_ctor(void *pmb, struct kmem_cache *cachep,
+ unsigned long flags)
{
struct pmb_entry *pmbe = pmb;
memset(pmb, 0, sizeof(struct pmb_entry));
- spin_lock_irq(&pmb_list_lock);
-
pmbe->entry = PMB_NO_ENTRY;
- pmb_list_add(pmbe);
-
- spin_unlock_irq(&pmb_list_lock);
-}
-
-static void pmb_cache_dtor(void *pmb, struct kmem_cache *cachep, unsigned long flags)
-{
- spin_lock_irq(&pmb_list_lock);
- pmb_list_del(pmb);
- spin_unlock_irq(&pmb_list_lock);
}
static int __init pmb_init(void)
@@ -312,8 +310,7 @@
BUG_ON(unlikely(nr_entries >= NR_PMB_ENTRIES));
pmb_cache = kmem_cache_create("pmb", sizeof(struct pmb_entry), 0,
- SLAB_PANIC, pmb_cache_ctor,
- pmb_cache_dtor);
+ SLAB_PANIC, pmb_cache_ctor, NULL);
jump_to_P2();
diff --git a/arch/sh/tools/mach-types b/arch/sh/tools/mach-types
index 554f801..fb40f18 100644
--- a/arch/sh/tools/mach-types
+++ b/arch/sh/tools/mach-types
@@ -7,8 +7,11 @@
#
SE SH_SOLUTION_ENGINE
7751SE SH_7751_SOLUTION_ENGINE
+7722SE SH_7722_SOLUTION_ENGINE
7300SE SH_7300_SOLUTION_ENGINE
7343SE SH_7343_SOLUTION_ENGINE
+7206SE SH_7206_SOLUTION_ENGINE
+7619SE SH_7619_SOLUTION_ENGINE
7780SE SH_7780_SOLUTION_ENGINE
73180SE SH_73180_SOLUTION_ENGINE
7751SYSTEMH SH_7751_SYSTEMH
@@ -31,5 +34,3 @@
TITAN SH_TITAN
SHMIN SH_SHMIN
7710VOIPGW SH_7710VOIPGW
-7206SE SH_7206_SOLUTION_ENGINE
-7619SE SH_7619_SOLUTION_ENGINE
diff --git a/arch/um/os-Linux/start_up.c b/arch/um/os-Linux/start_up.c
index 79471f8..3fc13fa 100644
--- a/arch/um/os-Linux/start_up.c
+++ b/arch/um/os-Linux/start_up.c
@@ -144,9 +144,7 @@
int exit_with = WEXITSTATUS(status);
if (exit_with == 2)
non_fatal("check_ptrace : child exited with status 2. "
- "Serious trouble happening! Try updating "
- "your host skas patch!\nDisabling SYSEMU "
- "support.");
+ "\nDisabling SYSEMU support.\n");
non_fatal("check_ptrace : child exited with exitcode %d, while "
"expecting %d; status 0x%x\n", exit_with,
exitcode, status);
@@ -209,6 +207,7 @@
static void __init check_sysemu(void)
{
void *stack;
+ unsigned long regs[MAX_REG_NR];
int pid, n, status, count=0;
non_fatal("Checking syscall emulation patch for ptrace...");
@@ -225,11 +224,20 @@
fatal("check_sysemu : expected SIGTRAP, got status = %d",
status);
- n = ptrace(PTRACE_POKEUSR, pid, PT_SYSCALL_RET_OFFSET,
- os_getpid());
- if(n < 0)
- fatal_perror("check_sysemu : failed to modify system call "
- "return");
+ if(ptrace(PTRACE_GETREGS, pid, 0, regs) < 0)
+ fatal_perror("check_sysemu : PTRACE_GETREGS failed");
+ if(PT_SYSCALL_NR(regs) != __NR_getpid){
+ non_fatal("check_sysemu got system call number %d, "
+ "expected %d...", PT_SYSCALL_NR(regs), __NR_getpid);
+ goto fail;
+ }
+
+ n = ptrace(PTRACE_POKEUSR, pid, PT_SYSCALL_RET_OFFSET, os_getpid());
+ if(n < 0){
+ non_fatal("check_sysemu : failed to modify system call "
+ "return");
+ goto fail;
+ }
if (stop_ptraced_child(pid, stack, 0, 0) < 0)
goto fail_stopped;
diff --git a/arch/x86_64/Kconfig b/arch/x86_64/Kconfig
index 145bb82..5ce9443 100644
--- a/arch/x86_64/Kconfig
+++ b/arch/x86_64/Kconfig
@@ -428,12 +428,15 @@
memory in the static kernel configuration.
config HOTPLUG_CPU
- bool "Support for hot-pluggable CPUs (EXPERIMENTAL)"
+ bool "Support for suspend on SMP and hot-pluggable CPUs (EXPERIMENTAL)"
depends on SMP && HOTPLUG && EXPERIMENTAL
help
Say Y here to experiment with turning CPUs off and on. CPUs
can be controlled through /sys/devices/system/cpu/cpu#.
- Say N if you want to disable CPU hotplug.
+ This is also required for suspend/hibernation on SMP systems.
+
+ Say N if you want to disable CPU hotplug and don't need to
+ suspend.
config ARCH_ENABLE_MEMORY_HOTPLUG
def_bool y
diff --git a/arch/x86_64/kernel/k8.c b/arch/x86_64/kernel/k8.c
index bc11b32..7377ccb 100644
--- a/arch/x86_64/kernel/k8.c
+++ b/arch/x86_64/kernel/k8.c
@@ -39,10 +39,10 @@
{
int i;
struct pci_dev *dev;
+
if (num_k8_northbridges)
return 0;
- num_k8_northbridges = 0;
dev = NULL;
while ((dev = next_k8_northbridge(dev)) != NULL)
num_k8_northbridges++;
@@ -52,6 +52,11 @@
if (!k8_northbridges)
return -ENOMEM;
+ if (!num_k8_northbridges) {
+ k8_northbridges[0] = NULL;
+ return 0;
+ }
+
flush_words = kmalloc(num_k8_northbridges * sizeof(u32), GFP_KERNEL);
if (!flush_words) {
kfree(k8_northbridges);
diff --git a/block/genhd.c b/block/genhd.c
index 93a2cf6..863a8c0 100644
--- a/block/genhd.c
+++ b/block/genhd.c
@@ -423,7 +423,10 @@
{
return sprintf(page, "%llu\n", (unsigned long long)get_capacity(disk));
}
-
+static ssize_t disk_capability_read(struct gendisk *disk, char *page)
+{
+ return sprintf(page, "%x\n", disk->flags);
+}
static ssize_t disk_stats_read(struct gendisk * disk, char *page)
{
preempt_disable();
@@ -466,6 +469,10 @@
.attr = {.name = "size", .mode = S_IRUGO },
.show = disk_size_read
};
+static struct disk_attribute disk_attr_capability = {
+ .attr = {.name = "capability", .mode = S_IRUGO },
+ .show = disk_capability_read
+};
static struct disk_attribute disk_attr_stat = {
.attr = {.name = "stat", .mode = S_IRUGO },
.show = disk_stats_read
@@ -506,6 +513,7 @@
&disk_attr_removable.attr,
&disk_attr_size.attr,
&disk_attr_stat.attr,
+ &disk_attr_capability.attr,
#ifdef CONFIG_FAIL_MAKE_REQUEST
&disk_attr_fail.attr,
#endif
@@ -688,6 +696,27 @@
.show = diskstats_show
};
+static void media_change_notify_thread(struct work_struct *work)
+{
+ struct gendisk *gd = container_of(work, struct gendisk, async_notify);
+ char event[] = "MEDIA_CHANGE=1";
+ char *envp[] = { event, NULL };
+
+ /*
+ * set enviroment vars to indicate which event this is for
+ * so that user space will know to go check the media status.
+ */
+ kobject_uevent_env(&gd->kobj, KOBJ_CHANGE, envp);
+ put_device(gd->driverfs_dev);
+}
+
+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);
+
struct gendisk *alloc_disk(int minors)
{
return alloc_disk_node(minors, -1);
@@ -717,6 +746,8 @@
kobj_set_kset_s(disk,block_subsys);
kobject_init(&disk->kobj);
rand_initialize_disk(disk);
+ INIT_WORK(&disk->async_notify,
+ media_change_notify_thread);
}
return disk;
}
diff --git a/drivers/ata/ata_piix.c b/drivers/ata/ata_piix.c
index 0458811..9c07b886 100644
--- a/drivers/ata/ata_piix.c
+++ b/drivers/ata/ata_piix.c
@@ -578,6 +578,7 @@
{ 0x27DF, 0x0005, 0x0280 }, /* ICH7 on Acer 5602WLMi */
{ 0x27DF, 0x1025, 0x0110 }, /* ICH7 on Acer 3682WLMi */
{ 0x27DF, 0x1043, 0x1267 }, /* ICH7 on Asus W5F */
+ { 0x24CA, 0x1025, 0x0061 }, /* ICH4 on ACER Aspire 2023WLMi */
/* end marker */
{ 0, }
};
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index a6de57e..3ca9c61 100644
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -3022,7 +3022,7 @@
if (!(status & ATA_BUSY))
return 0;
- if (status == 0xff)
+ if (!ata_port_online(ap) && status == 0xff)
return -ENODEV;
if (time_after(now, deadline))
return -EBUSY;
@@ -3368,7 +3368,7 @@
*/
if (!(ap->flags & ATA_FLAG_SKIP_D2H_BSY) && !ata_port_offline(ap)) {
rc = ata_wait_ready(ap, deadline);
- if (rc) {
+ if (rc && rc != -ENODEV) {
ata_port_printk(ap, KERN_WARNING, "device not ready "
"(errno=%d), forcing hardreset\n", rc);
ehc->i.action |= ATA_EH_HARDRESET;
diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c
index 242c43e..b3900cf 100644
--- a/drivers/ata/libata-scsi.c
+++ b/drivers/ata/libata-scsi.c
@@ -1050,14 +1050,15 @@
static void scsi_6_lba_len(const u8 *cdb, u64 *plba, u32 *plen)
{
u64 lba = 0;
- u32 len = 0;
+ u32 len;
VPRINTK("six-byte command\n");
+ lba |= ((u64)(cdb[1] & 0x1f)) << 16;
lba |= ((u64)cdb[2]) << 8;
lba |= ((u64)cdb[3]);
- len |= ((u32)cdb[4]);
+ len = cdb[4];
*plba = lba;
*plen = len;
diff --git a/drivers/ata/pata_artop.c b/drivers/ata/pata_artop.c
index 7b4810c..03b6ddd 100644
--- a/drivers/ata/pata_artop.c
+++ b/drivers/ata/pata_artop.c
@@ -97,7 +97,7 @@
* artop6260_cable_detect - identify cable type
* @ap: Port
*
- * Identify the cable type for the ARTOp interface in question
+ * Identify the cable type for the ARTOP interface in question
*/
static int artop6260_cable_detect(struct ata_port *ap)
diff --git a/drivers/ata/pata_hpt37x.c b/drivers/ata/pata_hpt37x.c
index a54c174..6446735 100644
--- a/drivers/ata/pata_hpt37x.c
+++ b/drivers/ata/pata_hpt37x.c
@@ -26,7 +26,7 @@
#include <linux/libata.h>
#define DRV_NAME "pata_hpt37x"
-#define DRV_VERSION "0.6.5"
+#define DRV_VERSION "0.6.6"
struct hpt_clock {
u8 xfer_speed;
@@ -931,15 +931,6 @@
.udma_mask = 0x7f,
.port_ops = &hpt372_port_ops
};
- /* HPT371, 372 and friends - UDMA100 at 50MHz clock */
- static const struct ata_port_info info_hpt372_50 = {
- .sht = &hpt37x_sht,
- .flags = ATA_FLAG_SLAVE_POSS|ATA_FLAG_SRST,
- .pio_mask = 0x1f,
- .mwdma_mask = 0x07,
- .udma_mask = 0x3f,
- .port_ops = &hpt372_port_ops
- };
/* HPT374 - UDMA133 */
static const struct ata_port_info info_hpt374 = {
.sht = &hpt37x_sht,
@@ -1098,17 +1089,21 @@
* use a 50MHz DPLL by choice
*/
unsigned int f_low, f_high;
- int adjust;
+ int dpll, adjust;
- clock_slot = 2;
+ /* Compute DPLL */
+ dpll = 2;
if (port->udma_mask & 0xE0)
- clock_slot = 3;
+ dpll = 3;
- f_low = (MHz[clock_slot] * chip_table->base) / 192;
+ f_low = (MHz[clock_slot] * 48) / MHz[dpll];
f_high = f_low + 2;
+ if (clock_slot > 1)
+ f_high += 2;
/* Select the DPLL clock. */
pci_write_config_byte(dev, 0x5b, 0x21);
+ pci_write_config_dword(dev, 0x5C, (f_high << 16) | f_low);
for(adjust = 0; adjust < 8; adjust++) {
if (hpt37x_calibrate_dpll(dev))
@@ -1124,12 +1119,12 @@
printk(KERN_WARNING "hpt37x: DPLL did not stabilize.\n");
return -ENODEV;
}
- if (clock_slot == 3)
+ if (dpll == 3)
private_data = (void *)hpt37x_timings_66;
else
private_data = (void *)hpt37x_timings_50;
- printk(KERN_INFO "hpt37x: Bus clock %dMHz, using DPLL.\n", MHz[clock_slot]);
+ printk(KERN_INFO "hpt37x: Bus clock %dMHz, using DPLL.\n", MHz[dpll]);
} else {
private_data = (void *)chip_table->clocks[clock_slot];
/*
diff --git a/drivers/ata/pata_hpt3x2n.c b/drivers/ata/pata_hpt3x2n.c
index f25154a..e947433 100644
--- a/drivers/ata/pata_hpt3x2n.c
+++ b/drivers/ata/pata_hpt3x2n.c
@@ -521,8 +521,8 @@
/* 371N if rev > 1 */
break;
case PCI_DEVICE_ID_TTI_HPT372:
- /* 372N if rev >= 1*/
- if (class_rev == 0)
+ /* 372N if rev >= 2*/
+ if (class_rev < 2)
return -ENODEV;
break;
case PCI_DEVICE_ID_TTI_HPT302:
diff --git a/drivers/ata/pata_it821x.c b/drivers/ata/pata_it821x.c
index ff9a6fd..b3456d7 100644
--- a/drivers/ata/pata_it821x.c
+++ b/drivers/ata/pata_it821x.c
@@ -1,5 +1,5 @@
/*
- * ata-it821x.c - IT821x PATA for new ATA layer
+ * pata_it821x.c - IT821x PATA for new ATA layer
* (C) 2005 Red Hat Inc
* Alan Cox <alan@redhat.com>
*
@@ -65,7 +65,6 @@
*
* TODO
* - ATAPI and other speed filtering
- * - Command filter in smart mode
* - RAID configuration ioctls
*/
diff --git a/drivers/ata/pata_scc.c b/drivers/ata/pata_scc.c
index aa138d2..61502bc 100644
--- a/drivers/ata/pata_scc.c
+++ b/drivers/ata/pata_scc.c
@@ -489,23 +489,26 @@
* Note: Original code is ata_bus_post_reset().
*/
-static void scc_bus_post_reset (struct ata_port *ap, unsigned int devmask)
+static int scc_bus_post_reset(struct ata_port *ap, unsigned int devmask,
+ unsigned long deadline)
{
struct ata_ioports *ioaddr = &ap->ioaddr;
unsigned int dev0 = devmask & (1 << 0);
unsigned int dev1 = devmask & (1 << 1);
- unsigned long timeout;
+ int rc;
/* if device 0 was found in ata_devchk, wait for its
* BSY bit to clear
*/
- if (dev0)
- ata_busy_sleep(ap, ATA_TMOUT_BOOT_QUICK, ATA_TMOUT_BOOT);
+ if (dev0) {
+ rc = ata_wait_ready(ap, deadline);
+ if (rc && rc != -ENODEV)
+ return rc;
+ }
/* if device 1 was found in ata_devchk, wait for
* register access, then wait for BSY to clear
*/
- timeout = jiffies + ATA_TMOUT_BOOT;
while (dev1) {
u8 nsect, lbal;
@@ -514,14 +517,15 @@
lbal = in_be32(ioaddr->lbal_addr);
if ((nsect == 1) && (lbal == 1))
break;
- if (time_after(jiffies, timeout)) {
- dev1 = 0;
- break;
- }
+ if (time_after(jiffies, deadline))
+ return -EBUSY;
msleep(50); /* give drive a breather */
}
- if (dev1)
- ata_busy_sleep(ap, ATA_TMOUT_BOOT_QUICK, ATA_TMOUT_BOOT);
+ if (dev1) {
+ rc = ata_wait_ready(ap, deadline);
+ if (rc && rc != -ENODEV)
+ return rc;
+ }
/* is all this really necessary? */
ap->ops->dev_select(ap, 0);
@@ -529,6 +533,8 @@
ap->ops->dev_select(ap, 1);
if (dev0)
ap->ops->dev_select(ap, 0);
+
+ return 0;
}
/**
@@ -537,8 +543,8 @@
* Note: Original code is ata_bus_softreset().
*/
-static unsigned int scc_bus_softreset (struct ata_port *ap,
- unsigned int devmask)
+static unsigned int scc_bus_softreset(struct ata_port *ap, unsigned int devmask,
+ unsigned long deadline)
{
struct ata_ioports *ioaddr = &ap->ioaddr;
@@ -570,7 +576,7 @@
if (scc_check_status(ap) == 0xFF)
return 0;
- scc_bus_post_reset(ap, devmask);
+ scc_bus_post_reset(ap, devmask, deadline);
return 0;
}
@@ -579,11 +585,13 @@
* scc_std_softreset - reset host port via ATA SRST
* @ap: port to reset
* @classes: resulting classes of attached devices
+ * @deadline: deadline jiffies for the operation
*
* Note: Original code is ata_std_softreset().
*/
-static int scc_std_softreset (struct ata_port *ap, unsigned int *classes)
+static int scc_std_softreset (struct ata_port *ap, unsigned int *classes,
+ unsigned long deadline)
{
unsigned int slave_possible = ap->flags & ATA_FLAG_SLAVE_POSS;
unsigned int devmask = 0, err_mask;
@@ -607,7 +615,7 @@
/* issue bus reset */
DPRINTK("about to softreset, devmask=%x\n", devmask);
- err_mask = scc_bus_softreset(ap, devmask);
+ err_mask = scc_bus_softreset(ap, devmask, deadline);
if (err_mask) {
ata_port_printk(ap, KERN_ERR, "SRST failed (err_mask=0x%x)\n",
err_mask);
@@ -676,10 +684,11 @@
if (reg & INTSTS_BMSINT) {
unsigned int classes;
+ unsigned long deadline = jiffies + ATA_TMOUT_BOOT;
printk(KERN_WARNING "%s: Internal Bus Error\n", DRV_NAME);
out_be32(bmid_base + SCC_DMA_INTST, INTSTS_BMSINT);
/* TBD: SW reset */
- scc_std_softreset(ap, &classes);
+ scc_std_softreset(ap, &classes, deadline);
continue;
}
@@ -862,9 +871,10 @@
/**
* scc_pata_prereset - prepare for reset
* @ap: ATA port to be reset
+ * @deadline: deadline jiffies for the operation
*/
-static int scc_pata_prereset (struct ata_port *ap, unsigned long deadline)
+static int scc_pata_prereset(struct ata_port *ap, unsigned long deadline)
{
ap->cbl = ATA_CBL_PATA80;
return ata_std_prereset(ap, deadline);
diff --git a/drivers/ata/pata_sis.c b/drivers/ata/pata_sis.c
index f223126..ec3ae93 100644
--- a/drivers/ata/pata_sis.c
+++ b/drivers/ata/pata_sis.c
@@ -73,14 +73,14 @@
}
/**
- * sis_port_base - return PCI configuration base for dev
+ * sis_old_port_base - return PCI configuration base for dev
* @adev: device
*
* Returns the base of the PCI configuration registers for this port
* number.
*/
-static int sis_port_base(struct ata_device *adev)
+static int sis_old_port_base(struct ata_device *adev)
{
return 0x40 + (4 * adev->ap->port_no) + (2 * adev->devno);
}
@@ -211,7 +211,7 @@
static void sis_old_set_piomode (struct ata_port *ap, struct ata_device *adev)
{
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
- int port = sis_port_base(adev);
+ int port = sis_old_port_base(adev);
u8 t1, t2;
int speed = adev->pio_mode - XFER_PIO_0;
@@ -248,7 +248,7 @@
static void sis_100_set_piomode (struct ata_port *ap, struct ata_device *adev)
{
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
- int port = sis_port_base(adev);
+ int port = sis_old_port_base(adev);
int speed = adev->pio_mode - XFER_PIO_0;
const u8 actrec[] = { 0x00, 0x67, 0x44, 0x33, 0x31 };
@@ -328,7 +328,7 @@
{
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
int speed = adev->dma_mode - XFER_MW_DMA_0;
- int drive_pci = sis_port_base(adev);
+ int drive_pci = sis_old_port_base(adev);
u16 timing;
const u16 mwdma_bits[] = { 0x707, 0x202, 0x202 };
@@ -367,7 +367,7 @@
{
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
int speed = adev->dma_mode - XFER_MW_DMA_0;
- int drive_pci = sis_port_base(adev);
+ int drive_pci = sis_old_port_base(adev);
u16 timing;
const u16 mwdma_bits[] = { 0x707, 0x202, 0x202 };
@@ -378,12 +378,12 @@
if (adev->dma_mode < XFER_UDMA_0) {
/* bits 3-0 hold recovery timing bits 8-10 active timing and
the higer bits are dependant on the device, bit 15 udma */
- timing &= ~ 0x870F;
+ timing &= ~0x870F;
timing |= mwdma_bits[speed];
} else {
/* Bit 15 is UDMA on/off, bit 12-14 are cycle time */
speed = adev->dma_mode - XFER_UDMA_0;
- timing &= ~0x6000;
+ timing &= ~0xF000;
timing |= udma_bits[speed];
}
pci_write_config_word(pdev, drive_pci, timing);
@@ -405,22 +405,22 @@
{
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
int speed = adev->dma_mode - XFER_MW_DMA_0;
- int drive_pci = sis_port_base(adev);
- u16 timing;
+ int drive_pci = sis_old_port_base(adev);
+ u8 timing;
- const u16 udma_bits[] = { 0x8B00, 0x8700, 0x8500, 0x8300, 0x8200, 0x8100};
+ const u8 udma_bits[] = { 0x8B, 0x87, 0x85, 0x83, 0x82, 0x81};
- pci_read_config_word(pdev, drive_pci, &timing);
+ pci_read_config_byte(pdev, drive_pci + 1, &timing);
if (adev->dma_mode < XFER_UDMA_0) {
/* NOT SUPPORTED YET: NEED DATA SHEET. DITTO IN OLD DRIVER */
} else {
- /* Bit 15 is UDMA on/off, bit 12-14 are cycle time */
+ /* Bit 7 is UDMA on/off, bit 0-3 are cycle time */
speed = adev->dma_mode - XFER_UDMA_0;
- timing &= ~0x0F00;
+ timing &= ~0x8F;
timing |= udma_bits[speed];
}
- pci_write_config_word(pdev, drive_pci, timing);
+ pci_write_config_byte(pdev, drive_pci + 1, timing);
}
/**
@@ -440,22 +440,22 @@
{
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
int speed = adev->dma_mode - XFER_MW_DMA_0;
- int drive_pci = sis_port_base(adev);
- u16 timing;
+ int drive_pci = sis_old_port_base(adev);
+ u8 timing;
+ /* Low 4 bits are timing */
+ static const u8 udma_bits[] = { 0x8F, 0x8A, 0x87, 0x85, 0x83, 0x82, 0x81};
- static const u16 udma_bits[] = { 0x8F00, 0x8A00, 0x8700, 0x8500, 0x8300, 0x8200, 0x8100};
-
- pci_read_config_word(pdev, drive_pci, &timing);
+ pci_read_config_byte(pdev, drive_pci + 1, &timing);
if (adev->dma_mode < XFER_UDMA_0) {
/* NOT SUPPORTED YET: NEED DATA SHEET. DITTO IN OLD DRIVER */
} else {
- /* Bit 15 is UDMA on/off, bit 12-14 are cycle time */
+ /* Bit 7 is UDMA on/off, bit 0-3 are cycle time */
speed = adev->dma_mode - XFER_UDMA_0;
- timing &= ~0x0F00;
+ timing &= ~0x8F;
timing |= udma_bits[speed];
}
- pci_write_config_word(pdev, drive_pci, timing);
+ pci_write_config_byte(pdev, drive_pci + 1, timing);
}
/**
diff --git a/drivers/ata/pata_via.c b/drivers/ata/pata_via.c
index e4c71f7..a8462f1 100644
--- a/drivers/ata/pata_via.c
+++ b/drivers/ata/pata_via.c
@@ -60,6 +60,7 @@
#include <linux/delay.h>
#include <scsi/scsi_host.h>
#include <linux/libata.h>
+#include <linux/dmi.h>
#define DRV_NAME "pata_via"
#define DRV_VERSION "0.3.1"
@@ -122,6 +123,31 @@
{ NULL }
};
+
+/*
+ * Cable special cases
+ */
+
+static struct dmi_system_id cable_dmi_table[] = {
+ {
+ .ident = "Acer Ferrari 3400",
+ .matches = {
+ DMI_MATCH(DMI_BOARD_VENDOR, "Acer,Inc."),
+ DMI_MATCH(DMI_BOARD_NAME, "Ferrari 3400"),
+ },
+ },
+ { }
+};
+
+static int via_cable_override(struct pci_dev *pdev)
+{
+ /* Systems by DMI */
+ if (dmi_check_system(cable_dmi_table))
+ return 1;
+ return 0;
+}
+
+
/**
* via_cable_detect - cable detection
* @ap: ATA port
@@ -139,6 +165,9 @@
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
u32 ata66;
+ if (via_cable_override(pdev))
+ return ATA_CBL_PATA40_SHORT;
+
/* Early chips are 40 wire */
if ((config->flags & VIA_UDMA) < VIA_UDMA_66)
return ATA_CBL_PATA40;
@@ -592,10 +621,11 @@
#endif
static const struct pci_device_id via[] = {
- { PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_82C576_1), },
- { PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_82C586_1), },
- { PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_6410), },
- { PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_SATA_EIDE), },
+ { PCI_VDEVICE(VIA, 0x0571), },
+ { PCI_VDEVICE(VIA, 0x0581), },
+ { PCI_VDEVICE(VIA, 0x1571), },
+ { PCI_VDEVICE(VIA, 0x3164), },
+ { PCI_VDEVICE(VIA, 0x5324), },
{ },
};
diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c
index 705a020..c957e6e 100644
--- a/drivers/ata/sata_mv.c
+++ b/drivers/ata/sata_mv.c
@@ -21,6 +21,50 @@
*
*/
+/*
+ sata_mv TODO list:
+
+ 1) Needs a full errata audit for all chipsets. I implemented most
+ of the errata workarounds found in the Marvell vendor driver, but
+ I distinctly remember a couple workarounds (one related to PCI-X)
+ are still needed.
+
+ 2) Convert to LibATA new EH. Required for hotplug, NCQ, and sane
+ probing/error handling in general. MUST HAVE.
+
+ 3) Add hotplug support (easy, once new-EH support appears)
+
+ 4) Add NCQ support (easy to intermediate, once new-EH support appears)
+
+ 5) Investigate problems with PCI Message Signalled Interrupts (MSI).
+
+ 6) Add port multiplier support (intermediate)
+
+ 7) Test and verify 3.0 Gbps support
+
+ 8) Develop a low-power-consumption strategy, and implement it.
+
+ 9) [Experiment, low priority] See if ATAPI can be supported using
+ "unknown FIS" or "vendor-specific FIS" support, or something creative
+ like that.
+
+ 10) [Experiment, low priority] Investigate interrupt coalescing.
+ Quite often, especially with PCI Message Signalled Interrupts (MSI),
+ the overhead reduced by interrupt mitigation is quite often not
+ worth the latency cost.
+
+ 11) [Experiment, Marvell value added] Is it possible to use target
+ mode to cross-connect two Linux boxes with Marvell cards? If so,
+ creating LibATA target mode support would be very interesting.
+
+ Target mode, for those without docs, is the ability to directly
+ connect two SATA controllers.
+
+ 13) Verify that 7042 is fully supported. I only have a 6042.
+
+*/
+
+
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/pci.h>
diff --git a/drivers/ata/sata_promise.c b/drivers/ata/sata_promise.c
index 3a7d9b5..2b924a6 100644
--- a/drivers/ata/sata_promise.c
+++ b/drivers/ata/sata_promise.c
@@ -297,7 +297,7 @@
/* board_2057x_pata */
{
- .flags = PDC_COMMON_FLAGS | ATA_FLAG_SLAVE_POSS,
+ .flags = PDC_COMMON_FLAGS | ATA_FLAG_SLAVE_POSS |
PDC_FLAG_GEN_II,
.pio_mask = 0x1f, /* pio0-4 */
.mwdma_mask = 0x07, /* mwdma0-2 */
diff --git a/drivers/ata/sata_sis.c b/drivers/ata/sata_sis.c
index 51d9251b0..221099d 100644
--- a/drivers/ata/sata_sis.c
+++ b/drivers/ata/sata_sis.c
@@ -255,7 +255,7 @@
{
static int printed_version;
struct ata_port_info pi = sis_port_info;
- const struct ata_port_info *ppi[] = { &pi, NULL };
+ const struct ata_port_info *ppi[] = { &pi, &pi };
struct ata_host *host;
u32 genctl, val;
u8 pmr;
diff --git a/drivers/ata/sata_via.c b/drivers/ata/sata_via.c
index 01bba26..e8b90e7 100644
--- a/drivers/ata/sata_via.c
+++ b/drivers/ata/sata_via.c
@@ -85,6 +85,9 @@
{ PCI_VDEVICE(VIA, 0x0591), vt6420 },
{ PCI_VDEVICE(VIA, 0x3149), vt6420 },
{ PCI_VDEVICE(VIA, 0x3249), vt6421 },
+ { PCI_VDEVICE(VIA, 0x5287), vt6420 },
+ { PCI_VDEVICE(VIA, 0x5372), vt6420 },
+ { PCI_VDEVICE(VIA, 0x7372), vt6420 },
{ } /* terminate list */
};
diff --git a/drivers/atm/idt77252.c b/drivers/atm/idt77252.c
index 057efbc..3800bc0 100644
--- a/drivers/atm/idt77252.c
+++ b/drivers/atm/idt77252.c
@@ -47,7 +47,8 @@
#include <linux/bitops.h>
#include <linux/wait.h>
#include <linux/jiffies.h>
-#include <asm/semaphore.h>
+#include <linux/mutex.h>
+
#include <asm/io.h>
#include <asm/uaccess.h>
#include <asm/atomic.h>
@@ -2435,7 +2436,7 @@
set_bit(ATM_VF_ADDR, &vcc->flags);
- down(&card->mutex);
+ mutex_lock(&card->mutex);
OPRINTK("%s: opening vpi.vci: %d.%d\n", card->name, vpi, vci);
@@ -2446,7 +2447,7 @@
break;
default:
printk("%s: Unsupported AAL: %d\n", card->name, vcc->qos.aal);
- up(&card->mutex);
+ mutex_unlock(&card->mutex);
return -EPROTONOSUPPORT;
}
@@ -2455,7 +2456,7 @@
card->vcs[index] = kzalloc(sizeof(struct vc_map), GFP_KERNEL);
if (!card->vcs[index]) {
printk("%s: can't alloc vc in open()\n", card->name);
- up(&card->mutex);
+ mutex_unlock(&card->mutex);
return -ENOMEM;
}
card->vcs[index]->card = card;
@@ -2484,14 +2485,14 @@
if (inuse) {
printk("%s: %s vci already in use.\n", card->name,
inuse == 1 ? "tx" : inuse == 2 ? "rx" : "tx and rx");
- up(&card->mutex);
+ mutex_unlock(&card->mutex);
return -EADDRINUSE;
}
if (vcc->qos.txtp.traffic_class != ATM_NONE) {
error = idt77252_init_tx(card, vc, vcc, &vcc->qos);
if (error) {
- up(&card->mutex);
+ mutex_unlock(&card->mutex);
return error;
}
}
@@ -2499,14 +2500,14 @@
if (vcc->qos.rxtp.traffic_class != ATM_NONE) {
error = idt77252_init_rx(card, vc, vcc, &vcc->qos);
if (error) {
- up(&card->mutex);
+ mutex_unlock(&card->mutex);
return error;
}
}
set_bit(ATM_VF_READY, &vcc->flags);
- up(&card->mutex);
+ mutex_unlock(&card->mutex);
return 0;
}
@@ -2520,7 +2521,7 @@
unsigned long addr;
unsigned long timeout;
- down(&card->mutex);
+ mutex_lock(&card->mutex);
IPRINTK("%s: idt77252_close: vc = %d (%d.%d)\n",
card->name, vc->index, vcc->vpi, vcc->vci);
@@ -2591,7 +2592,7 @@
free_scq(card, vc->scq);
}
- up(&card->mutex);
+ mutex_unlock(&card->mutex);
}
static int
@@ -2602,7 +2603,7 @@
struct vc_map *vc = vcc->dev_data;
int error = 0;
- down(&card->mutex);
+ mutex_lock(&card->mutex);
if (qos->txtp.traffic_class != ATM_NONE) {
if (!test_bit(VCF_TX, &vc->flags)) {
@@ -2648,7 +2649,7 @@
set_bit(ATM_VF_HASQOS, &vcc->flags);
out:
- up(&card->mutex);
+ mutex_unlock(&card->mutex);
return error;
}
@@ -3709,7 +3710,7 @@
membase = pci_resource_start(pcidev, 1);
srambase = pci_resource_start(pcidev, 2);
- init_MUTEX(&card->mutex);
+ mutex_init(&card->mutex);
spin_lock_init(&card->cmd_lock);
spin_lock_init(&card->tst_lock);
diff --git a/drivers/atm/idt77252.h b/drivers/atm/idt77252.h
index 544b397..6f2b4a5 100644
--- a/drivers/atm/idt77252.h
+++ b/drivers/atm/idt77252.h
@@ -37,7 +37,7 @@
#include <linux/ptrace.h>
#include <linux/skbuff.h>
#include <linux/workqueue.h>
-
+#include <linux/mutex.h>
/*****************************************************************************/
/* */
@@ -359,7 +359,7 @@
unsigned long srambase; /* SAR's sram base address */
void __iomem *fbq[4]; /* FBQ fill addresses */
- struct semaphore mutex;
+ struct mutex mutex;
spinlock_t cmd_lock; /* for r/w utility/sram */
unsigned long softstat;
diff --git a/drivers/block/floppy.c b/drivers/block/floppy.c
index 3587cb4..fe08804 100644
--- a/drivers/block/floppy.c
+++ b/drivers/block/floppy.c
@@ -670,7 +670,7 @@
if (drive == current_reqD)
drive = current_drive;
del_timer(&fd_timeout);
- if (drive < 0 || drive > N_DRIVE) {
+ if (drive < 0 || drive >= N_DRIVE) {
fd_timeout.expires = jiffies + 20UL * HZ;
drive = 0;
} else
diff --git a/drivers/bluetooth/hci_usb.c b/drivers/bluetooth/hci_usb.c
index b0238b4..7e04dd6 100644
--- a/drivers/bluetooth/hci_usb.c
+++ b/drivers/bluetooth/hci_usb.c
@@ -115,11 +115,11 @@
{ USB_DEVICE(0x0a5c, 0x2009), .driver_info = HCI_BCM92035 },
/* Broadcom BCM2045 */
- { USB_DEVICE(0x0a5c, 0x2101), .driver_info = HCI_WRONG_SCO_MTU },
+ { USB_DEVICE(0x0a5c, 0x2101), .driver_info = HCI_RESET | HCI_WRONG_SCO_MTU },
/* IBM/Lenovo ThinkPad with Broadcom chip */
- { USB_DEVICE(0x0a5c, 0x201e), .driver_info = HCI_WRONG_SCO_MTU },
- { USB_DEVICE(0x0a5c, 0x2110), .driver_info = HCI_WRONG_SCO_MTU },
+ { USB_DEVICE(0x0a5c, 0x201e), .driver_info = HCI_RESET | HCI_WRONG_SCO_MTU },
+ { USB_DEVICE(0x0a5c, 0x2110), .driver_info = HCI_RESET | HCI_WRONG_SCO_MTU },
/* Targus ACB10US */
{ USB_DEVICE(0x0a5c, 0x2100), .driver_info = HCI_RESET },
@@ -128,17 +128,17 @@
{ USB_DEVICE(0x0a5c, 0x2111), .driver_info = HCI_RESET },
/* HP laptop with Broadcom chip */
- { USB_DEVICE(0x03f0, 0x171d), .driver_info = HCI_WRONG_SCO_MTU },
+ { USB_DEVICE(0x03f0, 0x171d), .driver_info = HCI_RESET | HCI_WRONG_SCO_MTU },
/* Dell laptop with Broadcom chip */
- { USB_DEVICE(0x413c, 0x8126), .driver_info = HCI_WRONG_SCO_MTU },
+ { USB_DEVICE(0x413c, 0x8126), .driver_info = HCI_RESET | HCI_WRONG_SCO_MTU },
/* Microsoft Wireless Transceiver for Bluetooth 2.0 */
{ USB_DEVICE(0x045e, 0x009c), .driver_info = HCI_RESET },
/* Kensington Bluetooth USB adapter */
{ USB_DEVICE(0x047d, 0x105d), .driver_info = HCI_RESET },
- { USB_DEVICE(0x047d, 0x105e), .driver_info = HCI_WRONG_SCO_MTU },
+ { USB_DEVICE(0x047d, 0x105e), .driver_info = HCI_RESET | HCI_WRONG_SCO_MTU },
/* ISSC Bluetooth Adapter v3.1 */
{ USB_DEVICE(0x1131, 0x1001), .driver_info = HCI_RESET },
@@ -148,8 +148,8 @@
{ USB_DEVICE(0x0400, 0x080a), .driver_info = HCI_BROKEN_ISOC },
/* Belkin F8T012 and F8T013 devices */
- { USB_DEVICE(0x050d, 0x0012), .driver_info = HCI_WRONG_SCO_MTU },
- { USB_DEVICE(0x050d, 0x0013), .driver_info = HCI_WRONG_SCO_MTU },
+ { USB_DEVICE(0x050d, 0x0012), .driver_info = HCI_RESET | HCI_WRONG_SCO_MTU },
+ { USB_DEVICE(0x050d, 0x0013), .driver_info = HCI_RESET | HCI_WRONG_SCO_MTU },
/* Digianswer devices */
{ USB_DEVICE(0x08fd, 0x0001), .driver_info = HCI_DIGIANSWER },
diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig
index abcafac..ef683eb 100644
--- a/drivers/char/Kconfig
+++ b/drivers/char/Kconfig
@@ -815,7 +815,7 @@
config GEN_RTC
tristate "Generic /dev/rtc emulation"
- depends on RTC!=y && !IA64 && !ARM && !M32R && !SPARC && !FRV && !S390
+ depends on RTC!=y && !IA64 && !ARM && !M32R && !SPARC && !FRV && !S390 && !SUPERH
---help---
If you say Y here and create a character special file /dev/rtc with
major number 10 and minor number 135 using mknod ("man mknod"), you
diff --git a/drivers/char/cyclades.c b/drivers/char/cyclades.c
index c72ee97d..ca376b9 100644
--- a/drivers/char/cyclades.c
+++ b/drivers/char/cyclades.c
@@ -1061,6 +1061,7 @@
if (data & info->ignore_status_mask) {
info->icount.rx++;
+ spin_unlock(&cinfo->card_lock);
return;
}
if (tty_buffer_request_room(tty, 1)) {
diff --git a/drivers/crypto/geode-aes.c b/drivers/crypto/geode-aes.c
index 6d3840e..6a86958 100644
--- a/drivers/crypto/geode-aes.c
+++ b/drivers/crypto/geode-aes.c
@@ -102,10 +102,15 @@
u32 flags = 0;
unsigned long iflags;
- if (op->len == 0 || op->src == op->dst)
+ if (op->len == 0)
return 0;
- if (op->flags & AES_FLAGS_COHERENT)
+ /* If the source and destination is the same, then
+ * we need to turn on the coherent flags, otherwise
+ * we don't need to worry
+ */
+
+ if (op->src == op->dst)
flags |= (AES_CTRL_DCA | AES_CTRL_SCA);
if (op->dir == AES_DIR_ENCRYPT)
@@ -120,7 +125,7 @@
_writefield(AES_WRITEIV0_REG, op->iv);
}
- if (op->flags & AES_FLAGS_USRKEY) {
+ if (!(op->flags & AES_FLAGS_HIDDENKEY)) {
flags |= AES_CTRL_WRKEY;
_writefield(AES_WRITEKEY0_REG, op->key);
}
@@ -289,6 +294,7 @@
.setkey = geode_setkey,
.encrypt = geode_cbc_encrypt,
.decrypt = geode_cbc_decrypt,
+ .ivsize = AES_IV_LENGTH,
}
}
};
diff --git a/drivers/crypto/geode-aes.h b/drivers/crypto/geode-aes.h
index 8003a36..f479686 100644
--- a/drivers/crypto/geode-aes.h
+++ b/drivers/crypto/geode-aes.h
@@ -20,8 +20,7 @@
#define AES_DIR_DECRYPT 0
#define AES_DIR_ENCRYPT 1
-#define AES_FLAGS_USRKEY (1 << 0)
-#define AES_FLAGS_COHERENT (1 << 1)
+#define AES_FLAGS_HIDDENKEY (1 << 0)
struct geode_aes_op {
diff --git a/drivers/hwmon/applesmc.c b/drivers/hwmon/applesmc.c
index 0c160675..366f4a1 100644
--- a/drivers/hwmon/applesmc.c
+++ b/drivers/hwmon/applesmc.c
@@ -491,6 +491,12 @@
/* Sysfs Files */
+static ssize_t applesmc_name_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ return snprintf(buf, PAGE_SIZE, "applesmc\n");
+}
+
static ssize_t applesmc_position_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
@@ -913,6 +919,8 @@
.brightness_set = applesmc_brightness_set,
};
+static DEVICE_ATTR(name, 0444, applesmc_name_show, NULL);
+
static DEVICE_ATTR(position, 0444, applesmc_position_show, NULL);
static DEVICE_ATTR(calibrate, 0644,
applesmc_calibrate_show, applesmc_calibrate_store);
@@ -1197,6 +1205,8 @@
goto out_driver;
}
+ ret = sysfs_create_file(&pdev->dev.kobj, &dev_attr_name.attr);
+
/* Create key enumeration sysfs files */
ret = sysfs_create_group(&pdev->dev.kobj, &key_enumeration_group);
if (ret)
diff --git a/drivers/i2c/busses/i2c-s3c2410.c b/drivers/i2c/busses/i2c-s3c2410.c
index e68a96f..e4540fc 100644
--- a/drivers/i2c/busses/i2c-s3c2410.c
+++ b/drivers/i2c/busses/i2c-s3c2410.c
@@ -830,7 +830,8 @@
i2c->irq = res;
- dev_dbg(&pdev->dev, "irq resource %p (%ld)\n", res, res->start);
+ dev_dbg(&pdev->dev, "irq resource %p (%lu)\n", res,
+ (unsigned long)res->start);
ret = i2c_add_adapter(&i2c->adap);
if (ret < 0) {
diff --git a/drivers/i2c/busses/i2c-tiny-usb.c b/drivers/i2c/busses/i2c-tiny-usb.c
index 9079990..cb9abe7 100644
--- a/drivers/i2c/busses/i2c-tiny-usb.c
+++ b/drivers/i2c/busses/i2c-tiny-usb.c
@@ -208,7 +208,7 @@
dev->adapter.class = I2C_CLASS_HWMON;
dev->adapter.algo = &usb_algorithm;
dev->adapter.algo_data = dev;
- snprintf(dev->adapter.name, I2C_NAME_SIZE,
+ snprintf(dev->adapter.name, sizeof(dev->adapter.name),
"i2c-tiny-usb at bus %03d device %03d",
dev->usb_dev->bus->busnum, dev->usb_dev->devnum);
diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c
index 64f8e56..435925e 100644
--- a/drivers/i2c/i2c-core.c
+++ b/drivers/i2c/i2c-core.c
@@ -697,9 +697,10 @@
if (client->driver)
client->dev.driver = &client->driver->driver;
- if (client->driver && !is_newstyle_driver(client->driver))
+ if (client->driver && !is_newstyle_driver(client->driver)) {
client->dev.release = i2c_client_release;
- else
+ client->dev.uevent_suppress = 1;
+ } else
client->dev.release = i2c_client_dev_release;
snprintf(&client->dev.bus_id[0], sizeof(client->dev.bus_id),
diff --git a/drivers/ide/ide-dma.c b/drivers/ide/ide-dma.c
index b77b7d1..ead141e 100644
--- a/drivers/ide/ide-dma.c
+++ b/drivers/ide/ide-dma.c
@@ -119,15 +119,17 @@
{ "HITACHI CDR-8335" , "ALL" },
{ "HITACHI CDR-8435" , "ALL" },
{ "Toshiba CD-ROM XM-6202B" , "ALL" },
+ { "TOSHIBA CD-ROM XM-1702BC", "ALL" },
{ "CD-532E-A" , "ALL" },
{ "E-IDE CD-ROM CR-840", "ALL" },
{ "CD-ROM Drive/F5A", "ALL" },
{ "WPI CDD-820", "ALL" },
{ "SAMSUNG CD-ROM SC-148C", "ALL" },
{ "SAMSUNG CD-ROM SC", "ALL" },
- { "SanDisk SDP3B-64" , "ALL" },
{ "ATAPI CD-ROM DRIVE 40X MAXIMUM", "ALL" },
{ "_NEC DV5800A", "ALL" },
+ { "SAMSUNG CD-ROM SN-124", "N001" },
+ { "Seagate STT20000A", "ALL" },
{ NULL , NULL }
};
diff --git a/drivers/ide/ide-proc.c b/drivers/ide/ide-proc.c
index d50bd99..ea94c9a 100644
--- a/drivers/ide/ide-proc.c
+++ b/drivers/ide/ide-proc.c
@@ -67,6 +67,8 @@
case ide_4drives: name = "4drives"; break;
case ide_pmac: name = "mac-io"; break;
case ide_au1xxx: name = "au1xxx"; break;
+ case ide_etrax100: name = "etrax100"; break;
+ case ide_acorn: name = "acorn"; break;
default: name = "(unknown)"; break;
}
len = sprintf(page, "%s\n", name);
diff --git a/drivers/ide/pci/atiixp.c b/drivers/ide/pci/atiixp.c
index 0e52ad7..8ab33fa 100644
--- a/drivers/ide/pci/atiixp.c
+++ b/drivers/ide/pci/atiixp.c
@@ -317,6 +317,7 @@
{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP300_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP400_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP600_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1},
+ { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP700_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1},
{ 0, },
};
MODULE_DEVICE_TABLE(pci, atiixp_pci_tbl);
diff --git a/drivers/ide/pci/serverworks.c b/drivers/ide/pci/serverworks.c
index 6234f80..47bcd91 100644
--- a/drivers/ide/pci/serverworks.c
+++ b/drivers/ide/pci/serverworks.c
@@ -158,6 +158,12 @@
pci_read_config_word(dev, 0x4A, &csb5_pio);
pci_read_config_byte(dev, 0x54, &ultra_enable);
+ /* If we are in RAID mode (eg AMI MegaIDE) then we can't it
+ turns out trust the firmware configuration */
+
+ if ((dev->class >> 8) != PCI_CLASS_STORAGE_IDE)
+ goto oem_setup_failed;
+
/* Per Specified Design by OEM, and ASIC Architect */
if ((dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB6IDE) ||
(dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB6IDE2)) {
@@ -173,7 +179,7 @@
((dma_stat&(1<<(5+unit)))==(1<<(5+unit)))) {
u8 dmaspeed = dma_timing;
- dma_timing &= ~0xFF;
+ dma_timing &= ~0xFFU;
if ((dmaspeed & 0x20) == 0x20)
dmaspeed = XFER_MW_DMA_2;
else if ((dmaspeed & 0x21) == 0x21)
@@ -187,7 +193,7 @@
} else if (pio_timing) {
u8 piospeed = pio_timing;
- pio_timing &= ~0xFF;
+ pio_timing &= ~0xFFU;
if ((piospeed & 0x20) == 0x20)
piospeed = XFER_PIO_4;
else if ((piospeed & 0x22) == 0x22)
@@ -208,8 +214,8 @@
oem_setup_failed:
- pio_timing &= ~0xFF;
- dma_timing &= ~0xFF;
+ pio_timing &= ~0xFFU;
+ dma_timing &= ~0xFFU;
ultra_timing &= ~(0x0F << (4*unit));
ultra_enable &= ~(0x01 << drive->dn);
csb5_pio &= ~(0x0F << (4*drive->dn));
diff --git a/drivers/infiniband/hw/ehca/hcp_if.c b/drivers/infiniband/hw/ehca/hcp_if.c
index 7f0beec..5766ae3 100644
--- a/drivers/infiniband/hw/ehca/hcp_if.c
+++ b/drivers/infiniband/hw/ehca/hcp_if.c
@@ -331,7 +331,7 @@
0);
qp->ipz_qp_handle.handle = outs[0];
qp->real_qp_num = (u32)outs[1];
- parms->act_nr_send_sges =
+ parms->act_nr_send_wqes =
(u16)EHCA_BMASK_GET(H_ALL_RES_QP_ACT_OUTST_SEND_WR, outs[2]);
parms->act_nr_recv_wqes =
(u16)EHCA_BMASK_GET(H_ALL_RES_QP_ACT_OUTST_RECV_WR, outs[2]);
diff --git a/drivers/infiniband/hw/mlx4/qp.c b/drivers/infiniband/hw/mlx4/qp.c
index a824bc5..dc137de 100644
--- a/drivers/infiniband/hw/mlx4/qp.c
+++ b/drivers/infiniband/hw/mlx4/qp.c
@@ -270,9 +270,7 @@
struct ib_qp_init_attr *init_attr,
struct ib_udata *udata, int sqpn, struct mlx4_ib_qp *qp)
{
- struct mlx4_wqe_ctrl_seg *ctrl;
int err;
- int i;
mutex_init(&qp->mutex);
spin_lock_init(&qp->sq.lock);
@@ -319,20 +317,24 @@
if (err)
goto err_mtt;
- err = mlx4_ib_db_map_user(to_mucontext(pd->uobject->context),
- ucmd.db_addr, &qp->db);
- if (err)
- goto err_mtt;
+ if (!init_attr->srq) {
+ err = mlx4_ib_db_map_user(to_mucontext(pd->uobject->context),
+ ucmd.db_addr, &qp->db);
+ if (err)
+ goto err_mtt;
+ }
} else {
err = set_kernel_sq_size(dev, &init_attr->cap, init_attr->qp_type, qp);
if (err)
goto err;
- err = mlx4_ib_db_alloc(dev, &qp->db, 0);
- if (err)
- goto err;
+ if (!init_attr->srq) {
+ err = mlx4_ib_db_alloc(dev, &qp->db, 0);
+ if (err)
+ goto err;
- *qp->db.db = 0;
+ *qp->db.db = 0;
+ }
if (mlx4_buf_alloc(dev->dev, qp->buf_size, PAGE_SIZE * 2, &qp->buf)) {
err = -ENOMEM;
@@ -348,11 +350,6 @@
if (err)
goto err_mtt;
- for (i = 0; i < qp->sq.max; ++i) {
- ctrl = get_send_wqe(qp, i);
- ctrl->owner_opcode = cpu_to_be32(1 << 31);
- }
-
qp->sq.wrid = kmalloc(qp->sq.max * sizeof (u64), GFP_KERNEL);
qp->rq.wrid = kmalloc(qp->rq.max * sizeof (u64), GFP_KERNEL);
@@ -386,7 +383,7 @@
return 0;
err_wrid:
- if (pd->uobject)
+ if (pd->uobject && !init_attr->srq)
mlx4_ib_db_unmap_user(to_mucontext(pd->uobject->context), &qp->db);
else {
kfree(qp->sq.wrid);
@@ -403,7 +400,7 @@
mlx4_buf_free(dev->dev, qp->buf_size, &qp->buf);
err_db:
- if (!pd->uobject)
+ if (!pd->uobject && !init_attr->srq)
mlx4_ib_db_free(dev, &qp->db);
err:
@@ -481,14 +478,16 @@
mlx4_mtt_cleanup(dev->dev, &qp->mtt);
if (is_user) {
- mlx4_ib_db_unmap_user(to_mucontext(qp->ibqp.uobject->context),
- &qp->db);
+ if (!qp->ibqp.srq)
+ mlx4_ib_db_unmap_user(to_mucontext(qp->ibqp.uobject->context),
+ &qp->db);
ib_umem_release(qp->umem);
} else {
kfree(qp->sq.wrid);
kfree(qp->rq.wrid);
mlx4_buf_free(dev->dev, qp->buf_size, &qp->buf);
- mlx4_ib_db_free(dev, &qp->db);
+ if (!qp->ibqp.srq)
+ mlx4_ib_db_free(dev, &qp->db);
}
}
@@ -852,7 +851,7 @@
if (ibqp->srq)
context->srqn = cpu_to_be32(1 << 24 | to_msrq(ibqp->srq)->msrq.srqn);
- if (cur_state == IB_QPS_RESET && new_state == IB_QPS_INIT)
+ if (!ibqp->srq && cur_state == IB_QPS_RESET && new_state == IB_QPS_INIT)
context->db_rec_addr = cpu_to_be64(qp->db.dma);
if (cur_state == IB_QPS_INIT &&
@@ -872,6 +871,21 @@
else
sqd_event = 0;
+ /*
+ * Before passing a kernel QP to the HW, make sure that the
+ * ownership bits of the send queue are set so that the
+ * hardware doesn't start processing stale work requests.
+ */
+ if (!ibqp->uobject && cur_state == IB_QPS_RESET && new_state == IB_QPS_INIT) {
+ struct mlx4_wqe_ctrl_seg *ctrl;
+ int i;
+
+ for (i = 0; i < qp->sq.max; ++i) {
+ ctrl = get_send_wqe(qp, i);
+ ctrl->owner_opcode = cpu_to_be32(1 << 31);
+ }
+ }
+
err = mlx4_qp_modify(dev->dev, &qp->mtt, to_mlx4_state(cur_state),
to_mlx4_state(new_state), context, optpar,
sqd_event, &qp->mqp);
@@ -919,7 +933,8 @@
qp->rq.tail = 0;
qp->sq.head = 0;
qp->sq.tail = 0;
- *qp->db.db = 0;
+ if (!ibqp->srq)
+ *qp->db.db = 0;
}
out:
diff --git a/drivers/infiniband/ulp/ipoib/ipoib.h b/drivers/infiniband/ulp/ipoib/ipoib.h
index a0b3782..158759e 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib.h
+++ b/drivers/infiniband/ulp/ipoib/ipoib.h
@@ -429,6 +429,7 @@
void ipoib_pkey_poll(struct work_struct *work);
int ipoib_pkey_dev_delay_open(struct net_device *dev);
+void ipoib_drain_cq(struct net_device *dev);
#ifdef CONFIG_INFINIBAND_IPOIB_CM
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_cm.c b/drivers/infiniband/ulp/ipoib/ipoib_cm.c
index ffec794..f133b56 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_cm.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_cm.c
@@ -713,7 +713,7 @@
while (!list_empty(&priv->cm.rx_error_list) ||
!list_empty(&priv->cm.rx_flush_list) ||
!list_empty(&priv->cm.rx_drain_list)) {
- if (!time_after(jiffies, begin + 5 * HZ)) {
+ if (time_after(jiffies, begin + 5 * HZ)) {
ipoib_warn(priv, "RX drain timing out\n");
/*
@@ -726,6 +726,7 @@
}
spin_unlock_irq(&priv->lock);
msleep(1);
+ ipoib_drain_cq(dev);
spin_lock_irq(&priv->lock);
}
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_ib.c b/drivers/infiniband/ulp/ipoib/ipoib_ib.c
index c1aad06..8404f05b 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_ib.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_ib.c
@@ -550,13 +550,30 @@
return pending;
}
+void ipoib_drain_cq(struct net_device *dev)
+{
+ struct ipoib_dev_priv *priv = netdev_priv(dev);
+ int i, n;
+ do {
+ n = ib_poll_cq(priv->cq, IPOIB_NUM_WC, priv->ibwc);
+ for (i = 0; i < n; ++i) {
+ if (priv->ibwc[i].wr_id & IPOIB_CM_OP_SRQ)
+ ipoib_cm_handle_rx_wc(dev, priv->ibwc + i);
+ else if (priv->ibwc[i].wr_id & IPOIB_OP_RECV)
+ ipoib_ib_handle_rx_wc(dev, priv->ibwc + i);
+ else
+ ipoib_ib_handle_tx_wc(dev, priv->ibwc + i);
+ }
+ } while (n == IPOIB_NUM_WC);
+}
+
int ipoib_ib_dev_stop(struct net_device *dev, int flush)
{
struct ipoib_dev_priv *priv = netdev_priv(dev);
struct ib_qp_attr qp_attr;
unsigned long begin;
struct ipoib_tx_buf *tx_req;
- int i, n;
+ int i;
clear_bit(IPOIB_FLAG_INITIALIZED, &priv->flags);
netif_poll_disable(dev);
@@ -611,17 +628,7 @@
goto timeout;
}
- do {
- n = ib_poll_cq(priv->cq, IPOIB_NUM_WC, priv->ibwc);
- for (i = 0; i < n; ++i) {
- if (priv->ibwc[i].wr_id & IPOIB_CM_OP_SRQ)
- ipoib_cm_handle_rx_wc(dev, priv->ibwc + i);
- else if (priv->ibwc[i].wr_id & IPOIB_OP_RECV)
- ipoib_ib_handle_rx_wc(dev, priv->ibwc + i);
- else
- ipoib_ib_handle_tx_wc(dev, priv->ibwc + i);
- }
- } while (n == IPOIB_NUM_WC);
+ ipoib_drain_cq(dev);
msleep(1);
}
diff --git a/drivers/input/joystick/iforce/iforce-main.c b/drivers/input/joystick/iforce/iforce-main.c
index fb129c4..682244b 100644
--- a/drivers/input/joystick/iforce/iforce-main.c
+++ b/drivers/input/joystick/iforce/iforce-main.c
@@ -370,10 +370,8 @@
/*
* Disable spring, enable force feedback.
- * FIXME: We should use iforce_set_autocenter() et al here.
*/
-
- iforce_send_packet(iforce, FF_CMD_AUTOCENTER, "\004\000");
+ iforce_set_autocenter(input_dev, 0);
/*
* Find appropriate device entry
diff --git a/drivers/input/joystick/iforce/iforce-packets.c b/drivers/input/joystick/iforce/iforce-packets.c
index 21c4e13..3154ccd 100644
--- a/drivers/input/joystick/iforce/iforce-packets.c
+++ b/drivers/input/joystick/iforce/iforce-packets.c
@@ -246,6 +246,8 @@
int iforce_get_id_packet(struct iforce *iforce, char *packet)
{
+ int status;
+
switch (iforce->bus) {
case IFORCE_USB:
@@ -254,18 +256,22 @@
iforce->cr.bRequest = packet[0];
iforce->ctrl->dev = iforce->usbdev;
- if (usb_submit_urb(iforce->ctrl, GFP_ATOMIC))
+ status = usb_submit_urb(iforce->ctrl, GFP_ATOMIC);
+ if (status) {
+ err("usb_submit_urb failed %d", status);
return -1;
+ }
wait_event_interruptible_timeout(iforce->wait,
iforce->ctrl->status != -EINPROGRESS, HZ);
if (iforce->ctrl->status) {
+ dbg("iforce->ctrl->status = %d", iforce->ctrl->status);
usb_unlink_urb(iforce->ctrl);
return -1;
}
#else
- err("iforce_get_id_packet: iforce->bus = USB!");
+ dbg("iforce_get_id_packet: iforce->bus = USB!");
#endif
break;
diff --git a/drivers/input/joystick/iforce/iforce-usb.c b/drivers/input/joystick/iforce/iforce-usb.c
index 750099d..1457b73 100644
--- a/drivers/input/joystick/iforce/iforce-usb.c
+++ b/drivers/input/joystick/iforce/iforce-usb.c
@@ -65,6 +65,7 @@
XMIT_INC(iforce->xmit.tail, n);
if ( (n=usb_submit_urb(iforce->out, GFP_ATOMIC)) ) {
+ clear_bit(IFORCE_XMIT_RUNNING, iforce->xmit_flags);
warn("usb_submit_urb failed %d\n", n);
}
@@ -163,8 +164,8 @@
usb_fill_int_urb(iforce->irq, dev, usb_rcvintpipe(dev, epirq->bEndpointAddress),
iforce->data, 16, iforce_usb_irq, iforce, epirq->bInterval);
- usb_fill_bulk_urb(iforce->out, dev, usb_sndbulkpipe(dev, epout->bEndpointAddress),
- iforce + 1, 32, iforce_usb_out, iforce);
+ usb_fill_int_urb(iforce->out, dev, usb_sndintpipe(dev, epout->bEndpointAddress),
+ iforce + 1, 32, iforce_usb_out, iforce, epout->bInterval);
usb_fill_control_urb(iforce->ctrl, dev, usb_rcvctrlpipe(dev, 0),
(void*) &iforce->cr, iforce->edata, 16, iforce_usb_ctrl, iforce);
diff --git a/drivers/input/misc/input-polldev.c b/drivers/input/misc/input-polldev.c
index 1b2b9c9..b773d4c 100644
--- a/drivers/input/misc/input-polldev.c
+++ b/drivers/input/misc/input-polldev.c
@@ -12,6 +12,11 @@
#include <linux/mutex.h>
#include <linux/input-polldev.h>
+MODULE_AUTHOR("Dmitry Torokhov <dtor@mail.ru>");
+MODULE_DESCRIPTION("Generic implementation of a polled input device");
+MODULE_LICENSE("GPL v2");
+MODULE_VERSION("0.1");
+
static DEFINE_MUTEX(polldev_mutex);
static int polldev_users;
static struct workqueue_struct *polldev_wq;
diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c
index cf3e466..2c5f11a 100644
--- a/drivers/input/mouse/alps.c
+++ b/drivers/input/mouse/alps.c
@@ -251,11 +251,15 @@
dbg("E7 report: %2.2x %2.2x %2.2x", param[0], param[1], param[2]);
- for (i = 0; i < ARRAY_SIZE(rates) && param[2] != rates[i]; i++);
- *version = (param[0] << 8) | (param[1] << 4) | i;
+ if (version) {
+ for (i = 0; i < ARRAY_SIZE(rates) && param[2] != rates[i]; i++)
+ /* empty */;
+ *version = (param[0] << 8) | (param[1] << 4) | i;
+ }
for (i = 0; i < ARRAY_SIZE(alps_model_data); i++)
- if (!memcmp(param, alps_model_data[i].signature, sizeof(alps_model_data[i].signature)))
+ if (!memcmp(param, alps_model_data[i].signature,
+ sizeof(alps_model_data[i].signature)))
return alps_model_data + i;
return NULL;
@@ -380,32 +384,46 @@
return 0;
}
-static int alps_reconnect(struct psmouse *psmouse)
+static int alps_hw_init(struct psmouse *psmouse, int *version)
{
struct alps_data *priv = psmouse->private;
- int version;
- psmouse_reset(psmouse);
-
- if (!(priv->i = alps_get_model(psmouse, &version)))
+ priv->i = alps_get_model(psmouse, version);
+ if (!priv->i)
return -1;
if ((priv->i->flags & ALPS_PASS) && alps_passthrough_mode(psmouse, 1))
return -1;
if (alps_tap_mode(psmouse, 1)) {
- printk(KERN_WARNING "alps.c: Failed to reenable hardware tapping\n");
+ printk(KERN_WARNING "alps.c: Failed to enable hardware tapping\n");
return -1;
}
if (alps_absolute_mode(psmouse)) {
- printk(KERN_ERR "alps.c: Failed to reenable absolute mode\n");
+ printk(KERN_ERR "alps.c: Failed to enable absolute mode\n");
return -1;
}
if ((priv->i->flags & ALPS_PASS) && alps_passthrough_mode(psmouse, 0))
return -1;
+ /* ALPS needs stream mode, otherwise it won't report any data */
+ if (ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_SETSTREAM)) {
+ printk(KERN_ERR "alps.c: Failed to enable stream mode\n");
+ return -1;
+ }
+
+ return 0;
+}
+
+static int alps_reconnect(struct psmouse *psmouse)
+{
+ psmouse_reset(psmouse);
+
+ if (alps_hw_init(psmouse, NULL))
+ return -1;
+
return 0;
}
@@ -430,23 +448,9 @@
goto init_fail;
priv->dev2 = dev2;
+ psmouse->private = priv;
- priv->i = alps_get_model(psmouse, &version);
- if (!priv->i)
- goto init_fail;
-
- if ((priv->i->flags & ALPS_PASS) && alps_passthrough_mode(psmouse, 1))
- goto init_fail;
-
- if (alps_tap_mode(psmouse, 1))
- printk(KERN_WARNING "alps.c: Failed to enable hardware tapping\n");
-
- if (alps_absolute_mode(psmouse)) {
- printk(KERN_ERR "alps.c: Failed to enable absolute mode\n");
- goto init_fail;
- }
-
- if ((priv->i->flags & ALPS_PASS) && alps_passthrough_mode(psmouse, 0))
+ if (alps_hw_init(psmouse, &version))
goto init_fail;
dev1->evbit[LONG(EV_KEY)] |= BIT(EV_KEY);
@@ -493,13 +497,13 @@
/* We are having trouble resyncing ALPS touchpads so disable it for now */
psmouse->resync_time = 0;
- psmouse->private = priv;
return 0;
init_fail:
psmouse_reset(psmouse);
input_free_device(dev2);
kfree(priv);
+ psmouse->private = NULL;
return -1;
}
diff --git a/drivers/input/mouse/logips2pp.c b/drivers/input/mouse/logips2pp.c
index 9df74b7..0c5660d 100644
--- a/drivers/input/mouse/logips2pp.c
+++ b/drivers/input/mouse/logips2pp.c
@@ -221,6 +221,7 @@
{ 66, PS2PP_KIND_MX, /* MX3100 reciver */
PS2PP_WHEEL | PS2PP_SIDE_BTN | PS2PP_TASK_BTN |
PS2PP_EXTRA_BTN | PS2PP_NAV_BTN | PS2PP_HWHEEL },
+ { 72, PS2PP_KIND_TRACKMAN, 0 }, /* T-CH11: TrackMan Marble */
{ 73, 0, PS2PP_SIDE_BTN },
{ 75, PS2PP_KIND_WHEEL, PS2PP_WHEEL },
{ 76, PS2PP_KIND_WHEEL, PS2PP_WHEEL },
diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig
index 4f09180..e5cca9b 100644
--- a/drivers/input/touchscreen/Kconfig
+++ b/drivers/input/touchscreen/Kconfig
@@ -12,17 +12,17 @@
if INPUT_TOUCHSCREEN
config TOUCHSCREEN_ADS7846
- tristate "ADS 7846/7843 based touchscreens"
+ tristate "ADS7846/TSC2046 and ADS7843 based touchscreens"
depends on SPI_MASTER
depends on HWMON = n || HWMON
help
Say Y here if you have a touchscreen interface using the
- ADS7846 or ADS7843 controller, and your board-specific setup
- code includes that in its table of SPI devices.
+ ADS7846/TSC2046 or ADS7843 controller, and your board-specific
+ setup code includes that in its table of SPI devices.
If HWMON is selected, and the driver is told the reference voltage
on your board, you will also get hwmon interfaces for the voltage
- (and on ads7846, temperature) sensors of this chip.
+ (and on ads7846/tsc2046, temperature) sensors of this chip.
If unsure, say N (but it's safe to say "Y").
diff --git a/drivers/input/touchscreen/ads7846.c b/drivers/input/touchscreen/ads7846.c
index 693e3b2..1c9069c 100644
--- a/drivers/input/touchscreen/ads7846.c
+++ b/drivers/input/touchscreen/ads7846.c
@@ -39,6 +39,7 @@
/*
* This code has been heavily tested on a Nokia 770, and lightly
* tested on other ads7846 devices (OSK/Mistral, Lubbock).
+ * TSC2046 is just newer ads7846 silicon.
* Support for ads7843 tested on Atmel at91sam926x-EK.
* Support for ads7845 has only been stubbed in.
*
@@ -847,7 +848,7 @@
* may not. So we stick to very-portable 8 bit words, both RX and TX.
*/
spi->bits_per_word = 8;
- spi->mode = SPI_MODE_1;
+ spi->mode = SPI_MODE_0;
err = spi_setup(spi);
if (err < 0)
return err;
diff --git a/drivers/input/touchscreen/hp680_ts_input.c b/drivers/input/touchscreen/hp680_ts_input.c
index 61c1502..1a15475 100644
--- a/drivers/input/touchscreen/hp680_ts_input.c
+++ b/drivers/input/touchscreen/hp680_ts_input.c
@@ -1,7 +1,6 @@
#include <linux/input.h>
#include <linux/module.h>
#include <linux/init.h>
-
#include <linux/interrupt.h>
#include <asm/io.h>
#include <asm/delay.h>
@@ -18,12 +17,12 @@
#define PHDR 0xa400012e
#define SCPDR 0xa4000136
-static void do_softint(void *data);
+static void do_softint(struct work_struct *work);
static struct input_dev *hp680_ts_dev;
-static DECLARE_WORK(work, do_softint);
+static DECLARE_DELAYED_WORK(work, do_softint);
-static void do_softint(void *data)
+static void do_softint(struct work_struct *work)
{
int absx = 0, absy = 0;
u8 scpdr;
diff --git a/drivers/input/touchscreen/ucb1400_ts.c b/drivers/input/touchscreen/ucb1400_ts.c
index 6582816..f0cbcdb 100644
--- a/drivers/input/touchscreen/ucb1400_ts.c
+++ b/drivers/input/touchscreen/ucb1400_ts.c
@@ -288,9 +288,9 @@
struct ucb1400 *ucb = _ucb;
struct task_struct *tsk = current;
int valid = 0;
+ struct sched_param param = { .sched_priority = 1 };
- tsk->policy = SCHED_FIFO;
- tsk->rt_priority = 1;
+ sched_setscheduler(tsk, SCHED_FIFO, ¶m);
while (!kthread_should_stop()) {
unsigned int x, y, p;
diff --git a/drivers/isdn/hardware/eicon/capifunc.c b/drivers/isdn/hardware/eicon/capifunc.c
index ff284ae..82edc1c 100644
--- a/drivers/isdn/hardware/eicon/capifunc.c
+++ b/drivers/isdn/hardware/eicon/capifunc.c
@@ -189,21 +189,21 @@
{
appl->xbuffer_used[ref] = true;
DBG_PRV1(("%d:xbuf_used(%d)", appl->Id, ref + 1))
- return (void *) ref;
+ return (void *)(long)ref;
}
void *TransmitBufferGet(APPL * appl, void *p)
{
- if (appl->xbuffer_internal[(dword) p])
- return appl->xbuffer_internal[(dword) p];
+ if (appl->xbuffer_internal[(dword)(long)p])
+ return appl->xbuffer_internal[(dword)(long)p];
- return appl->xbuffer_ptr[(dword) p];
+ return appl->xbuffer_ptr[(dword)(long)p];
}
void TransmitBufferFree(APPL * appl, void *p)
{
- appl->xbuffer_used[(dword) p] = false;
- DBG_PRV1(("%d:xbuf_free(%d)", appl->Id, ((dword) p) + 1))
+ appl->xbuffer_used[(dword)(long)p] = false;
+ DBG_PRV1(("%d:xbuf_free(%d)", appl->Id, ((dword)(long)p) + 1))
}
void *ReceiveBufferGet(APPL * appl, int Num)
@@ -301,7 +301,7 @@
/* if DATA_B3_IND, copy data too */
if (command == _DATA_B3_I) {
dword data = GET_DWORD(&msg.info.data_b3_ind.Data);
- memcpy(write + length, (void *) data, dlength);
+ memcpy(write + length, (void *)(long)data, dlength);
}
#ifndef DIVA_NO_DEBUGLIB
@@ -318,7 +318,7 @@
if (myDriverDebugHandle.dbgMask & DL_BLK) {
xlog("\x00\x02", &msg, 0x81, length);
for (i = 0; i < dlength; i += 256) {
- DBG_BLK((((char *) GET_DWORD(&msg.info.data_b3_ind.Data)) + i,
+ DBG_BLK((((char *)(long)GET_DWORD(&msg.info.data_b3_ind.Data)) + i,
((dlength - i) < 256) ? (dlength - i) : 256))
if (!(myDriverDebugHandle.dbgMask & DL_PRV0))
break; /* not more if not explicitely requested */
diff --git a/drivers/isdn/hardware/eicon/message.c b/drivers/isdn/hardware/eicon/message.c
index 784232a..ccd35d0 100644
--- a/drivers/isdn/hardware/eicon/message.c
+++ b/drivers/isdn/hardware/eicon/message.c
@@ -1,4 +1,3 @@
-
/*
*
Copyright (c) Eicon Networks, 2002.
@@ -533,7 +532,7 @@
if (m->header.command == _DATA_B3_R)
{
- m->info.data_b3_req.Data = (dword)(TransmitBufferSet (appl, m->info.data_b3_req.Data));
+ m->info.data_b3_req.Data = (dword)(long)(TransmitBufferSet (appl, m->info.data_b3_req.Data));
}
@@ -1032,7 +1031,7 @@
{
TransmitBufferFree (plci->appl,
- (byte *)(((CAPI_MSG *)(&((byte *)(plci->msg_in_queue))[i]))->info.data_b3_req.Data));
+ (byte *)(long)(((CAPI_MSG *)(&((byte *)(plci->msg_in_queue))[i]))->info.data_b3_req.Data));
}
@@ -3118,7 +3117,7 @@
&& (((byte *)(parms[0].info)) < ((byte *)(plci->msg_in_queue)) + sizeof(plci->msg_in_queue)))
{
- data->P = (byte *)(*((dword *)(parms[0].info)));
+ data->P = (byte *)(long)(*((dword *)(parms[0].info)));
}
else
@@ -3151,7 +3150,7 @@
&& (((byte *)(parms[0].info)) < ((byte *)(plci->msg_in_queue)) + sizeof(plci->msg_in_queue)))
{
- TransmitBufferFree (appl, (byte *)(*((dword *)(parms[0].info))));
+ TransmitBufferFree (appl, (byte *)(long)(*((dword *)(parms[0].info))));
}
}
@@ -4057,7 +4056,7 @@
{
if (m->header.command == _DATA_B3_R)
- TransmitBufferFree (appl, (byte *)(m->info.data_b3_req.Data));
+ TransmitBufferFree (appl, (byte *)(long)(m->info.data_b3_req.Data));
dbug(1,dprintf("Error 0x%04x from msg(0x%04x)", i, m->header.command));
break;
@@ -7134,7 +7133,7 @@
case N_UDATA:
if (!(udata_forwarding_table[plci->NL.RBuffer->P[0] >> 5] & (1L << (plci->NL.RBuffer->P[0] & 0x1f))))
{
- plci->RData[0].P = plci->internal_ind_buffer + (-((int)(plci->internal_ind_buffer)) & 3);
+ plci->RData[0].P = plci->internal_ind_buffer + (-((int)(long)(plci->internal_ind_buffer)) & 3);
plci->RData[0].PLength = INTERNAL_IND_BUFFER_SIZE;
plci->NL.R = plci->RData;
plci->NL.RNum = 1;
diff --git a/drivers/isdn/hisax/config.c b/drivers/isdn/hisax/config.c
index da4196f2..8d53a7f 100644
--- a/drivers/isdn/hisax/config.c
+++ b/drivers/isdn/hisax/config.c
@@ -1551,7 +1551,7 @@
if (retval == 0) { // yuck
cards[i].typ = 0;
nrcards--;
- return retval;
+ return -EINVAL;
}
cs = cards[i].cs;
hisax_d_if->cs = cs;
diff --git a/drivers/isdn/hisax/hfc_usb.c b/drivers/isdn/hisax/hfc_usb.c
index 1f18f19..b1a26e0 100644
--- a/drivers/isdn/hisax/hfc_usb.c
+++ b/drivers/isdn/hisax/hfc_usb.c
@@ -485,7 +485,6 @@
{
int k;
- spin_lock_init(&urb->lock);
urb->dev = dev;
urb->pipe = pipe;
urb->complete = complete;
@@ -578,16 +577,14 @@
"HFC-S USB: Stopping iso chain for fifo %i.%i",
fifo->fifonum, i);
#endif
- usb_unlink_urb(fifo->iso[i].purb);
+ usb_kill_urb(fifo->iso[i].purb);
usb_free_urb(fifo->iso[i].purb);
fifo->iso[i].purb = NULL;
}
}
- if (fifo->urb) {
- usb_unlink_urb(fifo->urb);
- usb_free_urb(fifo->urb);
- fifo->urb = NULL;
- }
+ usb_kill_urb(fifo->urb);
+ usb_free_urb(fifo->urb);
+ fifo->urb = NULL;
fifo->active = 0;
}
@@ -1305,7 +1302,11 @@
}
/* default Prot: EURO ISDN, should be a module_param */
hfc->protocol = 2;
- hisax_register(&hfc->d_if, p_b_if, "hfc_usb", hfc->protocol);
+ i = hisax_register(&hfc->d_if, p_b_if, "hfc_usb", hfc->protocol);
+ if (i) {
+ printk(KERN_INFO "HFC-S USB: hisax_register -> %d\n", i);
+ return i;
+ }
#ifdef CONFIG_HISAX_DEBUG
hfc_debug = debug;
@@ -1626,11 +1627,9 @@
#endif
/* init the chip and register the driver */
if (usb_init(context)) {
- if (context->ctrl_urb) {
- usb_unlink_urb(context->ctrl_urb);
- usb_free_urb(context->ctrl_urb);
- context->ctrl_urb = NULL;
- }
+ usb_kill_urb(context->ctrl_urb);
+ usb_free_urb(context->ctrl_urb);
+ context->ctrl_urb = NULL;
kfree(context);
return (-EIO);
}
@@ -1682,21 +1681,15 @@
i);
#endif
}
- if (context->fifos[i].urb) {
- usb_unlink_urb(context->fifos[i].urb);
- usb_free_urb(context->fifos[i].urb);
- context->fifos[i].urb = NULL;
- }
+ usb_kill_urb(context->fifos[i].urb);
+ usb_free_urb(context->fifos[i].urb);
+ context->fifos[i].urb = NULL;
}
context->fifos[i].active = 0;
}
- /* wait for all URBS to terminate */
- mdelay(10);
- if (context->ctrl_urb) {
- usb_unlink_urb(context->ctrl_urb);
- usb_free_urb(context->ctrl_urb);
- context->ctrl_urb = NULL;
- }
+ usb_kill_urb(context->ctrl_urb);
+ usb_free_urb(context->ctrl_urb);
+ context->ctrl_urb = NULL;
hisax_unregister(&context->d_if);
kfree(context); /* free our structure again */
} /* hfc_usb_disconnect */
diff --git a/drivers/isdn/hisax/hisax_fcpcipnp.c b/drivers/isdn/hisax/hisax_fcpcipnp.c
index 9e088fc..7993e01 100644
--- a/drivers/isdn/hisax/hisax_fcpcipnp.c
+++ b/drivers/isdn/hisax/hisax_fcpcipnp.c
@@ -859,7 +859,11 @@
for (i = 0; i < 2; i++)
b_if[i] = &adapter->bcs[i].b_if;
- hisax_register(&adapter->isac.hisax_d_if, b_if, "fcpcipnp", protocol);
+ if (hisax_register(&adapter->isac.hisax_d_if, b_if, "fcpcipnp",
+ protocol) != 0) {
+ kfree(adapter);
+ adapter = NULL;
+ }
return adapter;
}
diff --git a/drivers/isdn/hisax/st5481_init.c b/drivers/isdn/hisax/st5481_init.c
index bb3a28a..1375123 100644
--- a/drivers/isdn/hisax/st5481_init.c
+++ b/drivers/isdn/hisax/st5481_init.c
@@ -107,12 +107,17 @@
for (i = 0; i < 2; i++)
b_if[i] = &adapter->bcs[i].b_if;
- hisax_register(&adapter->hisax_d_if, b_if, "st5481_usb", protocol);
+ if (hisax_register(&adapter->hisax_d_if, b_if, "st5481_usb",
+ protocol) != 0)
+ goto err_b1;
+
st5481_start(adapter);
usb_set_intfdata(intf, adapter);
return 0;
+ err_b1:
+ st5481_release_b(&adapter->bcs[1]);
err_b:
st5481_release_b(&adapter->bcs[0]);
err_d:
diff --git a/drivers/isdn/hisax/st5481_usb.c b/drivers/isdn/hisax/st5481_usb.c
index ff15951..4ada66b 100644
--- a/drivers/isdn/hisax/st5481_usb.c
+++ b/drivers/isdn/hisax/st5481_usb.c
@@ -407,7 +407,6 @@
{
int k;
- spin_lock_init(&urb->lock);
urb->dev=dev;
urb->pipe=pipe;
urb->interval = 1;
diff --git a/drivers/macintosh/adbhid.c b/drivers/macintosh/adbhid.c
index b77ef51..b46817f 100644
--- a/drivers/macintosh/adbhid.c
+++ b/drivers/macintosh/adbhid.c
@@ -628,16 +628,16 @@
*/
static int adbhid_kbd_event(struct input_dev *dev, unsigned int type, unsigned int code, int value)
{
- struct adbhid *adbhid = dev->private;
+ struct adbhid *adbhid = input_get_drvdata(dev);
unsigned char leds;
switch (type) {
case EV_LED:
- leds = (test_bit(LED_SCROLLL, dev->led) ? 4 : 0)
- | (test_bit(LED_NUML, dev->led) ? 1 : 0)
- | (test_bit(LED_CAPSL, dev->led) ? 2 : 0);
- real_leds(leds, adbhid->id);
- return 0;
+ leds = (test_bit(LED_SCROLLL, dev->led) ? 4 : 0) |
+ (test_bit(LED_NUML, dev->led) ? 1 : 0) |
+ (test_bit(LED_CAPSL, dev->led) ? 2 : 0);
+ real_leds(leds, adbhid->id);
+ return 0;
}
return -1;
@@ -649,7 +649,7 @@
switch (code) {
case ADB_MSG_PRE_RESET:
case ADB_MSG_POWERDOWN:
- /* Stop the repeat timer. Autopoll is already off at this point */
+ /* Stop the repeat timer. Autopoll is already off at this point */
{
int i;
for (i = 1; i < 16; i++) {
@@ -699,7 +699,7 @@
hid->current_handler_id = current_handler_id;
hid->mouse_kind = mouse_kind;
hid->flags = 0;
- input_dev->private = hid;
+ input_set_drvdata(input_dev, hid);
input_dev->name = hid->name;
input_dev->phys = hid->phys;
input_dev->id.bustype = BUS_ADB;
diff --git a/drivers/md/bitmap.c b/drivers/md/bitmap.c
index 5a4a74c..9620d45 100644
--- a/drivers/md/bitmap.c
+++ b/drivers/md/bitmap.c
@@ -255,19 +255,25 @@
}
-static int write_sb_page(mddev_t *mddev, long offset, struct page *page, int wait)
+static int write_sb_page(struct bitmap *bitmap, struct page *page, int wait)
{
mdk_rdev_t *rdev;
struct list_head *tmp;
+ mddev_t *mddev = bitmap->mddev;
ITERATE_RDEV(mddev, rdev, tmp)
if (test_bit(In_sync, &rdev->flags)
- && !test_bit(Faulty, &rdev->flags))
+ && !test_bit(Faulty, &rdev->flags)) {
+ int size = PAGE_SIZE;
+ if (page->index == bitmap->file_pages-1)
+ size = roundup(bitmap->last_page_size,
+ bdev_hardsect_size(rdev->bdev));
md_super_write(mddev, rdev,
- (rdev->sb_offset<<1) + offset
+ (rdev->sb_offset<<1) + bitmap->offset
+ page->index * (PAGE_SIZE/512),
- PAGE_SIZE,
+ size,
page);
+ }
if (wait)
md_super_wait(mddev);
@@ -282,7 +288,7 @@
struct buffer_head *bh;
if (bitmap->file == NULL)
- return write_sb_page(bitmap->mddev, bitmap->offset, page, wait);
+ return write_sb_page(bitmap, page, wait);
bh = page_buffers(page);
@@ -923,6 +929,7 @@
}
bitmap->filemap[bitmap->file_pages++] = page;
+ bitmap->last_page_size = count;
}
paddr = kmap_atomic(page, KM_USER0);
if (bitmap->flags & BITMAP_HOSTENDIAN)
diff --git a/drivers/md/linear.c b/drivers/md/linear.c
index d5ecd2d..1927410 100644
--- a/drivers/md/linear.c
+++ b/drivers/md/linear.c
@@ -139,8 +139,6 @@
if (!conf)
return NULL;
- mddev->private = conf;
-
cnt = 0;
conf->array_size = 0;
@@ -232,7 +230,7 @@
* First calculate the device offsets.
*/
conf->disks[0].offset = 0;
- for (i=1; i<mddev->raid_disks; i++)
+ for (i = 1; i < raid_disks; i++)
conf->disks[i].offset =
conf->disks[i-1].offset +
conf->disks[i-1].size;
@@ -244,7 +242,7 @@
curr_offset < conf->array_size;
curr_offset += conf->hash_spacing) {
- while (i < mddev->raid_disks-1 &&
+ while (i < raid_disks-1 &&
curr_offset >= conf->disks[i+1].offset)
i++;
@@ -299,9 +297,11 @@
*/
linear_conf_t *newconf;
- if (rdev->raid_disk != mddev->raid_disks)
+ if (rdev->saved_raid_disk != mddev->raid_disks)
return -EINVAL;
+ rdev->raid_disk = rdev->saved_raid_disk;
+
newconf = linear_conf(mddev,mddev->raid_disks+1);
if (!newconf)
diff --git a/drivers/md/md.c b/drivers/md/md.c
index c10ce91..1c54f3c 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -1298,8 +1298,9 @@
ITERATE_RDEV(mddev,rdev2,tmp)
if (rdev2->desc_nr+1 > max_dev)
max_dev = rdev2->desc_nr+1;
-
- sb->max_dev = cpu_to_le32(max_dev);
+
+ if (max_dev > le32_to_cpu(sb->max_dev))
+ sb->max_dev = cpu_to_le32(max_dev);
for (i=0; i<max_dev;i++)
sb->dev_roles[i] = cpu_to_le16(0xfffe);
@@ -1365,10 +1366,14 @@
}
/* make sure rdev->size exceeds mddev->size */
if (rdev->size && (mddev->size == 0 || rdev->size < mddev->size)) {
- if (mddev->pers)
- /* Cannot change size, so fail */
- return -ENOSPC;
- else
+ if (mddev->pers) {
+ /* Cannot change size, so fail
+ * If mddev->level <= 0, then we don't care
+ * about aligning sizes (e.g. linear)
+ */
+ if (mddev->level > 0)
+ return -ENOSPC;
+ } else
mddev->size = rdev->size;
}
@@ -2142,6 +2147,9 @@
rdev->desc_nr = i++;
rdev->raid_disk = rdev->desc_nr;
set_bit(In_sync, &rdev->flags);
+ } else if (rdev->raid_disk >= mddev->raid_disks) {
+ rdev->raid_disk = -1;
+ clear_bit(In_sync, &rdev->flags);
}
}
diff --git a/drivers/md/raid0.c b/drivers/md/raid0.c
index dfe3214..2c404f7 100644
--- a/drivers/md/raid0.c
+++ b/drivers/md/raid0.c
@@ -415,7 +415,7 @@
raid0_conf_t *conf = mddev_to_conf(mddev);
struct strip_zone *zone;
mdk_rdev_t *tmp_dev;
- unsigned long chunk;
+ sector_t chunk;
sector_t block, rsect;
const int rw = bio_data_dir(bio);
@@ -470,7 +470,6 @@
sector_div(x, zone->nb_dev);
chunk = x;
- BUG_ON(x != (sector_t)chunk);
x = block >> chunksize_bits;
tmp_dev = zone->dev[sector_div(x, zone->nb_dev)];
diff --git a/drivers/media/dvb/bt8xx/dst.c b/drivers/media/dvb/bt8xx/dst.c
index 0393a3d..e908e3c 100644
--- a/drivers/media/dvb/bt8xx/dst.c
+++ b/drivers/media/dvb/bt8xx/dst.c
@@ -1721,9 +1721,6 @@
symbol_put(dst_ca_attach);
#endif
}
-#ifdef CONFIG_DVB_CORE_ATTACH
- symbol_put(dst_attach);
-#endif
kfree(state);
}
diff --git a/drivers/media/dvb/dvb-core/dvbdev.c b/drivers/media/dvb/dvb-core/dvbdev.c
index e23d8a0..a9fa333 100644
--- a/drivers/media/dvb/dvb-core/dvbdev.c
+++ b/drivers/media/dvb/dvb-core/dvbdev.c
@@ -200,7 +200,7 @@
{
struct dvb_device *dvbdev;
struct file_operations *dvbdevfops;
-
+ struct class_device *clsdev;
int id;
mutex_lock(&dvbdev_register_lock);
@@ -242,8 +242,15 @@
mutex_unlock(&dvbdev_register_lock);
- class_device_create(dvb_class, NULL, MKDEV(DVB_MAJOR, nums2minor(adap->num, type, id)),
- adap->device, "dvb%d.%s%d", adap->num, dnames[type], id);
+ clsdev = class_device_create(dvb_class, NULL, MKDEV(DVB_MAJOR,
+ nums2minor(adap->num, type, id)),
+ adap->device, "dvb%d.%s%d", adap->num,
+ dnames[type], id);
+ if (IS_ERR(clsdev)) {
+ printk(KERN_ERR "%s: failed to create device dvb%d.%s%d (%ld)\n",
+ __FUNCTION__, adap->num, dnames[type], id, PTR_ERR(clsdev));
+ return PTR_ERR(clsdev);
+ }
dprintk("DVB: register adapter%d/%s%d @ minor: %i (0x%02x)\n",
adap->num, dnames[type], id, nums2minor(adap->num, type, id),
@@ -431,7 +438,7 @@
unregister_chrdev_region(MKDEV(DVB_MAJOR, 0), MAX_DVB_MINORS);
}
-module_init(init_dvbdev);
+subsys_initcall(init_dvbdev);
module_exit(exit_dvbdev);
MODULE_DESCRIPTION("DVB Core Driver");
diff --git a/drivers/media/video/cafe_ccic-regs.h b/drivers/media/video/cafe_ccic-regs.h
index b2c22a0..8e2a87cd 100644
--- a/drivers/media/video/cafe_ccic-regs.h
+++ b/drivers/media/video/cafe_ccic-regs.h
@@ -150,6 +150,12 @@
#define REG_GL_IMASK 0x300c /* Interrupt mask register */
#define GIMSK_CCIC_EN 0x00000004 /* CCIC Interrupt enable */
+#define REG_GL_FCR 0x3038 /* GPIO functional control register */
+#define GFCR_GPIO_ON 0x08 /* Camera GPIO enabled */
+#define REG_GL_GPIOR 0x315c /* GPIO register */
+#define GGPIO_OUT 0x80000 /* GPIO output */
+#define GGPIO_VAL 0x00008 /* Output pin value */
+
#define REG_LEN REG_GL_IMASK + 4
diff --git a/drivers/media/video/cafe_ccic.c b/drivers/media/video/cafe_ccic.c
index 96254db..c08f650 100644
--- a/drivers/media/video/cafe_ccic.c
+++ b/drivers/media/video/cafe_ccic.c
@@ -775,6 +775,12 @@
spin_lock_irqsave(&cam->dev_lock, flags);
cafe_reg_clear_bit(cam, REG_CTRL1, C1_PWRDWN);
/*
+ * Part one of the sensor dance: turn the global
+ * GPIO signal on.
+ */
+ cafe_reg_write(cam, REG_GL_FCR, GFCR_GPIO_ON);
+ cafe_reg_write(cam, REG_GL_GPIOR, GGPIO_OUT|GGPIO_VAL);
+ /*
* Put the sensor into operational mode (assumes OLPC-style
* wiring). Control 0 is reset - set to 1 to operate.
* Control 1 is power down, set to 0 to operate.
@@ -784,6 +790,7 @@
cafe_reg_write(cam, REG_GPR, GPR_C1EN|GPR_C0EN|GPR_C0);
// mdelay(1); /* Enough? */
spin_unlock_irqrestore(&cam->dev_lock, flags);
+ msleep(5); /* Just to be sure */
}
static void cafe_ctlr_power_down(struct cafe_camera *cam)
@@ -792,6 +799,8 @@
spin_lock_irqsave(&cam->dev_lock, flags);
cafe_reg_write(cam, REG_GPR, GPR_C1EN|GPR_C0EN|GPR_C1);
+ cafe_reg_write(cam, REG_GL_FCR, GFCR_GPIO_ON);
+ cafe_reg_write(cam, REG_GL_GPIOR, GGPIO_OUT);
cafe_reg_set_bit(cam, REG_CTRL1, C1_PWRDWN);
spin_unlock_irqrestore(&cam->dev_lock, flags);
}
@@ -851,6 +860,7 @@
ret = 0;
cam->state = S_IDLE;
out:
+ cafe_ctlr_power_down(cam);
mutex_unlock(&cam->s_mutex);
return ret;
}
@@ -2103,10 +2113,16 @@
ret = request_irq(pdev->irq, cafe_irq, IRQF_SHARED, "cafe-ccic", cam);
if (ret)
goto out_iounmap;
+ /*
+ * Initialize the controller and leave it powered up. It will
+ * stay that way until the sensor driver shows up.
+ */
cafe_ctlr_init(cam);
cafe_ctlr_power_up(cam);
/*
- * Set up I2C/SMBUS communications
+ * Set up I2C/SMBUS communications. We have to drop the mutex here
+ * because the sensor could attach in this call chain, leading to
+ * unsightly deadlocks.
*/
mutex_unlock(&cam->s_mutex); /* attach can deadlock */
ret = cafe_smbus_setup(cam);
diff --git a/drivers/media/video/em28xx/Kconfig b/drivers/media/video/em28xx/Kconfig
index 2c450bd..5b6a403 100644
--- a/drivers/media/video/em28xx/Kconfig
+++ b/drivers/media/video/em28xx/Kconfig
@@ -1,7 +1,6 @@
config VIDEO_EM28XX
tristate "Empia EM2800/2820/2840 USB video capture support"
- depends on VIDEO_V4L1 && I2C && PCI
- select VIDEO_BUF
+ depends on VIDEO_V4L1 && I2C
select VIDEO_TUNER
select VIDEO_TVEEPROM
select VIDEO_IR
diff --git a/drivers/media/video/ivtv/Kconfig b/drivers/media/video/ivtv/Kconfig
index 0cc98a0..1aaeaa0 100644
--- a/drivers/media/video/ivtv/Kconfig
+++ b/drivers/media/video/ivtv/Kconfig
@@ -1,6 +1,6 @@
config VIDEO_IVTV
tristate "Conexant cx23416/cx23415 MPEG encoder/decoder support"
- depends on VIDEO_V4L1 && VIDEO_V4L2 && USB && I2C && EXPERIMENTAL && PCI
+ depends on VIDEO_V4L1 && VIDEO_V4L2 && PCI && I2C && EXPERIMENTAL
select FW_LOADER
select VIDEO_TUNER
select VIDEO_TVEEPROM
diff --git a/drivers/media/video/ivtv/ivtv-driver.h b/drivers/media/video/ivtv/ivtv-driver.h
index 9a412d6..552f045 100644
--- a/drivers/media/video/ivtv/ivtv-driver.h
+++ b/drivers/media/video/ivtv/ivtv-driver.h
@@ -67,14 +67,6 @@
#include <media/ivtv.h>
-#ifdef CONFIG_LIRC_I2C
-# error "This driver is not compatible with the LIRC I2C kernel configuration option."
-#endif /* CONFIG_LIRC_I2C */
-
-#ifndef CONFIG_PCI
-# error "This driver requires kernel PCI support."
-#endif /* CONFIG_PCI */
-
#define IVTV_ENCODER_OFFSET 0x00000000
#define IVTV_ENCODER_SIZE 0x00800000 /* Last half isn't needed 0x01000000 */
diff --git a/drivers/media/video/ivtv/ivtv-ioctl.c b/drivers/media/video/ivtv/ivtv-ioctl.c
index 794a6a0..1989ec1 100644
--- a/drivers/media/video/ivtv/ivtv-ioctl.c
+++ b/drivers/media/video/ivtv/ivtv-ioctl.c
@@ -362,8 +362,6 @@
case V4L2_BUF_TYPE_VIDEO_OUTPUT:
if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
return -EINVAL;
- fmt->fmt.pix.left = itv->main_rect.left;
- fmt->fmt.pix.top = itv->main_rect.top;
fmt->fmt.pix.width = itv->main_rect.width;
fmt->fmt.pix.height = itv->main_rect.height;
fmt->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
@@ -402,8 +400,6 @@
break;
case V4L2_BUF_TYPE_VIDEO_CAPTURE:
- fmt->fmt.pix.left = 0;
- fmt->fmt.pix.top = 0;
fmt->fmt.pix.width = itv->params.width;
fmt->fmt.pix.height = itv->params.height;
fmt->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
@@ -498,15 +494,13 @@
if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
return -EINVAL;
field = fmt->fmt.pix.field;
- r.top = fmt->fmt.pix.top;
- r.left = fmt->fmt.pix.left;
+ r.top = 0;
+ r.left = 0;
r.width = fmt->fmt.pix.width;
r.height = fmt->fmt.pix.height;
ivtv_get_fmt(itv, streamtype, fmt);
if (itv->output_mode != OUT_UDMA_YUV) {
/* TODO: would setting the rect also be valid for this mode? */
- fmt->fmt.pix.top = r.top;
- fmt->fmt.pix.left = r.left;
fmt->fmt.pix.width = r.width;
fmt->fmt.pix.height = r.height;
}
@@ -1141,8 +1135,6 @@
fb->fmt.pixelformat = itv->osd_pixelformat;
fb->fmt.width = itv->osd_rect.width;
fb->fmt.height = itv->osd_rect.height;
- fb->fmt.left = itv->osd_rect.left;
- fb->fmt.top = itv->osd_rect.top;
fb->base = (void *)itv->osd_video_pbase;
if (itv->osd_global_alpha_state)
fb->flags |= V4L2_FBUF_FLAG_GLOBAL_ALPHA;
diff --git a/drivers/media/video/ov7670.c b/drivers/media/video/ov7670.c
index 03bc369..3ceb8a6 100644
--- a/drivers/media/video/ov7670.c
+++ b/drivers/media/video/ov7670.c
@@ -720,12 +720,22 @@
struct ov7670_format_struct *ovfmt;
struct ov7670_win_size *wsize;
struct ov7670_info *info = i2c_get_clientdata(c);
- unsigned char com7;
+ unsigned char com7, clkrc;
ret = ov7670_try_fmt(c, fmt, &ovfmt, &wsize);
if (ret)
return ret;
/*
+ * HACK: if we're running rgb565 we need to grab then rewrite
+ * CLKRC. If we're *not*, however, then rewriting clkrc hoses
+ * the colors.
+ */
+ if (fmt->fmt.pix.pixelformat == V4L2_PIX_FMT_RGB565) {
+ ret = ov7670_read(c, REG_CLKRC, &clkrc);
+ if (ret)
+ return ret;
+ }
+ /*
* COM7 is a pain in the ass, it doesn't like to be read then
* quickly written afterward. But we have everything we need
* to set it absolutely here, as long as the format-specific
@@ -744,7 +754,10 @@
if (wsize->regs)
ret = ov7670_write_array(c, wsize->regs);
info->fmt = ovfmt;
- return 0;
+
+ if (fmt->fmt.pix.pixelformat == V4L2_PIX_FMT_RGB565 && ret == 0)
+ ret = ov7670_write(c, REG_CLKRC, clkrc);
+ return ret;
}
/*
@@ -1267,7 +1280,9 @@
ret = ov7670_detect(client);
if (ret)
goto out_free_info;
- i2c_attach_client(client);
+ ret = i2c_attach_client(client);
+ if (ret)
+ goto out_free_info;
return 0;
out_free_info:
diff --git a/drivers/media/video/tuner-simple.c b/drivers/media/video/tuner-simple.c
index 1b9b074..c40b92c 100644
--- a/drivers/media/video/tuner-simple.c
+++ b/drivers/media/video/tuner-simple.c
@@ -205,9 +205,13 @@
/* 0x01 -> ??? no change ??? */
/* 0x02 -> PAL BDGHI / SECAM L */
/* 0x04 -> ??? PAL others / SECAM others ??? */
- cb &= ~0x02;
- if (t->std & V4L2_STD_SECAM)
- cb |= 0x02;
+ cb &= ~0x03;
+ if (t->std & V4L2_STD_SECAM_L) //also valid for V4L2_STD_SECAM
+ cb |= PHILIPS_MF_SET_PAL_L;
+ else if (t->std & V4L2_STD_SECAM_LC)
+ cb |= PHILIPS_MF_SET_PAL_L2;
+ else /* V4L2_STD_B|V4L2_STD_GH */
+ cb |= PHILIPS_MF_SET_BG;
break;
case TUNER_TEMIC_4046FM5:
diff --git a/drivers/message/fusion/mptbase.h b/drivers/message/fusion/mptbase.h
index d25d3be..165f81d 100644
--- a/drivers/message/fusion/mptbase.h
+++ b/drivers/message/fusion/mptbase.h
@@ -436,7 +436,7 @@
typedef struct _mpt_ioctl_events {
u32 event; /* Specified by define above */
u32 eventContext; /* Index or counter */
- int data[2]; /* First 8 bytes of Event Data */
+ u32 data[2]; /* First 8 bytes of Event Data */
} MPT_IOCTL_EVENTS;
/*
diff --git a/drivers/message/fusion/mptscsih.c b/drivers/message/fusion/mptscsih.c
index fa0f776..3bd94f1 100644
--- a/drivers/message/fusion/mptscsih.c
+++ b/drivers/message/fusion/mptscsih.c
@@ -2463,11 +2463,11 @@
ioc->events[idx].event = MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE;
ioc->events[idx].eventContext = ioc->eventContext;
- ioc->events[idx].data[0] = (pReq->LUN[1] << 24) ||
- (MPI_EVENT_SCSI_DEV_STAT_RC_SMART_DATA << 16) ||
- (sc->device->channel << 8) || sc->device->id;
+ ioc->events[idx].data[0] = (pReq->LUN[1] << 24) |
+ (MPI_EVENT_SCSI_DEV_STAT_RC_SMART_DATA << 16) |
+ (sc->device->channel << 8) | sc->device->id;
- ioc->events[idx].data[1] = (sense_data[13] << 8) || sense_data[12];
+ ioc->events[idx].data[1] = (sense_data[13] << 8) | sense_data[12];
ioc->eventContext++;
if (hd->ioc->pcidev->vendor ==
diff --git a/drivers/message/i2o/driver.c b/drivers/message/i2o/driver.c
index d3235f2..e0d474b 100644
--- a/drivers/message/i2o/driver.c
+++ b/drivers/message/i2o/driver.c
@@ -123,8 +123,12 @@
}
rc = driver_register(&drv->driver);
- if (rc)
- destroy_workqueue(drv->event_queue);
+ if (rc) {
+ if (drv->event) {
+ destroy_workqueue(drv->event_queue);
+ drv->event_queue = NULL;
+ }
+ }
return rc;
};
@@ -256,7 +260,7 @@
int i;
struct i2o_driver *drv;
- for (i = 0; i < I2O_MAX_DRIVERS; i++) {
+ for (i = 0; i < i2o_max_drivers; i++) {
drv = i2o_drivers[i];
if (drv)
@@ -276,7 +280,7 @@
int i;
struct i2o_driver *drv;
- for (i = 0; i < I2O_MAX_DRIVERS; i++) {
+ for (i = 0; i < i2o_max_drivers; i++) {
drv = i2o_drivers[i];
if (drv)
@@ -295,7 +299,7 @@
int i;
struct i2o_driver *drv;
- for (i = 0; i < I2O_MAX_DRIVERS; i++) {
+ for (i = 0; i < i2o_max_drivers; i++) {
drv = i2o_drivers[i];
if (drv)
@@ -314,7 +318,7 @@
int i;
struct i2o_driver *drv;
- for (i = 0; i < I2O_MAX_DRIVERS; i++) {
+ for (i = 0; i < i2o_max_drivers; i++) {
drv = i2o_drivers[i];
if (drv)
@@ -335,17 +339,15 @@
spin_lock_init(&i2o_drivers_lock);
- if ((i2o_max_drivers < 2) || (i2o_max_drivers > 64) ||
- ((i2o_max_drivers ^ (i2o_max_drivers - 1)) !=
- (2 * i2o_max_drivers - 1))) {
- osm_warn("max_drivers set to %d, but must be >=2 and <= 64 and "
- "a power of 2\n", i2o_max_drivers);
+ if ((i2o_max_drivers < 2) || (i2o_max_drivers > 64)) {
+ osm_warn("max_drivers set to %d, but must be >=2 and <= 64\n",
+ i2o_max_drivers);
i2o_max_drivers = I2O_MAX_DRIVERS;
}
osm_info("max drivers = %d\n", i2o_max_drivers);
i2o_drivers =
- kzalloc(i2o_max_drivers * sizeof(*i2o_drivers), GFP_KERNEL);
+ kcalloc(i2o_max_drivers, sizeof(*i2o_drivers), GFP_KERNEL);
if (!i2o_drivers)
return -ENOMEM;
diff --git a/drivers/mfd/ucb1x00-ts.c b/drivers/mfd/ucb1x00-ts.c
index cb8c264..7772bd1 100644
--- a/drivers/mfd/ucb1x00-ts.c
+++ b/drivers/mfd/ucb1x00-ts.c
@@ -207,16 +207,7 @@
struct ucb1x00_ts *ts = _ts;
struct task_struct *tsk = current;
DECLARE_WAITQUEUE(wait, tsk);
- int valid;
-
- /*
- * We could run as a real-time thread. However, thus far
- * this doesn't seem to be necessary.
- */
-// tsk->policy = SCHED_FIFO;
-// tsk->rt_priority = 1;
-
- valid = 0;
+ int valid = 0;
add_wait_queue(&ts->irq_wait, &wait);
while (!kthread_should_stop()) {
diff --git a/drivers/misc/phantom.c b/drivers/misc/phantom.c
index 35b139b..5108b7c 100644
--- a/drivers/misc/phantom.c
+++ b/drivers/misc/phantom.c
@@ -47,6 +47,7 @@
struct cdev cdev;
struct mutex open_lock;
+ spinlock_t ioctl_lock;
};
static unsigned char phantom_devices[PHANTOM_MAX_MINORS];
@@ -59,8 +60,11 @@
atomic_set(&dev->counter, 0);
iowrite32(PHN_CTL_IRQ, dev->iaddr + PHN_CONTROL);
iowrite32(0x43, dev->caddr + PHN_IRQCTL);
- } else if ((dev->status & PHB_RUNNING) && !(newstat & PHB_RUNNING))
+ ioread32(dev->caddr + PHN_IRQCTL); /* PCI posting */
+ } else if ((dev->status & PHB_RUNNING) && !(newstat & PHB_RUNNING)) {
iowrite32(0, dev->caddr + PHN_IRQCTL);
+ ioread32(dev->caddr + PHN_IRQCTL); /* PCI posting */
+ }
dev->status = newstat;
@@ -71,8 +75,8 @@
* File ops
*/
-static int phantom_ioctl(struct inode *inode, struct file *file, u_int cmd,
- u_long arg)
+static long phantom_ioctl(struct file *file, unsigned int cmd,
+ unsigned long arg)
{
struct phantom_device *dev = file->private_data;
struct phm_regs rs;
@@ -92,24 +96,32 @@
if (r.reg > 7)
return -EINVAL;
+ spin_lock(&dev->ioctl_lock);
if (r.reg == PHN_CONTROL && (r.value & PHN_CTL_IRQ) &&
- phantom_status(dev, dev->status | PHB_RUNNING))
+ phantom_status(dev, dev->status | PHB_RUNNING)){
+ spin_unlock(&dev->ioctl_lock);
return -ENODEV;
+ }
pr_debug("phantom: writing %x to %u\n", r.value, r.reg);
iowrite32(r.value, dev->iaddr + r.reg);
+ ioread32(dev->iaddr); /* PCI posting */
if (r.reg == PHN_CONTROL && !(r.value & PHN_CTL_IRQ))
phantom_status(dev, dev->status & ~PHB_RUNNING);
+ spin_unlock(&dev->ioctl_lock);
break;
case PHN_SET_REGS:
if (copy_from_user(&rs, argp, sizeof(rs)))
return -EFAULT;
pr_debug("phantom: SRS %u regs %x\n", rs.count, rs.mask);
+ spin_lock(&dev->ioctl_lock);
for (i = 0; i < min(rs.count, 8U); i++)
if ((1 << i) & rs.mask)
iowrite32(rs.values[i], dev->oaddr + i);
+ ioread32(dev->iaddr); /* PCI posting */
+ spin_unlock(&dev->ioctl_lock);
break;
case PHN_GET_REG:
if (copy_from_user(&r, argp, sizeof(r)))
@@ -128,9 +140,11 @@
return -EFAULT;
pr_debug("phantom: GRS %u regs %x\n", rs.count, rs.mask);
+ spin_lock(&dev->ioctl_lock);
for (i = 0; i < min(rs.count, 8U); i++)
if ((1 << i) & rs.mask)
rs.values[i] = ioread32(dev->iaddr + i);
+ spin_unlock(&dev->ioctl_lock);
if (copy_to_user(argp, &rs, sizeof(rs)))
return -EFAULT;
@@ -199,7 +213,7 @@
static struct file_operations phantom_file_ops = {
.open = phantom_open,
.release = phantom_release,
- .ioctl = phantom_ioctl,
+ .unlocked_ioctl = phantom_ioctl,
.poll = phantom_poll,
};
@@ -212,6 +226,7 @@
iowrite32(0, dev->iaddr);
iowrite32(0xc0, dev->iaddr);
+ ioread32(dev->iaddr); /* PCI posting */
atomic_inc(&dev->counter);
wake_up_interruptible(&dev->wait);
@@ -282,11 +297,13 @@
}
mutex_init(&pht->open_lock);
+ spin_lock_init(&pht->ioctl_lock);
init_waitqueue_head(&pht->wait);
cdev_init(&pht->cdev, &phantom_file_ops);
pht->cdev.owner = THIS_MODULE;
iowrite32(0, pht->caddr + PHN_IRQCTL);
+ ioread32(pht->caddr + PHN_IRQCTL); /* PCI posting */
retval = request_irq(pdev->irq, phantom_isr,
IRQF_SHARED | IRQF_DISABLED, "phantom", pht);
if (retval) {
@@ -337,6 +354,7 @@
cdev_del(&pht->cdev);
iowrite32(0, pht->caddr + PHN_IRQCTL);
+ ioread32(pht->caddr + PHN_IRQCTL); /* PCI posting */
free_irq(pdev->irq, pht);
pci_iounmap(pdev, pht->oaddr);
@@ -358,6 +376,7 @@
struct phantom_device *dev = pci_get_drvdata(pdev);
iowrite32(0, dev->caddr + PHN_IRQCTL);
+ ioread32(dev->caddr + PHN_IRQCTL); /* PCI posting */
return 0;
}
diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c
index a7562f7..540ff4b 100644
--- a/drivers/mmc/card/block.c
+++ b/drivers/mmc/card/block.c
@@ -135,23 +135,6 @@
struct mmc_data data;
};
-static int mmc_blk_prep_rq(struct mmc_queue *mq, struct request *req)
-{
- struct mmc_blk_data *md = mq->data;
- int stat = BLKPREP_OK;
-
- /*
- * If we have no device, we haven't finished initialising.
- */
- if (!md || !mq->card) {
- printk(KERN_ERR "%s: killing request - no device/host\n",
- req->rq_disk->disk_name);
- stat = BLKPREP_KILL;
- }
-
- return stat;
-}
-
static u32 mmc_sd_num_wr_blocks(struct mmc_card *card)
{
int err;
@@ -460,7 +443,6 @@
if (ret)
goto err_putdisk;
- md->queue.prep_fn = mmc_blk_prep_rq;
md->queue.issue_fn = mmc_blk_issue_rq;
md->queue.data = md;
diff --git a/drivers/mmc/card/queue.c b/drivers/mmc/card/queue.c
index 2e77963..dd97bc7 100644
--- a/drivers/mmc/card/queue.c
+++ b/drivers/mmc/card/queue.c
@@ -20,40 +20,21 @@
#define MMC_QUEUE_SUSPENDED (1 << 0)
/*
- * Prepare a MMC request. Essentially, this means passing the
- * preparation off to the media driver. The media driver will
- * create a mmc_io_request in req->special.
+ * Prepare a MMC request. This just filters out odd stuff.
*/
static int mmc_prep_request(struct request_queue *q, struct request *req)
{
- struct mmc_queue *mq = q->queuedata;
- int ret = BLKPREP_KILL;
-
- if (blk_special_request(req)) {
- /*
- * Special commands already have the command
- * blocks already setup in req->special.
- */
- BUG_ON(!req->special);
-
- ret = BLKPREP_OK;
- } else if (blk_fs_request(req) || blk_pc_request(req)) {
- /*
- * Block I/O requests need translating according
- * to the protocol.
- */
- ret = mq->prep_fn(mq, req);
- } else {
- /*
- * Everything else is invalid.
- */
+ /*
+ * We only like normal block requests.
+ */
+ if (!blk_fs_request(req) && !blk_pc_request(req)) {
blk_dump_rq_flags(req, "MMC bad request");
+ return BLKPREP_KILL;
}
- if (ret == BLKPREP_OK)
- req->cmd_flags |= REQ_DONTPREP;
+ req->cmd_flags |= REQ_DONTPREP;
- return ret;
+ return BLKPREP_OK;
}
static int mmc_queue_thread(void *d)
diff --git a/drivers/mmc/card/queue.h b/drivers/mmc/card/queue.h
index c9f139e..1590b3f 100644
--- a/drivers/mmc/card/queue.h
+++ b/drivers/mmc/card/queue.h
@@ -10,20 +10,12 @@
struct semaphore thread_sem;
unsigned int flags;
struct request *req;
- int (*prep_fn)(struct mmc_queue *, struct request *);
int (*issue_fn)(struct mmc_queue *, struct request *);
void *data;
struct request_queue *queue;
struct scatterlist *sg;
};
-struct mmc_io_request {
- struct request *rq;
- int num;
- struct mmc_command selcmd; /* mmc_queue private */
- struct mmc_command cmd[4]; /* max 4 commands */
-};
-
extern int mmc_init_queue(struct mmc_queue *, struct mmc_card *, spinlock_t *);
extern void mmc_cleanup_queue(struct mmc_queue *);
extern void mmc_queue_suspend(struct mmc_queue *);
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index 3b204ba..1798a9f 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -2218,7 +2218,7 @@
config VIA_VELOCITY
tristate "VIA Velocity support"
- depends on NET_PCI && PCI
+ depends on PCI
select CRC32
select CRC_CCITT
select MII
diff --git a/drivers/net/arcnet/Kconfig b/drivers/net/arcnet/Kconfig
index 7284cca..4030274 100644
--- a/drivers/net/arcnet/Kconfig
+++ b/drivers/net/arcnet/Kconfig
@@ -2,10 +2,8 @@
# Arcnet configuration
#
-menu "ARCnet devices"
+menuconfig ARCNET
depends on NETDEVICES && (ISA || PCI)
-
-config ARCNET
tristate "ARCnet support"
---help---
If you have a network card of this type, say Y and check out the
@@ -25,9 +23,10 @@
<file:Documentation/networking/net-modules.txt>. The module will
be called arcnet.
+if ARCNET
+
config ARCNET_1201
tristate "Enable standard ARCNet packet format (RFC 1201)"
- depends on ARCNET
help
This allows you to use RFC1201 with your ARCnet card via the virtual
arc0 device. You need to say Y here to communicate with
@@ -38,7 +37,6 @@
config ARCNET_1051
tristate "Enable old ARCNet packet format (RFC 1051)"
- depends on ARCNET
---help---
This allows you to use RFC1051 with your ARCnet card via the virtual
arc0s device. You only need arc0s if you want to talk to ARCnet
@@ -53,7 +51,6 @@
config ARCNET_RAW
tristate "Enable raw mode packet interface"
- depends on ARCNET
help
ARCnet "raw mode" packet encapsulation, no soft headers. Unlikely
to work unless talking to a copy of the same Linux arcnet driver,
@@ -61,7 +58,6 @@
config ARCNET_CAP
tristate "Enable CAP mode packet interface"
- depends on ARCNET
help
ARCnet "cap mode" packet encapsulation. Used to get the hardware
acknowledge back to userspace. After the initial protocol byte every
@@ -80,7 +76,6 @@
config ARCNET_COM90xx
tristate "ARCnet COM90xx (normal) chipset driver"
- depends on ARCNET
help
This is the chipset driver for the standard COM90xx cards. If you
have always used the old ARCnet driver without knowing what type of
@@ -92,7 +87,6 @@
config ARCNET_COM90xxIO
tristate "ARCnet COM90xx (IO mapped) chipset driver"
- depends on ARCNET
---help---
This is the chipset driver for the COM90xx cards, using them in
IO-mapped mode instead of memory-mapped mode. This is slower than
@@ -105,7 +99,6 @@
config ARCNET_RIM_I
tristate "ARCnet COM90xx (RIM I) chipset driver"
- depends on ARCNET
---help---
This is yet another chipset driver for the COM90xx cards, but this
time only using memory-mapped mode, and no IO ports at all. This
@@ -118,7 +111,6 @@
config ARCNET_COM20020
tristate "ARCnet COM20020 chipset driver"
- depends on ARCNET
help
This is the driver for the new COM20020 chipset. It supports such
things as promiscuous mode, so packet sniffing is possible, and
@@ -136,5 +128,4 @@
tristate "Support for COM20020 on PCI"
depends on ARCNET_COM20020 && PCI
-endmenu
-
+endif # ARCNET
diff --git a/drivers/net/cassini.c b/drivers/net/cassini.c
index 4aec747..9fe3a38 100644
--- a/drivers/net/cassini.c
+++ b/drivers/net/cassini.c
@@ -4919,7 +4919,10 @@
pci_cmd &= ~PCI_COMMAND_SERR;
pci_cmd |= PCI_COMMAND_PARITY;
pci_write_config_word(pdev, PCI_COMMAND, pci_cmd);
- pci_set_mwi(pdev);
+ if (pci_set_mwi(pdev))
+ printk(KERN_WARNING PFX "Could enable MWI for %s\n",
+ pci_name(pdev));
+
/*
* On some architectures, the default cache line size set
* by pci_set_mwi reduces perforamnce. We have to increase
diff --git a/drivers/net/chelsio/suni1x10gexp_regs.h b/drivers/net/chelsio/suni1x10gexp_regs.h
index 269d097..d0f87d8 100644
--- a/drivers/net/chelsio/suni1x10gexp_regs.h
+++ b/drivers/net/chelsio/suni1x10gexp_regs.h
@@ -105,7 +105,7 @@
#define mSUNI1x10GEXP_REG_RXXG_EXACT_MATCH_ADDR_LOW(filterId) (0x204A + mSUNI1x10GEXP_MAC_FILTER_OFFSET(filterId))
#define mSUNI1x10GEXP_REG_RXXG_EXACT_MATCH_ADDR_MID(filterId) (0x204B + mSUNI1x10GEXP_MAC_FILTER_OFFSET(filterId))
#define mSUNI1x10GEXP_REG_RXXG_EXACT_MATCH_ADDR_HIGH(filterId)(0x204C + mSUNI1x10GEXP_MAC_FILTER_OFFSET(filterId))
-#define mSUNI1x10GEXP_REG_RXXG_EXACT_MATCH_VID(filterId) (0x2062 + mSUNI1x10GEXP_MAC_VID_FILTER_OFFSET(filterId)
+#define mSUNI1x10GEXP_REG_RXXG_EXACT_MATCH_VID(filterId) (0x2062 + mSUNI1x10GEXP_MAC_VID_FILTER_OFFSET(filterId))
#define SUNI1x10GEXP_REG_RXXG_EXACT_MATCH_ADDR_0_LOW 0x204A
#define SUNI1x10GEXP_REG_RXXG_EXACT_MATCH_ADDR_0_MID 0x204B
#define SUNI1x10GEXP_REG_RXXG_EXACT_MATCH_ADDR_0_HIGH 0x204C
diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c
index 7a01802..4154fd0 100644
--- a/drivers/net/forcedeth.c
+++ b/drivers/net/forcedeth.c
@@ -195,7 +195,7 @@
#define NVREG_IRQ_TX_FORCED 0x0100
#define NVREG_IRQ_RECOVER_ERROR 0x8000
#define NVREG_IRQMASK_THROUGHPUT 0x00df
-#define NVREG_IRQMASK_CPU 0x0040
+#define NVREG_IRQMASK_CPU 0x0060
#define NVREG_IRQ_TX_ALL (NVREG_IRQ_TX_ERR|NVREG_IRQ_TX_OK|NVREG_IRQ_TX_FORCED)
#define NVREG_IRQ_RX_ALL (NVREG_IRQ_RX_ERROR|NVREG_IRQ_RX|NVREG_IRQ_RX_NOBUF|NVREG_IRQ_RX_FORCED)
#define NVREG_IRQ_OTHER (NVREG_IRQ_TIMER|NVREG_IRQ_LINK|NVREG_IRQ_RECOVER_ERROR)
diff --git a/drivers/net/meth.c b/drivers/net/meth.c
index 0343ea1..92b403b 100644
--- a/drivers/net/meth.c
+++ b/drivers/net/meth.c
@@ -8,15 +8,16 @@
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*/
-#include <linux/module.h>
-#include <linux/init.h>
-
-#include <linux/kernel.h> /* printk() */
#include <linux/delay.h>
+#include <linux/dma-mapping.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
#include <linux/slab.h>
-#include <linux/errno.h> /* error codes */
-#include <linux/types.h> /* size_t */
-#include <linux/interrupt.h> /* mark_bh */
+#include <linux/errno.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
#include <linux/in.h>
#include <linux/in6.h>
@@ -33,7 +34,6 @@
#include <asm/io.h>
#include <asm/scatterlist.h>
-#include <linux/dma-mapping.h>
#include "meth.h"
@@ -51,8 +51,6 @@
static const char *meth_str="SGI O2 Fast Ethernet";
-MODULE_AUTHOR("Ilya Volynets <ilya@theIlya.com>");
-MODULE_DESCRIPTION("SGI O2 Builtin Fast Ethernet driver");
#define HAVE_TX_TIMEOUT
/* The maximum time waited (in jiffies) before assuming a Tx failed. (400ms) */
@@ -784,15 +782,15 @@
/*
* The init function.
*/
-static struct net_device *meth_init(void)
+static int __init meth_probe(struct platform_device *pdev)
{
struct net_device *dev;
struct meth_private *priv;
- int ret;
+ int err;
dev = alloc_etherdev(sizeof(struct meth_private));
if (!dev)
- return ERR_PTR(-ENOMEM);
+ return -ENOMEM;
dev->open = meth_open;
dev->stop = meth_release;
@@ -808,11 +806,12 @@
priv = netdev_priv(dev);
spin_lock_init(&priv->meth_lock);
+ SET_NETDEV_DEV(dev, &pdev->dev);
- ret = register_netdev(dev);
- if (ret) {
+ err = register_netdev(dev);
+ if (err) {
free_netdev(dev);
- return ERR_PTR(ret);
+ return err;
}
printk(KERN_INFO "%s: SGI MACE Ethernet rev. %d\n",
@@ -820,21 +819,44 @@
return 0;
}
-static struct net_device *meth_dev;
+static int __exit meth_remove(struct platform_device *pdev)
+{
+ struct net_device *dev = platform_get_drvdata(pdev);
+
+ unregister_netdev(dev);
+ free_netdev(dev);
+ platform_set_drvdata(pdev, NULL);
+
+ return 0;
+}
+
+static struct platform_driver meth_driver = {
+ .probe = meth_probe,
+ .remove = __devexit_p(meth_remove),
+ .driver = {
+ .name = "meth",
+ }
+};
static int __init meth_init_module(void)
{
- meth_dev = meth_init();
- if (IS_ERR(meth_dev))
- return PTR_ERR(meth_dev);
- return 0;
+ int err;
+
+ err = platform_driver_register(&meth_driver);
+ if (err)
+ printk(KERN_ERR "Driver registration failed\n");
+
+ return err;
}
static void __exit meth_exit_module(void)
{
- unregister_netdev(meth_dev);
- free_netdev(meth_dev);
+ platform_driver_unregister(&meth_driver);
}
module_init(meth_init_module);
module_exit(meth_exit_module);
+
+MODULE_AUTHOR("Ilya Volynets <ilya@theIlya.com>");
+MODULE_DESCRIPTION("SGI O2 Builtin Fast Ethernet driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/net/phy/fixed.c b/drivers/net/phy/fixed.c
index 68c99b4c..bb96691 100644
--- a/drivers/net/phy/fixed.c
+++ b/drivers/net/phy/fixed.c
@@ -89,6 +89,7 @@
/*-----------------------------------------------------------------------------
* This is used for updating internal mii regs from the status
*-----------------------------------------------------------------------------*/
+#if defined(CONFIG_FIXED_MII_100_FDX) || defined(CONFIG_FIXED_MII_10_FDX)
static int fixed_mdio_update_regs(struct fixed_info *fixed)
{
u16 *regs = fixed->regs;
@@ -165,6 +166,7 @@
/*nothing here - no way/need to reset it*/
return 0;
}
+#endif
static int fixed_config_aneg(struct phy_device *phydev)
{
@@ -194,6 +196,7 @@
* number is used to create multiple fixed PHYs, so that several devices can
* utilize them simultaneously.
*-----------------------------------------------------------------------------*/
+#if defined(CONFIG_FIXED_MII_100_FDX) || defined(CONFIG_FIXED_MII_10_FDX)
static int fixed_mdio_register_device(int number, int speed, int duplex)
{
struct mii_bus *new_bus;
@@ -301,6 +304,7 @@
return err;
}
+#endif
MODULE_DESCRIPTION("Fixed PHY device & driver for PAL");
diff --git a/drivers/net/spider_net.c b/drivers/net/spider_net.c
index c3964c3..ef84d7c 100644
--- a/drivers/net/spider_net.c
+++ b/drivers/net/spider_net.c
@@ -1014,12 +1014,12 @@
*/
}
- /* pass skb up to stack */
- netif_receive_skb(skb);
-
/* update netdevice statistics */
card->netdev_stats.rx_packets++;
card->netdev_stats.rx_bytes += skb->len;
+
+ /* pass skb up to stack */
+ netif_receive_skb(skb);
}
#ifdef DEBUG
diff --git a/drivers/net/tokenring/Kconfig b/drivers/net/tokenring/Kconfig
index 99c4c19..e6b2e06 100644
--- a/drivers/net/tokenring/Kconfig
+++ b/drivers/net/tokenring/Kconfig
@@ -2,12 +2,10 @@
# Token Ring driver configuration
#
-menu "Token Ring devices"
- depends on NETDEVICES && !UML
-
# So far, we only have PCI, ISA, and MCA token ring devices
-config TR
+menuconfig TR
bool "Token Ring driver support"
+ depends on NETDEVICES && !UML
depends on (PCI || ISA || MCA || CCW)
select LLC
help
@@ -20,9 +18,11 @@
from <http://www.tldp.org/docs.html#howto>. Most people can
say N here.
+if TR
+
config IBMTR
tristate "IBM Tropic chipset based adapter support"
- depends on TR && (ISA || MCA)
+ depends on ISA || MCA
---help---
This is support for all IBM Token Ring cards that don't use DMA. If
you have such a beast, say Y and read the Token-Ring mini-HOWTO,
@@ -36,7 +36,7 @@
config IBMOL
tristate "IBM Olympic chipset PCI adapter support"
- depends on TR && PCI
+ depends on PCI
---help---
This is support for all non-Lanstreamer IBM PCI Token Ring Cards.
Specifically this is all IBM PCI, PCI Wake On Lan, PCI II, PCI II
@@ -54,7 +54,7 @@
config IBMLS
tristate "IBM Lanstreamer chipset PCI adapter support"
- depends on TR && PCI && !64BIT
+ depends on PCI && !64BIT
help
This is support for IBM Lanstreamer PCI Token Ring Cards.
@@ -66,7 +66,7 @@
config 3C359
tristate "3Com 3C359 Token Link Velocity XL adapter support"
- depends on TR && PCI
+ depends on PCI
---help---
This is support for the 3Com PCI Velocity XL cards, specifically
the 3Com 3C359, please note this is not for the 3C339 cards, you
@@ -84,7 +84,7 @@
config TMS380TR
tristate "Generic TMS380 Token Ring ISA/PCI adapter support"
- depends on TR && (PCI || ISA && ISA_DMA_API || MCA)
+ depends on PCI || ISA && ISA_DMA_API || MCA
select FW_LOADER
---help---
This driver provides generic support for token ring adapters
@@ -108,7 +108,7 @@
config TMSPCI
tristate "Generic TMS380 PCI support"
- depends on TR && TMS380TR && PCI
+ depends on TMS380TR && PCI
---help---
This tms380 module supports generic TMS380-based PCI cards.
@@ -123,7 +123,7 @@
config SKISA
tristate "SysKonnect TR4/16 ISA support"
- depends on TR && TMS380TR && ISA
+ depends on TMS380TR && ISA
help
This tms380 module supports SysKonnect TR4/16 ISA cards.
@@ -135,7 +135,7 @@
config PROTEON
tristate "Proteon ISA support"
- depends on TR && TMS380TR && ISA
+ depends on TMS380TR && ISA
help
This tms380 module supports Proteon ISA cards.
@@ -148,7 +148,7 @@
config ABYSS
tristate "Madge Smart 16/4 PCI Mk2 support"
- depends on TR && TMS380TR && PCI
+ depends on TMS380TR && PCI
help
This tms380 module supports the Madge Smart 16/4 PCI Mk2
cards (51-02).
@@ -158,7 +158,7 @@
config MADGEMC
tristate "Madge Smart 16/4 Ringnode MicroChannel"
- depends on TR && TMS380TR && MCA
+ depends on TMS380TR && MCA
help
This tms380 module supports the Madge Smart 16/4 MC16 and MC32
MicroChannel adapters.
@@ -168,7 +168,7 @@
config SMCTR
tristate "SMC ISA/MCA adapter support"
- depends on TR && (ISA || MCA_LEGACY) && (BROKEN || !64BIT)
+ depends on (ISA || MCA_LEGACY) && (BROKEN || !64BIT)
---help---
This is support for the ISA and MCA SMC Token Ring cards,
specifically SMC TokenCard Elite (8115T) and SMC TokenCard Elite/A
@@ -182,5 +182,4 @@
To compile this driver as a module, choose M here: the module will be
called smctr.
-endmenu
-
+endif # TR
diff --git a/drivers/net/ucc_geth.c b/drivers/net/ucc_geth.c
index c2ccbd0..18b731b 100644
--- a/drivers/net/ucc_geth.c
+++ b/drivers/net/ucc_geth.c
@@ -23,11 +23,8 @@
#include <linux/skbuff.h>
#include <linux/spinlock.h>
#include <linux/mm.h>
-#include <linux/ethtool.h>
-#include <linux/delay.h>
#include <linux/dma-mapping.h>
#include <linux/fsl_devices.h>
-#include <linux/ethtool.h>
#include <linux/mii.h>
#include <linux/phy.h>
#include <linux/workqueue.h>
diff --git a/drivers/net/ucc_geth_mii.c b/drivers/net/ucc_geth_mii.c
index f96966d..7bcb82f 100644
--- a/drivers/net/ucc_geth_mii.c
+++ b/drivers/net/ucc_geth_mii.c
@@ -260,8 +260,6 @@
{},
};
-MODULE_DEVICE_TABLE(of, uec_mdio_match);
-
static struct of_platform_driver uec_mdio_driver = {
.name = DRV_NAME,
.probe = uec_mdio_probe,
diff --git a/drivers/net/usb/asix.c b/drivers/net/usb/asix.c
index d5ef97b..6d95cac 100644
--- a/drivers/net/usb/asix.c
+++ b/drivers/net/usb/asix.c
@@ -1458,6 +1458,10 @@
// IO-DATA ETG-US2
USB_DEVICE (0x04bb, 0x0930),
.driver_info = (unsigned long) &ax88178_info,
+}, {
+ // Belkin F5D5055
+ USB_DEVICE(0x050d, 0x5055),
+ .driver_info = (unsigned long) &ax88178_info,
},
{ }, // END
};
diff --git a/drivers/net/usb/cdc_ether.c b/drivers/net/usb/cdc_ether.c
index 5a21f06..675ac99 100644
--- a/drivers/net/usb/cdc_ether.c
+++ b/drivers/net/usb/cdc_ether.c
@@ -91,6 +91,22 @@
"CDC descriptors on config\n");
}
+ /* Maybe CDC descriptors are after the endpoint? This bug has
+ * been seen on some 2Wire Inc RNDIS-ish products.
+ */
+ if (len == 0) {
+ struct usb_host_endpoint *hep;
+
+ hep = intf->cur_altsetting->endpoint;
+ if (hep) {
+ buf = hep->extra;
+ len = hep->extralen;
+ }
+ if (len)
+ dev_dbg(&intf->dev,
+ "CDC descriptors on endpoint\n");
+ }
+
/* this assumes that if there's a non-RNDIS vendor variant
* of cdc-acm, it'll fail RNDIS requests cleanly.
*/
diff --git a/drivers/net/usb/rndis_host.c b/drivers/net/usb/rndis_host.c
index 980e4aa..cd991a0 100644
--- a/drivers/net/usb/rndis_host.c
+++ b/drivers/net/usb/rndis_host.c
@@ -515,6 +515,7 @@
dev_err(&intf->dev,
"dev can't take %u byte packets (max %u)\n",
dev->hard_mtu, tmp);
+ retval = -EINVAL;
goto fail_and_release;
}
diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c
index f9cd42d..5b16d9a 100644
--- a/drivers/net/usb/usbnet.c
+++ b/drivers/net/usb/usbnet.c
@@ -1252,20 +1252,23 @@
/*-------------------------------------------------------------------------*/
-/* FIXME these suspend/resume methods assume non-CDC style
- * devices, with only one interface.
+/*
+ * suspend the whole driver as soon as the first interface is suspended
+ * resume only when the last interface is resumed
*/
int usbnet_suspend (struct usb_interface *intf, pm_message_t message)
{
struct usbnet *dev = usb_get_intfdata(intf);
- /* accelerate emptying of the rx and queues, to avoid
- * having everything error out.
- */
- netif_device_detach (dev->net);
- (void) unlink_urbs (dev, &dev->rxq);
- (void) unlink_urbs (dev, &dev->txq);
+ if (!dev->suspend_count++) {
+ /* accelerate emptying of the rx and queues, to avoid
+ * having everything error out.
+ */
+ netif_device_detach (dev->net);
+ (void) unlink_urbs (dev, &dev->rxq);
+ (void) unlink_urbs (dev, &dev->txq);
+ }
return 0;
}
EXPORT_SYMBOL_GPL(usbnet_suspend);
@@ -1274,8 +1277,10 @@
{
struct usbnet *dev = usb_get_intfdata(intf);
- netif_device_attach (dev->net);
- tasklet_schedule (&dev->bh);
+ if (!--dev->suspend_count) {
+ netif_device_attach (dev->net);
+ tasklet_schedule (&dev->bh);
+ }
return 0;
}
EXPORT_SYMBOL_GPL(usbnet_resume);
diff --git a/drivers/net/usb/usbnet.h b/drivers/net/usb/usbnet.h
index 82db5a8..a3f8b9e 100644
--- a/drivers/net/usb/usbnet.h
+++ b/drivers/net/usb/usbnet.h
@@ -32,6 +32,7 @@
const char *driver_name;
wait_queue_head_t *wait;
struct mutex phy_mutex;
+ unsigned char suspend_count;
/* i/o info: pipes etc */
unsigned in, out;
diff --git a/drivers/net/wireless/libertas/decl.h b/drivers/net/wireless/libertas/decl.h
index 606bdd0..dfe2764 100644
--- a/drivers/net/wireless/libertas/decl.h
+++ b/drivers/net/wireless/libertas/decl.h
@@ -46,7 +46,7 @@
u8 libertas_data_rate_to_index(u32 rate);
void libertas_get_fwversion(wlan_adapter * adapter, char *fwversion, int maxlen);
-int libertas_upload_rx_packet(wlan_private * priv, struct sk_buff *skb);
+void libertas_upload_rx_packet(wlan_private * priv, struct sk_buff *skb);
/** The proc fs interface */
int libertas_process_rx_command(wlan_private * priv);
diff --git a/drivers/net/wireless/libertas/fw.c b/drivers/net/wireless/libertas/fw.c
index 441123c..5c63c9b 100644
--- a/drivers/net/wireless/libertas/fw.c
+++ b/drivers/net/wireless/libertas/fw.c
@@ -333,18 +333,22 @@
unsigned long flags;
ptempnode = adapter->cur_cmd;
+ if (ptempnode == NULL) {
+ lbs_pr_debug(1, "PTempnode Empty\n");
+ return;
+ }
+
cmd = (struct cmd_ds_command *)ptempnode->bufvirtualaddr;
+ if (!cmd) {
+ lbs_pr_debug(1, "cmd is NULL\n");
+ return;
+ }
lbs_pr_info("command_timer_fn fired (%x)\n", cmd->command);
if (!adapter->fw_ready)
return;
- if (ptempnode == NULL) {
- lbs_pr_debug(1, "PTempnode Empty\n");
- return;
- }
-
spin_lock_irqsave(&adapter->driver_lock, flags);
adapter->cur_cmd = NULL;
spin_unlock_irqrestore(&adapter->driver_lock, flags);
diff --git a/drivers/net/wireless/libertas/rx.c b/drivers/net/wireless/libertas/rx.c
index d17924f..96619a32 100644
--- a/drivers/net/wireless/libertas/rx.c
+++ b/drivers/net/wireless/libertas/rx.c
@@ -136,7 +136,7 @@
LEAVE();
}
-int libertas_upload_rx_packet(wlan_private * priv, struct sk_buff *skb)
+void libertas_upload_rx_packet(wlan_private * priv, struct sk_buff *skb)
{
lbs_pr_debug(1, "skb->data=%p\n", skb->data);
@@ -148,8 +148,6 @@
skb->ip_summed = CHECKSUM_UNNECESSARY;
netif_rx(skb);
-
- return 0;
}
/**
@@ -269,15 +267,11 @@
wlan_compute_rssi(priv, p_rx_pd);
lbs_pr_debug(1, "RX Data: size of actual packet = %d\n", skb->len);
- if (libertas_upload_rx_packet(priv, skb)) {
- lbs_pr_debug(1, "RX error: libertas_upload_rx_packet"
- " returns failure\n");
- ret = -1;
- goto done;
- }
priv->stats.rx_bytes += skb->len;
priv->stats.rx_packets++;
+ libertas_upload_rx_packet(priv, skb);
+
ret = 0;
done:
LEAVE();
@@ -438,22 +432,14 @@
wlan_compute_rssi(priv, prxpd);
lbs_pr_debug(1, "RX Data: size of actual packet = %d\n", skb->len);
-
- if (libertas_upload_rx_packet(priv, skb)) {
- lbs_pr_debug(1, "RX error: libertas_upload_rx_packet "
- "returns failure\n");
- ret = -1;
- goto done;
- }
-
priv->stats.rx_bytes += skb->len;
priv->stats.rx_packets++;
+ libertas_upload_rx_packet(priv, skb);
+
ret = 0;
done:
LEAVE();
- skb->protocol = __constant_htons(0x0019); /* ETH_P_80211_RAW */
-
return (ret);
}
diff --git a/drivers/s390/scsi/zfcp_aux.c b/drivers/s390/scsi/zfcp_aux.c
index ddff40c..821cde65 100644
--- a/drivers/s390/scsi/zfcp_aux.c
+++ b/drivers/s390/scsi/zfcp_aux.c
@@ -1127,6 +1127,7 @@
int retval = 0;
unsigned long flags;
+ zfcp_adapter_scsi_unregister(adapter);
device_unregister(&adapter->generic_services);
zfcp_sysfs_adapter_remove_files(&adapter->ccw_device->dev);
dev_set_drvdata(&adapter->ccw_device->dev, NULL);
diff --git a/drivers/s390/scsi/zfcp_ccw.c b/drivers/s390/scsi/zfcp_ccw.c
index 81680ef..1c8f71a 100644
--- a/drivers/s390/scsi/zfcp_ccw.c
+++ b/drivers/s390/scsi/zfcp_ccw.c
@@ -189,9 +189,7 @@
* @ccw_device: pointer to belonging ccw device
*
* This function gets called by the common i/o layer and sets an adapter
- * into state offline. Setting an fcp device offline means that it will be
- * unregistered from the SCSI stack and that the adapter will be shut down
- * asynchronously.
+ * into state offline.
*/
static int
zfcp_ccw_set_offline(struct ccw_device *ccw_device)
@@ -202,7 +200,6 @@
adapter = dev_get_drvdata(&ccw_device->dev);
zfcp_erp_adapter_shutdown(adapter, 0);
zfcp_erp_wait(adapter);
- zfcp_adapter_scsi_unregister(adapter);
zfcp_erp_thread_kill(adapter);
zfcp_adapter_debug_unregister(adapter);
up(&zfcp_data.config_sema);
diff --git a/drivers/s390/scsi/zfcp_fsf.c b/drivers/s390/scsi/zfcp_fsf.c
index a8b0254..0eb31e1 100644
--- a/drivers/s390/scsi/zfcp_fsf.c
+++ b/drivers/s390/scsi/zfcp_fsf.c
@@ -156,44 +156,30 @@
kfree(fsf_req);
}
-/**
- * zfcp_fsf_req_dismiss - dismiss a single fsf request
- */
-static void zfcp_fsf_req_dismiss(struct zfcp_adapter *adapter,
- struct zfcp_fsf_req *fsf_req,
- unsigned int counter)
-{
- u64 dbg_tmp[2];
-
- dbg_tmp[0] = (u64) atomic_read(&adapter->reqs_active);
- dbg_tmp[1] = (u64) counter;
- debug_event(adapter->erp_dbf, 4, (void *) dbg_tmp, 16);
- list_del(&fsf_req->list);
- fsf_req->status |= ZFCP_STATUS_FSFREQ_DISMISSED;
- zfcp_fsf_req_complete(fsf_req);
-}
-
-/**
- * zfcp_fsf_req_dismiss_all - dismiss all remaining fsf requests
+/*
+ * Never ever call this without shutting down the adapter first.
+ * Otherwise the adapter would continue using and corrupting s390 storage.
+ * Included BUG_ON() call to ensure this is done.
+ * ERP is supposed to be the only user of this function.
*/
void zfcp_fsf_req_dismiss_all(struct zfcp_adapter *adapter)
{
- struct zfcp_fsf_req *request, *tmp;
+ struct zfcp_fsf_req *fsf_req, *tmp;
unsigned long flags;
LIST_HEAD(remove_queue);
- unsigned int i, counter;
+ unsigned int i;
+ BUG_ON(atomic_test_mask(ZFCP_STATUS_ADAPTER_QDIOUP, &adapter->status));
spin_lock_irqsave(&adapter->req_list_lock, flags);
atomic_set(&adapter->reqs_active, 0);
- for (i=0; i<REQUEST_LIST_SIZE; i++)
+ for (i = 0; i < REQUEST_LIST_SIZE; i++)
list_splice_init(&adapter->req_list[i], &remove_queue);
-
spin_unlock_irqrestore(&adapter->req_list_lock, flags);
- counter = 0;
- list_for_each_entry_safe(request, tmp, &remove_queue, list) {
- zfcp_fsf_req_dismiss(adapter, request, counter);
- counter++;
+ list_for_each_entry_safe(fsf_req, tmp, &remove_queue, list) {
+ list_del(&fsf_req->list);
+ fsf_req->status |= ZFCP_STATUS_FSFREQ_DISMISSED;
+ zfcp_fsf_req_complete(fsf_req);
}
}
diff --git a/drivers/s390/scsi/zfcp_scsi.c b/drivers/s390/scsi/zfcp_scsi.c
index 16e2d64..0acf6db 100644
--- a/drivers/s390/scsi/zfcp_scsi.c
+++ b/drivers/s390/scsi/zfcp_scsi.c
@@ -569,6 +569,9 @@
int retval = 0;
static unsigned int unique_id = 0;
+ if (adapter->scsi_host)
+ goto out;
+
/* register adapter as SCSI host with mid layer of SCSI stack */
adapter->scsi_host = scsi_host_alloc(&zfcp_data.scsi_host_template,
sizeof (struct zfcp_adapter *));
diff --git a/drivers/scsi/aacraid/aachba.c b/drivers/scsi/aacraid/aachba.c
index 1e82c69..8dcfe4e 100644
--- a/drivers/scsi/aacraid/aachba.c
+++ b/drivers/scsi/aacraid/aachba.c
@@ -146,7 +146,7 @@
static int nondasd = -1;
static int dacmode = -1;
-static int commit = -1;
+int aac_commit = -1;
int startup_timeout = 180;
int aif_timeout = 120;
@@ -154,7 +154,7 @@
MODULE_PARM_DESC(nondasd, "Control scanning of hba for nondasd devices. 0=off, 1=on");
module_param(dacmode, int, S_IRUGO|S_IWUSR);
MODULE_PARM_DESC(dacmode, "Control whether dma addressing is using 64 bit DAC. 0=off, 1=on");
-module_param(commit, int, S_IRUGO|S_IWUSR);
+module_param_named(commit, aac_commit, int, S_IRUGO|S_IWUSR);
MODULE_PARM_DESC(commit, "Control whether a COMMIT_CONFIG is issued to the adapter for foreign arrays.\nThis is typically needed in systems that do not have a BIOS. 0=off, 1=on");
module_param(startup_timeout, int, S_IRUGO|S_IWUSR);
MODULE_PARM_DESC(startup_timeout, "The duration of time in seconds to wait for adapter to have it's kernel up and\nrunning. This is typically adjusted for large systems that do not have a BIOS.");
@@ -173,6 +173,9 @@
module_param(expose_physicals, int, S_IRUGO|S_IWUSR);
MODULE_PARM_DESC(expose_physicals, "Expose physical components of the arrays. -1=protect 0=off, 1=on");
+int aac_reset_devices = 0;
+module_param_named(reset_devices, aac_reset_devices, int, S_IRUGO|S_IWUSR);
+MODULE_PARM_DESC(reset_devices, "Force an adapter reset at initialization.");
static inline int aac_valid_context(struct scsi_cmnd *scsicmd,
struct fib *fibptr) {
@@ -246,7 +249,7 @@
aac_fib_complete(fibptr);
/* Send a CT_COMMIT_CONFIG to enable discovery of devices */
if (status >= 0) {
- if ((commit == 1) || commit_flag) {
+ if ((aac_commit == 1) || commit_flag) {
struct aac_commit_config * dinfo;
aac_fib_init(fibptr);
dinfo = (struct aac_commit_config *) fib_data(fibptr);
@@ -261,7 +264,7 @@
1, 1,
NULL, NULL);
aac_fib_complete(fibptr);
- } else if (commit == 0) {
+ } else if (aac_commit == 0) {
printk(KERN_WARNING
"aac_get_config_status: Foreign device configurations are being ignored\n");
}
@@ -340,7 +343,7 @@
static void aac_internal_transfer(struct scsi_cmnd *scsicmd, void *data, unsigned int offset, unsigned int len)
{
void *buf;
- unsigned int transfer_len;
+ int transfer_len;
struct scatterlist *sg = scsicmd->request_buffer;
if (scsicmd->use_sg) {
@@ -351,7 +354,7 @@
transfer_len = min(scsicmd->request_bufflen, len + offset);
}
transfer_len -= offset;
- if (buf && transfer_len)
+ if (buf && transfer_len > 0)
memcpy(buf + offset, data, transfer_len);
if (scsicmd->use_sg)
diff --git a/drivers/scsi/aacraid/aacraid.h b/drivers/scsi/aacraid/aacraid.h
index 45ca3e8..c81edf3 100644
--- a/drivers/scsi/aacraid/aacraid.h
+++ b/drivers/scsi/aacraid/aacraid.h
@@ -1823,9 +1823,12 @@
int aac_probe_container(struct aac_dev *dev, int cid);
int _aac_rx_init(struct aac_dev *dev);
int aac_rx_select_comm(struct aac_dev *dev, int comm);
+int aac_rx_deliver_producer(struct fib * fib);
extern int numacb;
extern int acbsize;
extern char aac_driver_version[];
extern int startup_timeout;
extern int aif_timeout;
extern int expose_physicals;
+extern int aac_reset_devices;
+extern int aac_commit;
diff --git a/drivers/scsi/aacraid/rx.c b/drivers/scsi/aacraid/rx.c
index 291cd14..ae978a3 100644
--- a/drivers/scsi/aacraid/rx.c
+++ b/drivers/scsi/aacraid/rx.c
@@ -378,7 +378,7 @@
*
* Will send a fib, returning 0 if successful.
*/
-static int aac_rx_deliver_producer(struct fib * fib)
+int aac_rx_deliver_producer(struct fib * fib)
{
struct aac_dev *dev = fib->dev;
struct aac_queue *q = &dev->queues->queue[AdapNormCmdQueue];
@@ -488,6 +488,8 @@
return -EINVAL;
if (rx_readl(dev, MUnit.OMRx[0]) & KERNEL_PANIC)
return -ENODEV;
+ if (startup_timeout < 300)
+ startup_timeout = 300;
return 0;
}
@@ -542,7 +544,7 @@
dev->a_ops.adapter_sync_cmd = rx_sync_cmd;
dev->a_ops.adapter_enable_int = aac_rx_disable_interrupt;
dev->OIMR = status = rx_readb (dev, MUnit.OIMR);
- if ((((status & 0x0c) != 0x0c) || reset_devices) &&
+ if ((((status & 0x0c) != 0x0c) || aac_reset_devices || reset_devices) &&
!aac_rx_restart_adapter(dev, 0))
++restart;
/*
@@ -594,6 +596,8 @@
}
msleep(1);
}
+ if (restart)
+ aac_commit = 1;
/*
* Fill in the common function dispatch table.
*/
diff --git a/drivers/scsi/aacraid/sa.c b/drivers/scsi/aacraid/sa.c
index f4b5e97..85b91bc 100644
--- a/drivers/scsi/aacraid/sa.c
+++ b/drivers/scsi/aacraid/sa.c
@@ -5,7 +5,7 @@
* based on the old aacraid driver that is..
* Adaptec aacraid device driver for Linux.
*
- * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
+ * Copyright (c) 2000-2007 Adaptec, Inc. (aacraid@adaptec.com)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -257,6 +257,11 @@
NULL, NULL, NULL, NULL, NULL);
}
+static int aac_sa_restart_adapter(struct aac_dev *dev, int bled)
+{
+ return -EINVAL;
+}
+
/**
* aac_sa_check_health
* @dev: device to check if healthy
@@ -366,7 +371,9 @@
dev->a_ops.adapter_notify = aac_sa_notify_adapter;
dev->a_ops.adapter_sync_cmd = sa_sync_cmd;
dev->a_ops.adapter_check_health = aac_sa_check_health;
+ dev->a_ops.adapter_restart = aac_sa_restart_adapter;
dev->a_ops.adapter_intr = aac_sa_intr;
+ dev->a_ops.adapter_deliver = aac_rx_deliver_producer;
dev->a_ops.adapter_ioremap = aac_sa_ioremap;
/*
diff --git a/drivers/scsi/aic7xxx/aicasm/aicasm_gram.y b/drivers/scsi/aic7xxx/aicasm/aicasm_gram.y
index c328596..6066998 100644
--- a/drivers/scsi/aic7xxx/aicasm/aicasm_gram.y
+++ b/drivers/scsi/aic7xxx/aicasm/aicasm_gram.y
@@ -106,6 +106,7 @@
static void add_conditional(symbol_t *symbol);
static void add_version(const char *verstring);
static int is_download_const(expression_t *immed);
+void yyerror(const char *string);
#define SRAM_SYMNAME "SRAM_BASE"
#define SCB_SYMNAME "SCB_BASE"
diff --git a/drivers/scsi/aic7xxx/aicasm/aicasm_macro_gram.y b/drivers/scsi/aic7xxx/aicasm/aicasm_macro_gram.y
index 439f760..ff46aa6 100644
--- a/drivers/scsi/aic7xxx/aicasm/aicasm_macro_gram.y
+++ b/drivers/scsi/aic7xxx/aicasm/aicasm_macro_gram.y
@@ -65,6 +65,7 @@
static symbol_t *macro_symbol;
static void add_macro_arg(const char *argtext, int position);
+void mmerror(const char *string);
%}
diff --git a/drivers/scsi/aic94xx/aic94xx_tmf.c b/drivers/scsi/aic94xx/aic94xx_tmf.c
index 9a14a6d..c0d0b7d 100644
--- a/drivers/scsi/aic94xx/aic94xx_tmf.c
+++ b/drivers/scsi/aic94xx/aic94xx_tmf.c
@@ -290,6 +290,7 @@
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;
unsigned long flags;
@@ -298,10 +299,12 @@
res = asd_clear_nexus_tag(task);
else
res = asd_clear_nexus_index(task);
- wait_for_completion_timeout(&tascb->completion,
- AIC94XX_SCB_TIMEOUT);
+ leftover = wait_for_completion_timeout(&tascb->completion,
+ AIC94XX_SCB_TIMEOUT);
ASD_DPRINTK("came back from clear nexus\n");
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);
@@ -350,6 +353,7 @@
unsigned long flags;
struct asd_ascb *ascb = NULL;
struct scb *scb;
+ int leftover;
spin_lock_irqsave(&task->task_state_lock, flags);
if (task->task_state_flags & SAS_TASK_STATE_DONE) {
@@ -455,9 +459,11 @@
break;
case TF_TMF_TASK_DONE + 0xFF00: /* done but not reported yet */
res = TMF_RESP_FUNC_FAILED;
- wait_for_completion_timeout(&tascb->completion,
- AIC94XX_SCB_TIMEOUT);
+ 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);
diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c
index 4baa79e..fa6ff29 100644
--- a/drivers/scsi/ipr.c
+++ b/drivers/scsi/ipr.c
@@ -3954,6 +3954,13 @@
spin_unlock_irq(scsi_cmd->device->host->host_lock);
ata_do_eh(ap, NULL, NULL, ipr_sata_reset, NULL);
spin_lock_irq(scsi_cmd->device->host->host_lock);
+
+ list_for_each_entry(ipr_cmd, &ioa_cfg->pending_q, queue) {
+ if (ipr_cmd->ioarcb.res_handle == res->cfgte.res_handle) {
+ rc = -EIO;
+ break;
+ }
+ }
} else
rc = ipr_device_reset(ioa_cfg, res);
res->resetting_device = 0;
diff --git a/drivers/scsi/libsrp.c b/drivers/scsi/libsrp.c
index 5631c19..732446e 100644
--- a/drivers/scsi/libsrp.c
+++ b/drivers/scsi/libsrp.c
@@ -254,6 +254,7 @@
sg_init_one(&dummy, md, id->table_desc.len);
sg_dma_address(&dummy) = token;
+ sg_dma_len(&dummy) = id->table_desc.len;
err = rdma_io(sc, &dummy, 1, &id->table_desc, 1, DMA_TO_DEVICE,
id->table_desc.len);
if (err) {
diff --git a/drivers/scsi/megaraid/megaraid_sas.c b/drivers/scsi/megaraid/megaraid_sas.c
index 7a81267..e2cf12e 100644
--- a/drivers/scsi/megaraid/megaraid_sas.c
+++ b/drivers/scsi/megaraid/megaraid_sas.c
@@ -10,7 +10,7 @@
* 2 of the License, or (at your option) any later version.
*
* FILE : megaraid_sas.c
- * Version : v00.00.03.10-rc1
+ * Version : v00.00.03.10-rc5
*
* Authors:
* (email-id : megaraidlinux@lsi.com)
@@ -886,6 +886,7 @@
goto out_return_cmd;
cmd->scmd = scmd;
+ scmd->SCp.ptr = (char *)cmd;
/*
* Issue the command to the FW
@@ -919,7 +920,7 @@
* The RAID firmware may require extended timeouts.
*/
if (sdev->channel >= MEGASAS_MAX_PD_CHANNELS)
- sdev->timeout = 90 * HZ;
+ sdev->timeout = MEGASAS_DEFAULT_CMD_TIMEOUT * HZ;
return 0;
}
@@ -981,8 +982,8 @@
instance = (struct megasas_instance *)scmd->device->host->hostdata;
- scmd_printk(KERN_NOTICE, scmd, "megasas: RESET -%ld cmd=%x\n",
- scmd->serial_number, scmd->cmnd[0]);
+ scmd_printk(KERN_NOTICE, scmd, "megasas: RESET -%ld cmd=%x retries=%x\n",
+ scmd->serial_number, scmd->cmnd[0], scmd->retries);
if (instance->hw_crit_error) {
printk(KERN_ERR "megasas: cannot recover from previous reset "
@@ -1000,6 +1001,39 @@
}
/**
+ * megasas_reset_timer - quiesce the adapter if required
+ * @scmd: scsi cmnd
+ *
+ * Sets the FW busy flag and reduces the host->can_queue if the
+ * cmd has not been completed within the timeout period.
+ */
+static enum
+scsi_eh_timer_return megasas_reset_timer(struct scsi_cmnd *scmd)
+{
+ struct megasas_cmd *cmd = (struct megasas_cmd *)scmd->SCp.ptr;
+ struct megasas_instance *instance;
+ unsigned long flags;
+
+ if (time_after(jiffies, scmd->jiffies_at_alloc +
+ (MEGASAS_DEFAULT_CMD_TIMEOUT * 2) * HZ)) {
+ return EH_NOT_HANDLED;
+ }
+
+ instance = cmd->instance;
+ if (!(instance->flag & MEGASAS_FW_BUSY)) {
+ /* FW is busy, throttle IO */
+ spin_lock_irqsave(instance->host->host_lock, flags);
+
+ instance->host->can_queue = 16;
+ instance->last_time = jiffies;
+ instance->flag |= MEGASAS_FW_BUSY;
+
+ spin_unlock_irqrestore(instance->host->host_lock, flags);
+ }
+ return EH_RESET_TIMER;
+}
+
+/**
* megasas_reset_device - Device reset handler entry point
*/
static int megasas_reset_device(struct scsi_cmnd *scmd)
@@ -1112,6 +1146,7 @@
.eh_device_reset_handler = megasas_reset_device,
.eh_bus_reset_handler = megasas_reset_bus_host,
.eh_host_reset_handler = megasas_reset_bus_host,
+ .eh_timed_out = megasas_reset_timer,
.bios_param = megasas_bios_param,
.use_clustering = ENABLE_CLUSTERING,
};
@@ -1215,9 +1250,8 @@
int exception = 0;
struct megasas_header *hdr = &cmd->frame->hdr;
- if (cmd->scmd) {
- cmd->scmd->SCp.ptr = (char *)0;
- }
+ if (cmd->scmd)
+ cmd->scmd->SCp.ptr = NULL;
switch (hdr->cmd) {
@@ -1806,6 +1840,7 @@
u32 context;
struct megasas_cmd *cmd;
struct megasas_instance *instance = (struct megasas_instance *)instance_addr;
+ unsigned long flags;
/* If we have already declared adapter dead, donot complete cmds */
if (instance->hw_crit_error)
@@ -1828,6 +1863,22 @@
}
*instance->consumer = producer;
+
+ /*
+ * Check if we can restore can_queue
+ */
+ if (instance->flag & MEGASAS_FW_BUSY
+ && time_after(jiffies, instance->last_time + 5 * HZ)
+ && atomic_read(&instance->fw_outstanding) < 17) {
+
+ spin_lock_irqsave(instance->host->host_lock, flags);
+ instance->flag &= ~MEGASAS_FW_BUSY;
+ instance->host->can_queue =
+ instance->max_fw_cmds - MEGASAS_INT_CMDS;
+
+ spin_unlock_irqrestore(instance->host->host_lock, flags);
+ }
+
}
/**
@@ -2398,6 +2449,8 @@
instance->init_id = MEGASAS_DEFAULT_INIT_ID;
megasas_dbg_lvl = 0;
+ instance->flag = 0;
+ instance->last_time = 0;
/*
* Initialize MFI Firmware
diff --git a/drivers/scsi/megaraid/megaraid_sas.h b/drivers/scsi/megaraid/megaraid_sas.h
index e862992..4dffc91 100644
--- a/drivers/scsi/megaraid/megaraid_sas.h
+++ b/drivers/scsi/megaraid/megaraid_sas.h
@@ -18,9 +18,9 @@
/*
* MegaRAID SAS Driver meta data
*/
-#define MEGASAS_VERSION "00.00.03.10-rc1"
-#define MEGASAS_RELDATE "Feb 14, 2007"
-#define MEGASAS_EXT_VERSION "Wed Feb 14 10:14:25 PST 2007"
+#define MEGASAS_VERSION "00.00.03.10-rc5"
+#define MEGASAS_RELDATE "May 17, 2007"
+#define MEGASAS_EXT_VERSION "Thu May 17 10:09:32 PDT 2007"
/*
* Device IDs
@@ -539,6 +539,8 @@
#define MEGASAS_DBG_LVL 1
+#define MEGASAS_FW_BUSY 1
+
/*
* When SCSI mid-layer calls driver's reset routine, driver waits for
* MEGASAS_RESET_WAIT_TIME seconds for all outstanding IO to complete. Note
@@ -549,8 +551,8 @@
#define MEGASAS_RESET_WAIT_TIME 180
#define MEGASAS_INTERNAL_CMD_WAIT_TIME 180
#define MEGASAS_RESET_NOTICE_INTERVAL 5
-
#define MEGASAS_IOCTL_CMD 0
+#define MEGASAS_DEFAULT_CMD_TIMEOUT 90
/*
* FW reports the maximum of number of commands that it can accept (maximum
@@ -1073,7 +1075,6 @@
struct megasas_register_set __iomem *reg_set;
s8 init_id;
- u8 reserved[3];
u16 max_num_sge;
u16 max_fw_cmds;
@@ -1104,6 +1105,9 @@
struct megasas_instance_template *instancet;
struct tasklet_struct isr_tasklet;
+
+ u8 flag;
+ unsigned long last_time;
};
#define MEGASAS_IS_LOGICAL(scp) \
diff --git a/drivers/scsi/scsi_devinfo.c b/drivers/scsi/scsi_devinfo.c
index ce63044..18dd5cc 100644
--- a/drivers/scsi/scsi_devinfo.c
+++ b/drivers/scsi/scsi_devinfo.c
@@ -209,6 +209,7 @@
{"PIONEER", "CD-ROM DRM-602X", NULL, BLIST_FORCELUN | BLIST_SINGLELUN},
{"PIONEER", "CD-ROM DRM-604X", NULL, BLIST_FORCELUN | BLIST_SINGLELUN},
{"PIONEER", "CD-ROM DRM-624X", NULL, BLIST_FORCELUN | BLIST_SINGLELUN},
+ {"Promise", "", NULL, BLIST_SPARSELUN},
{"REGAL", "CDC-4X", NULL, BLIST_MAX5LUN | BLIST_SINGLELUN},
{"SanDisk", "ImageMate CF-SD1", NULL, BLIST_FORCELUN},
{"SEAGATE", "ST34555N", "0930", BLIST_NOTQ}, /* Chokes on tagged INQUIRY */
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
index 00e4666..3d8c9cb 100644
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
@@ -1789,7 +1789,7 @@
static int sd_suspend(struct device *dev, pm_message_t mesg)
{
struct scsi_disk *sdkp = scsi_disk_get_from_dev(dev);
- int ret;
+ int ret = 0;
if (!sdkp)
return 0; /* this can happen */
@@ -1798,30 +1798,34 @@
sd_printk(KERN_NOTICE, sdkp, "Synchronizing SCSI cache\n");
ret = sd_sync_cache(sdkp);
if (ret)
- return ret;
+ goto done;
}
if (mesg.event == PM_EVENT_SUSPEND &&
sdkp->device->manage_start_stop) {
sd_printk(KERN_NOTICE, sdkp, "Stopping disk\n");
ret = sd_start_stop_device(sdkp, 0);
- if (ret)
- return ret;
}
- return 0;
+done:
+ scsi_disk_put(sdkp);
+ return ret;
}
static int sd_resume(struct device *dev)
{
struct scsi_disk *sdkp = scsi_disk_get_from_dev(dev);
+ int ret = 0;
if (!sdkp->device->manage_start_stop)
- return 0;
+ goto done;
sd_printk(KERN_NOTICE, sdkp, "Starting disk\n");
+ ret = sd_start_stop_device(sdkp, 1);
- return sd_start_stop_device(sdkp, 1);
+done:
+ scsi_disk_put(sdkp);
+ return ret;
}
/**
diff --git a/drivers/scsi/stex.c b/drivers/scsi/stex.c
index 69be132..9ac83ab 100644
--- a/drivers/scsi/stex.c
+++ b/drivers/scsi/stex.c
@@ -32,11 +32,12 @@
#include <scsi/scsi_cmnd.h>
#include <scsi/scsi_host.h>
#include <scsi/scsi_tcq.h>
+#include <scsi/scsi_dbg.h>
#define DRV_NAME "stex"
-#define ST_DRIVER_VERSION "3.1.0.1"
+#define ST_DRIVER_VERSION "3.6.0000.1"
#define ST_VER_MAJOR 3
-#define ST_VER_MINOR 1
+#define ST_VER_MINOR 6
#define ST_OEM 0
#define ST_BUILD_VER 1
@@ -113,10 +114,6 @@
SG_CF_64B = 0x40, /* 64 bit item */
SG_CF_HOST = 0x20, /* sg in host memory */
- ST_MAX_ARRAY_SUPPORTED = 16,
- ST_MAX_TARGET_NUM = (ST_MAX_ARRAY_SUPPORTED+1),
- ST_MAX_LUN_PER_TARGET = 16,
-
st_shasta = 0,
st_vsc = 1,
st_vsc1 = 2,
@@ -586,7 +583,7 @@
u16 tag;
host = cmd->device->host;
id = cmd->device->id;
- lun = cmd->device->channel; /* firmware lun issue work around */
+ lun = cmd->device->lun;
hba = (struct st_hba *) &host->hostdata[0];
switch (cmd->cmnd[0]) {
@@ -605,8 +602,26 @@
stex_invalid_field(cmd, done);
return 0;
}
+ case REPORT_LUNS:
+ /*
+ * The shasta firmware does not report actual luns in the
+ * target, so fail the command to force sequential lun scan.
+ * Also, the console device does not support this command.
+ */
+ if (hba->cardtype == st_shasta || id == host->max_id - 1) {
+ stex_invalid_field(cmd, done);
+ return 0;
+ }
+ break;
+ case TEST_UNIT_READY:
+ if (id == host->max_id - 1) {
+ cmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8;
+ done(cmd);
+ return 0;
+ }
+ break;
case INQUIRY:
- if (id != ST_MAX_ARRAY_SUPPORTED)
+ if (id != host->max_id - 1)
break;
if (lun == 0 && (cmd->cmnd[1] & INQUIRY_EVPD) == 0) {
stex_direct_copy(cmd, console_inq_page,
@@ -624,7 +639,7 @@
ver.oem = ST_OEM;
ver.build = ST_BUILD_VER;
ver.signature[0] = PASSTHRU_SIGNATURE;
- ver.console_id = ST_MAX_ARRAY_SUPPORTED;
+ ver.console_id = host->max_id - 1;
ver.host_no = hba->host->host_no;
cmd->result = stex_direct_copy(cmd, &ver, sizeof(ver)) ?
DID_OK << 16 | COMMAND_COMPLETE << 8 :
@@ -645,13 +660,8 @@
req = stex_alloc_req(hba);
- if (hba->cardtype == st_yosemite) {
- req->lun = lun * (ST_MAX_TARGET_NUM - 1) + id;
- req->target = 0;
- } else {
- req->lun = lun;
- req->target = id;
- }
+ req->lun = lun;
+ req->target = id;
/* cdb */
memcpy(req->cdb, cmd->cmnd, STEX_CDB_LENGTH);
@@ -767,18 +777,6 @@
ccb->srb_status = SRB_STATUS_SELECTION_TIMEOUT;
else
ccb->srb_status = SRB_STATUS_SUCCESS;
- } else if (ccb->cmd->cmnd[0] == REPORT_LUNS) {
- u8 *report_lun_data = (u8 *)hba->copy_buffer;
-
- count = STEX_EXTRA_SIZE;
- stex_internal_copy(ccb->cmd, report_lun_data,
- &count, ccb->sg_count, ST_FROM_CMD);
- if (report_lun_data[2] || report_lun_data[3]) {
- report_lun_data[2] = 0x00;
- report_lun_data[3] = 0x08;
- stex_internal_copy(ccb->cmd, report_lun_data,
- &count, ccb->sg_count, ST_TO_CMD);
- }
}
}
@@ -995,6 +993,11 @@
u32 data;
int result = SUCCESS;
unsigned long flags;
+
+ printk(KERN_INFO DRV_NAME
+ "(%s): aborting command\n", pci_name(hba->pdev));
+ scsi_print_command(cmd);
+
base = hba->mmio_base;
spin_lock_irqsave(host->host_lock, flags);
if (tag < host->can_queue && hba->ccb[tag].cmd == cmd)
@@ -1051,7 +1054,12 @@
pci_read_config_byte(bus->self, PCI_BRIDGE_CONTROL, &pci_bctl);
pci_bctl |= PCI_BRIDGE_CTL_BUS_RESET;
pci_write_config_byte(bus->self, PCI_BRIDGE_CONTROL, pci_bctl);
- msleep(1);
+
+ /*
+ * 1 ms may be enough for 8-port controllers. But 16-port controllers
+ * require more time to finish bus reset. Use 100 ms here for safety
+ */
+ msleep(100);
pci_bctl &= ~PCI_BRIDGE_CTL_BUS_RESET;
pci_write_config_byte(bus->self, PCI_BRIDGE_CONTROL, pci_bctl);
@@ -1075,6 +1083,10 @@
unsigned long before;
hba = (struct st_hba *) &cmd->device->host->hostdata[0];
+ printk(KERN_INFO DRV_NAME
+ "(%s): resetting host\n", pci_name(hba->pdev));
+ scsi_print_command(cmd);
+
hba->mu_status = MU_STATE_RESETTING;
if (hba->cardtype == st_shasta)
@@ -1194,7 +1206,7 @@
goto out_scsi_host_put;
}
- hba->mmio_base = ioremap(pci_resource_start(pdev, 0),
+ hba->mmio_base = ioremap_nocache(pci_resource_start(pdev, 0),
pci_resource_len(pdev, 0));
if ( !hba->mmio_base) {
printk(KERN_ERR DRV_NAME "(%s): memory map failed\n",
@@ -1229,12 +1241,18 @@
hba->copy_buffer = hba->dma_mem + MU_BUFFER_SIZE;
hba->mu_status = MU_STATE_STARTING;
- /* firmware uses id/lun pair for a logical drive, but lun would be
- always 0 if CONFIG_SCSI_MULTI_LUN not configured, so we use
- channel to map lun here */
- host->max_channel = ST_MAX_LUN_PER_TARGET - 1;
- host->max_id = ST_MAX_TARGET_NUM;
- host->max_lun = 1;
+ if (hba->cardtype == st_shasta) {
+ host->max_lun = 8;
+ host->max_id = 16 + 1;
+ } else if (hba->cardtype == st_yosemite) {
+ host->max_lun = 128;
+ host->max_id = 1 + 1;
+ } else {
+ /* st_vsc and st_vsc1 */
+ host->max_lun = 1;
+ host->max_id = 128 + 1;
+ }
+ host->max_channel = 0;
host->unique_id = host->host_no;
host->max_cmd_len = STEX_CDB_LENGTH;
diff --git a/drivers/spi/mpc52xx_psc_spi.c b/drivers/spi/mpc52xx_psc_spi.c
index 052359f..11f36be 100644
--- a/drivers/spi/mpc52xx_psc_spi.c
+++ b/drivers/spi/mpc52xx_psc_spi.c
@@ -329,8 +329,8 @@
int ret = 0;
#if defined(CONFIG_PPC_MERGE)
- cdm = mpc52xx_find_and_map("mpc52xx-cdm");
- gpio = mpc52xx_find_and_map("mpc52xx-gpio");
+ cdm = mpc52xx_find_and_map("mpc5200-cdm");
+ gpio = mpc52xx_find_and_map("mpc5200-gpio");
#else
cdm = ioremap(MPC52xx_PA(MPC52xx_CDM_OFFSET), MPC52xx_CDM_SIZE);
gpio = ioremap(MPC52xx_PA(MPC52xx_GPIO_OFFSET), MPC52xx_GPIO_SIZE);
@@ -445,9 +445,6 @@
struct spi_master *master;
int ret;
- if (pdata == NULL)
- return -ENODEV;
-
master = spi_alloc_master(dev, sizeof *mps);
if (master == NULL)
return -ENOMEM;
@@ -594,17 +591,17 @@
}
regaddr64 = of_translate_address(op->node, regaddr_p);
+ /* get PSC id (1..6, used by port_config) */
if (op->dev.platform_data == NULL) {
- struct device_node *np;
- int i = 0;
+ const u32 *psc_nump;
- for_each_node_by_type(np, "spi") {
- if (of_find_device_by_node(np) == op) {
- id = i;
- break;
- }
- i++;
+ psc_nump = of_get_property(op->node, "cell-index", NULL);
+ if (!psc_nump || *psc_nump > 5) {
+ printk(KERN_ERR "mpc52xx_psc_spi: Device node %s has invalid "
+ "cell-index property\n", op->node->full_name);
+ return -EINVAL;
}
+ id = *psc_nump + 1;
}
return mpc52xx_psc_spi_do_probe(&op->dev, (u32)regaddr64, (u32)size64,
@@ -617,7 +614,7 @@
}
static struct of_device_id mpc52xx_psc_spi_of_match[] = {
- { .type = "spi", .compatible = "mpc52xx-psc-spi", },
+ { .type = "spi", .compatible = "mpc5200-psc-spi", },
{},
};
diff --git a/drivers/spi/omap_uwire.c b/drivers/spi/omap_uwire.c
index 96f62b2..95183e1 100644
--- a/drivers/spi/omap_uwire.c
+++ b/drivers/spi/omap_uwire.c
@@ -358,11 +358,11 @@
switch (spi->mode & (SPI_CPOL | SPI_CPHA)) {
case SPI_MODE_0:
case SPI_MODE_3:
- flags |= UWIRE_WRITE_RISING_EDGE | UWIRE_READ_FALLING_EDGE;
+ flags |= UWIRE_WRITE_FALLING_EDGE | UWIRE_READ_RISING_EDGE;
break;
case SPI_MODE_1:
case SPI_MODE_2:
- flags |= UWIRE_WRITE_FALLING_EDGE | UWIRE_READ_RISING_EDGE;
+ flags |= UWIRE_WRITE_RISING_EDGE | UWIRE_READ_FALLING_EDGE;
break;
}
diff --git a/drivers/spi/spidev.c b/drivers/spi/spidev.c
index 225d6b2..d04242a 100644
--- a/drivers/spi/spidev.c
+++ b/drivers/spi/spidev.c
@@ -168,6 +168,12 @@
n--, k_tmp++, u_tmp++) {
k_tmp->len = u_tmp->len;
+ total += k_tmp->len;
+ if (total > bufsiz) {
+ status = -EMSGSIZE;
+ goto done;
+ }
+
if (u_tmp->rx_buf) {
k_tmp->rx_buf = buf;
if (!access_ok(VERIFY_WRITE, u_tmp->rx_buf, u_tmp->len))
@@ -179,12 +185,6 @@
u_tmp->len))
goto done;
}
-
- total += k_tmp->len;
- if (total > bufsiz) {
- status = -EMSGSIZE;
- goto done;
- }
buf += k_tmp->len;
k_tmp->cs_change = !!u_tmp->cs_change;
@@ -364,6 +364,7 @@
break;
}
if (__copy_from_user(ioc, (void __user *)arg, tmp)) {
+ kfree(ioc);
retval = -EFAULT;
break;
}
diff --git a/drivers/usb/class/usblp.c b/drivers/usb/class/usblp.c
index 15e740e..7b1edfe 100644
--- a/drivers/usb/class/usblp.c
+++ b/drivers/usb/class/usblp.c
@@ -1003,7 +1003,7 @@
usblp->writebuf, usblp->writeurb->transfer_dma);
if (usblp->readbuf)
usb_buffer_free (usblp->dev, USBLP_BUF_SIZE,
- usblp->readbuf, usblp->writeurb->transfer_dma);
+ usblp->readbuf, usblp->readurb->transfer_dma);
kfree(usblp->statusbuf);
kfree(usblp->device_id_string);
usb_free_urb(usblp->writeurb);
diff --git a/drivers/usb/core/config.c b/drivers/usb/core/config.c
index bfb3731..2d4fd53 100644
--- a/drivers/usb/core/config.c
+++ b/drivers/usb/core/config.c
@@ -185,10 +185,12 @@
num_ep = USB_MAXENDPOINTS;
}
- len = sizeof(struct usb_host_endpoint) * num_ep;
- alt->endpoint = kzalloc(len, GFP_KERNEL);
- if (!alt->endpoint)
- return -ENOMEM;
+ if (num_ep > 0) { /* Can't allocate 0 bytes */
+ len = sizeof(struct usb_host_endpoint) * num_ep;
+ alt->endpoint = kzalloc(len, GFP_KERNEL);
+ if (!alt->endpoint)
+ return -ENOMEM;
+ }
/* Parse all the endpoint descriptors */
n = 0;
diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c
index b9f7f90..2619986 100644
--- a/drivers/usb/core/driver.c
+++ b/drivers/usb/core/driver.c
@@ -983,7 +983,10 @@
#else
-#define autosuspend_check(udev) 0
+static inline int autosuspend_check(struct usb_device *udev)
+{
+ return 0;
+}
#endif /* CONFIG_USB_SUSPEND */
@@ -1041,7 +1044,6 @@
if (status < 0)
goto done;
}
- cancel_delayed_work(&udev->autosuspend);
/* Suspend all the interfaces and then udev itself */
if (udev->actconfig) {
@@ -1062,9 +1064,16 @@
usb_resume_interface(intf);
}
+ /* Try another autosuspend when the interfaces aren't busy */
+ if (udev->auto_pm)
+ autosuspend_check(udev);
+
/* If the suspend succeeded, propagate it up the tree */
- } else if (parent)
- usb_autosuspend_device(parent);
+ } else {
+ cancel_delayed_work(&udev->autosuspend);
+ if (parent)
+ usb_autosuspend_device(parent);
+ }
done:
// dev_dbg(&udev->dev, "%s: status %d\n", __FUNCTION__, status);
@@ -1475,6 +1484,7 @@
usb_pm_lock(udev);
udev->auto_pm = 0;
status = usb_resume_both(udev);
+ udev->last_busy = jiffies;
usb_pm_unlock(udev);
/* Now that the device is awake, we can start trying to autosuspend
diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c
index 40cf882..8969e42 100644
--- a/drivers/usb/core/hcd.c
+++ b/drivers/usb/core/hcd.c
@@ -1018,8 +1018,8 @@
atomic_dec (&urb->use_count);
if (urb->reject)
wake_up (&usb_kill_urb_queue);
- usb_put_urb (urb);
usbmon_urb_submit_error(&hcd->self, urb, status);
+ usb_put_urb (urb);
}
return status;
}
@@ -1175,10 +1175,6 @@
struct urb *urb;
hcd = bus_to_hcd(udev->bus);
-
- WARN_ON (!HC_IS_RUNNING (hcd->state) && hcd->state != HC_STATE_HALT &&
- udev->state != USB_STATE_NOTATTACHED);
-
local_irq_disable ();
/* ep is already gone from udev->ep_{in,out}[]; no more submits */
@@ -1685,7 +1681,7 @@
spin_unlock_irq (&hcd_root_hub_lock);
#ifdef CONFIG_PM
- flush_workqueue(ksuspend_usb_wq);
+ cancel_work_sync(&hcd->wakeup_work);
#endif
mutex_lock(&usb_bus_list_lock);
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index f6b74a6..24f10a1 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -1158,6 +1158,30 @@
}
}
+#ifdef CONFIG_USB_SUSPEND
+
+static void usb_stop_pm(struct usb_device *udev)
+{
+ /* Synchronize with the ksuspend thread to prevent any more
+ * autosuspend requests from being submitted, and decrement
+ * the parent's count of unsuspended children.
+ */
+ usb_pm_lock(udev);
+ if (udev->parent && !udev->discon_suspended)
+ usb_autosuspend_device(udev->parent);
+ usb_pm_unlock(udev);
+
+ /* Stop any autosuspend requests already submitted */
+ cancel_rearming_delayed_work(&udev->autosuspend);
+}
+
+#else
+
+static inline void usb_stop_pm(struct usb_device *udev)
+{ }
+
+#endif
+
/**
* usb_disconnect - disconnect a device (usbcore-internal)
* @pdev: pointer to device being disconnected
@@ -1224,13 +1248,7 @@
*pdev = NULL;
spin_unlock_irq(&device_state_lock);
- /* Decrement the parent's count of unsuspended children */
- if (udev->parent) {
- usb_pm_lock(udev);
- if (!udev->discon_suspended)
- usb_autosuspend_device(udev->parent);
- usb_pm_unlock(udev);
- }
+ usb_stop_pm(udev);
put_device(&udev->dev);
}
@@ -2201,14 +2219,9 @@
continue;
}
- /* Use a short timeout the first time through,
- * so that recalcitrant full-speed devices with
- * 8- or 16-byte ep0-maxpackets won't slow things
- * down tremendously by NAKing the unexpectedly
- * early status stage. Also, retry on all errors;
- * some devices are flakey.
- * 255 is for WUSB devices, we actually need to use 512.
- * WUSB1.0[4.8.1].
+ /* Retry on all errors; some devices are flakey.
+ * 255 is for WUSB devices, we actually need to use
+ * 512 (WUSB1.0[4.8.1]).
*/
for (j = 0; j < 3; ++j) {
buf->bMaxPacketSize0 = 0;
@@ -2216,7 +2229,7 @@
USB_REQ_GET_DESCRIPTOR, USB_DIR_IN,
USB_DT_DEVICE << 8, 0,
buf, GET_DESCRIPTOR_BUFSIZE,
- (i ? USB_CTRL_GET_TIMEOUT : 1000));
+ USB_CTRL_GET_TIMEOUT);
switch (buf->bMaxPacketSize0) {
case 8: case 16: case 32: case 64: case 255:
if (buf->bDescriptorType ==
@@ -2426,10 +2439,10 @@
if (portchange & USB_PORT_STAT_C_CONNECTION) {
status = hub_port_debounce(hub, port1);
- if (status < 0 && printk_ratelimit()) {
- dev_err (hub_dev,
- "connect-debounce failed, port %d disabled\n",
- port1);
+ if (status < 0) {
+ if (printk_ratelimit())
+ dev_err (hub_dev, "connect-debounce failed, "
+ "port %d disabled\n", port1);
goto done;
}
portstatus = status;
diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c
index b743478..f9fed34 100644
--- a/drivers/usb/core/message.c
+++ b/drivers/usb/core/message.c
@@ -221,15 +221,10 @@
if ((ep->desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) ==
USB_ENDPOINT_XFER_INT) {
- int interval;
-
- if (usb_dev->speed == USB_SPEED_HIGH)
- interval = 1 << min(15, ep->desc.bInterval - 1);
- else
- interval = ep->desc.bInterval;
pipe = (pipe & ~(3 << 30)) | (PIPE_INTERRUPT << 30);
usb_fill_int_urb(urb, usb_dev, pipe, data, len,
- usb_api_blocking_completion, NULL, interval);
+ usb_api_blocking_completion, NULL,
+ ep->desc.bInterval);
} else
usb_fill_bulk_urb(urb, usb_dev, pipe, data, len,
usb_api_blocking_completion, NULL);
diff --git a/drivers/usb/core/sysfs.c b/drivers/usb/core/sysfs.c
index e7c9823..be37c86 100644
--- a/drivers/usb/core/sysfs.c
+++ b/drivers/usb/core/sysfs.c
@@ -232,12 +232,15 @@
int len = count;
char *cp;
int rc = 0;
+ int old_autosuspend_disabled, old_autoresume_disabled;
cp = memchr(buf, '\n', count);
if (cp)
len = cp - buf;
usb_lock_device(udev);
+ old_autosuspend_disabled = udev->autosuspend_disabled;
+ old_autoresume_disabled = udev->autoresume_disabled;
/* Setting the flags without calling usb_pm_lock is a subject to
* races, but who cares...
@@ -263,6 +266,10 @@
} else
rc = -EINVAL;
+ if (rc) {
+ udev->autosuspend_disabled = old_autosuspend_disabled;
+ udev->autoresume_disabled = old_autoresume_disabled;
+ }
usb_unlock_device(udev);
return (rc < 0 ? rc : count);
}
diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c
index 18ddc5e6..4a6299b 100644
--- a/drivers/usb/core/usb.c
+++ b/drivers/usb/core/usb.c
@@ -184,10 +184,6 @@
udev = to_usb_device(dev);
-#ifdef CONFIG_USB_SUSPEND
- cancel_delayed_work(&udev->autosuspend);
- flush_workqueue(ksuspend_usb_wq);
-#endif
usb_destroy_configuration(udev);
usb_put_hcd(bus_to_hcd(udev->bus));
kfree(udev->product);
@@ -205,7 +201,11 @@
static int ksuspend_usb_init(void)
{
- ksuspend_usb_wq = create_singlethread_workqueue("ksuspend_usbd");
+ /* This workqueue is supposed to be both freezable and
+ * singlethreaded. Its job doesn't justify running on more
+ * than one CPU.
+ */
+ ksuspend_usb_wq = create_freezeable_workqueue("ksuspend_usbd");
if (!ksuspend_usb_wq)
return -ENOMEM;
return 0;
diff --git a/drivers/usb/gadget/fsl_usb2_udc.c b/drivers/usb/gadget/fsl_usb2_udc.c
index 157054e..3ca2b31 100644
--- a/drivers/usb/gadget/fsl_usb2_udc.c
+++ b/drivers/usb/gadget/fsl_usb2_udc.c
@@ -228,13 +228,15 @@
/* Config PHY interface */
portctrl = fsl_readl(&dr_regs->portsc1);
- portctrl &= ~PORTSCX_PHY_TYPE_SEL;
+ portctrl &= ~(PORTSCX_PHY_TYPE_SEL & PORTSCX_PORT_WIDTH);
switch (udc->phy_mode) {
case FSL_USB2_PHY_ULPI:
portctrl |= PORTSCX_PTS_ULPI;
break;
- case FSL_USB2_PHY_UTMI:
case FSL_USB2_PHY_UTMI_WIDE:
+ portctrl |= PORTSCX_PTW_16BIT;
+ /* fall through */
+ case FSL_USB2_PHY_UTMI:
portctrl |= PORTSCX_PTS_UTMI;
break;
case FSL_USB2_PHY_SERIAL:
@@ -625,7 +627,7 @@
struct fsl_ep *ep;
if (!_ep)
- return NULL;
+ return;
ep = container_of(_ep, struct fsl_ep, ep);
diff --git a/drivers/usb/host/ehci-fsl.c b/drivers/usb/host/ehci-fsl.c
index a524805..c7a7c59 100644
--- a/drivers/usb/host/ehci-fsl.c
+++ b/drivers/usb/host/ehci-fsl.c
@@ -193,6 +193,19 @@
out_be32(non_ehci + FSL_SOC_USB_CTRL, 0x00000004);
out_be32(non_ehci + FSL_SOC_USB_SNOOP1, 0x0000001b);
+#if defined(CONFIG_PPC32) && !defined(CONFIG_NOT_COHERENT_CACHE)
+ /*
+ * Turn on cache snooping hardware, since some PowerPC platforms
+ * wholly rely on hardware to deal with cache coherent
+ */
+
+ /* Setup Snooping for all the 4GB space */
+ /* SNOOP1 starts from 0x0, size 2G */
+ out_be32(non_ehci + FSL_SOC_USB_SNOOP1, 0x0 | SNOOP_SIZE_2GB);
+ /* SNOOP2 starts from 0x80000000, size 2G */
+ out_be32(non_ehci + FSL_SOC_USB_SNOOP2, 0x80000000 | SNOOP_SIZE_2GB);
+#endif
+
if (pdata->operating_mode == FSL_USB2_DR_HOST)
mpc83xx_setup_phy(ehci, pdata->phy_mode, 0);
diff --git a/drivers/usb/host/ehci-fsl.h b/drivers/usb/host/ehci-fsl.h
index f28736a..b5e59db 100644
--- a/drivers/usb/host/ehci-fsl.h
+++ b/drivers/usb/host/ehci-fsl.h
@@ -34,4 +34,5 @@
#define FSL_SOC_USB_PRICTRL 0x40c /* NOTE: big-endian */
#define FSL_SOC_USB_SICTRL 0x410 /* NOTE: big-endian */
#define FSL_SOC_USB_CTRL 0x500 /* NOTE: big-endian */
+#define SNOOP_SIZE_2GB 0x1e
#endif /* _EHCI_FSL_H */
diff --git a/drivers/usb/host/ohci-pci.c b/drivers/usb/host/ohci-pci.c
index 7970560..ca62cb5 100644
--- a/drivers/usb/host/ohci-pci.c
+++ b/drivers/usb/host/ohci-pci.c
@@ -137,7 +137,7 @@
/* Toshiba portege 4000 */
.vendor = PCI_VENDOR_ID_AL,
.device = 0x5237,
- .subvendor = PCI_VENDOR_ID_TOSHIBA_2,
+ .subvendor = PCI_VENDOR_ID_TOSHIBA,
.subdevice = 0x0004,
.driver_data = (unsigned long) broken_suspend,
},
diff --git a/drivers/usb/host/pci-quirks.c b/drivers/usb/host/pci-quirks.c
index 2086165..c225159 100644
--- a/drivers/usb/host/pci-quirks.c
+++ b/drivers/usb/host/pci-quirks.c
@@ -44,6 +44,7 @@
#define EHCI_USBSTS 4 /* status register */
#define EHCI_USBSTS_HALTED (1 << 12) /* HCHalted bit */
#define EHCI_USBINTR 8 /* interrupt register */
+#define EHCI_CONFIGFLAG 0x40 /* configured flag register */
#define EHCI_USBLEGSUP 0 /* legacy support register */
#define EHCI_USBLEGSUP_BIOS (1 << 16) /* BIOS semaphore */
#define EHCI_USBLEGSUP_OS (1 << 24) /* OS semaphore */
@@ -216,6 +217,7 @@
u32 hcc_params, val;
u8 offset, cap_length;
int count = 256/4;
+ int tried_handoff = 0;
if (!mmio_resource_enabled(pdev, 0))
return;
@@ -273,6 +275,7 @@
*/
msec = 5000;
while ((cap & EHCI_USBLEGSUP_BIOS) && (msec > 0)) {
+ tried_handoff = 1;
msleep(10);
msec -= 10;
pci_read_config_dword(pdev, offset, &cap);
@@ -292,6 +295,12 @@
pci_write_config_dword(pdev,
offset + EHCI_USBLEGCTLSTS,
0);
+
+ /* If the BIOS ever owned the controller then we
+ * can't expect any power sessions to remain intact.
+ */
+ if (tried_handoff)
+ writel(0, op_reg_base + EHCI_CONFIGFLAG);
break;
case 0: /* illegal reserved capability */
cap = 0;
diff --git a/drivers/usb/host/u132-hcd.c b/drivers/usb/host/u132-hcd.c
index ff0dba0..e98df2e 100644
--- a/drivers/usb/host/u132-hcd.c
+++ b/drivers/usb/host/u132-hcd.c
@@ -57,6 +57,13 @@
#include <asm/system.h>
#include <asm/byteorder.h>
#include "../core/hcd.h"
+
+ /* FIXME ohci.h is ONLY for internal use by the OHCI driver.
+ * If you're going to try stuff like this, you need to split
+ * out shareable stuff (register declarations?) into its own
+ * file, maybe name <linux/usb/ohci.h>
+ */
+
#include "ohci.h"
#define OHCI_CONTROL_INIT OHCI_CTRL_CBSR
#define OHCI_INTR_INIT (OHCI_INTR_MIE | OHCI_INTR_UE | OHCI_INTR_RD | \
@@ -173,11 +180,6 @@
struct u132_endp *curr_endp;
struct delayed_work scheduler;
};
-#define OHCI_QUIRK_AMD756 0x01
-#define OHCI_QUIRK_SUPERIO 0x02
-#define OHCI_QUIRK_INITRESET 0x04
-#define OHCI_BIG_ENDIAN 0x08
-#define OHCI_QUIRK_ZFMICRO 0x10
struct u132 {
struct kref kref;
struct list_head u132_list;
diff --git a/drivers/usb/misc/auerswald.c b/drivers/usb/misc/auerswald.c
index 88fb56d..cac1500 100644
--- a/drivers/usb/misc/auerswald.c
+++ b/drivers/usb/misc/auerswald.c
@@ -1822,16 +1822,10 @@
pauerswald_t cp;
dbg("release");
- /* get the mutexes */
- if (down_interruptible (&ccp->mutex)) {
- return -ERESTARTSYS;
- }
+ down(&ccp->mutex);
cp = ccp->auerdev;
if (cp) {
- if (down_interruptible (&cp->mutex)) {
- up (&ccp->mutex);
- return -ERESTARTSYS;
- }
+ down(&cp->mutex);
/* remove an open service */
auerswald_removeservice (cp, &ccp->scontext);
/* detach from device */
diff --git a/drivers/usb/misc/ftdi-elan.c b/drivers/usb/misc/ftdi-elan.c
index e2172e5..e0f122e 100644
--- a/drivers/usb/misc/ftdi-elan.c
+++ b/drivers/usb/misc/ftdi-elan.c
@@ -73,6 +73,13 @@
#include "usb_u132.h"
#include <asm/io.h>
#include "../core/hcd.h"
+
+ /* FIXME ohci.h is ONLY for internal use by the OHCI driver.
+ * If you're going to try stuff like this, you need to split
+ * out shareable stuff (register declarations?) into its own
+ * file, maybe name <linux/usb/ohci.h>
+ */
+
#include "../host/ohci.h"
/* Define these values to match your devices*/
#define USB_FTDI_ELAN_VENDOR_ID 0x0403
@@ -2300,10 +2307,7 @@
offsetof(struct ohci_regs, member), 0, data);
#define ftdi_write_pcimem(ftdi, member, data) ftdi_elan_write_pcimem(ftdi, \
offsetof(struct ohci_regs, member), 0, data);
-#define OHCI_QUIRK_AMD756 0x01
-#define OHCI_QUIRK_SUPERIO 0x02
-#define OHCI_QUIRK_INITRESET 0x04
-#define OHCI_BIG_ENDIAN 0x08
+
#define OHCI_CONTROL_INIT OHCI_CTRL_CBSR
#define OHCI_INTR_INIT (OHCI_INTR_MIE | OHCI_INTR_UE | OHCI_INTR_RD | \
OHCI_INTR_WDH)
diff --git a/drivers/usb/misc/ldusb.c b/drivers/usb/misc/ldusb.c
index 11555bde..7bad494 100644
--- a/drivers/usb/misc/ldusb.c
+++ b/drivers/usb/misc/ldusb.c
@@ -165,6 +165,8 @@
size_t interrupt_in_endpoint_size;
int interrupt_in_running;
int interrupt_in_done;
+ int buffer_overflow;
+ spinlock_t rbsl;
char* interrupt_out_buffer;
struct usb_endpoint_descriptor* interrupt_out_endpoint;
@@ -230,10 +232,12 @@
} else {
dbg_info(&dev->intf->dev, "%s: nonzero status received: %d\n",
__FUNCTION__, urb->status);
+ spin_lock(&dev->rbsl);
goto resubmit; /* maybe we can recover */
}
}
+ spin_lock(&dev->rbsl);
if (urb->actual_length > 0) {
next_ring_head = (dev->ring_head+1) % ring_buffer_size;
if (next_ring_head != dev->ring_tail) {
@@ -244,21 +248,25 @@
dev->ring_head = next_ring_head;
dbg_info(&dev->intf->dev, "%s: received %d bytes\n",
__FUNCTION__, urb->actual_length);
- } else
+ } else {
dev_warn(&dev->intf->dev,
"Ring buffer overflow, %d bytes dropped\n",
urb->actual_length);
+ dev->buffer_overflow = 1;
+ }
}
resubmit:
/* resubmit if we're still running */
- if (dev->interrupt_in_running && dev->intf) {
+ if (dev->interrupt_in_running && !dev->buffer_overflow && dev->intf) {
retval = usb_submit_urb(dev->interrupt_in_urb, GFP_ATOMIC);
- if (retval)
+ if (retval) {
dev_err(&dev->intf->dev,
"usb_submit_urb failed (%d)\n", retval);
+ dev->buffer_overflow = 1;
+ }
}
-
+ spin_unlock(&dev->rbsl);
exit:
dev->interrupt_in_done = 1;
wake_up_interruptible(&dev->read_wait);
@@ -330,6 +338,7 @@
/* initialize in direction */
dev->ring_head = 0;
dev->ring_tail = 0;
+ dev->buffer_overflow = 0;
usb_fill_int_urb(dev->interrupt_in_urb,
interface_to_usbdev(interface),
usb_rcvintpipe(interface_to_usbdev(interface),
@@ -439,6 +448,7 @@
size_t *actual_buffer;
size_t bytes_to_read;
int retval = 0;
+ int rv;
dev = file->private_data;
@@ -460,7 +470,10 @@
}
/* wait for data */
+ spin_lock_irq(&dev->rbsl);
if (dev->ring_head == dev->ring_tail) {
+ dev->interrupt_in_done = 0;
+ spin_unlock_irq(&dev->rbsl);
if (file->f_flags & O_NONBLOCK) {
retval = -EAGAIN;
goto unlock_exit;
@@ -468,6 +481,8 @@
retval = wait_event_interruptible(dev->read_wait, dev->interrupt_in_done);
if (retval < 0)
goto unlock_exit;
+ } else {
+ spin_unlock_irq(&dev->rbsl);
}
/* actual_buffer contains actual_length + interrupt_in_buffer */
@@ -486,6 +501,17 @@
retval = bytes_to_read;
+ spin_lock_irq(&dev->rbsl);
+ if (dev->buffer_overflow) {
+ dev->buffer_overflow = 0;
+ spin_unlock_irq(&dev->rbsl);
+ rv = usb_submit_urb(dev->interrupt_in_urb, GFP_KERNEL);
+ if (rv < 0)
+ dev->buffer_overflow = 1;
+ } else {
+ spin_unlock_irq(&dev->rbsl);
+ }
+
unlock_exit:
/* unlock the device */
up(&dev->sem);
@@ -635,6 +661,7 @@
goto exit;
}
init_MUTEX(&dev->sem);
+ spin_lock_init(&dev->rbsl);
dev->intf = intf;
init_waitqueue_head(&dev->read_wait);
init_waitqueue_head(&dev->write_wait);
diff --git a/drivers/usb/serial/ark3116.c b/drivers/usb/serial/ark3116.c
index ea2175b..fe43712 100644
--- a/drivers/usb/serial/ark3116.c
+++ b/drivers/usb/serial/ark3116.c
@@ -63,7 +63,8 @@
request, requesttype, value, index,
buf, 0x0000001, 1000);
if (result)
- dbg("%03d < %d bytes [0x%02X]", seq, result, buf[0]);
+ dbg("%03d < %d bytes [0x%02X]", seq, result,
+ ((unsigned char *)buf)[0]);
else
dbg("%03d < 0 bytes", seq);
}
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c
index 95a1805..2353679 100644
--- a/drivers/usb/serial/ftdi_sio.c
+++ b/drivers/usb/serial/ftdi_sio.c
@@ -273,12 +273,18 @@
/* struct ftdi_sio_quirk is used by devices requiring special attention. */
struct ftdi_sio_quirk {
+ int (*probe)(struct usb_serial *);
void (*setup)(struct usb_serial *); /* Special settings during startup. */
};
+static int ftdi_olimex_probe (struct usb_serial *serial);
static void ftdi_USB_UIRT_setup (struct usb_serial *serial);
static void ftdi_HE_TIRA1_setup (struct usb_serial *serial);
+static struct ftdi_sio_quirk ftdi_olimex_quirk = {
+ .probe = ftdi_olimex_probe,
+};
+
static struct ftdi_sio_quirk ftdi_USB_UIRT_quirk = {
.setup = ftdi_USB_UIRT_setup,
};
@@ -319,6 +325,7 @@
{ USB_DEVICE(FTDI_VID, FTDI_8U2232C_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_MICRO_CHAMELEON_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_RELAIS_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_OPENDCC_PID) },
{ USB_DEVICE(INTERBIOMETRICS_VID, INTERBIOMETRICS_IOBOARD_PID) },
{ USB_DEVICE(INTERBIOMETRICS_VID, INTERBIOMETRICS_MINI_IOBOARD_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_XF_632_PID) },
@@ -525,6 +532,9 @@
{ USB_DEVICE(FTDI_VID, FTDI_TACTRIX_OPENPORT_13U_PID) },
{ USB_DEVICE(ELEKTOR_VID, ELEKTOR_FT323R_PID) },
{ USB_DEVICE(TELLDUS_VID, TELLDUS_TELLSTICK_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_MAXSTREAM_PID) },
+ { USB_DEVICE(OLIMEX_VID, OLIMEX_ARM_USB_OCD_PID),
+ .driver_info = (kernel_ulong_t)&ftdi_olimex_quirk },
{ }, /* Optional parameter entry */
{ } /* Terminating entry */
};
@@ -669,7 +679,7 @@
/*
* ***************************************************************************
- * Utlity functions
+ * Utility functions
* ***************************************************************************
*/
@@ -1171,9 +1181,17 @@
/* Probe function to check for special devices */
static int ftdi_sio_probe (struct usb_serial *serial, const struct usb_device_id *id)
{
+ struct ftdi_sio_quirk *quirk = (struct ftdi_sio_quirk *)id->driver_info;
+
+ if (quirk && quirk->probe) {
+ int ret = quirk->probe(serial);
+ if (ret != 0)
+ return ret;
+ }
+
usb_set_serial_data(serial, (void *)id->driver_info);
- return (0);
+ return 0;
}
static int ftdi_sio_port_probe(struct usb_serial_port *port)
@@ -1268,6 +1286,24 @@
priv->force_rtscts = 1;
} /* ftdi_HE_TIRA1_setup */
+/*
+ * First port on Olimex arm-usb-ocd is reserved for JTAG interface
+ * and can be accessed from userspace using openocd.
+ */
+static int ftdi_olimex_probe(struct usb_serial *serial)
+{
+ struct usb_device *udev = serial->dev;
+ struct usb_interface *interface = serial->interface;
+
+ dbg("%s",__FUNCTION__);
+
+ if (interface == udev->actconfig->interface[0]) {
+ info("Ignoring reserved serial port on Olimex arm-usb-ocd\n");
+ return -ENODEV;
+ }
+
+ 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 77ad0a0..33aee90 100644
--- a/drivers/usb/serial/ftdi_sio.h
+++ b/drivers/usb/serial/ftdi_sio.h
@@ -60,6 +60,9 @@
/* DMX4ALL DMX Interfaces */
#define FTDI_DMX4ALL 0xC850
+/* OpenDCC (www.opendcc.de) product id */
+#define FTDI_OPENDCC_PID 0xBFD8
+
/* www.crystalfontz.com devices - thanx for providing free devices for evaluation ! */
/* they use the ftdi chipset for the USB interface and the vendor id is the same */
#define FTDI_XF_632_PID 0xFC08 /* 632: 16x2 Character Display */
@@ -518,6 +521,15 @@
#define FTDI_IBS_PEDO_PID 0xff3e /* IBS PEDO-Modem (RF modem 868.35 MHz) */
#define FTDI_IBS_PROD_PID 0xff3f /* future device */
+/*
+ * MaxStream devices www.maxstream.net
+ */
+#define FTDI_MAXSTREAM_PID 0xEE18 /* Xbee PKG-U Module */
+
+/* Olimex */
+#define OLIMEX_VID 0x15BA
+#define OLIMEX_ARM_USB_OCD_PID 0x0003
+
/* 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/mos7840.c b/drivers/usb/serial/mos7840.c
index 2366e7b..36620c6 100644
--- a/drivers/usb/serial/mos7840.c
+++ b/drivers/usb/serial/mos7840.c
@@ -769,11 +769,6 @@
return;
}
- if (!mos7840_port) {
- dbg("%s", "NULL mos7840_port pointer \n");
- return;
- }
-
if (mos7840_port_paranoia_check(mos7840_port->port, __FUNCTION__)) {
dbg("%s", "Port Paranoia failed \n");
return;
diff --git a/drivers/usb/serial/omninet.c b/drivers/usb/serial/omninet.c
index 4adfab9..00afc17 100644
--- a/drivers/usb/serial/omninet.c
+++ b/drivers/usb/serial/omninet.c
@@ -165,12 +165,10 @@
{
struct usb_serial *serial = port->serial;
struct usb_serial_port *wport;
- struct omninet_data *od = usb_get_serial_port_data(port);
int result = 0;
dbg("%s - port %d", __FUNCTION__, port->number);
- od = kmalloc( sizeof(struct omninet_data), GFP_KERNEL );
wport = serial->port[1];
wport->tty = port->tty;
diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c
index 8c3f55b..89f067d9 100644
--- a/drivers/usb/serial/option.c
+++ b/drivers/usb/serial/option.c
@@ -165,7 +165,6 @@
{ 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, 0x1430) }, /* Novatel XU870 */
{ 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, 0x2130) }, /* Novatel Merlin ES620 SM Bus */
diff --git a/drivers/usb/serial/sierra.c b/drivers/usb/serial/sierra.c
index 644607d..ac1829c 100644
--- a/drivers/usb/serial/sierra.c
+++ b/drivers/usb/serial/sierra.c
@@ -35,6 +35,7 @@
{ USB_DEVICE(0x1199, 0x0218) }, /* Sierra Wireless MC5720 */
{ USB_DEVICE(0x1199, 0x0020) }, /* Sierra Wireless MC5725 */
{ USB_DEVICE(0x1199, 0x0019) }, /* Sierra Wireless AirCard 595 */
+ { USB_DEVICE(0x1199, 0x0120) }, /* Sierra Wireless AirCard 595U */
{ USB_DEVICE(0x1199, 0x0021) }, /* Sierra Wireless AirCard 597E */
{ USB_DEVICE(0x1199, 0x6802) }, /* Sierra Wireless MC8755 */
{ USB_DEVICE(0x1199, 0x6804) }, /* Sierra Wireless MC8755 */
@@ -60,6 +61,7 @@
{ USB_DEVICE(0x1199, 0x0218) }, /* Sierra Wireless MC5720 */
{ USB_DEVICE(0x1199, 0x0020) }, /* Sierra Wireless MC5725 */
{ USB_DEVICE(0x1199, 0x0019) }, /* Sierra Wireless AirCard 595 */
+ { USB_DEVICE(0x1199, 0x0120) }, /* Sierra Wireless AirCard 595U */
{ USB_DEVICE(0x1199, 0x0021) }, /* Sierra Wireless AirCard 597E */
{ USB_DEVICE(0x1199, 0x6802) }, /* Sierra Wireless MC8755 */
{ USB_DEVICE(0x1199, 0x6804) }, /* Sierra Wireless MC8755 */
diff --git a/drivers/usb/storage/onetouch.c b/drivers/usb/storage/onetouch.c
index 6d3dad3..d353693 100644
--- a/drivers/usb/storage/onetouch.c
+++ b/drivers/usb/storage/onetouch.c
@@ -84,7 +84,7 @@
static int usb_onetouch_open(struct input_dev *dev)
{
- struct usb_onetouch *onetouch = dev->private;
+ struct usb_onetouch *onetouch = input_get_drvdata(dev);
onetouch->is_open = 1;
onetouch->irq->dev = onetouch->udev;
@@ -98,7 +98,7 @@
static void usb_onetouch_close(struct input_dev *dev)
{
- struct usb_onetouch *onetouch = dev->private;
+ struct usb_onetouch *onetouch = input_get_drvdata(dev);
usb_kill_urb(onetouch->irq);
onetouch->is_open = 0;
@@ -185,13 +185,14 @@
input_dev->name = onetouch->name;
input_dev->phys = onetouch->phys;
usb_to_input_id(udev, &input_dev->id);
- input_dev->cdev.dev = &udev->dev;
+ input_dev->dev.parent = &udev->dev;
set_bit(EV_KEY, input_dev->evbit);
set_bit(ONETOUCH_BUTTON, input_dev->keybit);
clear_bit(0, input_dev->keybit);
- input_dev->private = onetouch;
+ input_set_drvdata(input_dev, onetouch);
+
input_dev->open = usb_onetouch_open;
input_dev->close = usb_onetouch_close;
diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h
index 8b3145ab..d230ee7 100644
--- a/drivers/usb/storage/unusual_devs.h
+++ b/drivers/usb/storage/unusual_devs.h
@@ -1179,14 +1179,20 @@
US_SC_DEVICE, US_PR_DEVICE, NULL,
US_FL_FIX_INQUIRY ),
-/* This is a virtual windows driver CD, which the zd1211rw driver automatically
- * converts into a WLAN device. */
+/* These are virtual windows driver CDs, which the zd1211rw driver automatically
+ * converts into a WLAN devices. */
UNUSUAL_DEV( 0x0ace, 0x2011, 0x0101, 0x0101,
"ZyXEL",
"G-220F USB-WLAN Install",
US_SC_DEVICE, US_PR_DEVICE, NULL,
US_FL_IGNORE_DEVICE ),
+UNUSUAL_DEV( 0x0ace, 0x20ff, 0x0101, 0x0101,
+ "SiteCom",
+ "WL-117 USB-WLAN Install",
+ US_SC_DEVICE, US_PR_DEVICE, NULL,
+ US_FL_IGNORE_DEVICE ),
+
#ifdef CONFIG_USB_STORAGE_ISD200
UNUSUAL_DEV( 0x0bf6, 0xa001, 0x0100, 0x0110,
"ATI",
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index 4d7485f..6e1f1ea 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -704,6 +704,91 @@
This is the frame buffer device driver for the CGsix (GX, TurboGX)
frame buffer.
+config FB_FFB
+ bool "Creator/Creator3D/Elite3D support"
+ depends on FB_SBUS && SPARC64
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ help
+ This is the frame buffer device driver for the Creator, Creator3D,
+ and Elite3D graphics boards.
+
+config FB_TCX
+ bool "TCX (SS4/SS5 only) support"
+ depends on FB_SBUS
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ help
+ This is the frame buffer device driver for the TCX 24/8bit frame
+ buffer.
+
+config FB_CG14
+ bool "CGfourteen (SX) support"
+ depends on FB_SBUS
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ help
+ This is the frame buffer device driver for the CGfourteen frame
+ buffer on Desktop SPARCsystems with the SX graphics option.
+
+config FB_P9100
+ bool "P9100 (Sparcbook 3 only) support"
+ depends on FB_SBUS
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ help
+ This is the frame buffer device driver for the P9100 card
+ supported on Sparcbook 3 machines.
+
+config FB_LEO
+ bool "Leo (ZX) support"
+ depends on FB_SBUS
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ help
+ This is the frame buffer device driver for the SBUS-based Sun ZX
+ (leo) frame buffer cards.
+
+config FB_IGA
+ bool "IGA 168x display support"
+ depends on FB && SPARC32
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ help
+ This is the framebuffer device for the INTERGRAPHICS 1680 and
+ successor frame buffer cards.
+
+config FB_XVR500
+ bool "Sun XVR-500 3DLABS Wildcat support"
+ depends on FB && PCI && SPARC64
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ help
+ This is the framebuffer device for the Sun XVR-500 and similar
+ graphics cards based upon the 3DLABS Wildcat chipset. The driver
+ only works on sparc64 systems where the system firwmare has
+ mostly initialized the card already. It is treated as a
+ completely dumb framebuffer device.
+
+config FB_XVR2500
+ bool "Sun XVR-2500 3DLABS Wildcat support"
+ depends on FB && PCI && SPARC64
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ help
+ This is the framebuffer device for the Sun XVR-2500 and similar
+ graphics cards based upon the 3DLABS Wildcat chipset. The driver
+ only works on sparc64 systems where the system firwmare has
+ mostly initialized the card already. It is treated as a
+ completely dumb framebuffer device.
+
config FB_PVR2
tristate "NEC PowerVR 2 display support"
depends on FB && SH_DREAMCAST
@@ -1195,7 +1280,7 @@
config FB_ATY_CT
bool "Mach64 CT/VT/GT/LT (incl. 3D RAGE) support"
depends on PCI && FB_ATY
- default y if SPARC64 && FB_PCI
+ default y if SPARC64 && PCI
help
Say Y here to support use of ATI's 64-bit Rage boards (or other
boards based on the Mach64 CT, VT, GT, and LT chipsets) as a
@@ -1484,95 +1569,6 @@
source "drivers/video/geode/Kconfig"
-config FB_FFB
- bool "Creator/Creator3D/Elite3D support"
- depends on FB_SBUS && SPARC64
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- help
- This is the frame buffer device driver for the Creator, Creator3D,
- and Elite3D graphics boards.
-
-config FB_TCX
- bool "TCX (SS4/SS5 only) support"
- depends on FB_SBUS
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- help
- This is the frame buffer device driver for the TCX 24/8bit frame
- buffer.
-
-config FB_CG14
- bool "CGfourteen (SX) support"
- depends on FB_SBUS
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- help
- This is the frame buffer device driver for the CGfourteen frame
- buffer on Desktop SPARCsystems with the SX graphics option.
-
-config FB_P9100
- bool "P9100 (Sparcbook 3 only) support"
- depends on FB_SBUS
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- help
- This is the frame buffer device driver for the P9100 card
- supported on Sparcbook 3 machines.
-
-config FB_LEO
- bool "Leo (ZX) support"
- depends on FB_SBUS
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- help
- This is the frame buffer device driver for the SBUS-based Sun ZX
- (leo) frame buffer cards.
-
-config FB_XVR500
- bool "Sun XVR-500 3DLABS Wildcat support"
- depends on (FB = y) && PCI && SPARC64
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- help
- This is the framebuffer device for the Sun XVR-500 and similar
- graphics cards based upon the 3DLABS Wildcat chipset. The driver
- only works on sparc64 systems where the system firwmare has
- mostly initialized the card already. It is treated as a
- completely dumb framebuffer device.
-
-config FB_XVR2500
- bool "Sun XVR-2500 3DLABS Wildcat support"
- depends on (FB = y) && PCI && SPARC64
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- help
- This is the framebuffer device for the Sun XVR-2500 and similar
- graphics cards based upon the 3DLABS Wildcat chipset. The driver
- only works on sparc64 systems where the system firwmare has
- mostly initialized the card already. It is treated as a
- completely dumb framebuffer device.
-
-config FB_PCI
- bool "PCI framebuffers"
- depends on (FB = y) && PCI && SPARC
-
-config FB_IGA
- bool "IGA 168x display support"
- depends on SPARC32 && FB_PCI
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- help
- This is the framebuffer device for the INTERGRAPHICS 1680 and
- successor frame buffer cards.
-
config FB_HIT
tristate "HD64461 Frame Buffer support"
depends on FB && HD64461
@@ -1796,9 +1792,10 @@
config FB_PS3
bool "PS3 GPU framebuffer driver"
depends on (FB = y) && PS3_PS3AV
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
+ select FB_SYS_FILLRECT
+ select FB_SYS_COPYAREA
+ select FB_SYS_IMAGEBLIT
+ select FB_SYS_FOPS
---help---
Include support for the virtual frame buffer in the PS3 platform.
diff --git a/drivers/video/imxfb.c b/drivers/video/imxfb.c
index 267c1ff..a125898 100644
--- a/drivers/video/imxfb.c
+++ b/drivers/video/imxfb.c
@@ -394,26 +394,18 @@
/* initialize GPIOs */
imx_gpio_mode(PD6_PF_LSCLK);
- imx_gpio_mode(PD10_PF_SPL_SPR);
imx_gpio_mode(PD11_PF_CONTRAST);
imx_gpio_mode(PD14_PF_FLM_VSYNC);
imx_gpio_mode(PD13_PF_LP_HSYNC);
- imx_gpio_mode(PD7_PF_REV);
- imx_gpio_mode(PD8_PF_CLS);
-
-#ifndef CONFIG_MACH_PIMX1
- /* on PiMX1 used as buffers enable signal
- */
- imx_gpio_mode(PD9_PF_PS);
-#endif
-
-#ifndef CONFIG_MACH_MX1FS2
- /* on mx1fs2 this pin is used to (de)activate the display, so we need
- * it as a normal gpio
- */
imx_gpio_mode(PD12_PF_ACD_OE);
-#endif
+ /* These are only needed for Sharp HR TFT displays */
+ if (fbi->pcr & PCR_SHARP) {
+ imx_gpio_mode(PD7_PF_REV);
+ imx_gpio_mode(PD8_PF_CLS);
+ imx_gpio_mode(PD9_PF_PS);
+ imx_gpio_mode(PD10_PF_SPL_SPR);
+ }
}
#ifdef CONFIG_PM
@@ -476,7 +468,6 @@
info->fbops = &imxfb_ops;
info->flags = FBINFO_FLAG_DEFAULT;
- info->pseudo_palette = (fbi + 1);
fbi->rgb[RGB_16] = &def_rgb_16;
fbi->rgb[RGB_8] = &def_rgb_8;
@@ -499,6 +490,7 @@
info->var.sync = inf->sync;
info->var.grayscale = inf->cmap_greyscale;
fbi->cmap_inverse = inf->cmap_inverse;
+ fbi->cmap_static = inf->cmap_static;
fbi->pcr = inf->pcr;
fbi->lscr1 = inf->lscr1;
fbi->dmacr = inf->dmacr;
diff --git a/drivers/video/pm2fb.c b/drivers/video/pm2fb.c
index ab5e668..0a04483a 100644
--- a/drivers/video/pm2fb.c
+++ b/drivers/video/pm2fb.c
@@ -183,15 +183,17 @@
index = PM2VR_RD_INDEXED_DATA;
break;
}
- mb();
+ wmb();
pm2_WR(p, index, v);
+ wmb();
}
static inline void pm2v_RDAC_WR(struct pm2fb_par* p, s32 idx, u32 v)
{
pm2_WR(p, PM2VR_RD_INDEX_LOW, idx & 0xff);
- mb();
+ wmb();
pm2_WR(p, PM2VR_RD_INDEXED_DATA, v);
+ wmb();
}
#ifdef CONFIG_FB_PM2_FIFO_DISCONNECT
@@ -466,11 +468,9 @@
WAIT_FIFO(par, 8);
pm2_WR(par, PM2VR_RD_INDEX_HIGH, PM2VI_RD_MCLK_CONTROL >> 8);
pm2v_RDAC_WR(par, PM2VI_RD_MCLK_CONTROL, 0);
- wmb();
pm2v_RDAC_WR(par, PM2VI_RD_MCLK_PRESCALE, m);
pm2v_RDAC_WR(par, PM2VI_RD_MCLK_FEEDBACK, n);
pm2v_RDAC_WR(par, PM2VI_RD_MCLK_POSTSCALE, p);
- wmb();
pm2v_RDAC_WR(par, PM2VI_RD_MCLK_CONTROL, 1);
rmb();
for (i = 256;
@@ -483,12 +483,9 @@
pm2_mnp(clk, &m, &n, &p);
WAIT_FIFO(par, 10);
pm2_RDAC_WR(par, PM2I_RD_MEMORY_CLOCK_3, 6);
- wmb();
pm2_RDAC_WR(par, PM2I_RD_MEMORY_CLOCK_1, m);
pm2_RDAC_WR(par, PM2I_RD_MEMORY_CLOCK_2, n);
- wmb();
pm2_RDAC_WR(par, PM2I_RD_MEMORY_CLOCK_3, 8|p);
- wmb();
pm2_RDAC_RD(par, PM2I_RD_MEMORY_CLOCK_STATUS);
rmb();
for (i = 256;
@@ -509,12 +506,9 @@
pm2_mnp(clk, &m, &n, &p);
WAIT_FIFO(par, 8);
pm2_RDAC_WR(par, PM2I_RD_PIXEL_CLOCK_A3, 0);
- wmb();
pm2_RDAC_WR(par, PM2I_RD_PIXEL_CLOCK_A1, m);
pm2_RDAC_WR(par, PM2I_RD_PIXEL_CLOCK_A2, n);
- wmb();
pm2_RDAC_WR(par, PM2I_RD_PIXEL_CLOCK_A3, 8|p);
- wmb();
pm2_RDAC_RD(par, PM2I_RD_PIXEL_CLOCK_STATUS);
rmb();
for (i = 256;
@@ -1066,10 +1060,9 @@
if (!w || !h)
return;
- WAIT_FIFO(par, 6);
+ WAIT_FIFO(par, 5);
pm2_WR(par, PM2R_CONFIG, PM2F_CONFIG_FB_WRITE_ENABLE |
PM2F_CONFIG_FB_READ_SOURCE_ENABLE);
- pm2_WR(par, PM2R_FB_PIXEL_OFFSET, 0);
if (copy)
pm2_WR(par, PM2R_FB_SOURCE_DELTA,
((ysrc-y) & 0xfff) << 16 | ((xsrc-x) & 0xfff));
diff --git a/drivers/video/pm3fb.c b/drivers/video/pm3fb.c
index c77a1a1..616a0c0 100644
--- a/drivers/video/pm3fb.c
+++ b/drivers/video/pm3fb.c
@@ -52,11 +52,6 @@
static char *mode_option __devinitdata;
/*
- * If your driver supports multiple boards, you should make the
- * below data types arrays, or allocate them dynamically (using kmalloc()).
- */
-
-/*
* This structure defines the hardware state of the graphics card. Normally
* you place this in a header file in linux/include/video. This file usually
* also includes register information. That allows other driver subsystems
@@ -67,7 +62,7 @@
unsigned char __iomem *v_regs;/* virtual address of p_regs */
u32 video; /* video flags before blanking */
u32 base; /* screen base (xoffset+yoffset) in 128 bits unit */
- u32 palette[16];
+ u32 palette[16];
};
/*
@@ -104,36 +99,28 @@
while (PM3_READ_REG(par, PM3InFIFOSpace) < n);
}
-static inline void PM3_SLOW_WRITE_REG(struct pm3_par *par, s32 off, u32 v)
-{
- if (par->v_regs) {
- mb();
- PM3_WAIT(par, 1);
- wmb();
- PM3_WRITE_REG(par, off, v);
- }
-}
-
-static inline void PM3_SET_INDEX(struct pm3_par *par, unsigned index)
-{
- PM3_SLOW_WRITE_REG(par, PM3RD_IndexHigh, (index >> 8) & 0xff);
- PM3_SLOW_WRITE_REG(par, PM3RD_IndexLow, index & 0xff);
-}
-
static inline void PM3_WRITE_DAC_REG(struct pm3_par *par, unsigned r, u8 v)
{
- PM3_SET_INDEX(par, r);
+ PM3_WAIT(par, 3);
+ PM3_WRITE_REG(par, PM3RD_IndexHigh, (r >> 8) & 0xff);
+ PM3_WRITE_REG(par, PM3RD_IndexLow, r & 0xff);
wmb();
PM3_WRITE_REG(par, PM3RD_IndexedData, v);
+ wmb();
}
static inline void pm3fb_set_color(struct pm3_par *par, unsigned char regno,
unsigned char r, unsigned char g, unsigned char b)
{
- PM3_SLOW_WRITE_REG(par, PM3RD_PaletteWriteAddress, regno);
- PM3_SLOW_WRITE_REG(par, PM3RD_PaletteData, r);
- PM3_SLOW_WRITE_REG(par, PM3RD_PaletteData, g);
- PM3_SLOW_WRITE_REG(par, PM3RD_PaletteData, b);
+ PM3_WAIT(par, 4);
+ PM3_WRITE_REG(par, PM3RD_PaletteWriteAddress, regno);
+ wmb();
+ PM3_WRITE_REG(par, PM3RD_PaletteData, r);
+ wmb();
+ PM3_WRITE_REG(par, PM3RD_PaletteData, g);
+ wmb();
+ PM3_WRITE_REG(par, PM3RD_PaletteData, b);
+ wmb();
}
static void pm3fb_clear_colormap(struct pm3_par *par,
@@ -141,7 +128,7 @@
{
int i;
- for (i = 0; i < 256 ; i++) /* fill color map with white */
+ for (i = 0; i < 256 ; i++)
pm3fb_set_color(par, i, r, g, b);
}
@@ -175,19 +162,26 @@
}
}
-static inline int pm3fb_shift_bpp(unsigned long depth, int v)
+static inline int pm3fb_depth(const struct fb_var_screeninfo *var)
{
- switch (depth) {
+ if ( var->bits_per_pixel == 16 )
+ return var->red.length + var->green.length
+ + var->blue.length;
+
+ return var->bits_per_pixel;
+}
+
+static inline int pm3fb_shift_bpp(unsigned bpp, int v)
+{
+ switch (bpp) {
case 8:
return (v >> 4);
- case 12:
- case 15:
case 16:
return (v >> 3);
case 32:
return (v >> 2);
}
- DPRINTK("Unsupported depth %ld\n", depth);
+ DPRINTK("Unsupported depth %u\n", bpp);
return 0;
}
@@ -206,56 +200,50 @@
const u32 vbend = vsend + info->var.upper_margin;
const u32 vtotal = info->var.yres + vbend;
const u32 width = (info->var.xres_virtual + 7) & ~7;
+ const unsigned bpp = info->var.bits_per_pixel;
- PM3_SLOW_WRITE_REG(par, PM3MemBypassWriteMask, 0xffffffff);
- PM3_SLOW_WRITE_REG(par, PM3Aperture0, 0x00000000);
- PM3_SLOW_WRITE_REG(par, PM3Aperture1, 0x00000000);
- PM3_SLOW_WRITE_REG(par, PM3FIFODis, 0x00000007);
+ PM3_WAIT(par, 20);
+ PM3_WRITE_REG(par, PM3MemBypassWriteMask, 0xffffffff);
+ PM3_WRITE_REG(par, PM3Aperture0, 0x00000000);
+ PM3_WRITE_REG(par, PM3Aperture1, 0x00000000);
+ PM3_WRITE_REG(par, PM3FIFODis, 0x00000007);
- PM3_SLOW_WRITE_REG(par, PM3HTotal,
- pm3fb_shift_bpp(info->var.bits_per_pixel,
- htotal - 1));
- PM3_SLOW_WRITE_REG(par, PM3HsEnd,
- pm3fb_shift_bpp(info->var.bits_per_pixel,
- hsend));
- PM3_SLOW_WRITE_REG(par, PM3HsStart,
- pm3fb_shift_bpp(info->var.bits_per_pixel,
- hsstart));
- PM3_SLOW_WRITE_REG(par, PM3HbEnd,
- pm3fb_shift_bpp(info->var.bits_per_pixel,
- hbend));
- PM3_SLOW_WRITE_REG(par, PM3HgEnd,
- pm3fb_shift_bpp(info->var.bits_per_pixel,
- hbend));
- PM3_SLOW_WRITE_REG(par, PM3ScreenStride,
- pm3fb_shift_bpp(info->var.bits_per_pixel,
- width));
- PM3_SLOW_WRITE_REG(par, PM3VTotal, vtotal - 1);
- PM3_SLOW_WRITE_REG(par, PM3VsEnd, vsend - 1);
- PM3_SLOW_WRITE_REG(par, PM3VsStart, vsstart - 1);
- PM3_SLOW_WRITE_REG(par, PM3VbEnd, vbend);
+ PM3_WRITE_REG(par, PM3HTotal,
+ pm3fb_shift_bpp(bpp, htotal - 1));
+ PM3_WRITE_REG(par, PM3HsEnd,
+ pm3fb_shift_bpp(bpp, hsend));
+ PM3_WRITE_REG(par, PM3HsStart,
+ pm3fb_shift_bpp(bpp, hsstart));
+ PM3_WRITE_REG(par, PM3HbEnd,
+ pm3fb_shift_bpp(bpp, hbend));
+ PM3_WRITE_REG(par, PM3HgEnd,
+ pm3fb_shift_bpp(bpp, hbend));
+ PM3_WRITE_REG(par, PM3ScreenStride,
+ pm3fb_shift_bpp(bpp, width));
+ PM3_WRITE_REG(par, PM3VTotal, vtotal - 1);
+ PM3_WRITE_REG(par, PM3VsEnd, vsend - 1);
+ PM3_WRITE_REG(par, PM3VsStart, vsstart - 1);
+ PM3_WRITE_REG(par, PM3VbEnd, vbend);
- switch (info->var.bits_per_pixel) {
+ switch (bpp) {
case 8:
- PM3_SLOW_WRITE_REG(par, PM3ByAperture1Mode,
+ PM3_WRITE_REG(par, PM3ByAperture1Mode,
PM3ByApertureMode_PIXELSIZE_8BIT);
- PM3_SLOW_WRITE_REG(par, PM3ByAperture2Mode,
+ PM3_WRITE_REG(par, PM3ByAperture2Mode,
PM3ByApertureMode_PIXELSIZE_8BIT);
break;
- case 12:
- case 15:
case 16:
#ifndef __BIG_ENDIAN
- PM3_SLOW_WRITE_REG(par, PM3ByAperture1Mode,
+ PM3_WRITE_REG(par, PM3ByAperture1Mode,
PM3ByApertureMode_PIXELSIZE_16BIT);
- PM3_SLOW_WRITE_REG(par, PM3ByAperture2Mode,
+ PM3_WRITE_REG(par, PM3ByAperture2Mode,
PM3ByApertureMode_PIXELSIZE_16BIT);
#else
- PM3_SLOW_WRITE_REG(par, PM3ByAperture1Mode,
+ PM3_WRITE_REG(par, PM3ByAperture1Mode,
PM3ByApertureMode_PIXELSIZE_16BIT |
PM3ByApertureMode_BYTESWAP_BADC);
- PM3_SLOW_WRITE_REG(par, PM3ByAperture2Mode,
+ PM3_WRITE_REG(par, PM3ByAperture2Mode,
PM3ByApertureMode_PIXELSIZE_16BIT |
PM3ByApertureMode_BYTESWAP_BADC);
#endif /* ! __BIG_ENDIAN */
@@ -263,23 +251,22 @@
case 32:
#ifndef __BIG_ENDIAN
- PM3_SLOW_WRITE_REG(par, PM3ByAperture1Mode,
+ PM3_WRITE_REG(par, PM3ByAperture1Mode,
PM3ByApertureMode_PIXELSIZE_32BIT);
- PM3_SLOW_WRITE_REG(par, PM3ByAperture2Mode,
+ PM3_WRITE_REG(par, PM3ByAperture2Mode,
PM3ByApertureMode_PIXELSIZE_32BIT);
#else
- PM3_SLOW_WRITE_REG(par, PM3ByAperture1Mode,
+ PM3_WRITE_REG(par, PM3ByAperture1Mode,
PM3ByApertureMode_PIXELSIZE_32BIT |
PM3ByApertureMode_BYTESWAP_DCBA);
- PM3_SLOW_WRITE_REG(par, PM3ByAperture2Mode,
+ PM3_WRITE_REG(par, PM3ByAperture2Mode,
PM3ByApertureMode_PIXELSIZE_32BIT |
PM3ByApertureMode_BYTESWAP_DCBA);
#endif /* ! __BIG_ENDIAN */
break;
default:
- DPRINTK("Unsupported depth %d\n",
- info->var.bits_per_pixel);
+ DPRINTK("Unsupported depth %d\n", bpp);
break;
}
@@ -296,14 +283,15 @@
PM3VideoControl_VSYNC_MASK);
video |= PM3VideoControl_HSYNC_ACTIVE_HIGH |
PM3VideoControl_VSYNC_ACTIVE_HIGH;
- PM3_SLOW_WRITE_REG(par, PM3VideoControl, video);
+ PM3_WRITE_REG(par, PM3VideoControl, video);
}
- PM3_SLOW_WRITE_REG(par, PM3VClkCtl,
+ PM3_WRITE_REG(par, PM3VClkCtl,
(PM3_READ_REG(par, PM3VClkCtl) & 0xFFFFFFFC));
- PM3_SLOW_WRITE_REG(par, PM3ScreenBase, par->base);
- PM3_SLOW_WRITE_REG(par, PM3ChipConfig,
+ PM3_WRITE_REG(par, PM3ScreenBase, par->base);
+ PM3_WRITE_REG(par, PM3ChipConfig,
(PM3_READ_REG(par, PM3ChipConfig) & 0xFFFFFFFD));
+ wmb();
{
unsigned char uninitialized_var(m); /* ClkPreScale */
unsigned char uninitialized_var(n); /* ClkFeedBackScale */
@@ -337,7 +325,7 @@
PM3_WRITE_DAC_REG(par, PM3RD_DACControl, 0x00);
- switch (info->var.bits_per_pixel) {
+ switch (pm3fb_depth(&info->var)) {
case 8:
PM3_WRITE_DAC_REG(par, PM3RD_PixelSize,
PM3RD_PixelSize_8_BIT_PIXELS);
@@ -393,57 +381,44 @@
* hardware independent functions
*/
int pm3fb_init(void);
-int pm3fb_setup(char*);
static int pm3fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
{
u32 lpitch;
+ unsigned bpp = var->red.length + var->green.length
+ + var->blue.length + var->transp.length;
- var->transp.offset = 0;
- var->transp.length = 0;
- switch(var->bits_per_pixel) {
- case 8:
- var->red.length = var->green.length = var->blue.length = 8;
- var->red.offset = var->green.offset = var->blue.offset = 0;
- break;
- case 12:
- var->red.offset = 8;
- var->red.length = 4;
- var->green.offset = 4;
- var->green.length = 4;
- var->blue.offset = 0;
- var->blue.length = 4;
- var->transp.offset = 12;
- var->transp.length = 4;
- case 15:
- var->red.offset = 10;
- var->red.length = 5;
- var->green.offset = 5;
- var->green.length = 5;
- var->blue.offset = 0;
- var->blue.length = 5;
- var->transp.offset = 15;
- var->transp.length = 1;
- break;
- case 16:
- var->red.offset = 11;
- var->red.length = 5;
- var->green.offset = 5;
- var->green.length = 6;
- var->blue.offset = 0;
- var->blue.length = 5;
- break;
- case 32:
- var->transp.offset = 24;
- var->transp.length = 8;
- var->red.offset = 16;
- var->green.offset = 8;
- var->blue.offset = 0;
- var->red.length = var->green.length = var->blue.length = 8;
- break;
- default:
- DPRINTK("depth not supported: %u\n", var->bits_per_pixel);
- return -EINVAL;
+ if ( bpp != var->bits_per_pixel ) {
+ /* set predefined mode for bits_per_pixel settings */
+
+ switch(var->bits_per_pixel) {
+ case 8:
+ var->red.length = var->green.length = var->blue.length = 8;
+ var->red.offset = var->green.offset = var->blue.offset = 0;
+ var->transp.offset = 0;
+ var->transp.length = 0;
+ break;
+ case 16:
+ var->red.length = var->blue.length = 5;
+ var->green.length = 6;
+ var->transp.length = 0;
+ break;
+ case 32:
+ var->red.length = var->green.length = var->blue.length = 8;
+ var->transp.length = 8;
+ break;
+ default:
+ DPRINTK("depth not supported: %u\n", var->bits_per_pixel);
+ return -EINVAL;
+ }
+ }
+ /* it is assumed BGRA order */
+ if (var->bits_per_pixel > 8 )
+ {
+ var->blue.offset = 0;
+ var->green.offset = var->blue.length;
+ var->red.offset = var->green.offset + var->green.length;
+ var->transp.offset = var->red.offset + var->red.length;
}
var->height = var->width = -1;
@@ -502,10 +477,9 @@
{
struct pm3_par *par = info->par;
const u32 xres = (info->var.xres + 31) & ~31;
- const int depth = (info->var.bits_per_pixel + 7) & ~7;
+ const unsigned bpp = info->var.bits_per_pixel;
- par->base = pm3fb_shift_bpp(info->var.bits_per_pixel,
- (info->var.yoffset * xres)
+ par->base = pm3fb_shift_bpp(bpp,(info->var.yoffset * xres)
+ info->var.xoffset);
par->video = 0;
@@ -530,12 +504,10 @@
par->video |= PM3VideoControl_DISABLE;
DPRINTK("PM3Video disabled\n");
}
- switch (depth) {
+ switch (bpp) {
case 8:
par->video |= PM3VideoControl_PIXELSIZE_8BIT;
break;
- case 12:
- case 15:
case 16:
par->video |= PM3VideoControl_PIXELSIZE_16BIT;
break;
@@ -548,9 +520,9 @@
}
info->fix.visual =
- (depth == 8) ? FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_TRUECOLOR;
+ (bpp == 8) ? FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_TRUECOLOR;
info->fix.line_length = ((info->var.xres_virtual + 7) & ~7)
- * depth / 8;
+ * bpp / 8;
/* pm3fb_clear_memory(info, 0);*/
pm3fb_clear_colormap(par, 0, 0, 0);
@@ -580,8 +552,8 @@
* var->{color}.length contains length of bitfield
* {hardwarespecific} contains width of DAC
* pseudo_palette[X] is programmed to (X << red.offset) |
- * (X << green.offset) |
- * (X << blue.offset)
+ * (X << green.offset) |
+ * (X << blue.offset)
* RAMDAC[X] is programmed to (red, green, blue)
* color depth = SUM(var->{color}.length)
*
@@ -621,7 +593,6 @@
case 8:
break;
case 16:
- case 24:
case 32:
((u32*)(info->pseudo_palette))[regno] = v;
break;
@@ -643,7 +614,8 @@
par->base = pm3fb_shift_bpp(var->bits_per_pixel,
(var->yoffset * xres)
+ var->xoffset);
- PM3_SLOW_WRITE_REG(par, PM3ScreenBase, par->base);
+ PM3_WAIT(par, 1);
+ PM3_WRITE_REG(par, PM3ScreenBase, par->base);
return 0;
}
@@ -665,31 +637,31 @@
switch (blank_mode) {
case FB_BLANK_UNBLANK:
- video = video | PM3VideoControl_ENABLE;
+ video |= PM3VideoControl_ENABLE;
break;
- case FB_BLANK_NORMAL: /* FIXME */
- video = video & ~(PM3VideoControl_ENABLE);
+ case FB_BLANK_NORMAL:
+ video &= ~(PM3VideoControl_ENABLE);
break;
case FB_BLANK_HSYNC_SUSPEND:
- video = video & ~(PM3VideoControl_HSYNC_MASK |
- PM3VideoControl_BLANK_ACTIVE_LOW);
+ video &= ~(PM3VideoControl_HSYNC_MASK |
+ PM3VideoControl_BLANK_ACTIVE_LOW);
break;
case FB_BLANK_VSYNC_SUSPEND:
- video = video & ~(PM3VideoControl_VSYNC_MASK |
- PM3VideoControl_BLANK_ACTIVE_LOW);
+ video &= ~(PM3VideoControl_VSYNC_MASK |
+ PM3VideoControl_BLANK_ACTIVE_LOW);
break;
case FB_BLANK_POWERDOWN:
- video = video & ~(PM3VideoControl_HSYNC_MASK |
- PM3VideoControl_VSYNC_MASK |
- PM3VideoControl_BLANK_ACTIVE_LOW);
+ video &= ~(PM3VideoControl_HSYNC_MASK |
+ PM3VideoControl_VSYNC_MASK |
+ PM3VideoControl_BLANK_ACTIVE_LOW);
break;
default:
DPRINTK("Unsupported blanking %d\n", blank_mode);
return 1;
}
- PM3_SLOW_WRITE_REG(par,PM3VideoControl, video);
-
+ PM3_WAIT(par, 1);
+ PM3_WRITE_REG(par,PM3VideoControl, video);
return 0;
}
@@ -703,9 +675,9 @@
.fb_set_par = pm3fb_set_par,
.fb_setcolreg = pm3fb_setcolreg,
.fb_pan_display = pm3fb_pan_display,
- .fb_fillrect = cfb_fillrect, /* Needed !!! */
- .fb_copyarea = cfb_copyarea, /* Needed !!! */
- .fb_imageblit = cfb_imageblit, /* Needed !!! */
+ .fb_fillrect = cfb_fillrect,
+ .fb_copyarea = cfb_copyarea,
+ .fb_imageblit = cfb_imageblit,
.fb_blank = pm3fb_blank,
};
@@ -722,7 +694,7 @@
unsigned long memsize = 0, tempBypass, i, temp1, temp2;
unsigned char __iomem *screen_mem;
- pm3fb_fix.smem_len = 64 * 1024 * 1024; /* request full aperture size */
+ pm3fb_fix.smem_len = 64 * 1024l * 1024; /* request full aperture size */
/* Linear frame buffer - request region and map it. */
if (!request_mem_region(pm3fb_fix.smem_start, pm3fb_fix.smem_len,
"pm3fb smem")) {
@@ -744,7 +716,8 @@
DPRINTK("PM3MemBypassWriteMask was: 0x%08lx\n", tempBypass);
- PM3_SLOW_WRITE_REG(par, PM3MemBypassWriteMask, 0xFFFFFFFF);
+ PM3_WAIT(par, 1);
+ PM3_WRITE_REG(par, PM3MemBypassWriteMask, 0xFFFFFFFF);
/* pm3 split up memory, replicates, and do a lot of nasty stuff IMHO ;-) */
for (i = 0; i < 32; i++) {
@@ -765,10 +738,9 @@
if (memsize + 1 == i) {
for (i = 0; i < 32; i++) {
/* Clear first 32MB ; 0 is 0, no need to byteswap */
- writel(0x0000000,
- (screen_mem + (i * 1048576)));
- mb();
+ writel(0x0000000, (screen_mem + (i * 1048576)));
}
+ wmb();
for (i = 32; i < 64; i++) {
fb_writel(i * 0x00345678,
@@ -787,7 +759,8 @@
}
DPRINTK("Second detect pass got %ld MB\n", memsize + 1);
- PM3_SLOW_WRITE_REG(par, PM3MemBypassWriteMask, tempBypass);
+ PM3_WAIT(par, 1);
+ PM3_WRITE_REG(par, PM3MemBypassWriteMask, tempBypass);
iounmap(screen_mem);
release_mem_region(pm3fb_fix.smem_start, pm3fb_fix.smem_len);
@@ -890,7 +863,6 @@
goto err_exit_both;
}
- /* This has to been done !!! */
if (fb_alloc_cmap(&info->cmap, 256, 0) < 0) {
retval = -ENOMEM;
goto err_exit_both;
@@ -907,7 +879,7 @@
}
printk(KERN_INFO "fb%d: %s frame buffer device\n", info->node,
info->fix.id);
- pci_set_drvdata(dev, info); /* or dev_set_drvdata(device, info) */
+ pci_set_drvdata(dev, info);
return 0;
err_exit_all:
@@ -949,8 +921,7 @@
static struct pci_device_id pm3fb_id_table[] = {
{ PCI_VENDOR_ID_3DLABS, 0x0a,
- PCI_ANY_ID, PCI_ANY_ID, PCI_BASE_CLASS_DISPLAY << 16,
- 0xff0000, 0 },
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
{ 0, }
};
@@ -964,6 +935,22 @@
MODULE_DEVICE_TABLE(pci, pm3fb_id_table);
+#ifndef MODULE
+ /*
+ * Setup
+ */
+
+/*
+ * Only necessary if your driver takes special options,
+ * otherwise we fall back on the generic fb_setup().
+ */
+static int __init pm3fb_setup(char *options)
+{
+ /* Parse user speficied options (`video=pm3fb:') */
+ return 0;
+}
+#endif /* MODULE */
+
int __init pm3fb_init(void)
{
/*
@@ -985,22 +972,6 @@
pci_unregister_driver(&pm3fb_driver);
}
-#ifndef MODULE
- /*
- * Setup
- */
-
-/*
- * Only necessary if your driver takes special options,
- * otherwise we fall back on the generic fb_setup().
- */
-int __init pm3fb_setup(char *options)
-{
- /* Parse user speficied options (`video=pm3fb:') */
- return 0;
-}
-#endif /* MODULE */
-
module_init(pm3fb_init);
module_exit(pm3fb_exit);
diff --git a/drivers/video/ps3fb.c b/drivers/video/ps3fb.c
index 9756a72..9cf92ba 100644
--- a/drivers/video/ps3fb.c
+++ b/drivers/video/ps3fb.c
@@ -951,12 +951,14 @@
static struct fb_ops ps3fb_ops = {
.fb_open = ps3fb_open,
.fb_release = ps3fb_release,
+ .fb_read = fb_sys_read,
+ .fb_write = fb_sys_write,
.fb_check_var = ps3fb_check_var,
.fb_set_par = ps3fb_set_par,
.fb_setcolreg = ps3fb_setcolreg,
- .fb_fillrect = cfb_fillrect,
- .fb_copyarea = cfb_copyarea,
- .fb_imageblit = cfb_imageblit,
+ .fb_fillrect = sys_fillrect,
+ .fb_copyarea = sys_copyarea,
+ .fb_imageblit = sys_imageblit,
.fb_mmap = ps3fb_mmap,
.fb_blank = ps3fb_blank,
.fb_ioctl = ps3fb_ioctl,
diff --git a/drivers/video/w100fb.c b/drivers/video/w100fb.c
index 5fc86ea..003c49a 100644
--- a/drivers/video/w100fb.c
+++ b/drivers/video/w100fb.c
@@ -660,7 +660,7 @@
err = -ENODEV;
goto out;
}
- printk(" at 0x%08lx.\n", mem->start+W100_CFG_BASE);
+ printk(" at 0x%08lx.\n", (unsigned long) mem->start+W100_CFG_BASE);
/* Remap the framebuffer */
remapped_fbuf = ioremap_nocache(mem->start+MEM_WINDOW_BASE, MEM_WINDOW_SIZE);
@@ -753,10 +753,14 @@
goto out;
}
- device_create_file(&pdev->dev, &dev_attr_fastpllclk);
- device_create_file(&pdev->dev, &dev_attr_reg_read);
- device_create_file(&pdev->dev, &dev_attr_reg_write);
- device_create_file(&pdev->dev, &dev_attr_flip);
+ err = device_create_file(&pdev->dev, &dev_attr_fastpllclk);
+ err |= device_create_file(&pdev->dev, &dev_attr_reg_read);
+ err |= device_create_file(&pdev->dev, &dev_attr_reg_write);
+ err |= device_create_file(&pdev->dev, &dev_attr_flip);
+
+ if (err != 0)
+ printk(KERN_WARNING "fb%d: failed to register attributes (%d)\n",
+ info->node, err);
printk(KERN_INFO "fb%d: %s frame buffer device\n", info->node, info->fix.id);
return 0;
diff --git a/fs/Kconfig.binfmt b/fs/Kconfig.binfmt
index 74c6440..d4fc609 100644
--- a/fs/Kconfig.binfmt
+++ b/fs/Kconfig.binfmt
@@ -38,7 +38,7 @@
config BINFMT_FLAT
tristate "Kernel support for flat binaries"
- depends on !MMU || SUPERH
+ depends on !MMU
help
Support uClinux FLAT format binaries.
diff --git a/fs/compat.c b/fs/compat.c
index 1de2331..4db6216 100644
--- a/fs/compat.c
+++ b/fs/compat.c
@@ -1544,9 +1544,10 @@
compat_ulong_t __user *outp, compat_ulong_t __user *exp, s64 *timeout)
{
fd_set_bits fds;
- char *bits;
+ void *bits;
int size, max_fds, ret = -EINVAL;
struct fdtable *fdt;
+ long stack_fds[SELECT_STACK_ALLOC/sizeof(long)];
if (n < 0)
goto out_nofds;
@@ -1564,11 +1565,14 @@
* since we used fdset we need to allocate memory in units of
* long-words.
*/
- ret = -ENOMEM;
size = FDS_BYTES(n);
- bits = kmalloc(6 * size, GFP_KERNEL);
- if (!bits)
- goto out_nofds;
+ bits = stack_fds;
+ if (size > sizeof(stack_fds) / 6) {
+ bits = kmalloc(6 * size, GFP_KERNEL);
+ ret = -ENOMEM;
+ if (!bits)
+ goto out_nofds;
+ }
fds.in = (unsigned long *) bits;
fds.out = (unsigned long *) (bits + size);
fds.ex = (unsigned long *) (bits + 2*size);
@@ -1600,7 +1604,8 @@
compat_set_fd_set(n, exp, fds.res_ex))
ret = -EFAULT;
out:
- kfree(bits);
+ if (bits != stack_fds)
+ kfree(bits);
out_nofds:
return ret;
}
diff --git a/fs/compat_ioctl.c b/fs/compat_ioctl.c
index 65643de..6b44cdc 100644
--- a/fs/compat_ioctl.c
+++ b/fs/compat_ioctl.c
@@ -1194,6 +1194,7 @@
{
struct tty_struct *tty;
struct inode *inode = file->f_path.dentry->d_inode;
+ struct vc_data *vc;
if (file->f_op->ioctl != tty_ioctl)
return -EINVAL;
@@ -1204,12 +1205,16 @@
if (tty->driver->ioctl != vt_ioctl)
return -EINVAL;
-
+
+ vc = (struct vc_data *)tty->driver_data;
+ if (!vc_cons_allocated(vc->vc_num)) /* impossible? */
+ return -ENOIOCTLCMD;
+
/*
* To have permissions to do most of the vt ioctls, we either have
- * to be the owner of the tty, or super-user.
+ * to be the owner of the tty, or have CAP_SYS_TTY_CONFIG.
*/
- if (current->signal->tty == tty || capable(CAP_SYS_ADMIN))
+ if (current->signal->tty == tty || capable(CAP_SYS_TTY_CONFIG))
return 1;
return 0;
}
@@ -1310,16 +1315,28 @@
struct unimapdesc32 tmp;
struct unimapdesc32 __user *user_ud = compat_ptr(arg);
int perm = vt_check(file);
-
- if (perm < 0) return perm;
+ struct vc_data *vc;
+
+ if (perm < 0)
+ return perm;
if (copy_from_user(&tmp, user_ud, sizeof tmp))
return -EFAULT;
+ if (tmp.entries)
+ if (!access_ok(VERIFY_WRITE, compat_ptr(tmp.entries),
+ tmp.entry_ct*sizeof(struct unipair)))
+ return -EFAULT;
+ vc = ((struct tty_struct *)file->private_data)->driver_data;
switch (cmd) {
case PIO_UNIMAP:
- if (!perm) return -EPERM;
- return con_set_unimap(vc_cons[fg_console].d, tmp.entry_ct, compat_ptr(tmp.entries));
+ if (!perm)
+ return -EPERM;
+ return con_set_unimap(vc, tmp.entry_ct,
+ compat_ptr(tmp.entries));
case GIO_UNIMAP:
- return con_get_unimap(vc_cons[fg_console].d, tmp.entry_ct, &(user_ud->entry_ct), compat_ptr(tmp.entries));
+ if (!perm && fg_console != vc->vc_num)
+ return -EPERM;
+ return con_get_unimap(vc, tmp.entry_ct, &(user_ud->entry_ct),
+ compat_ptr(tmp.entries));
}
return 0;
}
diff --git a/fs/ecryptfs/file.c b/fs/ecryptfs/file.c
index 9881b5c..59288d8 100644
--- a/fs/ecryptfs/file.c
+++ b/fs/ecryptfs/file.c
@@ -33,63 +33,6 @@
#include "ecryptfs_kernel.h"
/**
- * ecryptfs_llseek
- * @file: File we are seeking in
- * @offset: The offset to seek to
- * @origin: 2 - offset from i_size; 1 - offset from f_pos
- *
- * Returns the position we have seeked to, or negative on error
- */
-static loff_t ecryptfs_llseek(struct file *file, loff_t offset, int origin)
-{
- loff_t rv;
- loff_t new_end_pos;
- int rc;
- int expanding_file = 0;
- struct inode *inode = file->f_mapping->host;
-
- /* If our offset is past the end of our file, we're going to
- * need to grow it so we have a valid length of 0's */
- new_end_pos = offset;
- switch (origin) {
- case 2:
- new_end_pos += i_size_read(inode);
- expanding_file = 1;
- break;
- case 1:
- new_end_pos += file->f_pos;
- if (new_end_pos > i_size_read(inode)) {
- ecryptfs_printk(KERN_DEBUG, "new_end_pos(=[0x%.16x]) "
- "> i_size_read(inode)(=[0x%.16x])\n",
- new_end_pos, i_size_read(inode));
- expanding_file = 1;
- }
- break;
- default:
- if (new_end_pos > i_size_read(inode)) {
- ecryptfs_printk(KERN_DEBUG, "new_end_pos(=[0x%.16x]) "
- "> i_size_read(inode)(=[0x%.16x])\n",
- new_end_pos, i_size_read(inode));
- expanding_file = 1;
- }
- }
- ecryptfs_printk(KERN_DEBUG, "new_end_pos = [0x%.16x]\n", new_end_pos);
- if (expanding_file) {
- rc = ecryptfs_truncate(file->f_path.dentry, new_end_pos);
- if (rc) {
- rv = rc;
- ecryptfs_printk(KERN_ERR, "Error on attempt to "
- "truncate to (higher) offset [0x%.16x];"
- " rc = [%d]\n", new_end_pos, rc);
- goto out;
- }
- }
- rv = generic_file_llseek(file, offset, origin);
-out:
- return rv;
-}
-
-/**
* ecryptfs_read_update_atime
*
* generic_file_read updates the atime of upper layer inode. But, it
@@ -425,7 +368,7 @@
};
const struct file_operations ecryptfs_main_fops = {
- .llseek = ecryptfs_llseek,
+ .llseek = generic_file_llseek,
.read = do_sync_read,
.aio_read = ecryptfs_read_update_atime,
.write = do_sync_write,
diff --git a/fs/ecryptfs/mmap.c b/fs/ecryptfs/mmap.c
index 88ea669..55cec98 100644
--- a/fs/ecryptfs/mmap.c
+++ b/fs/ecryptfs/mmap.c
@@ -376,8 +376,15 @@
return 0;
}
-static int ecryptfs_prepare_write(struct file *file, struct page *page,
- unsigned from, unsigned to)
+/**
+ * eCryptfs does not currently support holes. When writing after a
+ * seek past the end of the file, eCryptfs fills in 0's through to the
+ * current location. The code to fill in the 0's to all the
+ * intermediate pages calls ecryptfs_prepare_write_no_truncate().
+ */
+static int
+ecryptfs_prepare_write_no_truncate(struct file *file, struct page *page,
+ unsigned from, unsigned to)
{
int rc = 0;
@@ -390,6 +397,31 @@
return rc;
}
+static int ecryptfs_prepare_write(struct file *file, struct page *page,
+ unsigned from, unsigned to)
+{
+ loff_t pos;
+ int rc = 0;
+
+ if (from == 0 && to == PAGE_CACHE_SIZE)
+ goto out; /* If we are writing a full page, it will be
+ up to date. */
+ if (!PageUptodate(page))
+ rc = ecryptfs_do_readpage(file, page, page->index);
+ pos = ((loff_t)page->index << PAGE_CACHE_SHIFT) + to;
+ if (pos > i_size_read(page->mapping->host)) {
+ rc = ecryptfs_truncate(file->f_path.dentry, pos);
+ if (rc) {
+ printk(KERN_ERR "Error on attempt to "
+ "truncate to (higher) offset [%lld];"
+ " rc = [%d]\n", pos, rc);
+ goto out;
+ }
+ }
+out:
+ return rc;
+}
+
int ecryptfs_writepage_and_release_lower_page(struct page *lower_page,
struct inode *lower_inode,
struct writeback_control *wbc)
@@ -744,10 +776,10 @@
rc = PTR_ERR(tmp_page);
goto out;
}
- rc = ecryptfs_prepare_write(file, tmp_page, start, start + num_zeros);
- if (rc) {
+ if ((rc = ecryptfs_prepare_write_no_truncate(file, tmp_page, start,
+ (start + num_zeros)))) {
ecryptfs_printk(KERN_ERR, "Error preparing to write zero's "
- "to remainder of page at index [0x%.16x]\n",
+ "to page at index [0x%.16x]\n",
index);
page_cache_release(tmp_page);
goto out;
diff --git a/fs/exec.c b/fs/exec.c
index 0b68588..f20561f 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -134,6 +134,9 @@
if (error)
goto out;
+ error = -EACCES;
+ if (nd.mnt->mnt_flags & MNT_NOEXEC)
+ goto exit;
error = -EINVAL;
if (!S_ISREG(nd.dentry->d_inode->i_mode))
goto exit;
diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c
index 8890eba..bd5a772 100644
--- a/fs/fuse/dir.c
+++ b/fs/fuse/dir.c
@@ -485,7 +485,7 @@
static int fuse_create(struct inode *dir, struct dentry *entry, int mode,
struct nameidata *nd)
{
- if (nd && (nd->flags & LOOKUP_CREATE)) {
+ if (nd && (nd->flags & LOOKUP_OPEN)) {
int err = fuse_create_open(dir, entry, mode, nd);
if (err != -ENOSYS)
return err;
diff --git a/fs/fuse/file.c b/fs/fuse/file.c
index d0ed60b..adf7995 100644
--- a/fs/fuse/file.c
+++ b/fs/fuse/file.c
@@ -610,7 +610,9 @@
ssize_t res;
/* Don't allow parallel writes to the same file */
mutex_lock(&inode->i_mutex);
- res = fuse_direct_io(file, buf, count, ppos, 1);
+ res = generic_write_checks(file, ppos, &count, 0);
+ if (!res)
+ res = fuse_direct_io(file, buf, count, ppos, 1);
mutex_unlock(&inode->i_mutex);
return res;
}
diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c
index 78f7a1d..9804c0c 100644
--- a/fs/fuse/inode.c
+++ b/fs/fuse/inode.c
@@ -454,6 +454,7 @@
.destroy_inode = fuse_destroy_inode,
.read_inode = fuse_read_inode,
.clear_inode = fuse_clear_inode,
+ .drop_inode = generic_delete_inode,
.remount_fs = fuse_remount_fs,
.put_super = fuse_put_super,
.umount_begin = fuse_umount_begin,
diff --git a/fs/nfs/direct.c b/fs/nfs/direct.c
index 345aa5c..0c542ec 100644
--- a/fs/nfs/direct.c
+++ b/fs/nfs/direct.c
@@ -122,19 +122,25 @@
return -EINVAL;
}
-static void nfs_direct_dirty_pages(struct page **pages, int npages)
+static void nfs_direct_dirty_pages(struct page **pages, unsigned int pgbase, size_t count)
{
- int i;
+ unsigned int npages;
+ unsigned int i;
+
+ if (count == 0)
+ return;
+ pages += (pgbase >> PAGE_SHIFT);
+ npages = (count + (pgbase & ~PAGE_MASK) + PAGE_SIZE - 1) >> PAGE_SHIFT;
for (i = 0; i < npages; i++) {
struct page *page = pages[i];
if (!PageCompound(page))
- set_page_dirty_lock(page);
+ set_page_dirty(page);
}
}
-static void nfs_direct_release_pages(struct page **pages, int npages)
+static void nfs_direct_release_pages(struct page **pages, unsigned int npages)
{
- int i;
+ unsigned int i;
for (i = 0; i < npages; i++)
page_cache_release(pages[i]);
}
@@ -224,17 +230,18 @@
if (nfs_readpage_result(task, data) != 0)
return;
- nfs_direct_dirty_pages(data->pagevec, data->npages);
- nfs_direct_release_pages(data->pagevec, data->npages);
-
spin_lock(&dreq->lock);
-
- if (likely(task->tk_status >= 0))
- dreq->count += data->res.count;
- else
+ if (unlikely(task->tk_status < 0)) {
dreq->error = task->tk_status;
-
- spin_unlock(&dreq->lock);
+ spin_unlock(&dreq->lock);
+ } else {
+ dreq->count += data->res.count;
+ spin_unlock(&dreq->lock);
+ nfs_direct_dirty_pages(data->pagevec,
+ data->args.pgbase,
+ data->res.count);
+ }
+ nfs_direct_release_pages(data->pagevec, data->npages);
if (put_dreq(dreq))
nfs_direct_complete(dreq);
@@ -279,9 +286,12 @@
result = get_user_pages(current, current->mm, user_addr,
data->npages, 1, 0, data->pagevec, NULL);
up_read(¤t->mm->mmap_sem);
- if (unlikely(result < data->npages)) {
- if (result > 0)
- nfs_direct_release_pages(data->pagevec, result);
+ if (result < 0) {
+ nfs_readdata_release(data);
+ break;
+ }
+ if ((unsigned)result < data->npages) {
+ nfs_direct_release_pages(data->pagevec, result);
nfs_readdata_release(data);
break;
}
@@ -610,9 +620,12 @@
result = get_user_pages(current, current->mm, user_addr,
data->npages, 0, 0, data->pagevec, NULL);
up_read(¤t->mm->mmap_sem);
- if (unlikely(result < data->npages)) {
- if (result > 0)
- nfs_direct_release_pages(data->pagevec, result);
+ if (result < 0) {
+ nfs_writedata_release(data);
+ break;
+ }
+ if ((unsigned)result < data->npages) {
+ nfs_direct_release_pages(data->pagevec, result);
nfs_writedata_release(data);
break;
}
diff --git a/fs/nfs/pagelist.c b/fs/nfs/pagelist.c
index cbdd1c6..c5bb51a 100644
--- a/fs/nfs/pagelist.c
+++ b/fs/nfs/pagelist.c
@@ -355,6 +355,26 @@
nfs_pageio_doio(desc);
}
+/**
+ * nfs_pageio_cond_complete - Conditional I/O completion
+ * @desc: pointer to io descriptor
+ * @index: page index
+ *
+ * It is important to ensure that processes don't try to take locks
+ * on non-contiguous ranges of pages as that might deadlock. This
+ * function should be called before attempting to wait on a locked
+ * nfs_page. It will complete the I/O if the page index 'index'
+ * is not contiguous with the existing list of pages in 'desc'.
+ */
+void nfs_pageio_cond_complete(struct nfs_pageio_descriptor *desc, pgoff_t index)
+{
+ if (!list_empty(&desc->pg_list)) {
+ struct nfs_page *prev = nfs_list_entry(desc->pg_list.prev);
+ if (index != prev->wb_index + 1)
+ nfs_pageio_doio(desc);
+ }
+}
+
#define NFS_SCAN_MAXENTRIES 16
/**
* nfs_scan_list - Scan a list for matching requests
diff --git a/fs/nfs/write.c b/fs/nfs/write.c
index b084c03..af344a15 100644
--- a/fs/nfs/write.c
+++ b/fs/nfs/write.c
@@ -273,8 +273,6 @@
* request as dirty (in which case we don't care).
*/
spin_unlock(req_lock);
- /* Prevent deadlock! */
- nfs_pageio_complete(pgio);
ret = nfs_wait_on_request(req);
nfs_release_request(req);
if (ret != 0)
@@ -321,6 +319,8 @@
pgio = &mypgio;
}
+ nfs_pageio_cond_complete(pgio, page->index);
+
err = nfs_page_async_flush(pgio, page);
if (err <= 0)
goto out;
@@ -329,6 +329,8 @@
if (!offset)
goto out;
+ nfs_pageio_cond_complete(pgio, page->index);
+
ctx = nfs_find_open_context(inode, NULL, FMODE_WRITE);
if (ctx == NULL) {
err = -EBADF;
diff --git a/fs/ocfs2/aops.c b/fs/ocfs2/aops.c
index 8e7cafb5..0023b31 100644
--- a/fs/ocfs2/aops.c
+++ b/fs/ocfs2/aops.c
@@ -222,7 +222,10 @@
goto out;
}
- down_read(&OCFS2_I(inode)->ip_alloc_sem);
+ if (down_read_trylock(&OCFS2_I(inode)->ip_alloc_sem) == 0) {
+ ret = AOP_TRUNCATED_PAGE;
+ goto out_meta_unlock;
+ }
/*
* i_size might have just been updated as we grabed the meta lock. We
@@ -235,10 +238,7 @@
* XXX sys_readahead() seems to get that wrong?
*/
if (start >= i_size_read(inode)) {
- char *addr = kmap(page);
- memset(addr, 0, PAGE_SIZE);
- flush_dcache_page(page);
- kunmap(page);
+ zero_user_page(page, 0, PAGE_SIZE, KM_USER0);
SetPageUptodate(page);
ret = 0;
goto out_alloc;
@@ -258,6 +258,7 @@
ocfs2_data_unlock(inode, 0);
out_alloc:
up_read(&OCFS2_I(inode)->ip_alloc_sem);
+out_meta_unlock:
ocfs2_meta_unlock(inode, 0);
out:
if (unlock)
diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c
index 9395b4f..ac6c964 100644
--- a/fs/ocfs2/file.c
+++ b/fs/ocfs2/file.c
@@ -326,6 +326,7 @@
(unsigned long long)OCFS2_I(inode)->ip_blkno,
(unsigned long long)new_i_size);
+ unmap_mapping_range(inode->i_mapping, new_i_size + PAGE_SIZE - 1, 0, 1);
truncate_inode_pages(inode->i_mapping, new_i_size);
fe = (struct ocfs2_dinode *) di_bh->b_data;
@@ -1418,36 +1419,6 @@
return total ? total : ret;
}
-static int ocfs2_check_iovec(const struct iovec *iov, size_t *counted,
- unsigned long *nr_segs)
-{
- size_t ocount; /* original count */
- unsigned long seg;
-
- ocount = 0;
- for (seg = 0; seg < *nr_segs; seg++) {
- const struct iovec *iv = &iov[seg];
-
- /*
- * If any segment has a negative length, or the cumulative
- * length ever wraps negative then return -EINVAL.
- */
- ocount += iv->iov_len;
- if (unlikely((ssize_t)(ocount|iv->iov_len) < 0))
- return -EINVAL;
- if (access_ok(VERIFY_READ, iv->iov_base, iv->iov_len))
- continue;
- if (seg == 0)
- return -EFAULT;
- *nr_segs = seg;
- ocount -= iv->iov_len; /* This segment is no good */
- break;
- }
-
- *counted = ocount;
- return 0;
-}
-
static ssize_t ocfs2_file_aio_write(struct kiocb *iocb,
const struct iovec *iov,
unsigned long nr_segs,
@@ -1470,7 +1441,7 @@
if (iocb->ki_left == 0)
return 0;
- ret = ocfs2_check_iovec(iov, &ocount, &nr_segs);
+ ret = generic_segment_checks(iov, &nr_segs, &ocount, VERIFY_READ);
if (ret)
return ret;
diff --git a/fs/ocfs2/localalloc.c b/fs/ocfs2/localalloc.c
index 4dedd97..545f789 100644
--- a/fs/ocfs2/localalloc.c
+++ b/fs/ocfs2/localalloc.c
@@ -471,9 +471,6 @@
mutex_lock(&local_alloc_inode->i_mutex);
- ac->ac_inode = local_alloc_inode;
- ac->ac_which = OCFS2_AC_USE_LOCAL;
-
if (osb->local_alloc_state != OCFS2_LA_ENABLED) {
status = -ENOSPC;
goto bail;
@@ -511,10 +508,14 @@
}
}
+ ac->ac_inode = local_alloc_inode;
+ ac->ac_which = OCFS2_AC_USE_LOCAL;
get_bh(osb->local_alloc_bh);
ac->ac_bh = osb->local_alloc_bh;
status = 0;
bail:
+ if (status < 0 && local_alloc_inode)
+ iput(local_alloc_inode);
mlog_exit(status);
return status;
diff --git a/fs/reiserfs/dir.c b/fs/reiserfs/dir.c
index 9c23fee..ffbfc2c 100644
--- a/fs/reiserfs/dir.c
+++ b/fs/reiserfs/dir.c
@@ -10,7 +10,7 @@
#include <linux/buffer_head.h>
#include <asm/uaccess.h>
-extern struct reiserfs_key MIN_KEY;
+extern const struct reiserfs_key MIN_KEY;
static int reiserfs_readdir(struct file *, void *, filldir_t);
static int reiserfs_dir_fsync(struct file *filp, struct dentry *dentry,
diff --git a/fs/signalfd.c b/fs/signalfd.c
index 7cfeab4..f1da892 100644
--- a/fs/signalfd.c
+++ b/fs/signalfd.c
@@ -11,6 +11,8 @@
* Now using anonymous inode source.
* Thanks to Oleg Nesterov for useful code review and suggestions.
* More comments and suggestions from Arnd Bergmann.
+ * Sat May 19, 2007: Davi E. M. Arnaut <davi@haxent.com.br>
+ * Retrieve multiple signals with one read() call
*/
#include <linux/file.h>
@@ -206,6 +208,59 @@
return err ? -EFAULT: sizeof(*uinfo);
}
+static ssize_t signalfd_dequeue(struct signalfd_ctx *ctx, siginfo_t *info,
+ int nonblock)
+{
+ ssize_t ret;
+ struct signalfd_lockctx lk;
+ DECLARE_WAITQUEUE(wait, current);
+
+ if (!signalfd_lock(ctx, &lk))
+ return 0;
+
+ ret = dequeue_signal(lk.tsk, &ctx->sigmask, info);
+ switch (ret) {
+ case 0:
+ if (!nonblock)
+ break;
+ ret = -EAGAIN;
+ default:
+ signalfd_unlock(&lk);
+ return ret;
+ }
+
+ add_wait_queue(&ctx->wqh, &wait);
+ for (;;) {
+ set_current_state(TASK_INTERRUPTIBLE);
+ ret = dequeue_signal(lk.tsk, &ctx->sigmask, info);
+ signalfd_unlock(&lk);
+ if (ret != 0)
+ break;
+ if (signal_pending(current)) {
+ ret = -ERESTARTSYS;
+ break;
+ }
+ schedule();
+ ret = signalfd_lock(ctx, &lk);
+ if (unlikely(!ret)) {
+ /*
+ * Let the caller read zero byte, ala socket
+ * recv() when the peer disconnect. This test
+ * must be done before doing a dequeue_signal(),
+ * because if the sighand has been orphaned,
+ * the dequeue_signal() call is going to crash
+ * because ->sighand will be long gone.
+ */
+ break;
+ }
+ }
+
+ remove_wait_queue(&ctx->wqh, &wait);
+ __set_current_state(TASK_RUNNING);
+
+ return ret;
+}
+
/*
* Returns either the size of a "struct signalfd_siginfo", or zero if the
* sighand we are attached to, has been orphaned. The "count" parameter
@@ -215,55 +270,30 @@
loff_t *ppos)
{
struct signalfd_ctx *ctx = file->private_data;
- ssize_t res = 0;
- int locked, signo;
+ struct signalfd_siginfo __user *siginfo;
+ int nonblock = file->f_flags & O_NONBLOCK;
+ ssize_t ret, total = 0;
siginfo_t info;
- struct signalfd_lockctx lk;
- DECLARE_WAITQUEUE(wait, current);
- if (count < sizeof(struct signalfd_siginfo))
+ count /= sizeof(struct signalfd_siginfo);
+ if (!count)
return -EINVAL;
- locked = signalfd_lock(ctx, &lk);
- if (!locked)
- return 0;
- res = -EAGAIN;
- signo = dequeue_signal(lk.tsk, &ctx->sigmask, &info);
- if (signo == 0 && !(file->f_flags & O_NONBLOCK)) {
- add_wait_queue(&ctx->wqh, &wait);
- for (;;) {
- set_current_state(TASK_INTERRUPTIBLE);
- signo = dequeue_signal(lk.tsk, &ctx->sigmask, &info);
- if (signo != 0)
- break;
- if (signal_pending(current)) {
- res = -ERESTARTSYS;
- break;
- }
- signalfd_unlock(&lk);
- schedule();
- locked = signalfd_lock(ctx, &lk);
- if (unlikely(!locked)) {
- /*
- * Let the caller read zero byte, ala socket
- * recv() when the peer disconnect. This test
- * must be done before doing a dequeue_signal(),
- * because if the sighand has been orphaned,
- * the dequeue_signal() call is going to crash.
- */
- res = 0;
- break;
- }
- }
- remove_wait_queue(&ctx->wqh, &wait);
- __set_current_state(TASK_RUNNING);
- }
- if (likely(locked))
- signalfd_unlock(&lk);
- if (likely(signo))
- res = signalfd_copyinfo((struct signalfd_siginfo __user *) buf,
- &info);
- return res;
+ siginfo = (struct signalfd_siginfo __user *) buf;
+
+ do {
+ ret = signalfd_dequeue(ctx, &info, nonblock);
+ if (unlikely(ret <= 0))
+ break;
+ ret = signalfd_copyinfo(siginfo, &info);
+ if (ret < 0)
+ break;
+ siginfo++;
+ total += ret;
+ nonblock = 1;
+ } while (--count);
+
+ return total ? total : ret;
}
static const struct file_operations signalfd_fops = {
diff --git a/include/asm-generic/bug.h b/include/asm-generic/bug.h
index 14fae1f..7f30cce 100644
--- a/include/asm-generic/bug.h
+++ b/include/asm-generic/bug.h
@@ -35,7 +35,7 @@
#define WARN_ON(condition) ({ \
typeof(condition) __ret_warn_on = (condition); \
if (unlikely(__ret_warn_on)) { \
- printk("BUG: at %s:%d %s()\n", __FILE__, \
+ printk("WARNING: at %s:%d %s()\n", __FILE__, \
__LINE__, __FUNCTION__); \
dump_stack(); \
} \
diff --git a/include/asm-i386/atomic.h b/include/asm-i386/atomic.h
index 0baa2f8..437aac8 100644
--- a/include/asm-i386/atomic.h
+++ b/include/asm-i386/atomic.h
@@ -182,7 +182,7 @@
int __i;
#ifdef CONFIG_M386
unsigned long flags;
- if(unlikely(boot_cpu_data.x86==3))
+ if(unlikely(boot_cpu_data.x86 <= 3))
goto no_xadd;
#endif
/* Modern 486+ processor */
diff --git a/include/asm-i386/local.h b/include/asm-i386/local.h
index e13d3e9..6e85975 100644
--- a/include/asm-i386/local.h
+++ b/include/asm-i386/local.h
@@ -135,7 +135,7 @@
long __i;
#ifdef CONFIG_M386
unsigned long flags;
- if(unlikely(boot_cpu_data.x86==3))
+ if(unlikely(boot_cpu_data.x86 <= 3))
goto no_xadd;
#endif
/* Modern 486+ processor */
diff --git a/include/asm-ia64/acpi.h b/include/asm-ia64/acpi.h
index 5d03792..5b52635 100644
--- a/include/asm-ia64/acpi.h
+++ b/include/asm-ia64/acpi.h
@@ -30,6 +30,8 @@
#ifdef __KERNEL__
+#include <acpi/pdc_intel.h>
+
#include <linux/init.h>
#include <linux/numa.h>
#include <asm/system.h>
@@ -119,11 +121,6 @@
extern int __initdata nid_to_pxm_map[MAX_NUMNODES];
#endif
-/*
- * Refer Intel ACPI _PDC support document for bit definitions
- */
-#define ACPI_PDC_EST_CAPABILITY_SMP 0x8
-
#endif /*__KERNEL__*/
#endif /*_ASM_ACPI_H*/
diff --git a/include/asm-ia64/unistd.h b/include/asm-ia64/unistd.h
index d7781a2..441c9e0 100644
--- a/include/asm-ia64/unistd.h
+++ b/include/asm-ia64/unistd.h
@@ -305,6 +305,19 @@
#define NR_syscalls 286 /* length of syscall table */
+/*
+ * The following defines stop scripts/checksyscalls.sh from complaining about
+ * unimplemented system calls. Glibc provides for each of these by using
+ * more modern equivalent system calls.
+ */
+#define __IGNORE_fork /* clone() */
+#define __IGNORE_time /* gettimeofday() */
+#define __IGNORE_alarm /* setitimer(ITIMER_REAL, ... */
+#define __IGNORE_pause /* rt_sigprocmask(), rt_sigsuspend() */
+#define __IGNORE_utime /* utimes() */
+#define __IGNORE_getpgrp /* getpgid() */
+#define __IGNORE_vfork /* clone() */
+
#define __ARCH_WANT_SYS_RT_SIGACTION
#define __ARCH_WANT_SYS_RT_SIGSUSPEND
diff --git a/include/asm-sh/dreamcast/sysasic.h b/include/asm-sh/dreamcast/sysasic.h
index 7874e3d..f334266 100644
--- a/include/asm-sh/dreamcast/sysasic.h
+++ b/include/asm-sh/dreamcast/sysasic.h
@@ -23,7 +23,7 @@
takes.
*/
-#define HW_EVENT_IRQ_BASE OFFCHIP_IRQ_BASE /* 48 */
+#define HW_EVENT_IRQ_BASE 48
/* IRQ 13 */
#define HW_EVENT_VSYNC (HW_EVENT_IRQ_BASE + 5) /* VSync */
diff --git a/include/asm-sh/kdebug.h b/include/asm-sh/kdebug.h
index 16578b7..382cfc7 100644
--- a/include/asm-sh/kdebug.h
+++ b/include/asm-sh/kdebug.h
@@ -6,10 +6,6 @@
/* Grossly misnamed. */
enum die_val {
DIE_TRAP,
- DIE_PAGE_FAULT,
};
-int register_page_fault_notifier(struct notifier_block *nb);
-int unregister_page_fault_notifier(struct notifier_block *nb);
-
#endif /* __ASM_SH_KDEBUG_H */
diff --git a/include/asm-sh/landisk/gio.h b/include/asm-sh/landisk/gio.h
index 3fce4c4..35d7368 100644
--- a/include/asm-sh/landisk/gio.h
+++ b/include/asm-sh/landisk/gio.h
@@ -29,16 +29,8 @@
#define GIODRV_IOCGGIODATA4 _IOR(GIODRV_IOC_MAGIC, 6, unsigned long *)
#define GIODRV_IOCSGIOSETADDR _IOW(GIODRV_IOC_MAGIC, 7, unsigned long *)
#define GIODRV_IOCHARDRESET _IO(GIODRV_IOC_MAGIC, 8) /* debugging tool */
-
-#define GIODRV_IOCSGIO_LED _IOW(GIODRV_IOC_MAGIC, 9, unsigned long *)
-#define GIODRV_IOCGGIO_LED _IOR(GIODRV_IOC_MAGIC, 10, unsigned long *)
-#define GIODRV_IOCSGIO_BUZZER _IOW(GIODRV_IOC_MAGIC, 11, unsigned long *)
-#define GIODRV_IOCGGIO_LANDISK _IOR(GIODRV_IOC_MAGIC, 14, unsigned long *)
-#define GIODRV_IOCGGIO_BTN _IOR(GIODRV_IOC_MAGIC, 22, unsigned long *)
-#define GIODRV_IOCSGIO_BTNPID _IOW(GIODRV_IOC_MAGIC, 23, unsigned long *)
-#define GIODRV_IOCGGIO_BTNPID _IOR(GIODRV_IOC_MAGIC, 24, unsigned long *)
-
#define GIODRV_IOC_MAXNR 8
+
#define GIO_READ 0x00000000
#define GIO_WRITE 0x00000001
diff --git a/include/asm-sh/landisk/iodata_landisk.h b/include/asm-sh/landisk/iodata_landisk.h
index c74d3c7..6fb04ab 100644
--- a/include/asm-sh/landisk/iodata_landisk.h
+++ b/include/asm-sh/landisk/iodata_landisk.h
@@ -22,16 +22,6 @@
/* 2003.10.31 I-O DATA NSD NWG add. for shutdown port clear */
#define PA_PWRINT_CLR 0xb0000006 /* Shutdown Interrupt clear Register */
-#define PA_LCD_CLRDSP 0x00 /* LCD Clear Display Offset */
-#define PA_LCD_RTNHOME 0x00 /* LCD Return Home Offset */
-#define PA_LCD_ENTMODE 0x00 /* LCD Entry Mode Offset */
-#define PA_LCD_DSPCTL 0x00 /* LCD Display ON/OFF Control Offset */
-#define PA_LCD_FUNC 0x00 /* LCD Function Set Offset */
-#define PA_LCD_CGRAM 0x00 /* LCD Set CGRAM Address Offset */
-#define PA_LCD_DDRAM 0x00 /* LCD Set DDRAM Address Offset */
-#define PA_LCD_RDFLAG 0x01 /* LCD Read Busy Flag Offset */
-#define PA_LCD_WTDATA 0x02 /* LCD Write Datat to RAM Offset */
-#define PA_LCD_RDDATA 0x03 /* LCD Read Data from RAM Offset */
#define PA_PIDE_OFFSET 0x40 /* CF IDE Offset */
#define PA_SIDE_OFFSET 0x40 /* HDD IDE Offset */
@@ -45,33 +35,6 @@
#define IRQ_BUTTON 12 /* USL-5P Button IRQ */
#define IRQ_FAULT 13 /* USL-5P Fault IRQ */
-#define SHUTDOWN_BTN_MAJOR 99 /* Shutdown button device major no. */
-
-#define SHUTDOWN_LOOP_CNT 5 /* Shutdown button Detection loop */
-#define SHUTDOWN_DELAY 200 /* Shutdown button delay value(ms) */
-
-
-/* added by kogiidena */
-/*
- * landisk_ledparam
- *
- * led ------10 -6543210 -6543210 -6543210
- * |000000..|0.......|0.......|U.......|
- * | HARD |fastblik| blink | on |
- *
- * led0: power U:update flag
- * led1: error
- * led2: usb1
- * led3: usb2
- * led4: usb3
- * led5: usb4
- * led6: usb5
- *
- */
-extern int landisk_ledparam; /* from setup.c */
-extern int landisk_buzzerparam; /* from setup.c */
-extern int landisk_arch; /* from setup.c */
-
#define __IO_PREFIX landisk
#include <asm/io_generic.h>
diff --git a/include/asm-sh/unistd.h b/include/asm-sh/unistd.h
index af71e37..77bcb09 100644
--- a/include/asm-sh/unistd.h
+++ b/include/asm-sh/unistd.h
@@ -329,8 +329,11 @@
#define __NR_getcpu 318
#define __NR_epoll_pwait 319
#define __NR_utimensat 320
+#define __NR_signalfd 321
+#define __NR_timerfd 322
+#define __NR_eventfd 323
-#define NR_syscalls 321
+#define NR_syscalls 324
#ifdef __KERNEL__
diff --git a/include/linux/capability.h b/include/linux/capability.h
index 6548b35..bbf8df7 100644
--- a/include/linux/capability.h
+++ b/include/linux/capability.h
@@ -16,6 +16,8 @@
#include <linux/types.h>
#include <linux/compiler.h>
+struct task_struct;
+
/* User-level do most of the mapping between kernel and user
capabilities based on the version tag given by the kernel. The
kernel might be somewhat backwards compatible, but don't bet on
diff --git a/include/linux/freezer.h b/include/linux/freezer.h
index 5e75e26..4631086 100644
--- a/include/linux/freezer.h
+++ b/include/linux/freezer.h
@@ -37,25 +37,25 @@
/*
* Wake up a frozen process
+ *
+ * task_lock() is taken to prevent the race with refrigerator() which may
+ * occur if the freezing of tasks fails. Namely, without the lock, if the
+ * freezing of tasks failed, thaw_tasks() might have run before a task in
+ * refrigerator() could call frozen_process(), in which case the task would be
+ * frozen and no one would thaw it.
*/
static inline int thaw_process(struct task_struct *p)
{
+ task_lock(p);
if (frozen(p)) {
p->flags &= ~PF_FROZEN;
+ task_unlock(p);
wake_up_process(p);
return 1;
}
- return 0;
-}
-
-/*
- * freezing is complete, mark process as frozen
- */
-static inline void frozen_process(struct task_struct *p)
-{
- p->flags |= PF_FROZEN;
- wmb();
clear_tsk_thread_flag(p, TIF_FREEZE);
+ task_unlock(p);
+ return 0;
}
extern void refrigerator(void);
@@ -71,14 +71,55 @@
return 0;
}
-extern void thaw_some_processes(int all);
+/*
+ * The PF_FREEZER_SKIP flag should be set by a vfork parent right before it
+ * calls wait_for_completion(&vfork) and reset right after it returns from this
+ * function. Next, the parent should call try_to_freeze() to freeze itself
+ * appropriately in case the child has exited before the freezing of tasks is
+ * complete. However, we don't want kernel threads to be frozen in unexpected
+ * places, so we allow them to block freeze_processes() instead or to set
+ * PF_NOFREEZE if needed and PF_FREEZER_SKIP is only set for userland vfork
+ * parents. Fortunately, in the ____call_usermodehelper() case the parent won't
+ * really block freeze_processes(), since ____call_usermodehelper() (the child)
+ * does a little before exec/exit and it can't be frozen before waking up the
+ * parent.
+ */
+
+/*
+ * If the current task is a user space one, tell the freezer not to count it as
+ * freezable.
+ */
+static inline void freezer_do_not_count(void)
+{
+ if (current->mm)
+ current->flags |= PF_FREEZER_SKIP;
+}
+
+/*
+ * If the current task is a user space one, tell the freezer to count it as
+ * freezable again and try to freeze it.
+ */
+static inline void freezer_count(void)
+{
+ if (current->mm) {
+ current->flags &= ~PF_FREEZER_SKIP;
+ try_to_freeze();
+ }
+}
+
+/*
+ * Check if the task should be counted as freezeable by the freezer
+ */
+static inline int freezer_should_skip(struct task_struct *p)
+{
+ return !!(p->flags & PF_FREEZER_SKIP);
+}
#else
static inline int frozen(struct task_struct *p) { return 0; }
static inline int freezing(struct task_struct *p) { return 0; }
static inline void freeze(struct task_struct *p) { BUG(); }
static inline int thaw_process(struct task_struct *p) { return 1; }
-static inline void frozen_process(struct task_struct *p) { BUG(); }
static inline void refrigerator(void) {}
static inline int freeze_processes(void) { BUG(); return 0; }
@@ -86,5 +127,7 @@
static inline int try_to_freeze(void) { return 0; }
-
+static inline void freezer_do_not_count(void) {}
+static inline void freezer_count(void) {}
+static inline int freezer_should_skip(struct task_struct *p) { return 0; }
#endif
diff --git a/include/linux/genhd.h b/include/linux/genhd.h
index 4c03ee3..9756fc1 100644
--- a/include/linux/genhd.h
+++ b/include/linux/genhd.h
@@ -66,6 +66,7 @@
#include <linux/smp.h>
#include <linux/string.h>
#include <linux/fs.h>
+#include <linux/workqueue.h>
struct partition {
unsigned char boot_ind; /* 0x80 - active */
@@ -94,6 +95,7 @@
#define GENHD_FL_REMOVABLE 1
#define GENHD_FL_DRIVERFS 2
+#define GENHD_FL_MEDIA_CHANGE_NOTIFY 4
#define GENHD_FL_CD 8
#define GENHD_FL_UP 16
#define GENHD_FL_SUPPRESS_PARTITION_INFO 32
@@ -138,6 +140,7 @@
#else
struct disk_stats dkstats;
#endif
+ struct work_struct async_notify;
};
/* Structure for sysfs attributes on block devices */
@@ -419,7 +422,7 @@
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 dev, unsigned long range,
struct module *module,
struct kobject *(*probe)(dev_t, int *, void *),
diff --git a/include/linux/netfilter/nf_conntrack_ftp.h b/include/linux/netfilter/nf_conntrack_ftp.h
index 81453ea..b7c360f 100644
--- a/include/linux/netfilter/nf_conntrack_ftp.h
+++ b/include/linux/netfilter/nf_conntrack_ftp.h
@@ -37,8 +37,7 @@
enum nf_ct_ftp_type type,
unsigned int matchoff,
unsigned int matchlen,
- struct nf_conntrack_expect *exp,
- u32 *seq);
+ struct nf_conntrack_expect *exp);
#endif /* __KERNEL__ */
#endif /* _NF_CONNTRACK_FTP_H */
diff --git a/include/linux/netfilter/nf_conntrack_h323_types.h b/include/linux/netfilter/nf_conntrack_h323_types.h
index 38d74d5..f35b6b4 100644
--- a/include/linux/netfilter/nf_conntrack_h323_types.h
+++ b/include/linux/netfilter/nf_conntrack_h323_types.h
@@ -1,4 +1,4 @@
-/* Generated by Jing Min Zhao's ASN.1 parser, Apr 20 2006
+/* Generated by Jing Min Zhao's ASN.1 parser, May 16 2007
*
* Copyright (c) 2006 Jing Min Zhao <zhaojingmin@users.sourceforge.net>
*
@@ -12,7 +12,7 @@
typedef struct TransportAddress_ip6Address { /* SEQUENCE */
int options; /* No use */
- unsigned ip6;
+ unsigned ip;
} TransportAddress_ip6Address;
typedef struct TransportAddress { /* CHOICE */
@@ -364,23 +364,6 @@
Alerting_UUIE_fastStart fastStart;
} Alerting_UUIE;
-typedef struct Information_UUIE_fastStart { /* SEQUENCE OF */
- int count;
- OpenLogicalChannel item[30];
-} Information_UUIE_fastStart;
-
-typedef struct Information_UUIE { /* SEQUENCE */
- enum {
- eInformation_UUIE_callIdentifier = (1 << 31),
- eInformation_UUIE_tokens = (1 << 30),
- eInformation_UUIE_cryptoTokens = (1 << 29),
- eInformation_UUIE_fastStart = (1 << 28),
- eInformation_UUIE_fastConnectRefused = (1 << 27),
- eInformation_UUIE_circuitInfo = (1 << 26),
- } options;
- Information_UUIE_fastStart fastStart;
-} Information_UUIE;
-
typedef struct FacilityReason { /* CHOICE */
enum {
eFacilityReason_routeCallToGatekeeper,
@@ -471,7 +454,6 @@
CallProceeding_UUIE callProceeding;
Connect_UUIE connect;
Alerting_UUIE alerting;
- Information_UUIE information;
Facility_UUIE facility;
Progress_UUIE progress;
};
@@ -561,6 +543,7 @@
} options;
OpenLogicalChannelAck_reverseLogicalChannelParameters
reverseLogicalChannelParameters;
+ NetworkAccessParameters separateStack;
OpenLogicalChannelAck_forwardMultiplexAckParameters
forwardMultiplexAckParameters;
} OpenLogicalChannelAck;
diff --git a/include/linux/nfs_page.h b/include/linux/nfs_page.h
index 41afab6..bd193af 100644
--- a/include/linux/nfs_page.h
+++ b/include/linux/nfs_page.h
@@ -81,6 +81,7 @@
extern int nfs_pageio_add_request(struct nfs_pageio_descriptor *,
struct nfs_page *);
extern void nfs_pageio_complete(struct nfs_pageio_descriptor *desc);
+extern void nfs_pageio_cond_complete(struct nfs_pageio_descriptor *, pgoff_t);
extern int nfs_wait_on_request(struct nfs_page *);
extern void nfs_unlock_request(struct nfs_page *req);
extern int nfs_set_page_writeback_locked(struct nfs_page *req);
diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h
index 62b3e00..4712e26 100644
--- a/include/linux/pci_ids.h
+++ b/include/linux/pci_ids.h
@@ -371,6 +371,7 @@
#define PCI_DEVICE_ID_ATI_IXP600_SMBUS 0x4385
#define PCI_DEVICE_ID_ATI_IXP600_IDE 0x438c
#define PCI_DEVICE_ID_ATI_IXP700_SATA 0x4390
+#define PCI_DEVICE_ID_ATI_IXP700_IDE 0x439c
#define PCI_VENDOR_ID_VLSI 0x1004
#define PCI_DEVICE_ID_VLSI_82C592 0x0005
diff --git a/include/linux/raid/bitmap.h b/include/linux/raid/bitmap.h
index 6db9a4c..dd5a05d 100644
--- a/include/linux/raid/bitmap.h
+++ b/include/linux/raid/bitmap.h
@@ -232,6 +232,7 @@
struct page **filemap; /* list of cache pages for the file */
unsigned long *filemap_attr; /* attributes associated w/ filemap pages */
unsigned long file_pages; /* number of pages in the file */
+ int last_page_size; /* bytes in the last page */
unsigned long flags;
diff --git a/include/linux/sched.h b/include/linux/sched.h
index a81897e..d58e74b 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -1182,6 +1182,7 @@
#define PF_SPREAD_SLAB 0x02000000 /* Spread some slab caches over cpuset */
#define PF_MEMPOLICY 0x10000000 /* Non-default NUMA mempolicy */
#define PF_MUTEX_TESTER 0x20000000 /* Thread belongs to the rt mutex tester */
+#define PF_FREEZER_SKIP 0x40000000 /* Freezer should not count it as freezeable */
/*
* Only the _current_ task can read/write to tsk->flags, but other
@@ -1615,11 +1616,13 @@
return 0;
}
-/* Reevaluate whether the task has signals pending delivery.
- This is required every time the blocked sigset_t changes.
- callers must hold sighand->siglock. */
-
-extern FASTCALL(void recalc_sigpending_tsk(struct task_struct *t));
+/*
+ * Reevaluate whether the task has signals pending delivery.
+ * Wake the task if so.
+ * This is required every time the blocked sigset_t changes.
+ * callers must hold sighand->siglock.
+ */
+extern void recalc_sigpending_and_wake(struct task_struct *t);
extern void recalc_sigpending(void);
extern void signal_wake_up(struct task_struct *t, int resume_stopped);
diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h
index a25c2af..e756038 100644
--- a/include/linux/videodev2.h
+++ b/include/linux/videodev2.h
@@ -267,8 +267,6 @@
__u32 sizeimage;
enum v4l2_colorspace colorspace;
__u32 priv; /* private data, depends on pixelformat */
- __u32 left; /* only valid if V4L2_CAP_VIDEO_OUTPUT_POS is set */
- __u32 top; /* only valid if V4L2_CAP_VIDEO_OUTPUT_POS is set */
};
/* Pixel format FOURCC depth Description */
diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h
index 8242a0e..87df4e8 100644
--- a/include/net/bluetooth/l2cap.h
+++ b/include/net/bluetooth/l2cap.h
@@ -129,8 +129,10 @@
__u8 data[0];
} __attribute__ ((packed));
-#define L2CAP_CONF_SUCCESS 0x00
-#define L2CAP_CONF_UNACCEPT 0x01
+#define L2CAP_CONF_SUCCESS 0x0000
+#define L2CAP_CONF_UNACCEPT 0x0001
+#define L2CAP_CONF_REJECT 0x0002
+#define L2CAP_CONF_UNKNOWN 0x0003
struct l2cap_conf_opt {
__u8 type;
@@ -215,6 +217,8 @@
__u32 link_mode;
+ __u8 conf_req[64];
+ __u8 conf_len;
__u8 conf_state;
__u8 conf_retry;
__u16 conf_mtu;
diff --git a/include/net/dst.h b/include/net/dst.h
index e12a8ce..82270f9 100644
--- a/include/net/dst.h
+++ b/include/net/dst.h
@@ -265,9 +265,16 @@
{
return 0;
}
+static inline int __xfrm_lookup(struct dst_entry **dst_p, struct flowi *fl,
+ struct sock *sk, int flags)
+{
+ return 0;
+}
#else
extern int xfrm_lookup(struct dst_entry **dst_p, struct flowi *fl,
struct sock *sk, int flags);
+extern int __xfrm_lookup(struct dst_entry **dst_p, struct flowi *fl,
+ struct sock *sk, int flags);
#endif
#endif
diff --git a/include/net/ipv6.h b/include/net/ipv6.h
index 4fa5dfe..78a0d06 100644
--- a/include/net/ipv6.h
+++ b/include/net/ipv6.h
@@ -469,6 +469,9 @@
extern int ip6_dst_lookup(struct sock *sk,
struct dst_entry **dst,
struct flowi *fl);
+extern int ip6_dst_blackhole(struct sock *sk,
+ struct dst_entry **dst,
+ struct flowi *fl);
extern int ip6_sk_dst_lookup(struct sock *sk,
struct dst_entry **dst,
struct flowi *fl);
diff --git a/kernel/exit.c b/kernel/exit.c
index c6d14b8..5b888c2 100644
--- a/kernel/exit.c
+++ b/kernel/exit.c
@@ -762,11 +762,8 @@
read_lock(&tasklist_lock);
spin_lock_irq(&tsk->sighand->siglock);
for (t = next_thread(tsk); t != tsk; t = next_thread(t))
- if (!signal_pending(t) && !(t->flags & PF_EXITING)) {
- recalc_sigpending_tsk(t);
- if (signal_pending(t))
- signal_wake_up(t, 0);
- }
+ if (!signal_pending(t) && !(t->flags & PF_EXITING))
+ recalc_sigpending_and_wake(t);
spin_unlock_irq(&tsk->sighand->siglock);
read_unlock(&tasklist_lock);
}
diff --git a/kernel/fork.c b/kernel/fork.c
index 87069cf..73ad5cd 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -45,6 +45,7 @@
#include <linux/acct.h>
#include <linux/tsacct_kern.h>
#include <linux/cn_proc.h>
+#include <linux/freezer.h>
#include <linux/delayacct.h>
#include <linux/taskstats_kern.h>
#include <linux/random.h>
@@ -1405,7 +1406,9 @@
}
if (clone_flags & CLONE_VFORK) {
+ freezer_do_not_count();
wait_for_completion(&vfork);
+ freezer_count();
if (unlikely (current->ptrace & PT_TRACE_VFORK_DONE)) {
current->ptrace_message = nr;
ptrace_notify ((PTRACE_EVENT_VFORK_DONE << 8) | SIGTRAP);
diff --git a/kernel/irq/spurious.c b/kernel/irq/spurious.c
index b0d81aa..bd9e272 100644
--- a/kernel/irq/spurious.c
+++ b/kernel/irq/spurious.c
@@ -135,6 +135,39 @@
}
}
+static inline int try_misrouted_irq(unsigned int irq, struct irq_desc *desc, irqreturn_t action_ret)
+{
+ struct irqaction *action;
+
+ if (!irqfixup)
+ return 0;
+
+ /* We didn't actually handle the IRQ - see if it was misrouted? */
+ if (action_ret == IRQ_NONE)
+ return 1;
+
+ /*
+ * But for 'irqfixup == 2' we also do it for handled interrupts if
+ * they are marked as IRQF_IRQPOLL (or for irq zero, which is the
+ * traditional PC timer interrupt.. Legacy)
+ */
+ if (irqfixup < 2)
+ return 0;
+
+ if (!irq)
+ return 1;
+
+ /*
+ * Since we don't get the descriptor lock, "action" can
+ * change under us. We don't really care, but we don't
+ * want to follow a NULL pointer. So tell the compiler to
+ * just load it once by using a barrier.
+ */
+ action = desc->action;
+ barrier();
+ return action && (action->flags & IRQF_IRQPOLL);
+}
+
void note_interrupt(unsigned int irq, struct irq_desc *desc,
irqreturn_t action_ret)
{
@@ -144,15 +177,10 @@
report_bad_irq(irq, desc, action_ret);
}
- if (unlikely(irqfixup)) {
- /* Don't punish working computers */
- if ((irqfixup == 2 && ((irq == 0) ||
- (desc->action->flags & IRQF_IRQPOLL))) ||
- action_ret == IRQ_NONE) {
- int ok = misrouted_irq(irq);
- if (action_ret == IRQ_NONE)
- desc->irqs_unhandled -= ok;
- }
+ if (unlikely(try_misrouted_irq(irq, desc, action_ret))) {
+ int ok = misrouted_irq(irq);
+ if (action_ret == IRQ_NONE)
+ desc->irqs_unhandled -= ok;
}
desc->irq_count++;
diff --git a/kernel/kthread.c b/kernel/kthread.c
index df8a8e8..bbd51b8 100644
--- a/kernel/kthread.c
+++ b/kernel/kthread.c
@@ -70,7 +70,7 @@
data = create->data;
/* OK, tell user we're spawned, wait for stop or wakeup */
- __set_current_state(TASK_INTERRUPTIBLE);
+ __set_current_state(TASK_UNINTERRUPTIBLE);
complete(&create->started);
schedule();
@@ -162,7 +162,10 @@
*/
void kthread_bind(struct task_struct *k, unsigned int cpu)
{
- BUG_ON(k->state != TASK_INTERRUPTIBLE);
+ if (k->state != TASK_UNINTERRUPTIBLE) {
+ WARN_ON(1);
+ return;
+ }
/* Must have done schedule() in kthread() before we set_task_cpu */
wait_task_inactive(k);
set_task_cpu(k, cpu);
diff --git a/kernel/power/process.c b/kernel/power/process.c
index 0884193..e0233d8 100644
--- a/kernel/power/process.c
+++ b/kernel/power/process.c
@@ -31,16 +31,36 @@
return 1;
}
+/*
+ * freezing is complete, mark current process as frozen
+ */
+static inline void frozen_process(void)
+{
+ if (!unlikely(current->flags & PF_NOFREEZE)) {
+ current->flags |= PF_FROZEN;
+ wmb();
+ }
+ clear_tsk_thread_flag(current, TIF_FREEZE);
+}
+
/* Refrigerator is place where frozen processes are stored :-). */
void refrigerator(void)
{
/* Hmm, should we be allowed to suspend when there are realtime
processes around? */
long save;
+
+ task_lock(current);
+ if (freezing(current)) {
+ frozen_process();
+ task_unlock(current);
+ } else {
+ task_unlock(current);
+ return;
+ }
save = current->state;
pr_debug("%s entered refrigerator\n", current->comm);
- frozen_process(current);
spin_lock_irq(¤t->sighand->siglock);
recalc_sigpending(); /* We sent fake signal, clean it up */
spin_unlock_irq(¤t->sighand->siglock);
@@ -81,7 +101,7 @@
pr_debug(" clean up: %s\n", p->comm);
do_not_freeze(p);
spin_lock_irqsave(&p->sighand->siglock, flags);
- recalc_sigpending_tsk(p);
+ recalc_sigpending_and_wake(p);
spin_unlock_irqrestore(&p->sighand->siglock, flags);
}
}
@@ -112,22 +132,12 @@
cancel_freezing(p);
continue;
}
- if (is_user_space(p)) {
- if (!freeze_user_space)
- continue;
+ if (freeze_user_space && !is_user_space(p))
+ continue;
- /* Freeze the task unless there is a vfork
- * completion pending
- */
- if (!p->vfork_done)
- freeze_process(p);
- } else {
- if (freeze_user_space)
- continue;
-
- freeze_process(p);
- }
- todo++;
+ freeze_process(p);
+ if (!freezer_should_skip(p))
+ todo++;
} while_each_thread(g, p);
read_unlock(&tasklist_lock);
yield(); /* Yield is okay here */
@@ -149,13 +159,16 @@
TIMEOUT / HZ, todo);
read_lock(&tasklist_lock);
do_each_thread(g, p) {
- if (is_user_space(p) == !freeze_user_space)
+ if (freeze_user_space && !is_user_space(p))
continue;
- if (freezeable(p) && !frozen(p))
+ task_lock(p);
+ if (freezeable(p) && !frozen(p) &&
+ !freezer_should_skip(p))
printk(KERN_ERR " %s\n", p->comm);
cancel_freezing(p);
+ task_unlock(p);
} while_each_thread(g, p);
read_unlock(&tasklist_lock);
}
@@ -200,9 +213,7 @@
if (is_user_space(p) == !thaw_user_space)
continue;
- if (!thaw_process(p))
- printk(KERN_WARNING " Strange, %s not stopped\n",
- p->comm );
+ thaw_process(p);
} while_each_thread(g, p);
read_unlock(&tasklist_lock);
}
diff --git a/kernel/power/swap.c b/kernel/power/swap.c
index b8b235c..8b1a1b8 100644
--- a/kernel/power/swap.c
+++ b/kernel/power/swap.c
@@ -584,7 +584,7 @@
resume_bdev = open_by_devnum(swsusp_resume_device, FMODE_READ);
if (!IS_ERR(resume_bdev)) {
set_blocksize(resume_bdev, PAGE_SIZE);
- memset(swsusp_header, 0, sizeof(PAGE_SIZE));
+ memset(swsusp_header, 0, PAGE_SIZE);
error = bio_read_page(swsusp_resume_block,
swsusp_header, NULL);
if (error)
diff --git a/kernel/sched.c b/kernel/sched.c
index 799d23b..13cdab3 100644
--- a/kernel/sched.c
+++ b/kernel/sched.c
@@ -4775,9 +4775,7 @@
BUG_ON(!in_softirq());
if (need_resched() && system_state == SYSTEM_RUNNING) {
- raw_local_irq_disable();
- _local_bh_enable();
- raw_local_irq_enable();
+ local_bh_enable();
__cond_resched();
local_bh_disable();
return 1;
diff --git a/kernel/signal.c b/kernel/signal.c
index 364fc95..acdfc05 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -96,15 +96,27 @@
#define PENDING(p,b) has_pending_signals(&(p)->signal, (b))
-fastcall void recalc_sigpending_tsk(struct task_struct *t)
+static int recalc_sigpending_tsk(struct task_struct *t)
{
if (t->signal->group_stop_count > 0 ||
(freezing(t)) ||
PENDING(&t->pending, &t->blocked) ||
- PENDING(&t->signal->shared_pending, &t->blocked))
+ PENDING(&t->signal->shared_pending, &t->blocked)) {
set_tsk_thread_flag(t, TIF_SIGPENDING);
- else
- clear_tsk_thread_flag(t, TIF_SIGPENDING);
+ return 1;
+ }
+ clear_tsk_thread_flag(t, TIF_SIGPENDING);
+ return 0;
+}
+
+/*
+ * After recalculating TIF_SIGPENDING, we need to make sure the task wakes up.
+ * This is superfluous when called on current, the wakeup is a harmless no-op.
+ */
+void recalc_sigpending_and_wake(struct task_struct *t)
+{
+ if (recalc_sigpending_tsk(t))
+ signal_wake_up(t, 0);
}
void recalc_sigpending(void)
@@ -744,7 +756,7 @@
action->sa.sa_handler = SIG_DFL;
if (blocked) {
sigdelset(&t->blocked, sig);
- recalc_sigpending_tsk(t);
+ recalc_sigpending_and_wake(t);
}
}
ret = specific_send_sig_info(sig, info, t);
@@ -2273,7 +2285,7 @@
rm_from_queue_full(&mask, &t->signal->shared_pending);
do {
rm_from_queue_full(&mask, &t->pending);
- recalc_sigpending_tsk(t);
+ recalc_sigpending_and_wake(t);
t = next_thread(t);
} while (t != current);
}
diff --git a/kernel/time/tick-broadcast.c b/kernel/time/tick-broadcast.c
index eadfce2..8001d37 100644
--- a/kernel/time/tick-broadcast.c
+++ b/kernel/time/tick-broadcast.c
@@ -243,11 +243,18 @@
{
int cpu = get_cpu();
- if (cpu == *oncpu)
- tick_do_broadcast_on_off(&reason);
- else
- smp_call_function_single(*oncpu, tick_do_broadcast_on_off,
- &reason, 1, 1);
+ if (!cpu_isset(*oncpu, cpu_online_map)) {
+ printk(KERN_ERR "tick-braodcast: ignoring broadcast for "
+ "offline CPU #%d\n", *oncpu);
+ } else {
+
+ if (cpu == *oncpu)
+ tick_do_broadcast_on_off(&reason);
+ else
+ smp_call_function_single(*oncpu,
+ tick_do_broadcast_on_off,
+ &reason, 1, 1);
+ }
put_cpu();
}
diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c
index 3483e6c..3e7ebc4 100644
--- a/kernel/time/tick-sched.c
+++ b/kernel/time/tick-sched.c
@@ -167,9 +167,15 @@
goto end;
cpu = smp_processor_id();
- if (unlikely(local_softirq_pending()))
- printk(KERN_ERR "NOHZ: local_softirq_pending %02x\n",
- local_softirq_pending());
+ if (unlikely(local_softirq_pending())) {
+ static int ratelimit;
+
+ if (ratelimit < 10) {
+ printk(KERN_ERR "NOHZ: local_softirq_pending %02x\n",
+ local_softirq_pending());
+ ratelimit++;
+ }
+ }
now = ktime_get();
/*
diff --git a/kernel/workqueue.c b/kernel/workqueue.c
index fb56fed..3bebf73 100644
--- a/kernel/workqueue.c
+++ b/kernel/workqueue.c
@@ -47,7 +47,6 @@
struct workqueue_struct *wq;
struct task_struct *thread;
- int should_stop;
int run_depth; /* Detect run_workqueue() recursion depth */
} ____cacheline_aligned;
@@ -71,7 +70,13 @@
static int singlethread_cpu __read_mostly;
static cpumask_t cpu_singlethread_map __read_mostly;
-/* optimization, we could use cpu_possible_map */
+/*
+ * _cpu_down() first removes CPU from cpu_online_map, then CPU_DEAD
+ * flushes cwq->worklist. This means that flush_workqueue/wait_on_work
+ * which comes in between can't use for_each_online_cpu(). We could
+ * use cpu_possible_map, the cpumask below is more a documentation
+ * than optimization.
+ */
static cpumask_t cpu_populated_map __read_mostly;
/* If it's single threaded, it isn't in the list of workqueues. */
@@ -272,24 +277,6 @@
spin_unlock_irq(&cwq->lock);
}
-/*
- * NOTE: the caller must not touch *cwq if this func returns true
- */
-static int cwq_should_stop(struct cpu_workqueue_struct *cwq)
-{
- int should_stop = cwq->should_stop;
-
- if (unlikely(should_stop)) {
- spin_lock_irq(&cwq->lock);
- should_stop = cwq->should_stop && list_empty(&cwq->worklist);
- if (should_stop)
- cwq->thread = NULL;
- spin_unlock_irq(&cwq->lock);
- }
-
- return should_stop;
-}
-
static int worker_thread(void *__cwq)
{
struct cpu_workqueue_struct *cwq = __cwq;
@@ -302,14 +289,15 @@
for (;;) {
prepare_to_wait(&cwq->more_work, &wait, TASK_INTERRUPTIBLE);
- if (!freezing(current) && !cwq->should_stop
- && list_empty(&cwq->worklist))
+ if (!freezing(current) &&
+ !kthread_should_stop() &&
+ list_empty(&cwq->worklist))
schedule();
finish_wait(&cwq->more_work, &wait);
try_to_freeze();
- if (cwq_should_stop(cwq))
+ if (kthread_should_stop())
break;
run_workqueue(cwq);
@@ -340,18 +328,21 @@
insert_work(cwq, &barr->work, tail);
}
-static void flush_cpu_workqueue(struct cpu_workqueue_struct *cwq)
+static int flush_cpu_workqueue(struct cpu_workqueue_struct *cwq)
{
+ int active;
+
if (cwq->thread == current) {
/*
* Probably keventd trying to flush its own queue. So simply run
* it by hand rather than deadlocking.
*/
run_workqueue(cwq);
+ active = 1;
} else {
struct wq_barrier barr;
- int active = 0;
+ active = 0;
spin_lock_irq(&cwq->lock);
if (!list_empty(&cwq->worklist) || cwq->current_work != NULL) {
insert_wq_barrier(cwq, &barr, 1);
@@ -362,6 +353,8 @@
if (active)
wait_for_completion(&barr.done);
}
+
+ return active;
}
/**
@@ -674,7 +667,6 @@
return PTR_ERR(p);
cwq->thread = p;
- cwq->should_stop = 0;
return 0;
}
@@ -740,29 +732,27 @@
static void cleanup_workqueue_thread(struct cpu_workqueue_struct *cwq, int cpu)
{
- struct wq_barrier barr;
- int alive = 0;
+ /*
+ * Our caller is either destroy_workqueue() or CPU_DEAD,
+ * workqueue_mutex protects cwq->thread
+ */
+ if (cwq->thread == NULL)
+ return;
- spin_lock_irq(&cwq->lock);
- if (cwq->thread != NULL) {
- insert_wq_barrier(cwq, &barr, 1);
- cwq->should_stop = 1;
- alive = 1;
- }
- spin_unlock_irq(&cwq->lock);
+ /*
+ * If the caller is CPU_DEAD the single flush_cpu_workqueue()
+ * is not enough, a concurrent flush_workqueue() can insert a
+ * barrier after us.
+ * When ->worklist becomes empty it is safe to exit because no
+ * more work_structs can be queued on this cwq: flush_workqueue
+ * checks list_empty(), and a "normal" queue_work() can't use
+ * a dead CPU.
+ */
+ while (flush_cpu_workqueue(cwq))
+ ;
- if (alive) {
- wait_for_completion(&barr.done);
-
- while (unlikely(cwq->thread != NULL))
- cpu_relax();
- /*
- * Wait until cwq->thread unlocks cwq->lock,
- * it won't touch *cwq after that.
- */
- smp_rmb();
- spin_unlock_wait(&cwq->lock);
- }
+ kthread_stop(cwq->thread);
+ cwq->thread = NULL;
}
/**
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
index fbc5c62..1ba77ca7 100644
--- a/lib/Kconfig.debug
+++ b/lib/Kconfig.debug
@@ -378,14 +378,13 @@
config RCU_TORTURE_TEST
tristate "torture tests for RCU"
depends on DEBUG_KERNEL
+ depends on m
default n
help
This option provides a kernel module that runs torture tests
on the RCU infrastructure. The kernel module may be built
after the fact on the running kernel to be tested, if desired.
- Say Y here if you want RCU torture tests to start automatically
- at boot time (you probably don't).
Say M if you want the RCU torture tests to build as a module.
Say N if you are unsure.
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index 8b000d6..d897062 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -136,6 +136,11 @@
#endif /* CONFIG_MEMORY_HOTPLUG_RESERVE */
#endif /* CONFIG_ARCH_POPULATES_NODE_MAP */
+#if MAX_NUMNODES > 1
+int nr_node_ids __read_mostly = MAX_NUMNODES;
+EXPORT_SYMBOL(nr_node_ids);
+#endif
+
#ifdef CONFIG_DEBUG_VM
static int page_outside_zone_boundaries(struct zone *zone, struct page *page)
{
@@ -669,26 +674,6 @@
return i;
}
-#if MAX_NUMNODES > 1
-int nr_node_ids __read_mostly = MAX_NUMNODES;
-EXPORT_SYMBOL(nr_node_ids);
-
-/*
- * Figure out the number of possible node ids.
- */
-static void __init setup_nr_node_ids(void)
-{
- unsigned int node;
- unsigned int highest = 0;
-
- for_each_node_mask(node, node_possible_map)
- highest = node;
- nr_node_ids = highest + 1;
-}
-#else
-static void __init setup_nr_node_ids(void) {}
-#endif
-
#ifdef CONFIG_NUMA
/*
* Called from the vmstat counter updater to drain pagesets of this
@@ -2733,6 +2718,26 @@
}
#ifdef CONFIG_ARCH_POPULATES_NODE_MAP
+
+#if MAX_NUMNODES > 1
+/*
+ * Figure out the number of possible node ids.
+ */
+static void __init setup_nr_node_ids(void)
+{
+ unsigned int node;
+ unsigned int highest = 0;
+
+ for_each_node_mask(node, node_possible_map)
+ highest = node;
+ nr_node_ids = highest + 1;
+}
+#else
+static inline void setup_nr_node_ids(void)
+{
+}
+#endif
+
/**
* add_active_range - Register a range of PFNs backed by physical memory
* @nid: The node ID the range resides on
diff --git a/mm/slub.c b/mm/slub.c
index 98801d4..3e5aefc 100644
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -939,7 +939,7 @@
* Debugging or ctor may create a need to move the free
* pointer. Fail if this happens.
*/
- if (s->size >= 65535 * sizeof(void *)) {
+ if (s->objsize >= 65535 * sizeof(void *)) {
BUG_ON(s->flags & (SLAB_RED_ZONE | SLAB_POISON |
SLAB_STORE_USER | SLAB_DESTROY_BY_RCU));
BUG_ON(s->ctor);
@@ -1917,7 +1917,6 @@
*/
s->inuse = size;
-#ifdef CONFIG_SLUB_DEBUG
if (((flags & (SLAB_DESTROY_BY_RCU | SLAB_POISON)) ||
s->ctor)) {
/*
@@ -1932,6 +1931,7 @@
size += sizeof(void *);
}
+#ifdef CONFIG_SLUB_DEBUG
if (flags & SLAB_STORE_USER)
/*
* Need to store information about allocs and frees after
diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c
index a59b1fb..670ff95 100644
--- a/net/bluetooth/l2cap.c
+++ b/net/bluetooth/l2cap.c
@@ -507,6 +507,7 @@
}
/* Default config options */
+ pi->conf_len = 0;
pi->conf_mtu = L2CAP_DEFAULT_MTU;
pi->flush_to = L2CAP_DEFAULT_FLUSH_TO;
}
@@ -1271,42 +1272,6 @@
return len;
}
-static inline void l2cap_parse_conf_req(struct sock *sk, void *data, int len)
-{
- int type, hint, olen;
- unsigned long val;
- void *ptr = data;
-
- BT_DBG("sk %p len %d", sk, len);
-
- while (len >= L2CAP_CONF_OPT_SIZE) {
- len -= l2cap_get_conf_opt(&ptr, &type, &olen, &val);
-
- hint = type & 0x80;
- type &= 0x7f;
-
- switch (type) {
- case L2CAP_CONF_MTU:
- l2cap_pi(sk)->conf_mtu = val;
- break;
-
- case L2CAP_CONF_FLUSH_TO:
- l2cap_pi(sk)->flush_to = val;
- break;
-
- case L2CAP_CONF_QOS:
- break;
-
- default:
- if (hint)
- break;
-
- /* FIXME: Reject unknown option */
- break;
- }
- }
-}
-
static void l2cap_add_conf_opt(void **ptr, u8 type, u8 len, unsigned long val)
{
struct l2cap_conf_opt *opt = *ptr;
@@ -1358,39 +1323,75 @@
return ptr - data;
}
-static inline int l2cap_conf_output(struct sock *sk, void **ptr)
+static int l2cap_parse_conf_req(struct sock *sk, void *data)
{
struct l2cap_pinfo *pi = l2cap_pi(sk);
- int result = 0;
+ struct l2cap_conf_rsp *rsp = data;
+ void *ptr = rsp->data;
+ void *req = pi->conf_req;
+ int len = pi->conf_len;
+ int type, hint, olen;
+ unsigned long val;
+ u16 result = L2CAP_CONF_SUCCESS;
- /* Configure output options and let the other side know
- * which ones we don't like. */
- if (pi->conf_mtu < pi->omtu)
- result = L2CAP_CONF_UNACCEPT;
- else
- pi->omtu = pi->conf_mtu;
+ BT_DBG("sk %p", sk);
- l2cap_add_conf_opt(ptr, L2CAP_CONF_MTU, 2, pi->omtu);
+ while (len >= L2CAP_CONF_OPT_SIZE) {
+ len -= l2cap_get_conf_opt(&req, &type, &olen, &val);
- BT_DBG("sk %p result %d", sk, result);
- return result;
+ hint = type & 0x80;
+ type &= 0x7f;
+
+ switch (type) {
+ case L2CAP_CONF_MTU:
+ pi->conf_mtu = val;
+ break;
+
+ case L2CAP_CONF_FLUSH_TO:
+ pi->flush_to = val;
+ break;
+
+ case L2CAP_CONF_QOS:
+ break;
+
+ default:
+ if (hint)
+ break;
+
+ result = L2CAP_CONF_UNKNOWN;
+ *((u8 *) ptr++) = type;
+ break;
+ }
+ }
+
+ if (result == L2CAP_CONF_SUCCESS) {
+ /* Configure output options and let the other side know
+ * which ones we don't like. */
+
+ if (pi->conf_mtu < pi->omtu)
+ result = L2CAP_CONF_UNACCEPT;
+ else
+ pi->omtu = pi->conf_mtu;
+
+ l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, pi->omtu);
+ }
+
+ rsp->scid = cpu_to_le16(pi->dcid);
+ rsp->result = cpu_to_le16(result);
+ rsp->flags = cpu_to_le16(0x0000);
+
+ return ptr - data;
}
-static int l2cap_build_conf_rsp(struct sock *sk, void *data, int *result)
+static int l2cap_build_conf_rsp(struct sock *sk, void *data, u16 result, u16 flags)
{
struct l2cap_conf_rsp *rsp = data;
void *ptr = rsp->data;
- u16 flags = 0;
- BT_DBG("sk %p complete %d", sk, result ? 1 : 0);
-
- if (result)
- *result = l2cap_conf_output(sk, &ptr);
- else
- flags = 0x0001;
+ BT_DBG("sk %p", sk);
rsp->scid = cpu_to_le16(l2cap_pi(sk)->dcid);
- rsp->result = cpu_to_le16(result ? *result : 0);
+ rsp->result = cpu_to_le16(result);
rsp->flags = cpu_to_le16(flags);
return ptr - data;
@@ -1535,7 +1536,7 @@
u16 dcid, flags;
u8 rsp[64];
struct sock *sk;
- int result;
+ int len;
dcid = __le16_to_cpu(req->dcid);
flags = __le16_to_cpu(req->flags);
@@ -1548,25 +1549,40 @@
if (sk->sk_state == BT_DISCONN)
goto unlock;
- l2cap_parse_conf_req(sk, req->data, cmd->len - sizeof(*req));
+ /* Reject if config buffer is too small. */
+ len = cmd->len - sizeof(*req);
+ if (l2cap_pi(sk)->conf_len + len > sizeof(l2cap_pi(sk)->conf_req)) {
+ l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
+ l2cap_build_conf_rsp(sk, rsp,
+ L2CAP_CONF_REJECT, flags), rsp);
+ goto unlock;
+ }
+
+ /* Store config. */
+ memcpy(l2cap_pi(sk)->conf_req + l2cap_pi(sk)->conf_len, req->data, len);
+ l2cap_pi(sk)->conf_len += len;
if (flags & 0x0001) {
/* Incomplete config. Send empty response. */
l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
- l2cap_build_conf_rsp(sk, rsp, NULL), rsp);
+ l2cap_build_conf_rsp(sk, rsp,
+ L2CAP_CONF_SUCCESS, 0x0001), rsp);
goto unlock;
}
/* Complete config. */
- l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP,
- l2cap_build_conf_rsp(sk, rsp, &result), rsp);
-
- if (result)
+ len = l2cap_parse_conf_req(sk, rsp);
+ if (len < 0)
goto unlock;
- /* Output config done */
+ l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP, len, rsp);
+
+ /* Output config done. */
l2cap_pi(sk)->conf_state |= L2CAP_CONF_OUTPUT_DONE;
+ /* Reset config buffer. */
+ l2cap_pi(sk)->conf_len = 0;
+
if (l2cap_pi(sk)->conf_state & L2CAP_CONF_INPUT_DONE) {
sk->sk_state = BT_CONNECTED;
l2cap_chan_ready(sk);
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index 8c971a2..27da9cd 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -437,7 +437,7 @@
a->tx_compressed = b->tx_compressed;
};
-static inline size_t if_nlmsg_size(int iwbuflen)
+static inline size_t if_nlmsg_size(void)
{
return NLMSG_ALIGN(sizeof(struct ifinfomsg))
+ nla_total_size(IFNAMSIZ) /* IFLA_IFNAME */
@@ -452,13 +452,12 @@
+ nla_total_size(4) /* IFLA_LINK */
+ nla_total_size(4) /* IFLA_MASTER */
+ nla_total_size(1) /* IFLA_OPERSTATE */
- + nla_total_size(1) /* IFLA_LINKMODE */
- + nla_total_size(iwbuflen);
+ + nla_total_size(1); /* IFLA_LINKMODE */
}
static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev,
- void *iwbuf, int iwbuflen, int type, u32 pid,
- u32 seq, u32 change, unsigned int flags)
+ int type, u32 pid, u32 seq, u32 change,
+ unsigned int flags)
{
struct ifinfomsg *ifm;
struct nlmsghdr *nlh;
@@ -523,9 +522,6 @@
}
}
- if (iwbuf)
- NLA_PUT(skb, IFLA_WIRELESS, iwbuflen, iwbuf);
-
return nlmsg_end(skb, nlh);
nla_put_failure:
@@ -543,7 +539,7 @@
for_each_netdev(dev) {
if (idx < s_idx)
goto cont;
- if (rtnl_fill_ifinfo(skb, dev, NULL, 0, RTM_NEWLINK,
+ if (rtnl_fill_ifinfo(skb, dev, RTM_NEWLINK,
NETLINK_CB(cb->skb).pid,
cb->nlh->nlmsg_seq, 0, NLM_F_MULTI) <= 0)
break;
@@ -689,8 +685,15 @@
}
- if (ifm->ifi_flags)
- dev_change_flags(dev, ifm->ifi_flags);
+ if (ifm->ifi_flags || ifm->ifi_change) {
+ unsigned int flags = ifm->ifi_flags;
+
+ /* bugwards compatibility: ifi_change == 0 is treated as ~0 */
+ if (ifm->ifi_change)
+ flags = (flags & ifm->ifi_change) |
+ (dev->flags & ~ifm->ifi_change);
+ dev_change_flags(dev, flags);
+ }
if (tb[IFLA_TXQLEN])
dev->tx_queue_len = nla_get_u32(tb[IFLA_TXQLEN]);
@@ -730,8 +733,6 @@
struct nlattr *tb[IFLA_MAX+1];
struct net_device *dev = NULL;
struct sk_buff *nskb;
- char *iw_buf = NULL, *iw = NULL;
- int iw_buf_len = 0;
int err;
err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFLA_MAX, ifla_policy);
@@ -746,14 +747,14 @@
} else
return -EINVAL;
- nskb = nlmsg_new(if_nlmsg_size(iw_buf_len), GFP_KERNEL);
+ nskb = nlmsg_new(if_nlmsg_size(), GFP_KERNEL);
if (nskb == NULL) {
err = -ENOBUFS;
goto errout;
}
- err = rtnl_fill_ifinfo(nskb, dev, iw, iw_buf_len, RTM_NEWLINK,
- NETLINK_CB(skb).pid, nlh->nlmsg_seq, 0, 0);
+ err = rtnl_fill_ifinfo(nskb, dev, RTM_NEWLINK, NETLINK_CB(skb).pid,
+ nlh->nlmsg_seq, 0, 0);
if (err < 0) {
/* -EMSGSIZE implies BUG in if_nlmsg_size */
WARN_ON(err == -EMSGSIZE);
@@ -762,7 +763,6 @@
}
err = rtnl_unicast(nskb, NETLINK_CB(skb).pid);
errout:
- kfree(iw_buf);
dev_put(dev);
return err;
@@ -797,11 +797,11 @@
struct sk_buff *skb;
int err = -ENOBUFS;
- skb = nlmsg_new(if_nlmsg_size(0), GFP_KERNEL);
+ skb = nlmsg_new(if_nlmsg_size(), GFP_KERNEL);
if (skb == NULL)
goto errout;
- err = rtnl_fill_ifinfo(skb, dev, NULL, 0, type, 0, 0, change, 0);
+ err = rtnl_fill_ifinfo(skb, dev, type, 0, 0, change, 0);
if (err < 0) {
/* -EMSGSIZE implies BUG in if_nlmsg_size() */
WARN_ON(err == -EMSGSIZE);
diff --git a/net/core/sock.c b/net/core/sock.c
index 22183c2..7e51d3a 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -206,7 +206,19 @@
return -EINVAL;
if (copy_from_user(&tv, optval, sizeof(tv)))
return -EFAULT;
+ if (tv.tv_usec < 0 || tv.tv_usec >= USEC_PER_SEC)
+ return -EDOM;
+ if (tv.tv_sec < 0) {
+ static int warned = 0;
+ *timeo_p = 0;
+ if (warned < 10 && net_ratelimit())
+ warned++;
+ printk(KERN_INFO "sock_set_timeout: `%s' (pid %d) "
+ "tries to set negative timeout\n",
+ current->comm, current->pid);
+ return 0;
+ }
*timeo_p = MAX_SCHEDULE_TIMEOUT;
if (tv.tv_sec == 0 && tv.tv_usec == 0)
return 0;
diff --git a/net/core/sysctl_net_core.c b/net/core/sysctl_net_core.c
index b297120..f34aca0 100644
--- a/net/core/sysctl_net_core.c
+++ b/net/core/sysctl_net_core.c
@@ -24,6 +24,7 @@
#ifdef CONFIG_XFRM
extern u32 sysctl_xfrm_aevent_etime;
extern u32 sysctl_xfrm_aevent_rseqth;
+extern int sysctl_xfrm_larval_drop;
#endif
ctl_table core_table[] = {
@@ -118,6 +119,14 @@
.mode = 0644,
.proc_handler = &proc_dointvec
},
+ {
+ .ctl_name = CTL_UNNUMBERED,
+ .procname = "xfrm_larval_drop",
+ .data = &sysctl_xfrm_larval_drop,
+ .maxlen = sizeof(int),
+ .mode = 0644,
+ .proc_handler = &proc_dointvec
+ },
#endif /* CONFIG_XFRM */
#endif /* CONFIG_NET */
{
diff --git a/net/dccp/Kconfig b/net/dccp/Kconfig
index b8a68dd..0549e47 100644
--- a/net/dccp/Kconfig
+++ b/net/dccp/Kconfig
@@ -1,8 +1,6 @@
-menu "DCCP Configuration (EXPERIMENTAL)"
- depends on INET && EXPERIMENTAL
-
-config IP_DCCP
+menuconfig IP_DCCP
tristate "The DCCP Protocol (EXPERIMENTAL)"
+ depends on INET && EXPERIMENTAL
---help---
Datagram Congestion Control Protocol (RFC 4340)
@@ -19,19 +17,20 @@
If in doubt, say N.
+if IP_DCCP
+
config INET_DCCP_DIAG
- depends on IP_DCCP && INET_DIAG
+ depends on INET_DIAG
def_tristate y if (IP_DCCP = y && INET_DIAG = y)
def_tristate m
config IP_DCCP_ACKVEC
- depends on IP_DCCP
bool
source "net/dccp/ccids/Kconfig"
menu "DCCP Kernel Hacking"
- depends on IP_DCCP && DEBUG_KERNEL=y
+ depends on DEBUG_KERNEL=y
config IP_DCCP_DEBUG
bool "DCCP debug messages"
@@ -61,4 +60,4 @@
endmenu
-endmenu
+endif # IP_DDCP
diff --git a/net/dccp/ccids/ccid3.c b/net/dccp/ccids/ccid3.c
index d7d9ce7..ec7fa4d 100644
--- a/net/dccp/ccids/ccid3.c
+++ b/net/dccp/ccids/ccid3.c
@@ -419,7 +419,6 @@
static void ccid3_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb)
{
- const struct dccp_sock *dp = dccp_sk(sk);
struct ccid3_hc_tx_sock *hctx = ccid3_hc_tx_sk(sk);
struct ccid3_options_received *opt_recv;
struct dccp_tx_hist_entry *packet;
@@ -491,7 +490,7 @@
ccid3_pr_debug("%s(%p), s=%u, MSS=%u, "
"R_sample=%uus, X=%u\n", dccp_role(sk),
sk, hctx->ccid3hctx_s,
- dp->dccps_mss_cache, r_sample,
+ dccp_sk(sk)->dccps_mss_cache, r_sample,
(unsigned)(hctx->ccid3hctx_x >> 6));
ccid3_hc_tx_set_state(sk, TFRC_SSTATE_FBACK);
diff --git a/net/dccp/ipv6.c b/net/dccp/ipv6.c
index 64eac25..31737cd 100644
--- a/net/dccp/ipv6.c
+++ b/net/dccp/ipv6.c
@@ -1043,9 +1043,13 @@
if (final_p)
ipv6_addr_copy(&fl.fl6_dst, final_p);
- err = xfrm_lookup(&dst, &fl, sk, 1);
- if (err < 0)
- goto failure;
+ err = __xfrm_lookup(&dst, &fl, sk, 1);
+ if (err < 0) {
+ if (err == -EREMOTE)
+ err = ip6_dst_blackhole(sk, &dst, &fl);
+ if (err < 0)
+ goto failure;
+ }
if (saddr == NULL) {
saddr = &fl.fl6_src;
diff --git a/net/ipv4/fib_hash.c b/net/ipv4/fib_hash.c
index 9cfecf1..07e843a 100644
--- a/net/ipv4/fib_hash.c
+++ b/net/ipv4/fib_hash.c
@@ -456,6 +456,8 @@
fib_release_info(fi_drop);
if (state & FA_S_ACCESSED)
rt_cache_flush(-1);
+ rtmsg_fib(RTM_NEWROUTE, key, fa, cfg->fc_dst_len, tb->tb_id,
+ &cfg->fc_nlinfo, NLM_F_REPLACE);
return 0;
}
@@ -523,7 +525,7 @@
rt_cache_flush(-1);
rtmsg_fib(RTM_NEWROUTE, key, new_fa, cfg->fc_dst_len, tb->tb_id,
- &cfg->fc_nlinfo);
+ &cfg->fc_nlinfo, 0);
return 0;
out_free_new_fa:
@@ -589,7 +591,7 @@
fa = fa_to_delete;
rtmsg_fib(RTM_DELROUTE, key, fa, cfg->fc_dst_len,
- tb->tb_id, &cfg->fc_nlinfo);
+ tb->tb_id, &cfg->fc_nlinfo, 0);
kill_fn = 0;
write_lock_bh(&fib_hash_lock);
diff --git a/net/ipv4/fib_lookup.h b/net/ipv4/fib_lookup.h
index 0e8b70b..eef9eec 100644
--- a/net/ipv4/fib_lookup.h
+++ b/net/ipv4/fib_lookup.h
@@ -30,7 +30,8 @@
int dst_len, u8 tos, struct fib_info *fi,
unsigned int);
extern void rtmsg_fib(int event, __be32 key, struct fib_alias *fa,
- int dst_len, u32 tb_id, struct nl_info *info);
+ int dst_len, u32 tb_id, struct nl_info *info,
+ unsigned int nlm_flags);
extern struct fib_alias *fib_find_alias(struct list_head *fah,
u8 tos, u32 prio);
extern int fib_detect_death(struct fib_info *fi, int order,
diff --git a/net/ipv4/fib_semantics.c b/net/ipv4/fib_semantics.c
index 406ea70..bb94550 100644
--- a/net/ipv4/fib_semantics.c
+++ b/net/ipv4/fib_semantics.c
@@ -301,7 +301,8 @@
}
void rtmsg_fib(int event, __be32 key, struct fib_alias *fa,
- int dst_len, u32 tb_id, struct nl_info *info)
+ int dst_len, u32 tb_id, struct nl_info *info,
+ unsigned int nlm_flags)
{
struct sk_buff *skb;
u32 seq = info->nlh ? info->nlh->nlmsg_seq : 0;
@@ -313,7 +314,7 @@
err = fib_dump_info(skb, info->pid, seq, event, tb_id,
fa->fa_type, fa->fa_scope, key, dst_len,
- fa->fa_tos, fa->fa_info, 0);
+ fa->fa_tos, fa->fa_info, nlm_flags);
if (err < 0) {
/* -EMSGSIZE implies BUG in fib_nlmsg_size() */
WARN_ON(err == -EMSGSIZE);
diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c
index 9be7da7..30e332a 100644
--- a/net/ipv4/fib_trie.c
+++ b/net/ipv4/fib_trie.c
@@ -1226,6 +1226,8 @@
fib_release_info(fi_drop);
if (state & FA_S_ACCESSED)
rt_cache_flush(-1);
+ rtmsg_fib(RTM_NEWROUTE, htonl(key), new_fa, plen,
+ tb->tb_id, &cfg->fc_nlinfo, NLM_F_REPLACE);
goto succeeded;
}
@@ -1278,7 +1280,7 @@
rt_cache_flush(-1);
rtmsg_fib(RTM_NEWROUTE, htonl(key), new_fa, plen, tb->tb_id,
- &cfg->fc_nlinfo);
+ &cfg->fc_nlinfo, 0);
succeeded:
return 0;
@@ -1624,7 +1626,7 @@
fa = fa_to_delete;
rtmsg_fib(RTM_DELROUTE, htonl(key), fa, plen, tb->tb_id,
- &cfg->fc_nlinfo);
+ &cfg->fc_nlinfo, 0);
l = fib_find_node(t, key);
li = find_leaf_info(l, plen);
diff --git a/net/ipv4/ipvs/Kconfig b/net/ipv4/ipvs/Kconfig
index 891b935..09d0c3f 100644
--- a/net/ipv4/ipvs/Kconfig
+++ b/net/ipv4/ipvs/Kconfig
@@ -1,10 +1,7 @@
#
# IP Virtual Server configuration
#
-menu "IP: Virtual Server Configuration"
- depends on NETFILTER
-
-config IP_VS
+menuconfig IP_VS
tristate "IP virtual server support (EXPERIMENTAL)"
depends on NETFILTER
---help---
@@ -25,9 +22,10 @@
If you want to compile it in kernel, say Y. To compile it as a
module, choose M here. If unsure, say N.
+if IP_VS
+
config IP_VS_DEBUG
bool "IP virtual server debugging"
- depends on IP_VS
---help---
Say Y here if you want to get additional messages useful in
debugging the IP virtual server code. You can change the debug
@@ -35,7 +33,6 @@
config IP_VS_TAB_BITS
int "IPVS connection table size (the Nth power of 2)"
- depends on IP_VS
default "12"
---help---
The IPVS connection hash table uses the chaining scheme to handle
@@ -61,42 +58,35 @@
needed for your box.
comment "IPVS transport protocol load balancing support"
- depends on IP_VS
config IP_VS_PROTO_TCP
bool "TCP load balancing support"
- depends on IP_VS
---help---
This option enables support for load balancing TCP transport
protocol. Say Y if unsure.
config IP_VS_PROTO_UDP
bool "UDP load balancing support"
- depends on IP_VS
---help---
This option enables support for load balancing UDP transport
protocol. Say Y if unsure.
config IP_VS_PROTO_ESP
bool "ESP load balancing support"
- depends on IP_VS
---help---
This option enables support for load balancing ESP (Encapsulation
Security Payload) transport protocol. Say Y if unsure.
config IP_VS_PROTO_AH
bool "AH load balancing support"
- depends on IP_VS
---help---
This option enables support for load balancing AH (Authentication
Header) transport protocol. Say Y if unsure.
comment "IPVS scheduler"
- depends on IP_VS
config IP_VS_RR
tristate "round-robin scheduling"
- depends on IP_VS
---help---
The robin-robin scheduling algorithm simply directs network
connections to different real servers in a round-robin manner.
@@ -106,7 +96,6 @@
config IP_VS_WRR
tristate "weighted round-robin scheduling"
- depends on IP_VS
---help---
The weighted robin-robin scheduling algorithm directs network
connections to different real servers based on server weights
@@ -120,7 +109,6 @@
config IP_VS_LC
tristate "least-connection scheduling"
- depends on IP_VS
---help---
The least-connection scheduling algorithm directs network
connections to the server with the least number of active
@@ -131,7 +119,6 @@
config IP_VS_WLC
tristate "weighted least-connection scheduling"
- depends on IP_VS
---help---
The weighted least-connection scheduling algorithm directs network
connections to the server with the least active connections
@@ -142,7 +129,6 @@
config IP_VS_LBLC
tristate "locality-based least-connection scheduling"
- depends on IP_VS
---help---
The locality-based least-connection scheduling algorithm is for
destination IP load balancing. It is usually used in cache cluster.
@@ -157,7 +143,6 @@
config IP_VS_LBLCR
tristate "locality-based least-connection with replication scheduling"
- depends on IP_VS
---help---
The locality-based least-connection with replication scheduling
algorithm is also for destination IP load balancing. It is
@@ -176,7 +161,6 @@
config IP_VS_DH
tristate "destination hashing scheduling"
- depends on IP_VS
---help---
The destination hashing scheduling algorithm assigns network
connections to the servers through looking up a statically assigned
@@ -187,7 +171,6 @@
config IP_VS_SH
tristate "source hashing scheduling"
- depends on IP_VS
---help---
The source hashing scheduling algorithm assigns network
connections to the servers through looking up a statically assigned
@@ -198,7 +181,6 @@
config IP_VS_SED
tristate "shortest expected delay scheduling"
- depends on IP_VS
---help---
The shortest expected delay scheduling algorithm assigns network
connections to the server with the shortest expected delay. The
@@ -212,7 +194,6 @@
config IP_VS_NQ
tristate "never queue scheduling"
- depends on IP_VS
---help---
The never queue scheduling algorithm adopts a two-speed model.
When there is an idle server available, the job will be sent to
@@ -225,11 +206,10 @@
module, choose M here. If unsure, say N.
comment 'IPVS application helper'
- depends on IP_VS
config IP_VS_FTP
tristate "FTP protocol helper"
- depends on IP_VS && IP_VS_PROTO_TCP
+ depends on IP_VS_PROTO_TCP
---help---
FTP is a protocol that transfers IP address and/or port number in
the payload. In the virtual server via Network Address Translation,
@@ -241,4 +221,4 @@
If you want to compile it in kernel, say Y. To compile it as a
module, choose M here. If unsure, say N.
-endmenu
+endif # IP_VS
diff --git a/net/ipv4/netfilter/nf_nat_ftp.c b/net/ipv4/netfilter/nf_nat_ftp.c
index 751b598..e6bc8e5 100644
--- a/net/ipv4/netfilter/nf_nat_ftp.c
+++ b/net/ipv4/netfilter/nf_nat_ftp.c
@@ -40,8 +40,7 @@
unsigned int matchoff,
unsigned int matchlen,
struct nf_conn *ct,
- enum ip_conntrack_info ctinfo,
- u32 *seq)
+ enum ip_conntrack_info ctinfo)
{
char buffer[sizeof("nnn,nnn,nnn,nnn,nnn,nnn")];
@@ -50,7 +49,6 @@
DEBUGP("calling nf_nat_mangle_tcp_packet\n");
- *seq += strlen(buffer) - matchlen;
return nf_nat_mangle_tcp_packet(pskb, ct, ctinfo, matchoff,
matchlen, buffer, strlen(buffer));
}
@@ -63,8 +61,7 @@
unsigned int matchoff,
unsigned int matchlen,
struct nf_conn *ct,
- enum ip_conntrack_info ctinfo,
- u32 *seq)
+ enum ip_conntrack_info ctinfo)
{
char buffer[sizeof("|1|255.255.255.255|65535|")];
@@ -72,7 +69,6 @@
DEBUGP("calling nf_nat_mangle_tcp_packet\n");
- *seq += strlen(buffer) - matchlen;
return nf_nat_mangle_tcp_packet(pskb, ct, ctinfo, matchoff,
matchlen, buffer, strlen(buffer));
}
@@ -85,8 +81,7 @@
unsigned int matchoff,
unsigned int matchlen,
struct nf_conn *ct,
- enum ip_conntrack_info ctinfo,
- u32 *seq)
+ enum ip_conntrack_info ctinfo)
{
char buffer[sizeof("|||65535|")];
@@ -94,14 +89,13 @@
DEBUGP("calling nf_nat_mangle_tcp_packet\n");
- *seq += strlen(buffer) - matchlen;
return nf_nat_mangle_tcp_packet(pskb, ct, ctinfo, matchoff,
matchlen, buffer, strlen(buffer));
}
static int (*mangle[])(struct sk_buff **, __be32, u_int16_t,
unsigned int, unsigned int, struct nf_conn *,
- enum ip_conntrack_info, u32 *seq)
+ enum ip_conntrack_info)
= {
[NF_CT_FTP_PORT] = mangle_rfc959_packet,
[NF_CT_FTP_PASV] = mangle_rfc959_packet,
@@ -116,8 +110,7 @@
enum nf_ct_ftp_type type,
unsigned int matchoff,
unsigned int matchlen,
- struct nf_conntrack_expect *exp,
- u32 *seq)
+ struct nf_conntrack_expect *exp)
{
__be32 newip;
u_int16_t port;
@@ -145,8 +138,7 @@
if (port == 0)
return NF_DROP;
- if (!mangle[type](pskb, newip, port, matchoff, matchlen, ct, ctinfo,
- seq)) {
+ if (!mangle[type](pskb, newip, port, matchoff, matchlen, ct, ctinfo)) {
nf_conntrack_unexpect_related(exp);
return NF_DROP;
}
diff --git a/net/ipv4/netfilter/nf_nat_h323.c b/net/ipv4/netfilter/nf_nat_h323.c
index fcebc96..c5d2a2d 100644
--- a/net/ipv4/netfilter/nf_nat_h323.c
+++ b/net/ipv4/netfilter/nf_nat_h323.c
@@ -455,9 +455,9 @@
if (idx > 0 &&
get_h225_addr(ct, *data, &taddr[0], &addr, &port) &&
(ntohl(addr.ip) & 0xff000000) == 0x7f000000) {
- set_h225_addr_hook(pskb, data, 0, &taddr[0],
- &ct->tuplehash[!dir].tuple.dst.u3,
- info->sig_port[!dir]);
+ set_h225_addr(pskb, data, 0, &taddr[0],
+ &ct->tuplehash[!dir].tuple.dst.u3,
+ info->sig_port[!dir]);
}
} else {
nf_conntrack_unexpect_related(exp);
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index df9fe4f..8603cfb 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -2598,6 +2598,69 @@
EXPORT_SYMBOL_GPL(__ip_route_output_key);
+static void ipv4_rt_blackhole_update_pmtu(struct dst_entry *dst, u32 mtu)
+{
+}
+
+static struct dst_ops ipv4_dst_blackhole_ops = {
+ .family = AF_INET,
+ .protocol = __constant_htons(ETH_P_IP),
+ .destroy = ipv4_dst_destroy,
+ .check = ipv4_dst_check,
+ .update_pmtu = ipv4_rt_blackhole_update_pmtu,
+ .entry_size = sizeof(struct rtable),
+};
+
+
+static int ipv4_blackhole_output(struct sk_buff *skb)
+{
+ kfree_skb(skb);
+ return 0;
+}
+
+static int ipv4_dst_blackhole(struct rtable **rp, struct flowi *flp, struct sock *sk)
+{
+ struct rtable *ort = *rp;
+ struct rtable *rt = (struct rtable *)
+ dst_alloc(&ipv4_dst_blackhole_ops);
+
+ if (rt) {
+ struct dst_entry *new = &rt->u.dst;
+
+ atomic_set(&new->__refcnt, 1);
+ new->__use = 1;
+ new->input = ipv4_blackhole_output;
+ new->output = ipv4_blackhole_output;
+ memcpy(new->metrics, ort->u.dst.metrics, RTAX_MAX*sizeof(u32));
+
+ new->dev = ort->u.dst.dev;
+ if (new->dev)
+ dev_hold(new->dev);
+
+ rt->fl = ort->fl;
+
+ rt->idev = ort->idev;
+ if (rt->idev)
+ in_dev_hold(rt->idev);
+ rt->rt_flags = ort->rt_flags;
+ rt->rt_type = ort->rt_type;
+ rt->rt_dst = ort->rt_dst;
+ rt->rt_src = ort->rt_src;
+ rt->rt_iif = ort->rt_iif;
+ rt->rt_gateway = ort->rt_gateway;
+ rt->rt_spec_dst = ort->rt_spec_dst;
+ rt->peer = ort->peer;
+ if (rt->peer)
+ atomic_inc(&rt->peer->refcnt);
+
+ dst_free(new);
+ }
+
+ dst_release(&(*rp)->u.dst);
+ *rp = rt;
+ return (rt ? 0 : -ENOMEM);
+}
+
int ip_route_output_flow(struct rtable **rp, struct flowi *flp, struct sock *sk, int flags)
{
int err;
@@ -2610,7 +2673,11 @@
flp->fl4_src = (*rp)->rt_src;
if (!flp->fl4_dst)
flp->fl4_dst = (*rp)->rt_dst;
- return xfrm_lookup((struct dst_entry **)rp, flp, sk, flags);
+ err = __xfrm_lookup((struct dst_entry **)rp, flp, sk, flags);
+ if (err == -EREMOTE)
+ err = ipv4_dst_blackhole(rp, flp, sk);
+
+ return err;
}
return 0;
@@ -3139,6 +3206,8 @@
kmem_cache_create("ip_dst_cache", sizeof(struct rtable), 0,
SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL, NULL);
+ ipv4_dst_blackhole_ops.kmem_cachep = ipv4_dst_ops.kmem_cachep;
+
rt_hash_table = (struct rt_hash_bucket *)
alloc_large_system_hash("IP route cache",
sizeof(struct rt_hash_bucket),
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index c7ea248..329de67 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -2154,15 +2154,6 @@
ASSERT_RTNL();
- if ((dev->type != ARPHRD_ETHER) &&
- (dev->type != ARPHRD_FDDI) &&
- (dev->type != ARPHRD_IEEE802_TR) &&
- (dev->type != ARPHRD_ARCNET) &&
- (dev->type != ARPHRD_INFINIBAND)) {
- /* Alas, we support only Ethernet autoconfiguration. */
- return;
- }
-
idev = addrconf_add_dev(dev);
if (idev == NULL)
return;
@@ -2250,13 +2241,33 @@
ip6_tnl_add_linklocal(idev);
}
+static int ipv6_hwtype(struct net_device *dev)
+{
+ if ((dev->type == ARPHRD_ETHER) ||
+ (dev->type == ARPHRD_LOOPBACK) ||
+ (dev->type == ARPHRD_SIT) ||
+ (dev->type == ARPHRD_TUNNEL6) ||
+ (dev->type == ARPHRD_FDDI) ||
+ (dev->type == ARPHRD_IEEE802_TR) ||
+ (dev->type == ARPHRD_ARCNET) ||
+ (dev->type == ARPHRD_INFINIBAND))
+ return 1;
+
+ return 0;
+}
+
static int addrconf_notify(struct notifier_block *this, unsigned long event,
void * data)
{
struct net_device *dev = (struct net_device *) data;
- struct inet6_dev *idev = __in6_dev_get(dev);
+ struct inet6_dev *idev;
int run_pending = 0;
+ if (!ipv6_hwtype(dev))
+ return NOTIFY_OK;
+
+ idev = __in6_dev_get(dev);
+
switch(event) {
case NETDEV_REGISTER:
if (!idev) {
diff --git a/net/ipv6/datagram.c b/net/ipv6/datagram.c
index 403eee6..b1fe7ac 100644
--- a/net/ipv6/datagram.c
+++ b/net/ipv6/datagram.c
@@ -177,8 +177,12 @@
if (final_p)
ipv6_addr_copy(&fl.fl6_dst, final_p);
- if ((err = xfrm_lookup(&dst, &fl, sk, 1)) < 0)
- goto out;
+ if ((err = __xfrm_lookup(&dst, &fl, sk, 1)) < 0) {
+ if (err == -EREMOTE)
+ err = ip6_dst_blackhole(sk, &dst, &fl);
+ if (err < 0)
+ goto out;
+ }
/* source address lookup done in ip6_dst_lookup */
diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c
index 009a104..a58459a 100644
--- a/net/ipv6/raw.c
+++ b/net/ipv6/raw.c
@@ -818,8 +818,12 @@
if (final_p)
ipv6_addr_copy(&fl.fl6_dst, final_p);
- if ((err = xfrm_lookup(&dst, &fl, sk, 1)) < 0)
- goto out;
+ if ((err = __xfrm_lookup(&dst, &fl, sk, 1)) < 0) {
+ if (err == -EREMOTE)
+ err = ip6_dst_blackhole(sk, &dst, &fl);
+ if (err < 0)
+ goto out;
+ }
if (hlimit < 0) {
if (ipv6_addr_is_multicast(&fl.fl6_dst))
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index b46ad53..1324b06 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -119,6 +119,19 @@
.entry_size = sizeof(struct rt6_info),
};
+static void ip6_rt_blackhole_update_pmtu(struct dst_entry *dst, u32 mtu)
+{
+}
+
+static struct dst_ops ip6_dst_blackhole_ops = {
+ .family = AF_INET6,
+ .protocol = __constant_htons(ETH_P_IPV6),
+ .destroy = ip6_dst_destroy,
+ .check = ip6_dst_check,
+ .update_pmtu = ip6_rt_blackhole_update_pmtu,
+ .entry_size = sizeof(struct rt6_info),
+};
+
struct rt6_info ip6_null_entry = {
.u = {
.dst = {
@@ -833,6 +846,54 @@
EXPORT_SYMBOL(ip6_route_output);
+static int ip6_blackhole_output(struct sk_buff *skb)
+{
+ kfree_skb(skb);
+ return 0;
+}
+
+int ip6_dst_blackhole(struct sock *sk, struct dst_entry **dstp, struct flowi *fl)
+{
+ struct rt6_info *ort = (struct rt6_info *) *dstp;
+ struct rt6_info *rt = (struct rt6_info *)
+ dst_alloc(&ip6_dst_blackhole_ops);
+ struct dst_entry *new = NULL;
+
+ if (rt) {
+ new = &rt->u.dst;
+
+ atomic_set(&new->__refcnt, 1);
+ new->__use = 1;
+ new->input = ip6_blackhole_output;
+ new->output = ip6_blackhole_output;
+
+ memcpy(new->metrics, ort->u.dst.metrics, RTAX_MAX*sizeof(u32));
+ new->dev = ort->u.dst.dev;
+ if (new->dev)
+ dev_hold(new->dev);
+ rt->rt6i_idev = ort->rt6i_idev;
+ if (rt->rt6i_idev)
+ in6_dev_hold(rt->rt6i_idev);
+ rt->rt6i_expires = 0;
+
+ ipv6_addr_copy(&rt->rt6i_gateway, &ort->rt6i_gateway);
+ rt->rt6i_flags = ort->rt6i_flags & ~RTF_EXPIRES;
+ rt->rt6i_metric = 0;
+
+ memcpy(&rt->rt6i_dst, &ort->rt6i_dst, sizeof(struct rt6key));
+#ifdef CONFIG_IPV6_SUBTREES
+ memcpy(&rt->rt6i_src, &ort->rt6i_src, sizeof(struct rt6key));
+#endif
+
+ dst_free(new);
+ }
+
+ dst_release(*dstp);
+ *dstp = new;
+ return (new ? 0 : -ENOMEM);
+}
+EXPORT_SYMBOL_GPL(ip6_dst_blackhole);
+
/*
* Destination cache support functions
*/
@@ -2495,6 +2556,8 @@
ip6_dst_ops.kmem_cachep =
kmem_cache_create("ip6_dst_cache", sizeof(struct rt6_info), 0,
SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL, NULL);
+ ip6_dst_blackhole_ops.kmem_cachep = ip6_dst_ops.kmem_cachep;
+
fib6_init();
#ifdef CONFIG_PROC_FS
p = proc_net_create("ipv6_route", 0, rt6_proc_info);
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
index e2f25ea..4f06a51 100644
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -265,8 +265,12 @@
if (final_p)
ipv6_addr_copy(&fl.fl6_dst, final_p);
- if ((err = xfrm_lookup(&dst, &fl, sk, 1)) < 0)
- goto failure;
+ if ((err = __xfrm_lookup(&dst, &fl, sk, 1)) < 0) {
+ if (err == -EREMOTE)
+ err = ip6_dst_blackhole(sk, &dst, &fl);
+ if (err < 0)
+ goto failure;
+ }
if (saddr == NULL) {
saddr = &fl.fl6_src;
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
index a7ae59c..d1fbddd 100644
--- a/net/ipv6/udp.c
+++ b/net/ipv6/udp.c
@@ -767,8 +767,12 @@
if (final_p)
ipv6_addr_copy(&fl.fl6_dst, final_p);
- if ((err = xfrm_lookup(&dst, &fl, sk, 1)) < 0)
- goto out;
+ if ((err = __xfrm_lookup(&dst, &fl, sk, 1)) < 0) {
+ if (err == -EREMOTE)
+ err = ip6_dst_blackhole(sk, &dst, &fl);
+ if (err < 0)
+ goto out;
+ }
if (hlimit < 0) {
if (ipv6_addr_is_multicast(&fl.fl6_dst))
diff --git a/net/netfilter/nf_conntrack_ftp.c b/net/netfilter/nf_conntrack_ftp.c
index a186799..82db2aa 100644
--- a/net/netfilter/nf_conntrack_ftp.c
+++ b/net/netfilter/nf_conntrack_ftp.c
@@ -48,8 +48,7 @@
enum nf_ct_ftp_type type,
unsigned int matchoff,
unsigned int matchlen,
- struct nf_conntrack_expect *exp,
- u32 *seq);
+ struct nf_conntrack_expect *exp);
EXPORT_SYMBOL_GPL(nf_nat_ftp_hook);
#if 0
@@ -335,15 +334,17 @@
if (info->seq_aft_nl[dir][i] == nl_seq)
return;
- if (oldest == info->seq_aft_nl_num[dir]
- || before(info->seq_aft_nl[dir][i], oldest))
+ if (oldest == info->seq_aft_nl_num[dir] ||
+ before(info->seq_aft_nl[dir][i],
+ info->seq_aft_nl[dir][oldest]))
oldest = i;
}
if (info->seq_aft_nl_num[dir] < NUM_SEQ_TO_REMEMBER) {
info->seq_aft_nl[dir][info->seq_aft_nl_num[dir]++] = nl_seq;
nf_conntrack_event_cache(IPCT_HELPINFO_VOLATILE, skb);
- } else if (oldest != NUM_SEQ_TO_REMEMBER) {
+ } else if (oldest != NUM_SEQ_TO_REMEMBER &&
+ after(nl_seq, info->seq_aft_nl[dir][oldest])) {
info->seq_aft_nl[dir][oldest] = nl_seq;
nf_conntrack_event_cache(IPCT_HELPINFO_VOLATILE, skb);
}
@@ -519,7 +520,7 @@
nf_nat_ftp = rcu_dereference(nf_nat_ftp_hook);
if (nf_nat_ftp && ct->status & IPS_NAT_MASK)
ret = nf_nat_ftp(pskb, ctinfo, search[dir][i].ftptype,
- matchoff, matchlen, exp, &seq);
+ matchoff, matchlen, exp);
else {
/* Can't expect this? Best to drop packet now. */
if (nf_conntrack_expect_related(exp) != 0)
diff --git a/net/netfilter/nf_conntrack_h323_main.c b/net/netfilter/nf_conntrack_h323_main.c
index b284db7..a1b95ac 100644
--- a/net/netfilter/nf_conntrack_h323_main.c
+++ b/net/netfilter/nf_conntrack_h323_main.c
@@ -520,6 +520,16 @@
}
}
+ if ((olca->options & eOpenLogicalChannelAck_separateStack) &&
+ olca->separateStack.networkAddress.choice ==
+ eNetworkAccessParameters_networkAddress_localAreaAddress) {
+ ret = expect_t120(pskb, ct, ctinfo, data, dataoff,
+ &olca->separateStack.networkAddress.
+ localAreaAddress);
+ if (ret < 0)
+ return -1;
+ }
+
return 0;
}
@@ -640,7 +650,7 @@
case eTransportAddress_ip6Address:
if (family != AF_INET6)
return 0;
- p = data + taddr->ip6Address.ip6;
+ p = data + taddr->ip6Address.ip;
len = 16;
break;
default:
@@ -977,30 +987,6 @@
}
/****************************************************************************/
-static int process_information(struct sk_buff **pskb,
- struct nf_conn *ct,
- enum ip_conntrack_info ctinfo,
- unsigned char **data, int dataoff,
- Information_UUIE *info)
-{
- int ret;
- int i;
-
- DEBUGP("nf_ct_q931: Information\n");
-
- if (info->options & eInformation_UUIE_fastStart) {
- for (i = 0; i < info->fastStart.count; i++) {
- ret = process_olc(pskb, ct, ctinfo, data, dataoff,
- &info->fastStart.item[i]);
- if (ret < 0)
- return -1;
- }
- }
-
- return 0;
-}
-
-/****************************************************************************/
static int process_facility(struct sk_buff **pskb, struct nf_conn *ct,
enum ip_conntrack_info ctinfo,
unsigned char **data, int dataoff,
@@ -1096,11 +1082,6 @@
ret = process_alerting(pskb, ct, ctinfo, data, dataoff,
&pdu->h323_message_body.alerting);
break;
- case eH323_UU_PDU_h323_message_body_information:
- ret = process_information(pskb, ct, ctinfo, data, dataoff,
- &pdu->h323_message_body.
- information);
- break;
case eH323_UU_PDU_h323_message_body_facility:
ret = process_facility(pskb, ct, ctinfo, data, dataoff,
&pdu->h323_message_body.facility);
diff --git a/net/netfilter/nf_conntrack_h323_types.c b/net/netfilter/nf_conntrack_h323_types.c
index 4c6f8b3..3a21fdf 100644
--- a/net/netfilter/nf_conntrack_h323_types.c
+++ b/net/netfilter/nf_conntrack_h323_types.c
@@ -1,4 +1,4 @@
-/* Generated by Jing Min Zhao's ASN.1 parser, Apr 20 2006
+/* Generated by Jing Min Zhao's ASN.1 parser, May 16 2007
*
* Copyright (c) 2006 Jing Min Zhao <zhaojingmin@users.sourceforge.net>
*
@@ -37,7 +37,7 @@
static field_t _TransportAddress_ip6Address[] = { /* SEQUENCE */
{FNAME("ip") OCTSTR, FIXD, 16, 0, DECODE,
- offsetof(TransportAddress_ip6Address, ip6), NULL},
+ offsetof(TransportAddress_ip6Address, ip), NULL},
{FNAME("port") INT, WORD, 0, 0, SKIP, 0, NULL},
};
@@ -67,7 +67,8 @@
{FNAME("ipxAddress") SEQ, 0, 3, 3, SKIP, 0,
_TransportAddress_ipxAddress},
{FNAME("ip6Address") SEQ, 0, 2, 2, DECODE | EXT,
- offsetof(TransportAddress, ip6Address), _TransportAddress_ip6Address},
+ offsetof(TransportAddress, ip6Address),
+ _TransportAddress_ip6Address},
{FNAME("netBios") OCTSTR, FIXD, 16, 0, SKIP, 0, NULL},
{FNAME("nsap") OCTSTR, 5, 1, 0, SKIP, 0, NULL},
{FNAME("nonStandardAddress") SEQ, 0, 2, 2, SKIP, 0,
@@ -638,7 +639,8 @@
};
static field_t _UnicastAddress_iP6Address[] = { /* SEQUENCE */
- {FNAME("network") OCTSTR, FIXD, 16, 0, SKIP, 0, NULL},
+ {FNAME("network") OCTSTR, FIXD, 16, 0, DECODE,
+ offsetof(UnicastAddress_iP6Address, network), NULL},
{FNAME("tsapIdentifier") INT, WORD, 0, 0, SKIP, 0, NULL},
};
@@ -665,8 +667,8 @@
offsetof(UnicastAddress, iPAddress), _UnicastAddress_iPAddress},
{FNAME("iPXAddress") SEQ, 0, 3, 3, SKIP | EXT, 0,
_UnicastAddress_iPXAddress},
- {FNAME("iP6Address") SEQ, 0, 2, 2, SKIP | EXT, 0,
- _UnicastAddress_iP6Address},
+ {FNAME("iP6Address") SEQ, 0, 2, 2, DECODE | EXT,
+ offsetof(UnicastAddress, iP6Address), _UnicastAddress_iP6Address},
{FNAME("netBios") OCTSTR, FIXD, 16, 0, SKIP, 0, NULL},
{FNAME("iPSourceRouteAddress") SEQ, 0, 4, 4, SKIP | EXT, 0,
_UnicastAddress_iPSourceRouteAddress},
@@ -984,19 +986,12 @@
{FNAME("featureSet") SEQ, 3, 4, 4, SKIP | EXT | OPT, 0, NULL},
};
-static field_t _Information_UUIE_fastStart[] = { /* SEQUENCE OF */
- {FNAME("item") SEQ, 1, 3, 5, DECODE | OPEN | EXT,
- sizeof(OpenLogicalChannel), _OpenLogicalChannel}
- ,
-};
-
static field_t _Information_UUIE[] = { /* SEQUENCE */
{FNAME("protocolIdentifier") OID, BYTE, 0, 0, SKIP, 0, NULL},
{FNAME("callIdentifier") SEQ, 0, 1, 1, SKIP | EXT, 0, NULL},
{FNAME("tokens") SEQOF, SEMI, 0, 0, SKIP | OPT, 0, NULL},
{FNAME("cryptoTokens") SEQOF, SEMI, 0, 0, SKIP | OPT, 0, NULL},
- {FNAME("fastStart") SEQOF, SEMI, 0, 30, DECODE | OPT,
- offsetof(Information_UUIE, fastStart), _Information_UUIE_fastStart},
+ {FNAME("fastStart") SEQOF, SEMI, 0, 30, SKIP | OPT, 0, NULL},
{FNAME("fastConnectRefused") NUL, FIXD, 0, 0, SKIP | OPT, 0, NULL},
{FNAME("circuitInfo") SEQ, 3, 3, 3, SKIP | EXT | OPT, 0, NULL},
};
@@ -1343,9 +1338,7 @@
offsetof(H323_UU_PDU_h323_message_body, connect), _Connect_UUIE},
{FNAME("alerting") SEQ, 1, 3, 17, DECODE | EXT,
offsetof(H323_UU_PDU_h323_message_body, alerting), _Alerting_UUIE},
- {FNAME("information") SEQ, 0, 1, 7, DECODE | EXT,
- offsetof(H323_UU_PDU_h323_message_body, information),
- _Information_UUIE},
+ {FNAME("information") SEQ, 0, 1, 7, SKIP | EXT, 0, _Information_UUIE},
{FNAME("releaseComplete") SEQ, 1, 2, 11, SKIP | EXT, 0,
_ReleaseComplete_UUIE},
{FNAME("facility") SEQ, 3, 5, 21, DECODE | EXT,
@@ -1430,7 +1423,9 @@
DECODE | EXT | OPT, offsetof(OpenLogicalChannelAck,
reverseLogicalChannelParameters),
_OpenLogicalChannelAck_reverseLogicalChannelParameters},
- {FNAME("separateStack") SEQ, 2, 4, 5, SKIP | EXT | OPT, 0, NULL},
+ {FNAME("separateStack") SEQ, 2, 4, 5, DECODE | EXT | OPT,
+ offsetof(OpenLogicalChannelAck, separateStack),
+ _NetworkAccessParameters},
{FNAME("forwardMultiplexAckParameters") CHOICE, 0, 1, 1,
DECODE | EXT | OPT, offsetof(OpenLogicalChannelAck,
forwardMultiplexAckParameters),
diff --git a/net/rxrpc/Kconfig b/net/rxrpc/Kconfig
index 91b3d52..e662f1d 100644
--- a/net/rxrpc/Kconfig
+++ b/net/rxrpc/Kconfig
@@ -4,7 +4,7 @@
config AF_RXRPC
tristate "RxRPC session sockets"
- depends on EXPERIMENTAL
+ depends on INET && EXPERIMENTAL
select KEYS
help
Say Y or M here to include support for RxRPC session sockets (just
diff --git a/net/rxrpc/ar-call.c b/net/rxrpc/ar-call.c
index 4d92d88..3c04b00 100644
--- a/net/rxrpc/ar-call.c
+++ b/net/rxrpc/ar-call.c
@@ -15,6 +15,25 @@
#include <net/af_rxrpc.h>
#include "ar-internal.h"
+const char *rxrpc_call_states[] = {
+ [RXRPC_CALL_CLIENT_SEND_REQUEST] = "ClSndReq",
+ [RXRPC_CALL_CLIENT_AWAIT_REPLY] = "ClAwtRpl",
+ [RXRPC_CALL_CLIENT_RECV_REPLY] = "ClRcvRpl",
+ [RXRPC_CALL_CLIENT_FINAL_ACK] = "ClFnlACK",
+ [RXRPC_CALL_SERVER_SECURING] = "SvSecure",
+ [RXRPC_CALL_SERVER_ACCEPTING] = "SvAccept",
+ [RXRPC_CALL_SERVER_RECV_REQUEST] = "SvRcvReq",
+ [RXRPC_CALL_SERVER_ACK_REQUEST] = "SvAckReq",
+ [RXRPC_CALL_SERVER_SEND_REPLY] = "SvSndRpl",
+ [RXRPC_CALL_SERVER_AWAIT_ACK] = "SvAwtACK",
+ [RXRPC_CALL_COMPLETE] = "Complete",
+ [RXRPC_CALL_SERVER_BUSY] = "SvBusy ",
+ [RXRPC_CALL_REMOTELY_ABORTED] = "RmtAbort",
+ [RXRPC_CALL_LOCALLY_ABORTED] = "LocAbort",
+ [RXRPC_CALL_NETWORK_ERROR] = "NetError",
+ [RXRPC_CALL_DEAD] = "Dead ",
+};
+
struct kmem_cache *rxrpc_call_jar;
LIST_HEAD(rxrpc_calls);
DEFINE_RWLOCK(rxrpc_call_lock);
diff --git a/net/rxrpc/ar-proc.c b/net/rxrpc/ar-proc.c
index 58f4b4e..1c0be0e 100644
--- a/net/rxrpc/ar-proc.c
+++ b/net/rxrpc/ar-proc.c
@@ -25,25 +25,6 @@
[RXRPC_CONN_NETWORK_ERROR] = "NetError",
};
-const char *rxrpc_call_states[] = {
- [RXRPC_CALL_CLIENT_SEND_REQUEST] = "ClSndReq",
- [RXRPC_CALL_CLIENT_AWAIT_REPLY] = "ClAwtRpl",
- [RXRPC_CALL_CLIENT_RECV_REPLY] = "ClRcvRpl",
- [RXRPC_CALL_CLIENT_FINAL_ACK] = "ClFnlACK",
- [RXRPC_CALL_SERVER_SECURING] = "SvSecure",
- [RXRPC_CALL_SERVER_ACCEPTING] = "SvAccept",
- [RXRPC_CALL_SERVER_RECV_REQUEST] = "SvRcvReq",
- [RXRPC_CALL_SERVER_ACK_REQUEST] = "SvAckReq",
- [RXRPC_CALL_SERVER_SEND_REPLY] = "SvSndRpl",
- [RXRPC_CALL_SERVER_AWAIT_ACK] = "SvAwtACK",
- [RXRPC_CALL_COMPLETE] = "Complete",
- [RXRPC_CALL_SERVER_BUSY] = "SvBusy ",
- [RXRPC_CALL_REMOTELY_ABORTED] = "RmtAbort",
- [RXRPC_CALL_LOCALLY_ABORTED] = "LocAbort",
- [RXRPC_CALL_NETWORK_ERROR] = "NetError",
- [RXRPC_CALL_DEAD] = "Dead ",
-};
-
/*
* generate a list of extant and dead calls in /proc/net/rxrpc_calls
*/
diff --git a/net/sched/sch_generic.c b/net/sched/sch_generic.c
index f28bb2d..cbefe22 100644
--- a/net/sched/sch_generic.c
+++ b/net/sched/sch_generic.c
@@ -169,8 +169,8 @@
else
q->ops->requeue(skb, q);
netif_schedule(dev);
- return 0;
}
+ return 0;
out:
BUG_ON((int) q->q.qlen < 0);
diff --git a/net/sched/sch_htb.c b/net/sched/sch_htb.c
index 99bcec8..035788c 100644
--- a/net/sched/sch_htb.c
+++ b/net/sched/sch_htb.c
@@ -976,8 +976,9 @@
if (q->now >= q->near_ev_cache[level]) {
event = htb_do_events(q, level);
- q->near_ev_cache[level] = event ? event :
- PSCHED_TICKS_PER_SEC;
+ if (!event)
+ event = q->now + PSCHED_TICKS_PER_SEC;
+ q->near_ev_cache[level] = event;
} else
event = q->near_ev_cache[level];
diff --git a/net/sctp/Kconfig b/net/sctp/Kconfig
index 9cba49e..8210f54 100644
--- a/net/sctp/Kconfig
+++ b/net/sctp/Kconfig
@@ -2,11 +2,9 @@
# SCTP configuration
#
-menu "SCTP Configuration (EXPERIMENTAL)"
- depends on INET && EXPERIMENTAL
-
-config IP_SCTP
+menuconfig IP_SCTP
tristate "The SCTP Protocol (EXPERIMENTAL)"
+ depends on INET && EXPERIMENTAL
depends on IPV6 || IPV6=n
select CRYPTO if SCTP_HMAC_SHA1 || SCTP_HMAC_MD5
select CRYPTO_HMAC if SCTP_HMAC_SHA1 || SCTP_HMAC_MD5
@@ -36,9 +34,10 @@
If in doubt, say N.
+if IP_SCTP
+
config SCTP_DBG_MSG
bool "SCTP: Debug messages"
- depends on IP_SCTP
help
If you say Y, this will enable verbose debugging messages.
@@ -47,7 +46,6 @@
config SCTP_DBG_OBJCNT
bool "SCTP: Debug object counts"
- depends on IP_SCTP
help
If you say Y, this will enable debugging support for counting the
type of objects that are currently allocated. This is useful for
@@ -59,7 +57,6 @@
choice
prompt "SCTP: Cookie HMAC Algorithm"
- depends on IP_SCTP
default SCTP_HMAC_MD5
help
HMAC algorithm to be used during association initialization. It
@@ -86,4 +83,5 @@
advised to use either HMAC-MD5 or HMAC-SHA1.
endchoice
-endmenu
+
+endif # IP_SCTP
diff --git a/net/tipc/Kconfig b/net/tipc/Kconfig
index f9e367d..3b30d11 100644
--- a/net/tipc/Kconfig
+++ b/net/tipc/Kconfig
@@ -2,11 +2,9 @@
# TIPC configuration
#
-menu "TIPC Configuration (EXPERIMENTAL)"
- depends on INET && EXPERIMENTAL
-
-config TIPC
+menuconfig TIPC
tristate "The TIPC Protocol (EXPERIMENTAL)"
+ depends on INET && EXPERIMENTAL
---help---
The Transparent Inter Process Communication (TIPC) protocol is
specially designed for intra cluster communication. This protocol
@@ -22,9 +20,10 @@
If in doubt, say N.
+if TIPC
+
config TIPC_ADVANCED
bool "TIPC: Advanced configuration"
- depends on TIPC
default n
help
Saying Y here will open some advanced configuration
@@ -33,7 +32,7 @@
config TIPC_ZONES
int "Maximum number of zones in network"
- depends on TIPC && TIPC_ADVANCED
+ depends on TIPC_ADVANCED
default "3"
help
Max number of zones inside TIPC network. Max supported value
@@ -44,7 +43,7 @@
config TIPC_CLUSTERS
int "Maximum number of clusters in a zone"
- depends on TIPC && TIPC_ADVANCED
+ depends on TIPC_ADVANCED
default "1"
help
***Only 1 (one cluster in a zone) is supported by current code.
@@ -59,7 +58,7 @@
config TIPC_NODES
int "Maximum number of nodes in cluster"
- depends on TIPC && TIPC_ADVANCED
+ depends on TIPC_ADVANCED
default "255"
help
Maximum number of nodes inside a TIPC cluster. Maximum
@@ -70,7 +69,7 @@
config TIPC_SLAVE_NODES
int "Maximum number of slave nodes in cluster"
- depends on TIPC && TIPC_ADVANCED
+ depends on TIPC_ADVANCED
default "0"
help
***This capability is not supported by current code.***
@@ -83,7 +82,7 @@
config TIPC_PORTS
int "Maximum number of ports in a node"
- depends on TIPC && TIPC_ADVANCED
+ depends on TIPC_ADVANCED
default "8191"
help
Maximum number of ports within a node. Maximum
@@ -94,7 +93,7 @@
config TIPC_LOG
int "Size of log buffer"
- depends on TIPC && TIPC_ADVANCED
+ depends on TIPC_ADVANCED
default 0
help
Size (in bytes) of TIPC's internal log buffer, which records the
@@ -106,7 +105,6 @@
config TIPC_DEBUG
bool "Enable debugging support"
- depends on TIPC
default n
help
This will enable debugging of TIPC.
@@ -114,4 +112,4 @@
Only say Y here if you are having trouble with TIPC. It will
enable the display of detailed information about what is going on.
-endmenu
+endif # TIPC
diff --git a/net/tipc/eth_media.c b/net/tipc/eth_media.c
index 0ee6ded..77d2d9c 100644
--- a/net/tipc/eth_media.c
+++ b/net/tipc/eth_media.c
@@ -120,18 +120,20 @@
static int enable_bearer(struct tipc_bearer *tb_ptr)
{
- struct net_device *dev, *pdev;
+ struct net_device *dev = NULL;
+ struct net_device *pdev = NULL;
struct eth_bearer *eb_ptr = ð_bearers[0];
struct eth_bearer *stop = ð_bearers[MAX_ETH_BEARERS];
char *driver_name = strchr((const char *)tb_ptr->name, ':') + 1;
/* Find device with specified name */
- dev = NULL;
- for_each_netdev(pdev)
- if (!strncmp(dev->name, driver_name, IFNAMSIZ)) {
+
+ for_each_netdev(pdev){
+ if (!strncmp(pdev->name, driver_name, IFNAMSIZ)) {
dev = pdev;
break;
}
+ }
if (!dev)
return -ENODEV;
diff --git a/net/xfrm/xfrm_algo.c b/net/xfrm/xfrm_algo.c
index 8a72def..5ced62c 100644
--- a/net/xfrm/xfrm_algo.c
+++ b/net/xfrm/xfrm_algo.c
@@ -407,27 +407,27 @@
static int xfrm_alg_id_match(const struct xfrm_algo_desc *entry,
const void *data)
{
- return entry->desc.sadb_alg_id == (int)data;
+ return entry->desc.sadb_alg_id == (unsigned long)data;
}
struct xfrm_algo_desc *xfrm_aalg_get_byid(int alg_id)
{
return xfrm_find_algo(&xfrm_aalg_list, xfrm_alg_id_match,
- (void *)alg_id, 1);
+ (void *)(unsigned long)alg_id, 1);
}
EXPORT_SYMBOL_GPL(xfrm_aalg_get_byid);
struct xfrm_algo_desc *xfrm_ealg_get_byid(int alg_id)
{
return xfrm_find_algo(&xfrm_ealg_list, xfrm_alg_id_match,
- (void *)alg_id, 1);
+ (void *)(unsigned long)alg_id, 1);
}
EXPORT_SYMBOL_GPL(xfrm_ealg_get_byid);
struct xfrm_algo_desc *xfrm_calg_get_byid(int alg_id)
{
return xfrm_find_algo(&xfrm_calg_list, xfrm_alg_id_match,
- (void *)alg_id, 1);
+ (void *)(unsigned long)alg_id, 1);
}
EXPORT_SYMBOL_GPL(xfrm_calg_get_byid);
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
index d0882e5..b8bab89 100644
--- a/net/xfrm/xfrm_policy.c
+++ b/net/xfrm/xfrm_policy.c
@@ -29,6 +29,8 @@
#include "xfrm_hash.h"
+int sysctl_xfrm_larval_drop;
+
DEFINE_MUTEX(xfrm_cfg_mutex);
EXPORT_SYMBOL(xfrm_cfg_mutex);
@@ -1390,8 +1392,8 @@
* At the moment we eat a raw IP route. Mostly to speed up lookups
* on interfaces with disabled IPsec.
*/
-int xfrm_lookup(struct dst_entry **dst_p, struct flowi *fl,
- struct sock *sk, int flags)
+int __xfrm_lookup(struct dst_entry **dst_p, struct flowi *fl,
+ struct sock *sk, int flags)
{
struct xfrm_policy *policy;
struct xfrm_policy *pols[XFRM_POLICY_TYPE_MAX];
@@ -1509,6 +1511,13 @@
if (unlikely(nx<0)) {
err = nx;
+ if (err == -EAGAIN && sysctl_xfrm_larval_drop) {
+ /* EREMOTE tells the caller to generate
+ * a one-shot blackhole route.
+ */
+ xfrm_pol_put(policy);
+ return -EREMOTE;
+ }
if (err == -EAGAIN && flags) {
DECLARE_WAITQUEUE(wait, current);
@@ -1598,6 +1607,21 @@
*dst_p = NULL;
return err;
}
+EXPORT_SYMBOL(__xfrm_lookup);
+
+int xfrm_lookup(struct dst_entry **dst_p, struct flowi *fl,
+ struct sock *sk, int flags)
+{
+ int err = __xfrm_lookup(dst_p, fl, sk, flags);
+
+ if (err == -EREMOTE) {
+ dst_release(*dst_p);
+ *dst_p = NULL;
+ err = -EAGAIN;
+ }
+
+ return err;
+}
EXPORT_SYMBOL(xfrm_lookup);
static inline int