Merge branch 'agp-patches' of git://git.kernel.org/pub/scm/linux/kernel/git/airlied/agp-2.6
* 'agp-patches' of git://git.kernel.org/pub/scm/linux/kernel/git/airlied/agp-2.6:
agp: balance ioremap checks
agp: Add device id for P4M900 to via-agp module
efficeon-agp leaks 'struct agp_bridge_data' in error paths of agp_efficeon_probe()
diff --git a/Documentation/DocBook/deviceiobook.tmpl b/Documentation/DocBook/deviceiobook.tmpl
index 90ed23d..c917de6 100644
--- a/Documentation/DocBook/deviceiobook.tmpl
+++ b/Documentation/DocBook/deviceiobook.tmpl
@@ -316,7 +316,8 @@
<chapter id="pubfunctions">
<title>Public Functions Provided</title>
-!Einclude/asm-i386/io.h
+!Iinclude/asm-i386/io.h
+!Elib/iomap.c
</chapter>
</book>
diff --git a/Documentation/DocBook/uio-howto.tmpl b/Documentation/DocBook/uio-howto.tmpl
index e3bb29a..c119484 100644
--- a/Documentation/DocBook/uio-howto.tmpl
+++ b/Documentation/DocBook/uio-howto.tmpl
@@ -133,10 +133,6 @@
<para>updates of your driver can take place without recompiling
the kernel.</para>
</listitem>
-<listitem>
- <para>if you need to keep some parts of your driver closed source,
- you can do so without violating the GPL license on the kernel.</para>
-</listitem>
</itemizedlist>
<sect1 id="how_uio_works">
diff --git a/Documentation/HOWTO b/Documentation/HOWTO
index f8cc3f8..c64e969 100644
--- a/Documentation/HOWTO
+++ b/Documentation/HOWTO
@@ -208,7 +208,7 @@
Cross-Reference project, which is able to present source code in a
self-referential, indexed webpage format. An excellent up-to-date
repository of the kernel code may be found at:
- http://sosdg.org/~coywolf/lxr/
+ http://users.sosdg.org/~qiyong/lxr/
The development process
@@ -384,7 +384,7 @@
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 earn merit amongst the developers, because
+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.
diff --git a/Documentation/SubmittingPatches b/Documentation/SubmittingPatches
index d6b45a9..3975758 100644
--- a/Documentation/SubmittingPatches
+++ b/Documentation/SubmittingPatches
@@ -560,7 +560,7 @@
<http://marc.theaimsgroup.com/?l=linux-kernel&m=112112749912944&w=2>
Kernel Documentation/CodingStyle:
- <http://sosdg.org/~coywolf/lxr/source/Documentation/CodingStyle>
+ <http://users.sosdg.org/~qiyong/lxr/source/Documentation/CodingStyle>
Linus Torvalds's mail on the canonical patch format:
<http://lkml.org/lkml/2005/4/7/183>
diff --git a/Documentation/accounting/getdelays.c b/Documentation/accounting/getdelays.c
index 24c5aad..cbee3a2 100644
--- a/Documentation/accounting/getdelays.c
+++ b/Documentation/accounting/getdelays.c
@@ -196,7 +196,7 @@
"IO %15s%15s\n"
" %15llu%15llu\n"
"MEM %15s%15s\n"
- " %15llu%15llu\n"
+ " %15llu%15llu\n",
"count", "real total", "virtual total", "delay total",
t->cpu_count, t->cpu_run_real_total, t->cpu_run_virtual_total,
t->cpu_delay_total,
diff --git a/Documentation/dvb/get_dvb_firmware b/Documentation/dvb/get_dvb_firmware
index b4d306a..f2e908d 100644
--- a/Documentation/dvb/get_dvb_firmware
+++ b/Documentation/dvb/get_dvb_firmware
@@ -111,21 +111,21 @@
}
sub tda10046 {
- my $sourcefile = "tt_budget_217g.zip";
- my $url = "http://www.technotrend.de/new/217g/$sourcefile";
- my $hash = "6a7e1e2f2644b162ff0502367553c72d";
- my $outfile = "dvb-fe-tda10046.fw";
- my $tmpdir = tempdir(DIR => "/tmp", CLEANUP => 1);
+ my $sourcefile = "TT_PCI_2.19h_28_11_2006.zip";
+ my $url = "http://technotrend-online.com/download/software/219/$sourcefile";
+ my $hash = "6a7e1e2f2644b162ff0502367553c72d";
+ my $outfile = "dvb-fe-tda10046.fw";
+ my $tmpdir = tempdir(DIR => "/tmp", CLEANUP => 1);
- checkstandard();
+ checkstandard();
- wgetfile($sourcefile, $url);
- unzip($sourcefile, $tmpdir);
- extract("$tmpdir/software/OEM/PCI/App/ttlcdacc.dll", 0x3f731, 24478, "$tmpdir/fwtmp");
- verify("$tmpdir/fwtmp", $hash);
- copy("$tmpdir/fwtmp", $outfile);
+ wgetfile($sourcefile, $url);
+ unzip($sourcefile, $tmpdir);
+ extract("$tmpdir/TT_PCI_2.19h_28_11_2006/software/OEM/PCI/App/ttlcdacc.dll", 0x65389, 24478, "$tmpdir/fwtmp");
+ verify("$tmpdir/fwtmp", $hash);
+ copy("$tmpdir/fwtmp", $outfile);
- $outfile;
+ $outfile;
}
sub tda10046lifeview {
diff --git a/Documentation/fb/pvr2fb.txt b/Documentation/fb/pvr2fb.txt
index 2bf6c23..36bdeff 100644
--- a/Documentation/fb/pvr2fb.txt
+++ b/Documentation/fb/pvr2fb.txt
@@ -9,14 +9,13 @@
Advantages:
* It provides a nice large console (128 cols + 48 lines with 1024x768)
- without using tiny, unreadable fonts.
+ without using tiny, unreadable fonts (NOT on the Dreamcast)
* You can run XF86_FBDev on top of /dev/fb0
* Most important: boot logo :-)
Disadvantages:
- * Driver is currently limited to the Dreamcast PowerVR 2 implementation
- at the time of this writing.
+ * Driver is largely untested on non-Dreamcast systems.
Configuration
=============
@@ -29,11 +28,16 @@
font:X - default font to use. All fonts are supported, including the
SUN12x22 font which is very nice at high resolutions.
-mode:X - default video mode. The following video modes are supported:
- 640x240-60, 640x480-60.
+mode:X - default video mode with format [xres]x[yres]-<bpp>@<refresh rate>
+ The following video modes are supported:
+ 640x640-16@60, 640x480-24@60, 640x480-32@60. The Dreamcast
+ defaults to 640x480-16@60. At the time of writing the
+ 24bpp and 32bpp modes function poorly. Work to fix that is
+ ongoing
+
Note: the 640x240 mode is currently broken, and should not be
- used for any reason. It is only mentioned as a reference.
+ used for any reason. It is only mentioned here as a reference.
inverse - invert colors on screen (for LCD displays)
@@ -52,10 +56,10 @@
X11
===
-XF86_FBDev should work, in theory. At the time of this writing it is
-totally untested and may or may not even portray the beginnings of
-working. If you end up testing this, please let me know!
+XF86_FBDev has been shown to work on the Dreamcast in the past - though not yet
+on any 2.6 series kernel.
--
Paul Mundt <lethal@linuxdc.org>
+Updated by Adrian McMenamin <adrian@mcmen.demon.co.uk>
diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt
index a43d287..b9a3fdc 100644
--- a/Documentation/feature-removal-schedule.txt
+++ b/Documentation/feature-removal-schedule.txt
@@ -197,6 +197,14 @@
---------------------------
+What: /proc/acpi/event
+When: February 2008
+Why: /proc/acpi/event has been replaced by events via the input layer
+ and netlink since 2.6.23.
+Who: Len Brown <len.brown@intel.com>
+
+---------------------------
+
What: Compaq touchscreen device emulation
When: Oct 2007
Files: drivers/input/tsdev.c
diff --git a/Documentation/filesystems/9p.txt b/Documentation/filesystems/9p.txt
index bbd8b28..cda6905 100644
--- a/Documentation/filesystems/9p.txt
+++ b/Documentation/filesystems/9p.txt
@@ -6,12 +6,26 @@
v9fs is a Unix implementation of the Plan 9 9p remote filesystem protocol.
-This software was originally developed by Ron Minnich <rminnich@lanl.gov>
-and Maya Gokhale <maya@lanl.gov>. Additional development by Greg Watson
+This software was originally developed by Ron Minnich <rminnich@sandia.gov>
+and Maya Gokhale. Additional development by Greg Watson
<gwatson@lanl.gov> and most recently Eric Van Hensbergen
<ericvh@gmail.com>, Latchesar Ionkov <lucho@ionkov.net> and Russ Cox
<rsc@swtch.com>.
+The best detailed explanation of the Linux implementation and applications of
+the 9p client is available in the form of a USENIX paper:
+ http://www.usenix.org/events/usenix05/tech/freenix/hensbergen.html
+
+Other applications are described in the following papers:
+ * XCPU & Clustering
+ http://www.xcpu.org/xcpu-talk.pdf
+ * KVMFS: control file system for KVM
+ http://www.xcpu.org/kvmfs.pdf
+ * CellFS: A New ProgrammingModel for the Cell BE
+ http://www.xcpu.org/cellfs-talk.pdf
+ * PROSE I/O: Using 9p to enable Application Partitions
+ http://plan9.escet.urjc.es/iwp9/cready/PROSE_iwp9_2006.pdf
+
USAGE
=====
@@ -90,9 +104,9 @@
and export.
A Linux version of the 9p server is now maintained under the npfs project
-on sourceforge (http://sourceforge.net/projects/npfs). There is also a
-more stable single-threaded version of the server (named spfs) available from
-the same CVS repository.
+on sourceforge (http://sourceforge.net/projects/npfs). The currently
+maintained version is the single-threaded version of the server (named spfs)
+available from the same CVS repository.
There are user and developer mailing lists available through the v9fs project
on sourceforge (http://sourceforge.net/projects/v9fs).
diff --git a/Documentation/i386/zero-page.txt b/Documentation/i386/zero-page.txt
index 75b3680..6c0817c 100644
--- a/Documentation/i386/zero-page.txt
+++ b/Documentation/i386/zero-page.txt
@@ -1,3 +1,13 @@
+---------------------------------------------------------------------------
+!!!!!!!!!!!!!!!WARNING!!!!!!!!
+The zero page is a kernel internal data structure, not a stable ABI. It might change
+without warning and the kernel has no way to detect old version of it.
+If you're writing some external code like a boot loader you should only use
+the stable versioned real mode boot protocol described in boot.txt. Otherwise the kernel
+might break you at any time.
+!!!!!!!!!!!!!WARNING!!!!!!!!!!!
+----------------------------------------------------------------------------
+
Summary of boot_params layout (kernel point of view)
( collected by Hans Lermen and Martin Mares )
diff --git a/Documentation/kbuild/kconfig-language.txt b/Documentation/kbuild/kconfig-language.txt
index 536d5bf..fe8b0c4 100644
--- a/Documentation/kbuild/kconfig-language.txt
+++ b/Documentation/kbuild/kconfig-language.txt
@@ -98,6 +98,15 @@
times, the limit is set to the largest selection.
Reverse dependencies can only be used with boolean or tristate
symbols.
+ Note:
+ select is evil.... select will by brute force set a symbol
+ equal to 'y' without visiting the dependencies. So abusing
+ select you are able to select a symbol FOO even if FOO depends
+ on BAR that is not set. In general use select only for
+ non-visible symbols (no promts anywhere) and for symbols with
+ no dependencies. That will limit the usefulness but on the
+ other hand avoid the illegal configurations all over. kconfig
+ should one day warn about such things.
- numerical ranges: "range" <symbol> <symbol> ["if" <expr>]
This allows to limit the range of possible input values for int
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index efdb42f..b41cde3 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -163,6 +163,8 @@
acpi_irq_isa= [HW,ACPI] If irq_balance, mark listed IRQs used by ISA
Format: <irq>,<irq>...
+ acpi_no_auto_ssdt [HW,ACPI] Disable automatic loading of SSDT
+
acpi_os_name= [HW,ACPI] Tell ACPI BIOS the name of the OS
Format: To spoof as Windows 98: ="Microsoft Windows"
@@ -950,14 +952,10 @@
Format: <1-256>
maxcpus= [SMP] Maximum number of processors that an SMP kernel
- should make use of.
- Using "nosmp" or "maxcpus=0" will disable SMP
- entirely (the MPS table probe still happens, though).
- A command-line option of "maxcpus=<NUM>", where <NUM>
- is an integer greater than 0, limits the maximum number
- of CPUs activated in SMP mode to <NUM>.
- Using "maxcpus=1" on an SMP kernel is the trivial
- case of an SMP kernel with only one CPU.
+ should make use of. maxcpus=n : n >= 0 limits the
+ kernel to using 'n' processors. n=0 is a special case,
+ it is equivalent to "nosmp", which also disables
+ the IO APIC.
max_addr=[KMG] [KNL,BOOT,ia64] All physical memory greater than or
equal to this physical address is ignored.
@@ -1182,7 +1180,8 @@
nosep [BUGS=X86-32] Disables x86 SYSENTER/SYSEXIT support.
- nosmp [SMP] Tells an SMP kernel to act as a UP kernel.
+ nosmp [SMP] Tells an SMP kernel to act as a UP kernel,
+ and disable the IO APIC. legacy for "maxcpus=0".
nosoftlockup [KNL] Disable the soft-lockup detector.
@@ -1820,6 +1819,30 @@
thash_entries= [KNL,NET]
Set number of hash buckets for TCP connection
+ thermal.act= [HW,ACPI]
+ -1: disable all active trip points in all thermal zones
+ <degrees C>: override all lowest active trip points
+
+ thermal.crt= [HW,ACPI]
+ -1: disable all critical trip points in all thermal zones
+ <degrees C>: lower all critical trip points
+
+ thermal.nocrt= [HW,ACPI]
+ Set to disable actions on ACPI thermal zone
+ critical and hot trip points.
+
+ thermal.off= [HW,ACPI]
+ 1: disable ACPI thermal control
+
+ thermal.psv= [HW,ACPI]
+ -1: disable all passive trip points
+ <degrees C>: override all passive trip points to this value
+
+ thermal.tzp= [HW,ACPI]
+ Specify global default ACPI thermal zone polling rate
+ <deci-seconds>: poll all this frequency
+ 0: no polling (default)
+
time Show timing data prefixed to each printk message line
[deprecated, see 'printk.time']
@@ -1922,7 +1945,7 @@
See header of drivers/scsi/wd7000.c.
wdt= [WDT] Watchdog
- See Documentation/watchdog/watchdog.txt.
+ See Documentation/watchdog/wdt.txt.
xd= [HW,XT] Original XT pre-IDE (RLL encoded) disks.
xd_geo= See header of drivers/block/xd.c.
diff --git a/Documentation/ko_KR/HOWTO b/Documentation/ko_KR/HOWTO
new file mode 100644
index 0000000..b51d7ca
--- /dev/null
+++ b/Documentation/ko_KR/HOWTO
@@ -0,0 +1,623 @@
+NOTE:
+This is a version of Documentation/HOWTO translated into korean
+This document is maintained by minchan Kim < minchan.kim@gmail.com>
+If you find any difference between this document and the original file or
+a problem with the translation, please contact the maintainer of this file.
+
+Please also note that the purpose of this file is to be easier to
+read for non English (read: korean) speakers and is not intended as
+a fork. So if you have any comments or updates for this file please
+try to update the original English file first.
+
+==================================
+이 문서는
+Documentation/HOWTO
+의 한글 번역입니다.
+
+역자: 김민찬 <minchan.kim@gmail.com >
+감수: 이제이미 <jamee.lee@samsung.com>
+==================================
+
+어떻게 리눅스 커널 개발을 하는가
+---------------------------------
+
+이 문서는 커널 개발에 있어 가장 중요한 문서이다. 이 문서는
+리눅스 커널 개발자가 되는 법과 리눅스 커널 개발 커뮤니티와 일하는
+법을 담고있다. 커널 프로그래밍의기술적인 측면과 관련된 내용들은
+포함하지 않으려고 하였지만 올바으로 여러분을 안내하는 데 도움이
+될 것이다.
+
+이 문서에서 오래된 것을 발견하면 문서의 아래쪽에 나열된 메인트너에게
+패치를 보내달라.
+
+
+소개
+----
+
+자, 여러분은 리눅스 커널 개발자가 되는 법을 배우고 싶은가? 아니면
+상사로부터"이 장치를 위한 리눅스 드라이버를 작성하시오"라는 말을
+들었는가? 이 문서는 여러분이 겪게 될 과정과 커뮤니티와 일하는 법을
+조언하여 여러분의 목적을 달성하기 위해 필요한 것 모두를 알려주는
+것이다.
+
+커널은 대부분은 C로 작성되었어고 몇몇 아키텍쳐의 의존적인 부분은
+어셈블리로 작성되었다. 커널 개발을 위해 C를 잘 이해하고 있어야 한다.
+여러분이 특정 아키텍쳐의 low-level 개발을 할 것이 아니라면
+어셈블리(특정 아키텍쳐)는 잘 알아야 할 필요는 없다.
+다음의 참고서적들은 기본에 충실한 C 교육이나 수년간의 경험에 견주지는
+못하지만 적어도 참고 용도로는 좋을 것이다
+ - "The C Programming Language" by Kernighan and Ritchie [Prentice Hall]
+ - "Practical C Programming" by Steve Oualline [O'Reilly]
+ - "C: A Reference Manual" by Harbison and Steele [Prentice Hall]
+
+커널은 GNU C와 GNU 툴체인을 사용하여 작성되었다. 이 툴들은 ISO C89 표준을
+따르는 반면 표준에 있지 않은 많은 확장기능도 가지고 있다. 커널은 표준 C
+라이브러리와는 관계없이 freestanding C 환경이어서 C 표준의 일부는
+지원되지 않는다. 임의의 long long 나누기나 floating point는 지원되지 않는다.
+때론 이런 이유로 커널이 그런 확장 기능을 가진 툴체인을 가지고 만들어졌다는
+것이 이해하기 어려울 수도 있고 게다가 불행하게도 그런 것을 정확하게 설명하는
+어떤 참고문서도 있지 않다. 정보를 얻기 위해서는 gcc info (`info gcc`)페이지를
+살펴보라.
+
+여러분은 기존의 개발 커뮤니티와 일하는 법을 배우려고 하고 있다는 것을
+기억하라. 코딩, 스타일, 절차에 관한 훌륭한 표준을 가진 사람들이 모인
+다양한 그룹이 있다. 이 표준들은 오랜동안 크고 지역적으로 분산된 팀들에
+의해 가장 좋은 방법으로 일하기위하여 찾은 것을 기초로 만들어져왔다.
+그 표준들은 문서화가 잘 되어 있기 때문에 가능한한 미리 많은 표준들에
+관하여 배우려고 시도하라. 다른 사람들은 여러분이나 여러분의 회사가
+일하는 방식에 적응하는 것을 원하지는 않는다.
+
+
+법적 문제
+---------
+
+리눅스 커널 소스 코드는 GPL로 배포(release)되었다. 소스트리의 메인
+디렉토리에 있는 라이센스에 관하여 상세하게 쓰여 있는 COPYING이라는
+파일을 봐라.여러분이 라이센스에 관한 더 깊은 문제를 가지고 있다면
+리눅스 커널 메일링 리스트에 묻지말고 변호사와 연락하라. 메일링
+리스트들에 있는 사람들은 변호사가 아니기 때문에 법적 문제에 관하여
+그들의 말에 의지해서는 안된다.
+
+GPL에 관한 잦은 질문들과 답변들은 다음을 참조하라.
+ http://www.gnu.org/licenses/gpl-faq.html
+
+
+문서
+----
+
+리눅스 커널 소스 트리는 커널 커뮤니티와 일하는 법을 배우기 위한 많은
+귀중한 문서들을 가지고 있다. 새로운 기능들이 커널에 들어가게 될 때,
+그 기능을 어떻게 사용하는지에 관한 설명을 위하여 새로운 문서 파일을
+추가하는 것을 권장한다. 커널이 유저스페이스로 노출하는 인터페이스를
+변경하게 되면 변경을 설명하는 메뉴얼 페이지들에 대한 패치나 정보를
+mtk-manpages@gmx.net의 메인트너에게 보낼 것을 권장한다.
+
+다음은 커널 소스 트리에 있는 읽어야 할 파일들의 리스트이다.
+ README
+ 이 파일은 리눅스 커널에 관하여 간단한 배경 설명과 커널을 설정하고
+ 빌드하기 위해 필요한 것을 설명한다. 커널에 입문하는 사람들은 여기서
+ 시작해야 한다.
+
+ Documentation/Changes
+ 이 파일은 커널을 성공적으로 빌드하고 실행시키기 위해 필요한 다양한
+ 소프트웨어 패키지들의 최소 버젼을 나열한다.
+
+ Documentation/CodingStyle
+ 이 문서는 리눅스 커널 코딩 스타일과 그렇게 한 몇몇 이유를 설명한다.
+ 모든 새로운 코드는 이 문서에 가이드라인들을 따라야 한다. 대부분의
+ 메인트너들은 이 규칙을 따르는 패치들만을 받아들일 것이고 많은 사람들이
+ 그 패치가 올바른 스타일일 경우만 코드를 검토할 것이다.
+
+ Documentation/SubmittingPatches
+ Documentation/SubmittingDrivers
+ 이 파일들은 성공적으로 패치를 만들고 보내는 법을 다음의 내용들로
+ 굉장히 상세히 설명하고 있다(그러나 다음으로 한정되진 않는다).
+ - Email 내용들
+ - Email 양식
+ - 그것을 누구에게 보낼지
+ 이러한 규칙들을 따르는 것이 성공을 보장하진 않는다(왜냐하면 모든
+ 패치들은 내용과 스타일에 관하여 면밀히 검토되기 때문이다).
+ 그러나 규칙을 따르지 않는다면 거의 성공하지도 못할 것이다.
+
+ 올바른 패치들을 만드는 법에 관한 훌륭한 다른 문서들이 있다.
+ "The Perfect Patch"
+ http://www.zip.com.au/~akpm/linux/patches/stuff/tpp.txt
+ "Linux kernel patch submission format"
+ http://linux.yyz.us/patch-format.html
+
+ Documentation/stable_api_nonsense.txt
+ 이 문서는 의도적으로 커널이 변하지 않는 API를 갖지 않도록 결정한
+ 이유를 설명하며 다음과 같은 것들을 포함한다.
+ - 서브시스템 shim-layer(호환성을 위해?)
+ - 운영 체제들 간의 드라이버 이식성
+ - 커널 소스 트리내에 빠른 변화를 늦추는 것(또는 빠른 변화를 막는 것)
+ 이 문서는 리눅스 개발 철학을 이해하는데 필수적이며 다른 운영체제에서
+ 리눅스로 옮겨오는 사람들에게는 매우 중요하다.
+
+
+ Documentation/SecurityBugs
+ 여러분들이 리눅스 커널의 보안 문제를 발견했다고 생각한다면 이 문서에
+ 나온 단계에 따라서 커널 개발자들에게 알리고 그 문제를 해결할 수 있도록
+ 도와 달라.
+
+ Documentation/ManagementStyle
+ 이 문서는 리눅스 커널 메인트너들이 어떻게 그들의 방법론의 정신을
+ 어떻게 공유하고 운영하는지를 설명한다. 이것은 커널 개발에 입문하는
+ 모든 사람들(또는 커널 개발에 작은 호기심이라도 있는 사람들)이
+ 읽어야 할 중요한 문서이다. 왜냐하면 이 문서는 커널 메인트너들의
+ 독특한 행동에 관하여 흔히 있는 오해들과 혼란들을 해소하고 있기
+ 때문이다.
+
+ Documentation/stable_kernel_rules.txt
+ 이 문서는 안정적인 커널 배포가 이루어지는 규칙을 설명하고 있으며
+ 여러분들이 이러한 배포들 중 하나에 변경을 하길 원한다면
+ 무엇을 해야 하는지를 설명한다.
+
+ Documentation/kernel-docs.txt
+ 커널 개발에 관계된 외부 문서의 리스트이다. 커널 내의 포함된 문서들
+ 중에 여러분이 찾고 싶은 문서를 발견하지 못할 경우 이 리스트를
+ 살펴보라.
+
+ Documentation/applying-patches.txt
+ 패치가 무엇이며 그것을 커널의 다른 개발 브랜치들에 어떻게
+ 적용하는지에 관하여 자세히 설명 하고 있는 좋은 입문서이다.
+
+커널은 소스 코드 그 자체에서 자동적으로 만들어질 수 있는 많은 문서들을
+가지고 있다. 이것은 커널 내의 API에 대한 모든 설명, 그리고 락킹을
+올바르게 처리하는 법에 관한 규칙을 포함하고 있다. 이 문서는
+Documentation/DocBook/ 디렉토리 내에서 만들어지며 PDF, Postscript, HTML,
+그리고 man 페이지들로 다음과 같이 실행하여 만들어 진다.
+ make pdfdocs
+ make psdocs
+ make htmldocs
+ make mandocs
+각각의 명령을 메인 커널 소스 디렉토리로부터 실행한다.
+
+
+커널 개발자가 되는 것
+---------------------
+
+여러분이 리눅스 커널 개발에 관하여 아무것도 모른다면 Linux KernelNewbies
+프로젝트를 봐야 한다.
+ http://kernelnewbies.org
+그곳은 거의 모든 종류의 기본적인 커널 개발 질문들(질문하기 전에 먼저
+아카이브를 찾아봐라. 과거에 이미 답변되었을 수도 있다)을 할수있는 도움이
+될만한 메일링 리스트가 있다. 또한 실시간으로 질문 할수 있는 IRC 채널도
+가지고 있으며 리눅스 커널 개발을 배우는 데 유용한 문서들을 보유하고 있다.
+
+웹사이트는 코드구성, 서브시스템들, 그리고 현재 프로젝트들
+(트리 내, 외부에 존재하는)에 관한 기본적인 정보들을 가지고 있다. 또한
+그곳은 커널 컴파일이나 패치를 하는 법과 같은 기본적인 것들을 설명한다.
+
+여러분이 어디서 시작해야 할진 모르지만 커널 개발 커뮤니티에 참여할 수
+있는 일들을 찾길 원한다면 리눅스 커널 Janitor 프로젝트를 살펴봐라.
+ http://janitor.kernelnewbies.org/
+그곳은 시작하기에 아주 딱 좋은 곳이다. 그곳은 리눅스 커널 소스 트리내에
+간단히 정리되고 수정될 수 있는 문제들에 관하여 설명한다. 여러분은 이
+프로젝트를 대표하는 개발자들과 일하면서 자신의 패치를 리눅스 커널 트리에
+반영하기 위한 기본적인 것들을 배우게 될것이며 여러분이 아직 아이디어를
+가지고 있지 않다면 다음에 무엇을 해야할지에 관한 방향을 배울 수 있을
+것이다.
+
+여러분들이 이미 커널 트리에 반영하길 원하는 코드 묶음을 가지고 있지만
+올바른 포맷으로 포장하는데 도움이 필요하다면 그러한 문제를 돕기 위해
+만들어진 kernel-mentors 프로젝트가 있다. 그곳은 메일링 리스트이며
+다음에서 참조할 수 있다.
+ http://selenic.com/mailman/listinfo/kernel-mentors
+
+리눅스 커널 코드에 실제 변경을 하기 전에 반드시 그 코드가 어떻게
+동작하는지 이해하고 있어야 한다. 코드를 분석하기 위하여 특정한 툴의
+도움을 빌려서라도 코드를 직접 읽는 것보다 좋은 것은 없다(대부분의
+자잘한 부분들은 잘 코멘트되어 있다). 그런 툴들 중에 특히 추천할만한
+것은 Linux Cross-Reference project이며 그것은 자기 참조 방식이며
+소스코드를 인덱스된 웹 페이지들의 형태로 보여준다. 최신의 멋진 커널
+코드 저장소는 다음을 통하여 참조할 수 있다.
+ http://sosdg.org/~coywolf/lxr/
+
+
+개발 프로세스
+-------------
+
+리눅스 커널 개발 프로세스는 현재 몇몇 다른 메인 커널 "브랜치들"과
+서브시스템에 특화된 커널 브랜치들로 구성된다. 몇몇 다른 메인
+브랜치들은 다음과 같다.
+ - main 2.6.x 커널 트리
+ - 2.6.x.y - 안정된 커널 트리
+ - 2.6.x -git 커널 패치들
+ - 2.6.x -mm 커널 패치들
+ - 서브시스템을 위한 커널 트리들과 패치들
+
+2.6.x 커널 트리
+---------------
+
+2.6.x 커널들은 Linux Torvalds가 관리하며 kernel.org의 pub/linux/kernel/v2.6/
+디렉토리에서 참조될 수 있다.개발 프로세스는 다음과 같다.
+ - 새로운 커널이 배포되자마자 2주의 시간이 주어진다. 이 기간동은
+ 메인트너들은 큰 diff들을 Linus에게 제출할 수 있다. 대개 이 패치들은
+ 몇 주 동안 -mm 커널내에 이미 있었던 것들이다. 큰 변경들을 제출하는 데
+ 선호되는 방법은 git(커널의 소스 관리 툴, 더 많은 정보들은 http://git.or.cz/
+ 에서 참조할 수 있다)를 사용하는 것이지만 순수한 패치파일의 형식으로 보내도
+ 것도 무관하다.
+ - 2주 후에 -rc1 커널이 배포되며 지금부터는 전체 커널의 안정성에 영향을
+ 미칠수 있는 새로운 기능들을 포함하지 않는 패치들만을 추가될 수 있다.
+ 완전히 새로운 드라이버(혹은 파일시스템)는 -rc1 이후에만 받아들여진다는
+ 것을 기억해라. 왜냐하면 변경이 자체내에서만 발생하고 추가된 코드가
+ 드라이버 외부의 다른 부분에는 영향을 주지 않으므로 그런 변경은
+ 퇴보(regression)를 일으킬 만한 위험을 가지고 있지 않기 때문이다. -rc1이
+ 배포된 이후에 git를 사용하여 패치들을 Linus에게 보낼수 있지만 패치들은
+ 공식적인 메일링 리스트로 보내서 검토를 받을 필요가 있다.
+ - 새로운 -rc는 Linus는 현재 git tree가 테스트 하기에 충분히 안정된 상태에
+ 있다고 판단될 때마다 배포된다. 목표는 새로운 -rc 커널을 매주 배포하는
+ 것이다.
+ - 이러한 프로세스는 커널이 "준비"되었다고 여겨질때까지 계속된다.
+ 프로세스는 대체로 6주간 지속된다.
+ - 각 -rc 배포에 있는 알려진 퇴보의 목록들은 다음 URI에 남겨진다.
+ http://kernelnewbies.org/known_regressions
+
+커널 배포에 있어서 언급할만한 가치가 있는 리눅스 커널 메일링 리스트의
+Andrew Morton의 글이 있다.
+ "커널이 언제 배포될지는 아무로 모른다. 왜냐하면 배포는 알려진
+ 버그의 상황에 따라 배포되는 것이지 미리정해 놓은 시간에 따라
+ 배포되는 것은 아니기 때문이다."
+
+2.6.x.y - 안정 커널 트리
+------------------------
+
+4 자리 숫자로 이루어진 버젼의 커널들은 -stable 커널들이다. 그것들은 2.6.x
+커널에서 발견된 큰 퇴보들이나 보안 문제들 중 비교적 작고 중요한 수정들을
+포함한다.
+
+이것은 가장 최근의 안정적인 커널을 원하는 사용자에게 추천되는 브랜치이며,
+개발/실험적 버젼을 테스트하는 것을 돕는데는 별로 관심이 없다.
+
+어떤 2.6.x.y 커널도 사용가능하지 않다면 그때는 가장 높은 숫자의 2.6.x
+커널이 현재의 안정 커널이다.
+
+2.6.x.y는 "stable" 팀<stable@kernel.org>에 의해 관리되며 거의 매번 격주로
+배포된다.
+
+커널 트리 문서들 내에 Documentation/stable_kernel_rules.txt 파일은 어떤
+종류의 변경들이 -stable 트리로 들어왔는지와 배포 프로세스가 어떻게
+진행되는지를 설명한다.
+
+
+2.6.x -git 패치들
+------------------
+git 저장소(그러므로 -git이라는 이름이 붙음)에는 날마다 관리되는 Linus의
+커널 트리의 snapshot 들이 있다. 이 패치들은 일반적으로 날마다 배포되며
+Linus의 트리의 현재 상태를 나타낸다. 이 패치들은 정상적인지 조금도
+살펴보지 않고 자동적으로 생성된 것이므로 -rc 커널들 보다도 더 실험적이다.
+
+2.6.x -mm 커널 패치들
+---------------------
+Andrew Morton에 의해 배포된 실험적인 커널 패치들이다. Andrew는 모든 다른
+서브시스템 커널 트리와 패치들을 가져와서 리눅스 커널 메일링 리스트로
+온 많은 패치들과 한데 묶는다. 이 트리는 새로운 기능들과 패치들을 위한
+장소를 제공하는 역할을 한다. 하나의 패치가 -mm에 한동안 있으면서 그 가치가
+증명되게 되면 Andrew나 서브시스템 메인트너는 그것을 메인라인에 포함시키기
+위하여 Linus에게 보낸다.
+
+커널 트리에 포함하고 싶은 모든 새로운 패치들은 Linus에게 보내지기 전에
+-mm 트리에서 테스트를 하는 것을 적극 추천한다.
+
+이 커널들은 안정되게 사용할 시스템에서에 실행하는 것은 적합하지 않으며
+다른 브랜치들의 어떤 것들보다 위험하다.
+
+여러분이 커널 개발 프로세스를 돕길 원한다면 이 커널 배포들을 사용하고
+테스트한 후 어떤 문제를 발견하거나 또는 모든 것이 잘 동작한다면 리눅스
+커널 메일링 리스트로 피드백을 해달라.
+
+이 커널들은 일반적으로 모든 다른 실험적인 패치들과 배포될 당시의
+사용가능한 메인라인 -git 커널들의 몇몇 변경을 포함한다.
+
+-mm 커널들은 정해진 일정대로 배포되지 않는다. 하지만 대개 몇몇 -mm 커널들은
+각 -rc 커널(1부터 3이 흔함) 사이에서 배포된다.
+
+서브시스템 커널 트리들과 패치들
+-------------------------------
+많은 다른 커널 서브시스템 개발자들은 커널의 다른 부분들에서 무슨 일이
+일어나고 있는지를 볼수 있도록 그들의 개발 트리를 공개한다. 이 트리들은
+위에서 설명하였던 것 처럼 -mm 커널 배포들로 합쳐진다.
+
+다음은 활용가능한 커널 트리들을 나열한다.
+ git trees:
+ - Kbuild development tree, Sam Ravnborg < sam@ravnborg.org>
+ git.kernel.org:/pub/scm/linux/kernel/git/sam/kbuild.git
+
+ - ACPI development tree, Len Brown <len.brown@intel.com >
+ git.kernel.org:/pub/scm/linux/kernel/git/lenb/linux-acpi-2.6.git
+
+ - Block development tree, Jens Axboe <axboe@suse.de>
+ git.kernel.org:/pub/scm/linux/kernel/git/axboe/linux-2.6-block.git
+
+ - DRM development tree, Dave Airlie <airlied@linux.ie>
+ git.kernel.org:/pub/scm/linux/kernel/git/airlied/drm-2.6.git
+
+ - ia64 development tree, Tony Luck < tony.luck@intel.com>
+ git.kernel.org:/pub/scm/linux/kernel/git/aegl/linux-2.6.git
+
+ - infiniband, Roland Dreier <rolandd@cisco.com >
+ git.kernel.org:/pub/scm/linux/kernel/git/roland/infiniband.git
+
+ - libata, Jeff Garzik <jgarzik@pobox.com>
+ git.kernel.org:/pub/scm/linux/kernel/git/jgarzik/libata-dev.git
+
+ - network drivers, Jeff Garzik <jgarzik@pobox.com>
+ git.kernel.org:/pub/scm/linux/kernel/git/jgarzik/netdev-2.6.git
+
+ - pcmcia, Dominik Brodowski < linux@dominikbrodowski.net>
+ git.kernel.org:/pub/scm/linux/kernel/git/brodo/pcmcia-2.6.git
+
+ - SCSI, James Bottomley < James.Bottomley@SteelEye.com>
+ git.kernel.org:/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6.git
+
+ quilt trees:
+ - USB, PCI, Driver Core, and I2C, Greg Kroah-Hartman < gregkh@suse.de>
+ kernel.org/pub/linux/kernel/people/gregkh/gregkh-2.6/
+ - x86-64, partly i386, Andi Kleen < ak@suse.de>
+ ftp.firstfloor.org:/pub/ak/x86_64/quilt/
+
+ 다른 커널 트리들은 http://kernel.org/git와 MAINTAINERS 파일에서 참조할 수
+ 있다.
+
+버그 보고
+---------
+bugzilla.kernel.org는 리눅스 커널 개발자들이 커널의 버그를 추적하는 곳이다.
+사용자들은 발견한 모든 버그들을 보고하기 위하여 이 툴을 사용할 것을 권장한다.
+kernel bugzilla를 사용하는 자세한 방법은 다음을 참조하라.
+ http://test.kernel.org/bugzilla/faq.html
+
+메인 커널 소스 디렉토리에 있는 REPORTING-BUGS 파일은 커널 버그일 것 같은
+것을 보고하는는 법에 관한 좋은 템플릿이고 문제를 추적하기 위해서 커널
+개발자들이 필요로 하는 정보가 무엇들인지를 상세히 설명하고 있다.
+
+
+버그 리포트들의 관리
+--------------------
+
+여러분의 해킹 기술을 연습하는 가장 좋은 방법 중의 하는 다른 사람들이
+보고한 버그들을 수정하는 것이다. 여러분은 커널을 더욱 안정화시키는데
+도움을 줄 뿐만이 아니라 실제있는 문제들을 수정하는 법을 배우게 되고
+그와 함께 여러분들의 기술은 향상될 것이며 다른 개발자들이 여러분의
+존재에 대해 알게 될 것이다. 버그를 수정하는 것은 개발자들 사이에서
+점수를 얻을 수 있는 가장 좋은 방법중의 하나이다. 왜냐하면 많은 사람들은
+다른 사람들의 버그들을 수정하기 위하여 시간을 낭비하지 않기 때문이다.
+
+이미 보고된 버그 리포트들을 가지고 작업하기 위해서 http://bugzilla.kernelorg를
+참조하라. 여러분이 앞으로 생겨날 버그 리포트들의 조언자가 되길 원한다면
+bugme-new 메일링 리스트나(새로운 버그 리포트들만이 이곳에서 메일로 전해진다)
+bugme-janitor 메일링 리스트(bugzilla에 모든 변화들이 여기서 메일로 전해진다)
+에 등록하면 된다.
+
+ http://lists.osdl.org/mailman/listinfo/bugme-new
+ http://lists.osdl.org/mailman/listinfo/bugme-janitors
+
+
+
+메일링 리스트들
+---------------
+
+위의 몇몇 문서들이 설명하였지만 핵심 커널 개발자들의 대다수는
+리눅스 커널 메일링 리스트에 참여하고 있다. 리스트에 등록하고 해지하는
+방법에 관한 자세한 사항은 다음에서 참조할 수 있다.
+ http://vger.kernel.org/vger-lists.html#linux-kernel
+웹상의 많은 다른 곳에도 메일링 리스트의 아카이브들이 있다.
+이러한 아카이브들을 찾으려면 검색 엔진을 사용하라. 예를 들어:
+ http://dir.gmane.org/gmane.linux.kernel
+여러분이 새로운 문제에 관해 리스트에 올리기 전에 말하고 싶은 주제에 대한
+것을 아카이브에서 먼저 찾기를 강력히 권장한다. 이미 상세하게 토론된 많은
+것들이 메일링 리스트의 아카이브에 기록되어 있다.
+
+각각의 커널 서브시스템들의 대부분은 자신들의 개발에 관한 노력들로 이루어진
+분리된 메일링 리스트를 따로 가지고 있다. 다른 그룹들이 무슨 리스트를 가지고
+있는지는 MAINTAINERS 파일을 참조하라.
+
+많은 리스트들은 kernel.org에서 호스트되고 있다. 그 정보들은 다음에서 참조될 수 있다.
+ http://vger.kernel.org/vger-lists.html
+
+리스트들을 사용할 때는 올바른 예절을 따를 것을 유념해라.
+대단하진 않지만 다음 URL은 리스트(혹은 모든 리스트)와 대화하는 몇몇 간단한
+가이드라인을 가지고 있다.
+ http://www.albion.com/netiquette/
+
+여러 사람들이 여러분의 메일에 응답한다면 CC: 즉 수신 리스트는 꽤 커지게
+될 것이다. 아무 이유없이 CC에서 어떤 사람도 제거하거나 리스트 주소로만
+회신하지 마라. 메일을 보낸 사람으로서 하나를 받고 리스트로부터 또
+하나를 받아 두번 받는 것에 익숙하여 있으니 mail-header를 조작하려고 하지
+말아라. 사람들은 그런 것을 좋아하지 않을 것이다.
+
+여러분의 회신의 문맥을 원래대로 유지해야 한다. 여러분들의 회신의 윗부분에
+"John 커널해커는 작성했다...."를 유지하며 여러분들의 의견을 그 메일의 윗부분에
+작성하지 말고 각 인용한 단락들 사이에 넣어라.
+
+여러분들이 패치들을 메일에 넣는다면 그것들은 Documentation/SubmittingPatches에
+나와있는데로 명백히(plain) 읽을 수 있는 텍스트여야 한다. 커널 개발자들은
+첨부파일이나 압축된 패치들을 원하지 않는다. 그들은 여러분들의 패치의
+각 라인 단위로 코멘트를 하길 원하며 압축하거나 첨부하지 않고 보내는 것이
+그렇게 할 수 있는 유일한 방법이다. 여러분들이 사용하는 메일 프로그램이
+스페이스나 탭 문자들을 조작하지 않는지 확인하라. 가장 좋은 첫 테스트는
+메일을 자신에게 보내보고 스스로 그 패치를 적용해보라. 그것이 동작하지
+않는다면 여러분의 메일 프로그램을 고치던가 제대로 동작하는 프로그램으로
+바꾸어라.
+
+무엇보다도 메일링 리스트의 다른 구독자들에게 보여주려 한다는 것을 기억하라.
+
+
+커뮤니티와 일하는 법
+--------------------
+
+커널 커뮤니티의 목적은 가능한한 가장 좋은 커널을 제공하는 것이다. 여러분이
+받아들여질 패치를 제출하게 되면 그 패치의 기술적인 이점으로 검토될 것이다.
+그럼 여러분들은 무엇을 기대하고 있어야 하는가?
+ - 비판
+ - 의견
+ - 변경을 위한 요구
+ - 당위성을 위한 요구
+ - 고요
+
+기억하라. 이것들은 여러분의 패치가 커널로 들어가기 위한 과정이다. 여러분의
+패치들은 비판과 다른 의견을 받을 수 있고 그것들을 기술적인 레벨로 평가하고
+재작업하거나 또는 왜 수정하면 안되는지에 관하여 명료하고 간결한 이유를
+말할 수 있어야 한다. 여러분이 제출한 것에 어떤 응답도 있지 않다면 몇 일을
+기다려보고 다시 시도해라. 때론 너무 많은 메일들 속에 묻혀버리기도 한다.
+
+여러분은 무엇을 해서는 안되는가?
+ - 여러분의 패치가 아무 질문 없이 받아들여지기를 기대하는 것
+ - 방어적이 되는 것
+ - 의견을 무시하는 것
+ - 요청된 변경을 하지 않고 패치를 다시 제출하는 것
+
+가능한한 가장 좋은 기술적인 해답을 찾고 있는 커뮤니티에서는 항상
+어떤 패치가 얼마나 좋은지에 관하여 다른 의견들이 있을 수 있다. 여러분은
+협조적이어야 하고 기꺼이 여러분의 생각을 커널 내에 맞추어야 한다. 아니면
+적어도 여러분의 것이 가치있다는 것을 중명하여야 한다. 잘못된 것도 여러분이
+올바른 방향의 해결책으로 이끌어갈 의지가 있다면 받아들여질 것이라는 점을
+기억하라.
+
+여러분의 첫 패치에 여러분이 수정해야하는 십여개 정도의 회신이 오는
+경우도 흔하다. 이것은 여러분의 패치가 받아들여지지 않을 것이라는 것을
+의미하는 것이 아니고 개인적으로 여러분에게 감정이 있어서 그러는 것도
+아니다. 간단히 여러분의 패치에 제기된 문제들을 수정하고 그것을 다시
+보내라.
+
+
+커널 커뮤니티와 기업 조직간의 차이점
+-----------------------------------------------------------------
+커널 커뮤니티는 가장 전통적인 회사의 개발 환경과는 다르다. 여기에 여러분들의
+문제를 피하기 위한 목록이 있다.
+ 여러분들이 제안한 변경들에 관하여 말할 때 좋은 것들 :
+ - " 이것은 여러 문제들을 해겹합니다."
+ - "이것은 2000 라인의 코드를 제거합니다."
+ - "이것은 내가 말하려는 것에 관해 설명하는 패치입니다."
+ - "나는 5개의 다른 아키텍쳐에서 그것을 테스트했슴으로..."
+ - "여기에 일련의 작은 패치들이 있습음로..."
+ - "이것은 일반적인 머신에서 성능을 향상시키므로..."
+
+ 여러분들이 말할 때 피해야 할 좋지 않은 것들 :
+ - "우리를 그것을 AIT/ptx/Solaris에서 이러한 방법으로 했다. 그러므로 그것은 좋은 것임에 틀립없다..."
+ - "나는 20년동안 이것을 해왔다. 그러므로..."
+ - "이것은 돈을 벌기위해 나의 회사가 필요로 하는 것이다."
+ - "이것은 우리의 엔터프라이즈 상품 라인을 위한 것이다."
+ - "여기에 나의 생각을 말하고 있는 1000 페이지 설계 문서가 있다."
+ - "나는 6달동안 이것을 했으니..."
+ - "여기세 5000라인 짜리 패치가 있으니..."
+ - "나는 현재 뒤죽박죽인 것을 재작성했다. 그리고 여기에..."
+ - "나는 마감시한을 가지고 있으므로 이 패치는 지금 적용될 필요가 있다."
+
+커널 커뮤니티가 전통적인 소프트웨어 엔지니어링 개발 환경들과
+또 다른 점은 얼굴을 보지 않고 일한다는 점이다. 이메일과 irc를 대화의
+주요수단으로 사용하는 것의 한가지 장점은 성별이나 인종의 차별이
+없다는 것이다. 리눅스 커널의 작업 환경에서는 단지 이메일 주소만
+알수 있기 때문에 여성과 소수 민족들도 모두 받아들여진다. 국제적으로
+일하게 되는 측면은 사람의 이름에 근거하여 성별을 추측할 수 없게
+하기때문에 차별을 없애는 데 도움을 준다. Andrea라는 이름을 가진 남자와
+Pat이라는 이름을 가진 여자가 있을 수도 있는 것이다. 리눅스 커널에서
+작업하며 생각을 표현해왔던 대부분의 여성들은 긍정적인 경험을 가지고
+있다.
+
+언어 장벽은 영어에 익숙하지 않은 몇몇 사람들에게 문제가 될 수도 있다.
+ 언어의 훌륭한 구사는 메일링 리스트에서 올바르게 자신의 생각을
+표현하기 위하여 필요하다. 그래서 여러분은 이메일을 보내기 전에
+영어를 올바르게 사용하고 있는지를 체크하는 것이 바람직하다.
+
+
+여러분의 변경을 나누어라
+------------------------
+
+리눅스 커널 커뮤니티는 한꺼번에 굉장히 큰 코드의 묶음을 쉽게
+받아들이지 않는다. 변경은 적절하게 소개되고, 검토되고, 각각의
+부분으로 작게 나누어져야 한다. 이것은 회사에서 하는 것과는 정확히
+반대되는 것이다. 여러분들의 제안은 개발 초기에 일찍이 소개되야 한다.
+그래서 여러분들은 자신이 하고 있는 것에 관하여 피드백을 받을 수 있게
+된다. 커뮤니티가 여러분들이 커뮤니티와 함께 일하고 있다는 것을
+느끼도록 만들고 커뮤니티가 여러분의 기능을 위한 쓰레기 장으로서
+사용되지 않고 있다는 것을 느끼게 하자. 그러나 메일링 리스트에 한번에
+50개의 이메일을 보내지는 말아라. 여러분들의 일련의 패치들은 항상
+더 작아야 한다.
+
+패치를 나누는 이유는 다음과 같다.
+
+1) 작은 패치들은 여러분의 패치들이 적용될 수 있는 확률을 높여준다.
+ 왜냐하면 다른 사람들은 정확성을 검증하기 위하여 많은 시간과 노력을
+ 들이기를 원하지 않는다. 5줄의 패치는 메인트너가 거의 몇 초간 힐끗
+ 보면 적용될 수 있다. 그러나 500 줄의 패치는 정확성을 검토하기 위하여
+ 몇시간이 걸릴 수도 있다(걸리는 시간은 패치의 크기 혹은 다른 것에
+ 비례하여 기하급수적으로 늘어난다).
+
+ 패치를 작게 만드는 것은 무엇인가 잘못되었을 때 디버그하는 것을
+ 쉽게 만든다. 즉, 그렇게 만드는 것은 매우 큰 패치를 적용한 후에
+ 조사하는 것 보다 작은 패치를 적용한 후에 (그리고 몇몇의 것이
+ 깨졌을 때) 하나씩 패치들을 제거해가며 디버그 하기 쉽도록 만들어 준다.
+
+2) 작은 패치들을 보내는 것뿐만 아니라 패치들을 제출하기전에 재작성하고
+ 간단하게(혹은 간단한게 재배치하여) 하는 것도 중요하다.
+
+여기에 커널 개발자 Al Viro의 이야기가 있다.
+ "학생의 수학 숙제를 채점하는 선생님을 생각해보라. 선생님은 학생들이
+ 답을 얻을때까지 겪은 시행착오를 보길 원하지 않는다. 선생님들은
+ 간결하고 가장 뛰어난 답을 보길 원한다. 훌륭한 학생은 이것을 알고
+ 마지막으로 답을 얻기 전 중간 과정들을 제출하진 않는다.
+
+ 커널 개발도 마찬가지이다. 메인트너들과 검토하는 사람들은 문제를
+ 풀어나가는 과정속에 숨겨진 과정을 보길 원하진 않는다. 그들은
+ 간결하고 멋진 답을 보길 원한다."
+
+커뮤니티와 함께 일하며 뛰어난 답을 찾고 여러분들의 완성되지 않은 일들
+사이에 균형을 유지해야 하는 어려움이 있을 수 있다. 그러므로 프로세스의
+초반에 여러분의 일을 향상시키기위한 피드백을 얻는 것 뿐만 아니라
+여러분들의 변경들을 작은 묶음으로 유지해서 심지어는 여러분의 작업의
+모든 부분이 지금은 포함될 준비가 되어있지 않지만 작은 부분은 이미
+받아들여질 수 있도록 유지하는 것이 바람직하다.
+
+또한 완성되지 않았고 "나중에 수정될 것이다." 와 같은 것들은 포함하는
+패치들은 받아들여지지 않을 것이라는 점을 유념하라.
+
+변경을 정당화해라
+-----------------
+
+여러분들의 나누어진 패치들을 리눅스 커뮤니티가 왜 반영해야 하는지를
+알도록 하는 것은 매우 중요하다. 새로운 기능들이 필요하고 유용하다는
+것은 반드시 그에 맞는 이유가 있어야 한다.
+
+
+변경을 문서화해라
+-----------------
+
+여러분이 패치를 보내려 할때는 여러분이 무엇을 말하려고 하는지를 충분히
+생각하여 이메일을 작성해야 한다. 이 정보는 패치를 위한 ChangeLog가 될
+것이다. 그리고 항상 그 내용을 보길 원하는 모든 사람들을 위해 보존될
+것이다. 패치는 완벽하게 다음과 같은 내용들을 포함하여 설명해야 한다.
+ - 변경이 왜 필요한지
+ - 패치에 관한 전체 설계 어프로치
+ - 구현 상세들
+ - 테스트 결과들
+
+이것이 무엇인지 더 자세한 것을 알고 싶다면 다음 문서의 ChageLog 항을 봐라.
+ "The Perfect Patch"
+ http://www.zip.com.au/~akpm/linux/patches/stuff/tpp.txt
+
+
+
+
+이 모든 것을 하는 것은 매우 어려운 일이다. 완벽히 소화하는 데는 적어도 몇년이
+걸릴 수도 있다. 많은 인내와 결의가 필요한 계속되는 개선의 과정이다. 그러나
+가능한한 포기하지 말라. 많은 사람들은 이전부터 해왔던 것이고 그 사람들도
+정확하게 여러분들이 지금 서 있는 그 곳부터 시작했었다.
+
+
+
+
+----------
+"개발 프로세스"(http://linux.tar.gz/articles/2.6-development_process) 섹션을
+작성하는데 있어 참고할 문서를 사용하도록 허락해준 Paolo Ciarrocchi에게
+감사한다. 여러분들이 말해야 할 것과 말해서는 안되는 것의 목록 중 일부를 제공해준
+Randy Dunlap과 Gerrit Huizenga에게 감사한다. 또한 검토와 의견 그리고
+공헌을 아끼지 않은 Pat Mochel, Hanna Linder, Randy Dunlap, Kay Sievers,
+Vojtech Pavlik, Jan Kara, Josh Boyer, Kees Cook, Andrew Morton, Andi Kleen,
+Vadim Lobanov, Jesper Juhl, Adrian Bunk, Keri Harris, Frans Pop,
+David A. Wheeler, Junio Hamano, Michael Kerrisk, and Alex Shepard에게도 감사를 전한다.
+그들의 도움이 없었다면 이 문서는 존재하지 않았을 것이다.
+
+
+
+메인트너: Greg Kroah-Hartman <greg@kroah.com>
diff --git a/Documentation/lguest/Makefile b/Documentation/lguest/Makefile
index 31e794e..c0b7a45 100644
--- a/Documentation/lguest/Makefile
+++ b/Documentation/lguest/Makefile
@@ -13,7 +13,9 @@
CFLAGS:=-Wall -Wmissing-declarations -Wmissing-prototypes -O3 -Wl,-T,lguest.lds
LDLIBS:=-lz
-
+# Removing this works for some versions of ld.so (eg. Ubuntu Feisty) and
+# not others (eg. FC7).
+LDFLAGS+=-static
all: lguest.lds lguest
# The linker script on x86 is so complex the only way of creating one
diff --git a/Documentation/memory-hotplug.txt b/Documentation/memory-hotplug.txt
new file mode 100644
index 0000000..5fbcc22
--- /dev/null
+++ b/Documentation/memory-hotplug.txt
@@ -0,0 +1,322 @@
+==============
+Memory Hotplug
+==============
+
+Last Updated: Jul 28 2007
+
+This document is about memory hotplug including how-to-use and current status.
+Because Memory Hotplug is still under development, contents of this text will
+be changed often.
+
+1. Introduction
+ 1.1 purpose of memory hotplug
+ 1.2. Phases of memory hotplug
+ 1.3. Unit of Memory online/offline operation
+2. Kernel Configuration
+3. sysfs files for memory hotplug
+4. Physical memory hot-add phase
+ 4.1 Hardware(Firmware) Support
+ 4.2 Notify memory hot-add event by hand
+5. Logical Memory hot-add phase
+ 5.1. State of memory
+ 5.2. How to online memory
+6. Logical memory remove
+ 6.1 Memory offline and ZONE_MOVABLE
+ 6.2. How to offline memory
+7. Physical memory remove
+8. Future Work List
+
+Note(1): x86_64's has special implementation for memory hotplug.
+ This text does not describe it.
+Note(2): This text assumes that sysfs is mounted at /sys.
+
+
+---------------
+1. Introduction
+---------------
+
+1.1 purpose of memory hotplug
+------------
+Memory Hotplug allows users to increase/decrease the amount of memory.
+Generally, there are two purposes.
+
+(A) For changing the amount of memory.
+ This is to allow a feature like capacity on demand.
+(B) For installing/removing DIMMs or NUMA-nodes physically.
+ This is to exchange DIMMs/NUMA-nodes, reduce power consumption, etc.
+
+(A) is required by highly virtualized environments and (B) is required by
+hardware which supports memory power management.
+
+Linux memory hotplug is designed for both purpose.
+
+
+1.2. Phases of memory hotplug
+---------------
+There are 2 phases in Memory Hotplug.
+ 1) Physical Memory Hotplug phase
+ 2) Logical Memory Hotplug phase.
+
+The First phase is to communicate hardware/firmware and make/erase
+environment for hotplugged memory. Basically, this phase is necessary
+for the purpose (B), but this is good phase for communication between
+highly virtualized environments too.
+
+When memory is hotplugged, the kernel recognizes new memory, makes new memory
+management tables, and makes sysfs files for new memory's operation.
+
+If firmware supports notification of connection of new memory to OS,
+this phase is triggered automatically. ACPI can notify this event. If not,
+"probe" operation by system administration is used instead.
+(see Section 4.).
+
+Logical Memory Hotplug phase is to change memory state into
+avaiable/unavailable for users. Amount of memory from user's view is
+changed by this phase. The kernel makes all memory in it as free pages
+when a memory range is available.
+
+In this document, this phase is described as online/offline.
+
+Logical Memory Hotplug phase is triggred by write of sysfs file by system
+administrator. For the hot-add case, it must be executed after Physical Hotplug
+phase by hand.
+(However, if you writes udev's hotplug scripts for memory hotplug, these
+ phases can be execute in seamless way.)
+
+
+1.3. Unit of Memory online/offline operation
+------------
+Memory hotplug uses SPARSEMEM memory model. SPARSEMEM divides the whole memory
+into chunks of the same size. The chunk is called a "section". The size of
+a section is architecture dependent. For example, power uses 16MiB, ia64 uses
+1GiB. The unit of online/offline operation is "one section". (see Section 3.)
+
+To determine the size of sections, please read this file:
+
+/sys/devices/system/memory/block_size_bytes
+
+This file shows the size of sections in byte.
+
+-----------------------
+2. Kernel Configuration
+-----------------------
+To use memory hotplug feature, kernel must be compiled with following
+config options.
+
+- For all memory hotplug
+ Memory model -> Sparse Memory (CONFIG_SPARSEMEM)
+ Allow for memory hot-add (CONFIG_MEMORY_HOTPLUG)
+
+- To enable memory removal, the followings are also necessary
+ Allow for memory hot remove (CONFIG_MEMORY_HOTREMOVE)
+ Page Migration (CONFIG_MIGRATION)
+
+- For ACPI memory hotplug, the followings are also necessary
+ Memory hotplug (under ACPI Support menu) (CONFIG_ACPI_HOTPLUG_MEMORY)
+ This option can be kernel module.
+
+- As a related configuration, if your box has a feature of NUMA-node hotplug
+ via ACPI, then this option is necessary too.
+ ACPI0004,PNP0A05 and PNP0A06 Container Driver (under ACPI Support menu)
+ (CONFIG_ACPI_CONTAINER).
+ This option can be kernel module too.
+
+--------------------------------
+3 sysfs files for memory hotplug
+--------------------------------
+All sections have their device information under /sys/devices/system/memory as
+
+/sys/devices/system/memory/memoryXXX
+(XXX is section id.)
+
+Now, XXX is defined as start_address_of_section / section_size.
+
+For example, assume 1GiB section size. A device for a memory starting at
+0x100000000 is /sys/device/system/memory/memory4
+(0x100000000 / 1Gib = 4)
+This device covers address range [0x100000000 ... 0x140000000)
+
+Under each section, you can see 3 files.
+
+/sys/devices/system/memory/memoryXXX/phys_index
+/sys/devices/system/memory/memoryXXX/phys_device
+/sys/devices/system/memory/memoryXXX/state
+
+'phys_index' : read-only and contains section id, same as XXX.
+'state' : read-write
+ at read: contains online/offline state of memory.
+ at write: user can specify "online", "offline" command
+'phys_device': read-only: designed to show the name of physical memory device.
+ This is not well implemented now.
+
+NOTE:
+ These directories/files appear after physical memory hotplug phase.
+
+
+--------------------------------
+4. Physical memory hot-add phase
+--------------------------------
+
+4.1 Hardware(Firmware) Support
+------------
+On x86_64/ia64 platform, memory hotplug by ACPI is supported.
+
+In general, the firmware (ACPI) which supports memory hotplug defines
+memory class object of _HID "PNP0C80". When a notify is asserted to PNP0C80,
+Linux's ACPI handler does hot-add memory to the system and calls a hotplug udev
+script. This will be done automatically.
+
+But scripts for memory hotplug are not contained in generic udev package(now).
+You may have to write it by yourself or online/offline memory by hand.
+Please see "How to online memory", "How to offline memory" in this text.
+
+If firmware supports NUMA-node hotplug, and defines an object _HID "ACPI0004",
+"PNP0A05", or "PNP0A06", notification is asserted to it, and ACPI handler
+calls hotplug code for all of objects which are defined in it.
+If memory device is found, memory hotplug code will be called.
+
+
+4.2 Notify memory hot-add event by hand
+------------
+In some environments, especially virtualized environment, firmware will not
+notify memory hotplug event to the kernel. For such environment, "probe"
+interface is supported. This interface depends on CONFIG_ARCH_MEMORY_PROBE.
+
+Now, CONFIG_ARCH_MEMORY_PROBE is supported only by powerpc but it does not
+contain highly architecture codes. Please add config if you need "probe"
+interface.
+
+Probe interface is located at
+/sys/devices/system/memory/probe
+
+You can tell the physical address of new memory to the kernel by
+
+% echo start_address_of_new_memory > /sys/devices/system/memory/probe
+
+Then, [start_address_of_new_memory, start_address_of_new_memory + section_size)
+memory range is hot-added. In this case, hotplug script is not called (in
+current implementation). You'll have to online memory by yourself.
+Please see "How to online memory" in this text.
+
+
+
+------------------------------
+5. Logical Memory hot-add phase
+------------------------------
+
+5.1. State of memory
+------------
+To see (online/offline) state of memory section, read 'state' file.
+
+% cat /sys/device/system/memory/memoryXXX/state
+
+
+If the memory section is online, you'll read "online".
+If the memory section is offline, you'll read "offline".
+
+
+5.2. How to online memory
+------------
+Even if the memory is hot-added, it is not at ready-to-use state.
+For using newly added memory, you have to "online" the memory section.
+
+For onlining, you have to write "online" to the section's state file as:
+
+% echo online > /sys/devices/system/memory/memoryXXX/state
+
+After this, section memoryXXX's state will be 'online' and the amount of
+available memory will be increased.
+
+Currently, newly added memory is added as ZONE_NORMAL (for powerpc, ZONE_DMA).
+This may be changed in future.
+
+
+
+------------------------
+6. Logical memory remove
+------------------------
+
+6.1 Memory offline and ZONE_MOVABLE
+------------
+Memory offlining is more complicated than memory online. Because memory offline
+has to make the whole memory section be unused, memory offline can fail if
+the section includes memory which cannot be freed.
+
+In general, memory offline can use 2 techniques.
+
+(1) reclaim and free all memory in the section.
+(2) migrate all pages in the section.
+
+In the current implementation, Linux's memory offline uses method (2), freeing
+all pages in the section by page migration. But not all pages are
+migratable. Under current Linux, migratable pages are anonymous pages and
+page caches. For offlining a section by migration, the kernel has to guarantee
+that the section contains only migratable pages.
+
+Now, a boot option for making a section which consists of migratable pages is
+supported. By specifying "kernelcore=" or "movablecore=" boot option, you can
+create ZONE_MOVABLE...a zone which is just used for movable pages.
+(See also Documentation/kernel-parameters.txt)
+
+Assume the system has "TOTAL" amount of memory at boot time, this boot option
+creates ZONE_MOVABLE as following.
+
+1) When kernelcore=YYYY boot option is used,
+ Size of memory not for movable pages (not for offline) is YYYY.
+ Size of memory for movable pages (for offline) is TOTAL-YYYY.
+
+2) When movablecore=ZZZZ boot option is used,
+ Size of memory not for movable pages (not for offline) is TOTAL - ZZZZ.
+ Size of memory for movable pages (for offline) is ZZZZ.
+
+
+Note) Unfortunately, there is no information to show which section belongs
+to ZONE_MOVABLE. This is TBD.
+
+
+6.2. How to offline memory
+------------
+You can offline a section by using the same sysfs interface that was used in
+memory onlining.
+
+% echo offline > /sys/devices/system/memory/memoryXXX/state
+
+If offline succeeds, the state of the memory section is changed to be "offline".
+If it fails, some error core (like -EBUSY) will be returned by the kernel.
+Even if a section does not belong to ZONE_MOVABLE, you can try to offline it.
+If it doesn't contain 'unmovable' memory, you'll get success.
+
+A section under ZONE_MOVABLE is considered to be able to be offlined easily.
+But under some busy state, it may return -EBUSY. Even if a memory section
+cannot be offlined due to -EBUSY, you can retry offlining it and may be able to
+offline it (or not).
+(For example, a page is referred to by some kernel internal call and released
+ soon.)
+
+Consideration:
+Memory hotplug's design direction is to make the possibility of memory offlining
+higher and to guarantee unplugging memory under any situation. But it needs
+more work. Returning -EBUSY under some situation may be good because the user
+can decide to retry more or not by himself. Currently, memory offlining code
+does some amount of retry with 120 seconds timeout.
+
+-------------------------
+7. Physical memory remove
+-------------------------
+Need more implementation yet....
+ - Notification completion of remove works by OS to firmware.
+ - Guard from remove if not yet.
+
+--------------
+8. Future Work
+--------------
+ - allowing memory hot-add to ZONE_MOVABLE. maybe we need some switch like
+ sysctl or new control file.
+ - showing memory section and physical device relationship.
+ - showing memory section and node relationship (maybe good for NUMA)
+ - showing memory section is under ZONE_MOVABLE or not
+ - test and make it better memory offlining.
+ - support HugeTLB page migration and offlining.
+ - memmap removing at memory offline.
+ - physical remove memory.
+
diff --git a/Documentation/sched-design-CFS.txt b/Documentation/sched-design-CFS.txt
index 16feebb..84901e7 100644
--- a/Documentation/sched-design-CFS.txt
+++ b/Documentation/sched-design-CFS.txt
@@ -83,7 +83,7 @@
CFS uses nanosecond granularity accounting and does not rely on any
jiffies or other HZ detail. Thus the CFS scheduler has no notion of
'timeslices' and has no heuristics whatsoever. There is only one
- central tunable:
+ central tunable (you have to switch on CONFIG_SCHED_DEBUG):
/proc/sys/kernel/sched_granularity_ns
diff --git a/Documentation/sched-nice-design.txt b/Documentation/sched-nice-design.txt
new file mode 100644
index 0000000..e2bae5a
--- /dev/null
+++ b/Documentation/sched-nice-design.txt
@@ -0,0 +1,108 @@
+This document explains the thinking about the revamped and streamlined
+nice-levels implementation in the new Linux scheduler.
+
+Nice levels were always pretty weak under Linux and people continuously
+pestered us to make nice +19 tasks use up much less CPU time.
+
+Unfortunately that was not that easy to implement under the old
+scheduler, (otherwise we'd have done it long ago) because nice level
+support was historically coupled to timeslice length, and timeslice
+units were driven by the HZ tick, so the smallest timeslice was 1/HZ.
+
+In the O(1) scheduler (in 2003) we changed negative nice levels to be
+much stronger than they were before in 2.4 (and people were happy about
+that change), and we also intentionally calibrated the linear timeslice
+rule so that nice +19 level would be _exactly_ 1 jiffy. To better
+understand it, the timeslice graph went like this (cheesy ASCII art
+alert!):
+
+
+ A
+ \ | [timeslice length]
+ \ |
+ \ |
+ \ |
+ \ |
+ \|___100msecs
+ |^ . _
+ | ^ . _
+ | ^ . _
+ -*----------------------------------*-----> [nice level]
+ -20 | +19
+ |
+ |
+
+So that if someone wanted to really renice tasks, +19 would give a much
+bigger hit than the normal linear rule would do. (The solution of
+changing the ABI to extend priorities was discarded early on.)
+
+This approach worked to some degree for some time, but later on with
+HZ=1000 it caused 1 jiffy to be 1 msec, which meant 0.1% CPU usage which
+we felt to be a bit excessive. Excessive _not_ because it's too small of
+a CPU utilization, but because it causes too frequent (once per
+millisec) rescheduling. (and would thus trash the cache, etc. Remember,
+this was long ago when hardware was weaker and caches were smaller, and
+people were running number crunching apps at nice +19.)
+
+So for HZ=1000 we changed nice +19 to 5msecs, because that felt like the
+right minimal granularity - and this translates to 5% CPU utilization.
+But the fundamental HZ-sensitive property for nice+19 still remained,
+and we never got a single complaint about nice +19 being too _weak_ in
+terms of CPU utilization, we only got complaints about it (still) being
+too _strong_ :-)
+
+To sum it up: we always wanted to make nice levels more consistent, but
+within the constraints of HZ and jiffies and their nasty design level
+coupling to timeslices and granularity it was not really viable.
+
+The second (less frequent but still periodically occuring) complaint
+about Linux's nice level support was its assymetry around the origo
+(which you can see demonstrated in the picture above), or more
+accurately: the fact that nice level behavior depended on the _absolute_
+nice level as well, while the nice API itself is fundamentally
+"relative":
+
+ int nice(int inc);
+
+ asmlinkage long sys_nice(int increment)
+
+(the first one is the glibc API, the second one is the syscall API.)
+Note that the 'inc' is relative to the current nice level. Tools like
+bash's "nice" command mirror this relative API.
+
+With the old scheduler, if you for example started a niced task with +1
+and another task with +2, the CPU split between the two tasks would
+depend on the nice level of the parent shell - if it was at nice -10 the
+CPU split was different than if it was at +5 or +10.
+
+A third complaint against Linux's nice level support was that negative
+nice levels were not 'punchy enough', so lots of people had to resort to
+run audio (and other multimedia) apps under RT priorities such as
+SCHED_FIFO. But this caused other problems: SCHED_FIFO is not starvation
+proof, and a buggy SCHED_FIFO app can also lock up the system for good.
+
+The new scheduler in v2.6.23 addresses all three types of complaints:
+
+To address the first complaint (of nice levels being not "punchy"
+enough), the scheduler was decoupled from 'time slice' and HZ concepts
+(and granularity was made a separate concept from nice levels) and thus
+it was possible to implement better and more consistent nice +19
+support: with the new scheduler nice +19 tasks get a HZ-independent
+1.5%, instead of the variable 3%-5%-9% range they got in the old
+scheduler.
+
+To address the second complaint (of nice levels not being consistent),
+the new scheduler makes nice(1) have the same CPU utilization effect on
+tasks, regardless of their absolute nice levels. So on the new
+scheduler, running a nice +10 and a nice 11 task has the same CPU
+utilization "split" between them as running a nice -5 and a nice -4
+task. (one will get 55% of the CPU, the other 45%.) That is why nice
+levels were changed to be "multiplicative" (or exponential) - that way
+it does not matter which nice level you start out from, the 'relative
+result' will always be the same.
+
+The third complaint (of negative nice levels not being "punchy" enough
+and forcing audio apps to run under the more dangerous SCHED_FIFO
+scheduling policy) is addressed by the new scheduler almost
+automatically: stronger negative nice levels are an automatic
+side-effect of the recalibrated dynamic range of nice levels.
diff --git a/Documentation/sysrq.txt b/Documentation/sysrq.txt
index ba328f2..ef19142 100644
--- a/Documentation/sysrq.txt
+++ b/Documentation/sysrq.txt
@@ -1,6 +1,6 @@
Linux Magic System Request Key Hacks
Documentation for sysrq.c
-Last update: 2007-MAR-14
+Last update: 2007-AUG-04
* What is the magic SysRq key?
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -78,7 +78,7 @@
'g' - Used by kgdb on ppc and sh platforms.
'h' - Will display help (actually any other key than those listed
- above will display help. but 'h' is easy to remember :-)
+ here will display help. but 'h' is easy to remember :-)
'i' - Send a SIGKILL to all processes, except for init.
diff --git a/Documentation/thinkpad-acpi.txt b/Documentation/thinkpad-acpi.txt
index 6711fbc..eb2f598 100644
--- a/Documentation/thinkpad-acpi.txt
+++ b/Documentation/thinkpad-acpi.txt
@@ -105,10 +105,10 @@
as a driver attribute (see below).
Sysfs driver attributes are on the driver's sysfs attribute space,
-for 2.6.20 this is /sys/bus/platform/drivers/thinkpad-acpi/.
+for 2.6.20 this is /sys/bus/platform/drivers/thinkpad_acpi/.
Sysfs device attributes are on the driver's sysfs attribute space,
-for 2.6.20 this is /sys/devices/platform/thinkpad-acpi/.
+for 2.6.20 this is /sys/devices/platform/thinkpad_acpi/.
Driver version
--------------
diff --git a/Documentation/vm/numa_memory_policy.txt b/Documentation/vm/numa_memory_policy.txt
new file mode 100644
index 0000000..8242f52
--- /dev/null
+++ b/Documentation/vm/numa_memory_policy.txt
@@ -0,0 +1,332 @@
+
+What is Linux Memory Policy?
+
+In the Linux kernel, "memory policy" determines from which node the kernel will
+allocate memory in a NUMA system or in an emulated NUMA system. Linux has
+supported platforms with Non-Uniform Memory Access architectures since 2.4.?.
+The current memory policy support was added to Linux 2.6 around May 2004. This
+document attempts to describe the concepts and APIs of the 2.6 memory policy
+support.
+
+Memory policies should not be confused with cpusets (Documentation/cpusets.txt)
+which is an administrative mechanism for restricting the nodes from which
+memory may be allocated by a set of processes. Memory policies are a
+programming interface that a NUMA-aware application can take advantage of. When
+both cpusets and policies are applied to a task, the restrictions of the cpuset
+takes priority. See "MEMORY POLICIES AND CPUSETS" below for more details.
+
+MEMORY POLICY CONCEPTS
+
+Scope of Memory Policies
+
+The Linux kernel supports _scopes_ of memory policy, described here from
+most general to most specific:
+
+ System Default Policy: this policy is "hard coded" into the kernel. It
+ is the policy that governs all page allocations that aren't controlled
+ by one of the more specific policy scopes discussed below. When the
+ system is "up and running", the system default policy will use "local
+ allocation" described below. However, during boot up, the system
+ default policy will be set to interleave allocations across all nodes
+ with "sufficient" memory, so as not to overload the initial boot node
+ with boot-time allocations.
+
+ Task/Process Policy: this is an optional, per-task policy. When defined
+ for a specific task, this policy controls all page allocations made by or
+ on behalf of the task that aren't controlled by a more specific scope.
+ If a task does not define a task policy, then all page allocations that
+ would have been controlled by the task policy "fall back" to the System
+ Default Policy.
+
+ The task policy applies to the entire address space of a task. Thus,
+ it is inheritable, and indeed is inherited, across both fork()
+ [clone() w/o the CLONE_VM flag] and exec*(). This allows a parent task
+ to establish the task policy for a child task exec()'d from an
+ executable image that has no awareness of memory policy. See the
+ MEMORY POLICY APIS section, below, for an overview of the system call
+ that a task may use to set/change it's task/process policy.
+
+ In a multi-threaded task, task policies apply only to the thread
+ [Linux kernel task] that installs the policy and any threads
+ subsequently created by that thread. Any sibling threads existing
+ at the time a new task policy is installed retain their current
+ policy.
+
+ A task policy applies only to pages allocated after the policy is
+ installed. Any pages already faulted in by the task when the task
+ changes its task policy remain where they were allocated based on
+ the policy at the time they were allocated.
+
+ VMA Policy: A "VMA" or "Virtual Memory Area" refers to a range of a task's
+ virtual adddress space. A task may define a specific policy for a range
+ of its virtual address space. See the MEMORY POLICIES APIS section,
+ below, for an overview of the mbind() system call used to set a VMA
+ policy.
+
+ A VMA policy will govern the allocation of pages that back this region of
+ the address space. Any regions of the task's address space that don't
+ have an explicit VMA policy will fall back to the task policy, which may
+ itself fall back to the System Default Policy.
+
+ VMA policies have a few complicating details:
+
+ VMA policy applies ONLY to anonymous pages. These include pages
+ allocated for anonymous segments, such as the task stack and heap, and
+ any regions of the address space mmap()ed with the MAP_ANONYMOUS flag.
+ If a VMA policy is applied to a file mapping, it will be ignored if
+ the mapping used the MAP_SHARED flag. If the file mapping used the
+ MAP_PRIVATE flag, the VMA policy will only be applied when an
+ anonymous page is allocated on an attempt to write to the mapping--
+ i.e., at Copy-On-Write.
+
+ VMA policies are shared between all tasks that share a virtual address
+ space--a.k.a. threads--independent of when the policy is installed; and
+ they are inherited across fork(). However, because VMA policies refer
+ to a specific region of a task's address space, and because the address
+ space is discarded and recreated on exec*(), VMA policies are NOT
+ inheritable across exec(). Thus, only NUMA-aware applications may
+ use VMA policies.
+
+ A task may install a new VMA policy on a sub-range of a previously
+ mmap()ed region. When this happens, Linux splits the existing virtual
+ memory area into 2 or 3 VMAs, each with it's own policy.
+
+ By default, VMA policy applies only to pages allocated after the policy
+ is installed. Any pages already faulted into the VMA range remain
+ where they were allocated based on the policy at the time they were
+ allocated. However, since 2.6.16, Linux supports page migration via
+ the mbind() system call, so that page contents can be moved to match
+ a newly installed policy.
+
+ Shared Policy: Conceptually, shared policies apply to "memory objects"
+ mapped shared into one or more tasks' distinct address spaces. An
+ application installs a shared policies the same way as VMA policies--using
+ the mbind() system call specifying a range of virtual addresses that map
+ the shared object. However, unlike VMA policies, which can be considered
+ to be an attribute of a range of a task's address space, shared policies
+ apply directly to the shared object. Thus, all tasks that attach to the
+ object share the policy, and all pages allocated for the shared object,
+ by any task, will obey the shared policy.
+
+ As of 2.6.22, only shared memory segments, created by shmget() or
+ mmap(MAP_ANONYMOUS|MAP_SHARED), support shared policy. When shared
+ policy support was added to Linux, the associated data structures were
+ added to hugetlbfs shmem segments. At the time, hugetlbfs did not
+ support allocation at fault time--a.k.a lazy allocation--so hugetlbfs
+ shmem segments were never "hooked up" to the shared policy support.
+ Although hugetlbfs segments now support lazy allocation, their support
+ for shared policy has not been completed.
+
+ As mentioned above [re: VMA policies], allocations of page cache
+ pages for regular files mmap()ed with MAP_SHARED ignore any VMA
+ policy installed on the virtual address range backed by the shared
+ file mapping. Rather, shared page cache pages, including pages backing
+ private mappings that have not yet been written by the task, follow
+ task policy, if any, else System Default Policy.
+
+ The shared policy infrastructure supports different policies on subset
+ ranges of the shared object. However, Linux still splits the VMA of
+ the task that installs the policy for each range of distinct policy.
+ Thus, different tasks that attach to a shared memory segment can have
+ different VMA configurations mapping that one shared object. This
+ can be seen by examining the /proc/<pid>/numa_maps of tasks sharing
+ a shared memory region, when one task has installed shared policy on
+ one or more ranges of the region.
+
+Components of Memory Policies
+
+ A Linux memory policy is a tuple consisting of a "mode" and an optional set
+ of nodes. The mode determine the behavior of the policy, while the
+ optional set of nodes can be viewed as the arguments to the behavior.
+
+ Internally, memory policies are implemented by a reference counted
+ structure, struct mempolicy. Details of this structure will be discussed
+ in context, below, as required to explain the behavior.
+
+ Note: in some functions AND in the struct mempolicy itself, the mode
+ is called "policy". However, to avoid confusion with the policy tuple,
+ this document will continue to use the term "mode".
+
+ Linux memory policy supports the following 4 behavioral modes:
+
+ Default Mode--MPOL_DEFAULT: The behavior specified by this mode is
+ context or scope dependent.
+
+ As mentioned in the Policy Scope section above, during normal
+ system operation, the System Default Policy is hard coded to
+ contain the Default mode.
+
+ In this context, default mode means "local" allocation--that is
+ attempt to allocate the page from the node associated with the cpu
+ where the fault occurs. If the "local" node has no memory, or the
+ node's memory can be exhausted [no free pages available], local
+ allocation will "fallback to"--attempt to allocate pages from--
+ "nearby" nodes, in order of increasing "distance".
+
+ Implementation detail -- subject to change: "Fallback" uses
+ a per node list of sibling nodes--called zonelists--built at
+ boot time, or when nodes or memory are added or removed from
+ the system [memory hotplug]. These per node zonelist are
+ constructed with nodes in order of increasing distance based
+ on information provided by the platform firmware.
+
+ When a task/process policy or a shared policy contains the Default
+ mode, this also means "local allocation", as described above.
+
+ In the context of a VMA, Default mode means "fall back to task
+ policy"--which may or may not specify Default mode. Thus, Default
+ mode can not be counted on to mean local allocation when used
+ on a non-shared region of the address space. However, see
+ MPOL_PREFERRED below.
+
+ The Default mode does not use the optional set of nodes.
+
+ MPOL_BIND: This mode specifies that memory must come from the
+ set of nodes specified by the policy.
+
+ The memory policy APIs do not specify an order in which the nodes
+ will be searched. However, unlike "local allocation", the Bind
+ policy does not consider the distance between the nodes. Rather,
+ allocations will fallback to the nodes specified by the policy in
+ order of numeric node id. Like everything in Linux, this is subject
+ to change.
+
+ MPOL_PREFERRED: This mode specifies that the allocation should be
+ attempted from the single node specified in the policy. If that
+ allocation fails, the kernel will search other nodes, exactly as
+ it would for a local allocation that started at the preferred node
+ in increasing distance from the preferred node. "Local" allocation
+ policy can be viewed as a Preferred policy that starts at the node
+ containing the cpu where the allocation takes place.
+
+ Internally, the Preferred policy uses a single node--the
+ preferred_node member of struct mempolicy. A "distinguished
+ value of this preferred_node, currently '-1', is interpreted
+ as "the node containing the cpu where the allocation takes
+ place"--local allocation. This is the way to specify
+ local allocation for a specific range of addresses--i.e. for
+ VMA policies.
+
+ MPOL_INTERLEAVED: This mode specifies that page allocations be
+ interleaved, on a page granularity, across the nodes specified in
+ the policy. This mode also behaves slightly differently, based on
+ the context where it is used:
+
+ For allocation of anonymous pages and shared memory pages,
+ Interleave mode indexes the set of nodes specified by the policy
+ using the page offset of the faulting address into the segment
+ [VMA] containing the address modulo the number of nodes specified
+ by the policy. It then attempts to allocate a page, starting at
+ the selected node, as if the node had been specified by a Preferred
+ policy or had been selected by a local allocation. That is,
+ allocation will follow the per node zonelist.
+
+ For allocation of page cache pages, Interleave mode indexes the set
+ of nodes specified by the policy using a node counter maintained
+ per task. This counter wraps around to the lowest specified node
+ after it reaches the highest specified node. This will tend to
+ spread the pages out over the nodes specified by the policy based
+ on the order in which they are allocated, rather than based on any
+ page offset into an address range or file. During system boot up,
+ the temporary interleaved system default policy works in this
+ mode.
+
+MEMORY POLICY APIs
+
+Linux supports 3 system calls for controlling memory policy. These APIS
+always affect only the calling task, the calling task's address space, or
+some shared object mapped into the calling task's address space.
+
+ Note: the headers that define these APIs and the parameter data types
+ for user space applications reside in a package that is not part of
+ the Linux kernel. The kernel system call interfaces, with the 'sys_'
+ prefix, are defined in <linux/syscalls.h>; the mode and flag
+ definitions are defined in <linux/mempolicy.h>.
+
+Set [Task] Memory Policy:
+
+ long set_mempolicy(int mode, const unsigned long *nmask,
+ unsigned long maxnode);
+
+ Set's the calling task's "task/process memory policy" to mode
+ specified by the 'mode' argument and the set of nodes defined
+ by 'nmask'. 'nmask' points to a bit mask of node ids containing
+ at least 'maxnode' ids.
+
+ See the set_mempolicy(2) man page for more details
+
+
+Get [Task] Memory Policy or Related Information
+
+ long get_mempolicy(int *mode,
+ const unsigned long *nmask, unsigned long maxnode,
+ void *addr, int flags);
+
+ Queries the "task/process memory policy" of the calling task, or
+ the policy or location of a specified virtual address, depending
+ on the 'flags' argument.
+
+ See the get_mempolicy(2) man page for more details
+
+
+Install VMA/Shared Policy for a Range of Task's Address Space
+
+ long mbind(void *start, unsigned long len, int mode,
+ const unsigned long *nmask, unsigned long maxnode,
+ unsigned flags);
+
+ mbind() installs the policy specified by (mode, nmask, maxnodes) as
+ a VMA policy for the range of the calling task's address space
+ specified by the 'start' and 'len' arguments. Additional actions
+ may be requested via the 'flags' argument.
+
+ See the mbind(2) man page for more details.
+
+MEMORY POLICY COMMAND LINE INTERFACE
+
+Although not strictly part of the Linux implementation of memory policy,
+a command line tool, numactl(8), exists that allows one to:
+
++ set the task policy for a specified program via set_mempolicy(2), fork(2) and
+ exec(2)
+
++ set the shared policy for a shared memory segment via mbind(2)
+
+The numactl(8) tool is packages with the run-time version of the library
+containing the memory policy system call wrappers. Some distributions
+package the headers and compile-time libraries in a separate development
+package.
+
+
+MEMORY POLICIES AND CPUSETS
+
+Memory policies work within cpusets as described above. For memory policies
+that require a node or set of nodes, the nodes are restricted to the set of
+nodes whose memories are allowed by the cpuset constraints. If the
+intersection of the set of nodes specified for the policy and the set of nodes
+allowed by the cpuset is the empty set, the policy is considered invalid and
+cannot be installed.
+
+The interaction of memory policies and cpusets can be problematic for a
+couple of reasons:
+
+1) the memory policy APIs take physical node id's as arguments. However, the
+ memory policy APIs do not provide a way to determine what nodes are valid
+ in the context where the application is running. An application MAY consult
+ the cpuset file system [directly or via an out of tree, and not generally
+ available, libcpuset API] to obtain this information, but then the
+ application must be aware that it is running in a cpuset and use what are
+ intended primarily as administrative APIs.
+
+ However, as long as the policy specifies at least one node that is valid
+ in the controlling cpuset, the policy can be used.
+
+2) when tasks in two cpusets share access to a memory region, such as shared
+ memory segments created by shmget() of mmap() with the MAP_ANONYMOUS and
+ MAP_SHARED flags, and any of the tasks install shared policy on the region,
+ only nodes whose memories are allowed in both cpusets may be used in the
+ policies. Again, obtaining this information requires "stepping outside"
+ the memory policy APIs, as well as knowing in what cpusets other task might
+ be attaching to the shared region, to use the cpuset information.
+ Furthermore, if the cpusets' allowed memory sets are disjoint, "local"
+ allocation is the only valid policy.
diff --git a/Documentation/vm/slabinfo.c b/Documentation/vm/slabinfo.c
index d4f21ff..1af7bd5 100644
--- a/Documentation/vm/slabinfo.c
+++ b/Documentation/vm/slabinfo.c
@@ -396,7 +396,7 @@
if (strcmp(s->name, "*") == 0)
return;
- printf("\nSlabcache: %-20s Aliases: %2d Order : %2d Objects: %d\n",
+ printf("\nSlabcache: %-20s Aliases: %2d Order : %2d Objects: %lu\n",
s->name, s->aliases, s->order, s->objects);
if (s->hwcache_align)
printf("** Hardware cacheline aligned\n");
diff --git a/Documentation/watchdog/00-INDEX b/Documentation/watchdog/00-INDEX
new file mode 100644
index 0000000..c3ea47e
--- /dev/null
+++ b/Documentation/watchdog/00-INDEX
@@ -0,0 +1,10 @@
+00-INDEX
+ - this file.
+pcwd-watchdog.txt
+ - documentation for Berkshire Products PC Watchdog ISA cards.
+src/
+ - directory holding watchdog related example programs.
+watchdog-api.txt
+ - description of the Linux Watchdog driver API.
+wdt.txt
+ - description of the Watchdog Timer Interfaces for Linux.
diff --git a/MAINTAINERS b/MAINTAINERS
index e65e96a..10a6f57 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -97,6 +97,12 @@
L: netdev@vger.kernel.org
S: Maintained
+3C59X NETWORK DRIVER
+P: Steffen Klassert
+M: klassert@mathematik.tu-chemnitz.de
+L: netdev@vger.kernel.org
+S: Maintained
+
3CR990 NETWORK DRIVER
P: David Dillow
M: dave@thedillows.org
@@ -161,11 +167,11 @@
P: Eric Van Hensbergen
M: ericvh@gmail.com
P: Ron Minnich
-M: rminnich@lanl.gov
+M: rminnich@sandia.gov
P: Latchesar Ionkov
M: lucho@ionkov.net
L: v9fs-developer@lists.sourceforge.net
-W: http://v9fs.sf.net
+W: http://swik.net/v9fs
T: git kernel.org:/pub/scm/linux/kernel/ericvh/v9fs.git
S: Maintained
@@ -612,6 +618,15 @@
W: http://xf.iksaif.net/acpi4asus
S: Maintained
+ASYNCHRONOUS TRANSFERS/TRANSFORMS API
+P: Dan Williams
+M: dan.j.williams@intel.com
+P: Shannon Nelson
+M: shannon.nelson@intel.com
+L: linux-kernel@vger.kernel.org
+W: http://sourceforge.net/projects/xscaleiop
+S: Supported
+
ATA OVER ETHERNET DRIVER
P: Ed L. Cashin
M: ecashin@coraid.com
@@ -664,7 +679,7 @@
AUDIT SUBSYSTEM
P: David Woodhouse
M: dwmw2@infradead.org
-L: linux-audit@redhat.com
+L: linux-audit@redhat.com (subscribers-only)
W: http://people.redhat.com/sgrubb/audit/
T: git kernel.org:/pub/scm/linux/kernel/git/dwmw2/audit-2.6.git
S: Maintained
@@ -994,7 +1009,7 @@
M: sfrench@samba.org
L: linux-cifs-client@lists.samba.org
L: samba-technical@lists.samba.org
-W: http://us1.samba.org/samba/Linux_CIFS_client.html
+W: http://linux-cifs.samba.org/
T: git kernel.org:/pub/scm/linux/kernel/git/sfrench/cifs-2.6.git
S: Supported
@@ -1277,11 +1292,13 @@
L: netdev@vger.kernel.org
S: Maintained
-DMA GENERIC MEMCPY SUBSYSTEM
+DMA GENERIC OFFLOAD ENGINE SUBSYSTEM
P: Shannon Nelson
M: shannon.nelson@intel.com
+P: Dan Williams
+M: dan.j.williams@intel.com
L: linux-kernel@vger.kernel.org
-S: Maintained
+S: Supported
DME1737 HARDWARE MONITOR DRIVER
P: Juerg Haefliger
@@ -1958,6 +1975,12 @@
L: linux-kernel@vger.kernel.org
S: Supported
+INTEL IOP-ADMA DMA DRIVER
+P: Dan Williams
+M: dan.j.williams@intel.com
+L: linux-kernel@vger.kernel.org
+S: Supported
+
INTEL IXP4XX RANDOM NUMBER GENERATOR SUPPORT
P: Deepak Saxena
M: dsaxena@plexity.net
@@ -3429,7 +3452,7 @@
TPM DEVICE DRIVER
P: Kylene Hall
-M: kjhall@us.ibm.com
+M: tpmdd-devel@lists.sourceforge.net
W: http://tpmdd.sourceforge.net
P: Marcel Selhorst
M: tpm@selhorst.net
diff --git a/Makefile b/Makefile
index 91759a6..f3229a4 100644
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
VERSION = 2
PATCHLEVEL = 6
SUBLEVEL = 23
-EXTRAVERSION =-rc2
+EXTRAVERSION =-rc3
NAME = Holy Dancing Manatees, Batman!
# *DOCUMENTATION*
diff --git a/arch/alpha/kernel/sys_titan.c b/arch/alpha/kernel/sys_titan.c
index 1d3c139..52c91cc 100644
--- a/arch/alpha/kernel/sys_titan.c
+++ b/arch/alpha/kernel/sys_titan.c
@@ -271,6 +271,19 @@
* Titan Family
*/
static void __init
+titan_request_irq(unsigned int irq, irq_handler_t handler,
+ unsigned long irqflags, const char *devname,
+ void *dev_id)
+{
+ int err;
+ err = request_irq(irq, handler, irqflags, devname, dev_id);
+ if (err) {
+ printk("titan_request_irq for IRQ %d returned %d; ignoring\n",
+ irq, err);
+ }
+}
+
+static void __init
titan_late_init(void)
{
/*
@@ -278,15 +291,15 @@
* all reported to the kernel as machine checks, so the handler
* is a nop so it can be called to count the individual events.
*/
- request_irq(63+16, titan_intr_nop, IRQF_DISABLED,
+ titan_request_irq(63+16, titan_intr_nop, IRQF_DISABLED,
"CChip Error", NULL);
- request_irq(62+16, titan_intr_nop, IRQF_DISABLED,
+ titan_request_irq(62+16, titan_intr_nop, IRQF_DISABLED,
"PChip 0 H_Error", NULL);
- request_irq(61+16, titan_intr_nop, IRQF_DISABLED,
+ titan_request_irq(61+16, titan_intr_nop, IRQF_DISABLED,
"PChip 1 H_Error", NULL);
- request_irq(60+16, titan_intr_nop, IRQF_DISABLED,
+ titan_request_irq(60+16, titan_intr_nop, IRQF_DISABLED,
"PChip 0 C_Error", NULL);
- request_irq(59+16, titan_intr_nop, IRQF_DISABLED,
+ titan_request_irq(59+16, titan_intr_nop, IRQF_DISABLED,
"PChip 1 C_Error", NULL);
/*
@@ -345,9 +358,9 @@
* Hook a couple of extra err interrupts that the
* common titan code won't.
*/
- request_irq(53+16, titan_intr_nop, IRQF_DISABLED,
+ titan_request_irq(53+16, titan_intr_nop, IRQF_DISABLED,
"NMI", NULL);
- request_irq(50+16, titan_intr_nop, IRQF_DISABLED,
+ titan_request_irq(50+16, titan_intr_nop, IRQF_DISABLED,
"Temperature Warning", NULL);
/*
diff --git a/arch/arm/configs/iop13xx_defconfig b/arch/arm/configs/iop13xx_defconfig
index 43c4a37..add03c9 100644
--- a/arch/arm/configs/iop13xx_defconfig
+++ b/arch/arm/configs/iop13xx_defconfig
@@ -1,12 +1,18 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.20-rc1-git5
-# Tue Dec 19 21:38:01 2006
+# Linux kernel version: 2.6.22
+# Thu Jul 19 15:57:52 2007
#
CONFIG_ARM=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+# CONFIG_GENERIC_GPIO is not set
# CONFIG_GENERIC_TIME is not set
+# CONFIG_GENERIC_CLOCKEVENTS is not set
CONFIG_MMU=y
+# CONFIG_NO_IOPORT is not set
CONFIG_GENERIC_HARDIRQS=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
CONFIG_TRACE_IRQFLAGS_SUPPORT=y
CONFIG_HARDIRQS_SW_RESEND=y
CONFIG_GENERIC_IRQ_PROBE=y
@@ -15,6 +21,7 @@
# CONFIG_ARCH_HAS_ILOG2_U64 is not set
CONFIG_GENERIC_HWEIGHT=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_ZONE_DMA=y
CONFIG_VECTORS_BASE=0xffff0000
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
@@ -32,17 +39,19 @@
# CONFIG_LOCALVERSION_AUTO is not set
CONFIG_SWAP=y
CONFIG_SYSVIPC=y
-# CONFIG_IPC_NS is not set
+CONFIG_SYSVIPC_SYSCTL=y
CONFIG_POSIX_MQUEUE=y
CONFIG_BSD_PROCESS_ACCT=y
# CONFIG_BSD_PROCESS_ACCT_V3 is not set
# CONFIG_TASKSTATS is not set
-# CONFIG_UTS_NS is not set
+# CONFIG_USER_NS is not set
# CONFIG_AUDIT is not set
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=14
CONFIG_SYSFS_DEPRECATED=y
# CONFIG_RELAY is not set
+CONFIG_BLK_DEV_INITRD=y
CONFIG_INITRAMFS_SOURCE=""
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
CONFIG_SYSCTL=y
@@ -57,32 +66,30 @@
CONFIG_ELF_CORE=y
CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
+CONFIG_ANON_INODES=y
CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
CONFIG_SHMEM=y
-CONFIG_SLAB=y
CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_SLAB=y
+# CONFIG_SLUB is not set
+# CONFIG_SLOB is not set
CONFIG_RT_MUTEXES=y
# CONFIG_TINY_SHMEM is not set
CONFIG_BASE_SMALL=0
-# CONFIG_SLOB is not set
-
-#
-# Loadable module support
-#
CONFIG_MODULES=y
CONFIG_MODULE_UNLOAD=y
# CONFIG_MODULE_FORCE_UNLOAD is not set
CONFIG_MODVERSIONS=y
# CONFIG_MODULE_SRCVERSION_ALL is not set
CONFIG_KMOD=y
-
-#
-# Block layer
-#
CONFIG_BLOCK=y
# CONFIG_LBD is not set
# CONFIG_BLK_DEV_IO_TRACE is not set
# CONFIG_LSF is not set
+# CONFIG_BLK_DEV_BSG is not set
#
# IO Schedulers
@@ -114,13 +121,15 @@
# CONFIG_ARCH_NETX is not set
# CONFIG_ARCH_H720X is not set
# CONFIG_ARCH_IMX is not set
+CONFIG_ARCH_IOP13XX=y
# CONFIG_ARCH_IOP32X is not set
# CONFIG_ARCH_IOP33X is not set
-CONFIG_ARCH_IOP13XX=y
-# CONFIG_ARCH_IXP4XX is not set
-# CONFIG_ARCH_IXP2000 is not set
# CONFIG_ARCH_IXP23XX is not set
+# CONFIG_ARCH_IXP2000 is not set
+# CONFIG_ARCH_IXP4XX is not set
# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_KS8695 is not set
+# CONFIG_ARCH_NS9XXX is not set
# CONFIG_ARCH_PNX4008 is not set
# CONFIG_ARCH_PXA is not set
# CONFIG_ARCH_RPC is not set
@@ -128,6 +137,7 @@
# CONFIG_ARCH_S3C2410 is not set
# CONFIG_ARCH_SHARK is not set
# CONFIG_ARCH_LH7A40X is not set
+# CONFIG_ARCH_DAVINCI is not set
# CONFIG_ARCH_OMAP is not set
#
@@ -141,6 +151,12 @@
CONFIG_MACH_IQ81340MC=y
#
+# IOP13XX IMU Support
+#
+# CONFIG_IOP_IMU is not set
+CONFIG_PLAT_IOP=y
+
+#
# Processor Type
#
CONFIG_CPU_32=y
@@ -159,13 +175,16 @@
CONFIG_ARM_THUMB=y
# CONFIG_CPU_DCACHE_DISABLE is not set
# CONFIG_CPU_BPREDICT_DISABLE is not set
+# CONFIG_OUTER_CACHE is not set
# CONFIG_IWMMXT is not set
#
# Bus support
#
CONFIG_PCI=y
-# CONFIG_PCI_MULTITHREAD_PROBE is not set
+CONFIG_PCI_SYSCALL=y
+CONFIG_ARCH_SUPPORTS_MSI=y
+# CONFIG_PCI_MSI is not set
#
# PCCARD (PCMCIA/CardBus) support
@@ -175,6 +194,7 @@
#
# Kernel Features
#
+# CONFIG_TICK_ONESHOT is not set
# CONFIG_PREEMPT is not set
# CONFIG_NO_IDLE_HZ is not set
CONFIG_HZ=100
@@ -189,6 +209,9 @@
# CONFIG_SPARSEMEM_STATIC is not set
CONFIG_SPLIT_PTLOCK_CPUS=4096
# CONFIG_RESOURCES_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=1
+CONFIG_BOUNCE=y
+CONFIG_VIRT_TO_BUS=y
CONFIG_ALIGNMENT_TRAP=y
#
@@ -198,6 +221,7 @@
CONFIG_ZBOOT_ROM_BSS=0x0
CONFIG_CMDLINE="ip=bootp root=nfs console=ttyS0,115200 nfsroot=,tcp,v3,wsize=8192,rsize=8192"
# CONFIG_XIP_KERNEL is not set
+# CONFIG_KEXEC is not set
#
# Floating point emulation
@@ -222,7 +246,6 @@
# Power management options
#
# CONFIG_PM is not set
-# CONFIG_APM is not set
#
# Networking
@@ -232,14 +255,15 @@
#
# Networking options
#
-# CONFIG_NETDEBUG is not set
CONFIG_PACKET=y
CONFIG_PACKET_MMAP=y
CONFIG_UNIX=y
CONFIG_XFRM=y
# CONFIG_XFRM_USER is not set
# CONFIG_XFRM_SUB_POLICY is not set
+# CONFIG_XFRM_MIGRATE is not set
CONFIG_NET_KEY=y
+# CONFIG_NET_KEY_MIGRATE is not set
CONFIG_INET=y
CONFIG_IP_MULTICAST=y
# CONFIG_IP_ADVANCED_ROUTER is not set
@@ -270,6 +294,7 @@
CONFIG_IPV6=y
# CONFIG_IPV6_PRIVACY is not set
# CONFIG_IPV6_ROUTER_PREF is not set
+# CONFIG_IPV6_OPTIMISTIC_DAD is not set
# CONFIG_INET6_AH is not set
# CONFIG_INET6_ESP is not set
# CONFIG_INET6_IPCOMP is not set
@@ -285,20 +310,8 @@
# CONFIG_IPV6_MULTIPLE_TABLES is not set
# CONFIG_NETWORK_SECMARK is not set
# CONFIG_NETFILTER is not set
-
-#
-# DCCP Configuration (EXPERIMENTAL)
-#
# CONFIG_IP_DCCP is not set
-
-#
-# SCTP Configuration (EXPERIMENTAL)
-#
# CONFIG_IP_SCTP is not set
-
-#
-# TIPC Configuration (EXPERIMENTAL)
-#
# CONFIG_TIPC is not set
# CONFIG_ATM is not set
# CONFIG_BRIDGE is not set
@@ -324,7 +337,17 @@
# CONFIG_HAMRADIO is not set
# CONFIG_IRDA is not set
# CONFIG_BT is not set
+# CONFIG_AF_RXRPC is not set
+
+#
+# Wireless
+#
+# CONFIG_CFG80211 is not set
+# CONFIG_WIRELESS_EXT is not set
+# CONFIG_MAC80211 is not set
# CONFIG_IEEE80211 is not set
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
#
# Device Drivers
@@ -337,15 +360,7 @@
CONFIG_PREVENT_FIRMWARE_BUILD=y
# CONFIG_FW_LOADER is not set
# CONFIG_SYS_HYPERVISOR is not set
-
-#
-# Connector - unified userspace <-> kernelspace linker
-#
# CONFIG_CONNECTOR is not set
-
-#
-# Memory Technology Devices (MTD)
-#
CONFIG_MTD=y
# CONFIG_MTD_DEBUG is not set
# CONFIG_MTD_CONCAT is not set
@@ -361,6 +376,7 @@
# User Modules And Translation Layers
#
# CONFIG_MTD_CHAR is not set
+CONFIG_MTD_BLKDEVS=y
CONFIG_MTD_BLOCK=y
# CONFIG_FTL is not set
# CONFIG_NFTL is not set
@@ -397,7 +413,6 @@
# CONFIG_MTD_RAM is not set
# CONFIG_MTD_ROM is not set
# CONFIG_MTD_ABSENT is not set
-# CONFIG_MTD_OBSOLETE_CHIPS is not set
#
# Mapping drivers for chip access
@@ -425,42 +440,27 @@
# CONFIG_MTD_DOC2000 is not set
# CONFIG_MTD_DOC2001 is not set
# CONFIG_MTD_DOC2001PLUS is not set
-
-#
-# NAND Flash Device Drivers
-#
# CONFIG_MTD_NAND is not set
-
-#
-# OneNAND Flash Device Drivers
-#
# CONFIG_MTD_ONENAND is not set
#
-# Parallel port support
+# UBI - Unsorted block images
#
+# CONFIG_MTD_UBI is not set
# CONFIG_PARPORT is not set
-
-#
-# Plug and Play support
-#
-
-#
-# Block devices
-#
+CONFIG_BLK_DEV=y
# CONFIG_BLK_CPQ_DA is not set
# CONFIG_BLK_CPQ_CISS_DA is not set
# CONFIG_BLK_DEV_DAC960 is not set
# CONFIG_BLK_DEV_UMEM is not set
# CONFIG_BLK_DEV_COW_COMMON is not set
# CONFIG_BLK_DEV_LOOP is not set
-CONFIG_BLK_DEV_NBD=y
+# CONFIG_BLK_DEV_NBD is not set
# CONFIG_BLK_DEV_SX8 is not set
CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_RAM_COUNT=2
CONFIG_BLK_DEV_RAM_SIZE=8192
CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
-CONFIG_BLK_DEV_INITRD=y
# CONFIG_CDROM_PKTCDVD is not set
# CONFIG_ATA_OVER_ETH is not set
@@ -469,6 +469,7 @@
#
# CONFIG_RAID_ATTRS is not set
CONFIG_SCSI=y
+CONFIG_SCSI_DMA=y
# CONFIG_SCSI_TGT is not set
# CONFIG_SCSI_NETLINK is not set
CONFIG_SCSI_PROC_FS=y
@@ -490,6 +491,7 @@
CONFIG_SCSI_CONSTANTS=y
# CONFIG_SCSI_LOGGING is not set
# CONFIG_SCSI_SCAN_ASYNC is not set
+CONFIG_SCSI_WAIT_SCAN=m
#
# SCSI Transports
@@ -534,15 +536,7 @@
# CONFIG_SCSI_NSP32 is not set
# CONFIG_SCSI_DEBUG is not set
# CONFIG_SCSI_SRP is not set
-
-#
-# Serial ATA (prod) and Parallel ATA (experimental) drivers
-#
# CONFIG_ATA is not set
-
-#
-# Multi-device support (RAID and LVM)
-#
CONFIG_MD=y
CONFIG_BLK_DEV_MD=y
# CONFIG_MD_LINEAR is not set
@@ -560,6 +554,7 @@
# CONFIG_DM_MIRROR is not set
# CONFIG_DM_ZERO is not set
# CONFIG_DM_MULTIPATH is not set
+# CONFIG_DM_DELAY is not set
#
# Fusion MPT device support
@@ -572,39 +567,19 @@
#
# IEEE 1394 (FireWire) support
#
+# CONFIG_FIREWIRE is not set
# CONFIG_IEEE1394 is not set
-
-#
-# I2O device support
-#
# CONFIG_I2O is not set
-
-#
-# Network device support
-#
CONFIG_NETDEVICES=y
+# CONFIG_NETDEVICES_MULTIQUEUE is not set
# CONFIG_DUMMY is not set
# CONFIG_BONDING is not set
+# CONFIG_MACVLAN is not set
# CONFIG_EQUALIZER is not set
# CONFIG_TUN is not set
-
-#
-# ARCnet devices
-#
# CONFIG_ARCNET is not set
-
-#
-# PHY device support
-#
-
-#
-# Ethernet (10 or 100Mbit)
-#
# CONFIG_NET_ETHERNET is not set
-
-#
-# Ethernet (1000 Mbit)
-#
+CONFIG_NETDEV_1000=y
# CONFIG_ACENIC is not set
# CONFIG_DL2K is not set
CONFIG_E1000=y
@@ -617,33 +592,26 @@
# CONFIG_SIS190 is not set
# CONFIG_SKGE is not set
# CONFIG_SKY2 is not set
-# CONFIG_SK98LIN is not set
+# CONFIG_VIA_VELOCITY is not set
# CONFIG_TIGON3 is not set
# CONFIG_BNX2 is not set
# CONFIG_QLA3XXX is not set
-
-#
-# Ethernet (10000 Mbit)
-#
+# CONFIG_ATL1 is not set
+CONFIG_NETDEV_10000=y
# CONFIG_CHELSIO_T1 is not set
+# CONFIG_CHELSIO_T3 is not set
# CONFIG_IXGB is not set
# CONFIG_S2IO is not set
# CONFIG_MYRI10GE is not set
# CONFIG_NETXEN_NIC is not set
-
-#
-# Token Ring devices
-#
+# CONFIG_MLX4_CORE is not set
# CONFIG_TR is not set
#
-# Wireless LAN (non-hamradio)
+# Wireless LAN
#
-# CONFIG_NET_RADIO is not set
-
-#
-# Wan interfaces
-#
+# CONFIG_WLAN_PRE80211 is not set
+# CONFIG_WLAN_80211 is not set
# CONFIG_WAN is not set
# CONFIG_FDDI is not set
# CONFIG_HIPPI is not set
@@ -654,10 +622,6 @@
# CONFIG_NETCONSOLE is not set
# CONFIG_NETPOLL is not set
# CONFIG_NET_POLL_CONTROLLER is not set
-
-#
-# ISDN subsystem
-#
# CONFIG_ISDN is not set
#
@@ -665,6 +629,7 @@
#
CONFIG_INPUT=y
# CONFIG_INPUT_FF_MEMLESS is not set
+# CONFIG_INPUT_POLLDEV is not set
#
# Userland interfaces
@@ -684,6 +649,7 @@
# CONFIG_INPUT_KEYBOARD is not set
# CONFIG_INPUT_MOUSE is not set
# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
# CONFIG_INPUT_TOUCHSCREEN is not set
# CONFIG_INPUT_MISC is not set
@@ -721,33 +687,18 @@
CONFIG_UNIX98_PTYS=y
CONFIG_LEGACY_PTYS=y
CONFIG_LEGACY_PTY_COUNT=256
-
-#
-# IPMI
-#
# CONFIG_IPMI_HANDLER is not set
-
-#
-# Watchdog Cards
-#
# CONFIG_WATCHDOG is not set
CONFIG_HW_RANDOM=y
# CONFIG_NVRAM is not set
-# CONFIG_DTLK is not set
# CONFIG_R3964 is not set
# CONFIG_APPLICOM is not set
# CONFIG_DRM is not set
# CONFIG_RAW_DRIVER is not set
-
-#
-# TPM devices
-#
# CONFIG_TCG_TPM is not set
-
-#
-# I2C support
-#
+CONFIG_DEVPORT=y
CONFIG_I2C=y
+CONFIG_I2C_BOARDINFO=y
# CONFIG_I2C_CHARDEV is not set
#
@@ -774,25 +725,28 @@
# CONFIG_I2C_PARPORT_LIGHT is not set
# CONFIG_I2C_PROSAVAGE is not set
# CONFIG_I2C_SAVAGE4 is not set
+# CONFIG_I2C_SIMTEC is not set
# CONFIG_I2C_SIS5595 is not set
# CONFIG_I2C_SIS630 is not set
# CONFIG_I2C_SIS96X is not set
+# CONFIG_I2C_TAOS_EVM is not set
# CONFIG_I2C_STUB is not set
# CONFIG_I2C_VIA is not set
# CONFIG_I2C_VIAPRO is not set
# CONFIG_I2C_VOODOO3 is not set
-# CONFIG_I2C_PCA_ISA is not set
#
# Miscellaneous I2C Chip support
#
# CONFIG_SENSORS_DS1337 is not set
# CONFIG_SENSORS_DS1374 is not set
+# CONFIG_DS1682 is not set
# CONFIG_SENSORS_EEPROM is not set
# CONFIG_SENSORS_PCF8574 is not set
# CONFIG_SENSORS_PCA9539 is not set
# CONFIG_SENSORS_PCF8591 is not set
# CONFIG_SENSORS_MAX6875 is not set
+# CONFIG_SENSORS_TSL2550 is not set
# CONFIG_I2C_DEBUG_CORE is not set
# CONFIG_I2C_DEBUG_ALGO is not set
# CONFIG_I2C_DEBUG_BUS is not set
@@ -803,21 +757,15 @@
#
# CONFIG_SPI is not set
# CONFIG_SPI_MASTER is not set
-
-#
-# Dallas's 1-wire bus
-#
# CONFIG_W1 is not set
-
-#
-# Hardware Monitoring support
-#
CONFIG_HWMON=y
# CONFIG_HWMON_VID is not set
# CONFIG_SENSORS_ABITUGURU is not set
+# CONFIG_SENSORS_AD7418 is not set
# CONFIG_SENSORS_ADM1021 is not set
# CONFIG_SENSORS_ADM1025 is not set
# CONFIG_SENSORS_ADM1026 is not set
+# CONFIG_SENSORS_ADM1029 is not set
# CONFIG_SENSORS_ADM1031 is not set
# CONFIG_SENSORS_ADM9240 is not set
# CONFIG_SENSORS_ASB100 is not set
@@ -840,6 +788,7 @@
# CONFIG_SENSORS_LM90 is not set
# CONFIG_SENSORS_LM92 is not set
# CONFIG_SENSORS_MAX1619 is not set
+# CONFIG_SENSORS_MAX6650 is not set
# CONFIG_SENSORS_PC87360 is not set
# CONFIG_SENSORS_PC87427 is not set
# CONFIG_SENSORS_SIS5595 is not set
@@ -857,14 +806,18 @@
# CONFIG_SENSORS_W83627HF is not set
# CONFIG_SENSORS_W83627EHF is not set
# CONFIG_HWMON_DEBUG_CHIP is not set
-
-#
-# Misc devices
-#
+CONFIG_MISC_DEVICES=y
+# CONFIG_PHANTOM is not set
+# CONFIG_EEPROM_93CX6 is not set
# CONFIG_SGI_IOC4 is not set
# CONFIG_TIFM_CORE is not set
#
+# Multifunction device drivers
+#
+# CONFIG_MFD_SM501 is not set
+
+#
# LED devices
#
# CONFIG_NEW_LEDS is not set
@@ -881,16 +834,19 @@
# Multimedia devices
#
# CONFIG_VIDEO_DEV is not set
-
-#
-# Digital Video Broadcasting Devices
-#
-# CONFIG_DVB is not set
+# CONFIG_DVB_CORE is not set
+CONFIG_DAB=y
#
# Graphics support
#
-CONFIG_FIRMWARE_EDID=y
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+# CONFIG_VGASTATE is not set
# CONFIG_FB is not set
#
@@ -898,21 +854,15 @@
#
# CONFIG_VGA_CONSOLE is not set
CONFIG_DUMMY_CONSOLE=y
-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
#
# Sound
#
# CONFIG_SOUND is not set
-
-#
-# HID Devices
-#
+CONFIG_HID_SUPPORT=y
CONFIG_HID=y
-
-#
-# USB support
-#
+# CONFIG_HID_DEBUG is not set
+CONFIG_USB_SUPPORT=y
CONFIG_USB_ARCH_HAS_HCD=y
CONFIG_USB_ARCH_HAS_OHCI=y
CONFIG_USB_ARCH_HAS_EHCI=y
@@ -926,10 +876,6 @@
# USB Gadget Support
#
# CONFIG_USB_GADGET is not set
-
-#
-# MMC/SD Card support
-#
# CONFIG_MMC is not set
#
@@ -939,6 +885,22 @@
# CONFIG_RTC_CLASS is not set
#
+# DMA Engine support
+#
+CONFIG_DMA_ENGINE=y
+
+#
+# DMA Clients
+#
+# CONFIG_NET_DMA is not set
+
+#
+# DMA Devices
+#
+# CONFIG_INTEL_IOATDMA is not set
+CONFIG_INTEL_IOP_ADMA=y
+
+#
# File systems
#
CONFIG_EXT2_FS=y
@@ -1004,7 +966,6 @@
# CONFIG_BEFS_FS is not set
# CONFIG_BFS_FS is not set
# CONFIG_EFS_FS is not set
-# CONFIG_JFFS_FS is not set
CONFIG_JFFS2_FS=y
CONFIG_JFFS2_FS_DEBUG=0
CONFIG_JFFS2_FS_WRITEBUFFER=y
@@ -1014,7 +975,7 @@
CONFIG_JFFS2_ZLIB=y
CONFIG_JFFS2_RTIME=y
# CONFIG_JFFS2_RUBIN is not set
-# CONFIG_CRAMFS is not set
+CONFIG_CRAMFS=y
# CONFIG_VXFS_FS is not set
# CONFIG_HPFS_FS is not set
# CONFIG_QNX4FS_FS is not set
@@ -1040,6 +1001,7 @@
CONFIG_EXPORTFS=y
CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=y
+# CONFIG_SUNRPC_BIND34 is not set
# CONFIG_RPCSEC_GSS_KRB5 is not set
# CONFIG_RPCSEC_GSS_SPKM3 is not set
CONFIG_SMB_FS=m
@@ -1053,7 +1015,6 @@
# CONFIG_NCP_FS is not set
# CONFIG_CODA_FS is not set
# CONFIG_AFS_FS is not set
-# CONFIG_9P_FS is not set
#
# Partition Types
@@ -1075,6 +1036,7 @@
# CONFIG_SUN_PARTITION is not set
# CONFIG_KARMA_PARTITION is not set
# CONFIG_EFI_PARTITION is not set
+# CONFIG_SYSV68_PARTITION is not set
#
# Native Language Support
@@ -1140,7 +1102,6 @@
# CONFIG_DEBUG_FS is not set
# CONFIG_HEADERS_CHECK is not set
# CONFIG_DEBUG_KERNEL is not set
-CONFIG_LOG_BUF_SHIFT=14
CONFIG_DEBUG_BUGVERBOSE=y
CONFIG_FRAME_POINTER=y
CONFIG_DEBUG_USER=y
@@ -1151,10 +1112,10 @@
CONFIG_KEYS=y
CONFIG_KEYS_DEBUG_PROC_KEYS=y
# CONFIG_SECURITY is not set
-
-#
-# Cryptographic options
-#
+CONFIG_XOR_BLOCKS=y
+CONFIG_ASYNC_CORE=y
+CONFIG_ASYNC_MEMCPY=y
+CONFIG_ASYNC_XOR=y
CONFIG_CRYPTO=y
CONFIG_CRYPTO_ALGAPI=y
CONFIG_CRYPTO_BLKCIPHER=y
@@ -1173,8 +1134,11 @@
CONFIG_CRYPTO_GF128MUL=y
CONFIG_CRYPTO_ECB=y
CONFIG_CRYPTO_CBC=y
+CONFIG_CRYPTO_PCBC=m
CONFIG_CRYPTO_LRW=y
+# CONFIG_CRYPTO_CRYPTD is not set
CONFIG_CRYPTO_DES=y
+# CONFIG_CRYPTO_FCRYPT is not set
CONFIG_CRYPTO_BLOWFISH=y
CONFIG_CRYPTO_TWOFISH=y
CONFIG_CRYPTO_TWOFISH_COMMON=y
@@ -1189,11 +1153,9 @@
CONFIG_CRYPTO_DEFLATE=y
CONFIG_CRYPTO_MICHAEL_MIC=y
CONFIG_CRYPTO_CRC32C=y
+# CONFIG_CRYPTO_CAMELLIA is not set
# CONFIG_CRYPTO_TEST is not set
-
-#
-# Hardware crypto devices
-#
+CONFIG_CRYPTO_HW=y
#
# Library routines
@@ -1201,9 +1163,13 @@
CONFIG_BITREVERSE=y
CONFIG_CRC_CCITT=y
# CONFIG_CRC16 is not set
+# CONFIG_CRC_ITU_T is not set
CONFIG_CRC32=y
+# CONFIG_CRC7 is not set
CONFIG_LIBCRC32C=y
CONFIG_ZLIB_INFLATE=y
CONFIG_ZLIB_DEFLATE=y
CONFIG_PLIST=y
-CONFIG_IOMAP_COPY=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
diff --git a/arch/arm/configs/iop32x_defconfig b/arch/arm/configs/iop32x_defconfig
index 7909a55..027aef2 100644
--- a/arch/arm/configs/iop32x_defconfig
+++ b/arch/arm/configs/iop32x_defconfig
@@ -1,12 +1,18 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.20-rc1-git5
-# Tue Dec 19 21:37:52 2006
+# Linux kernel version: 2.6.22
+# Thu Jul 19 16:00:36 2007
#
CONFIG_ARM=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+# CONFIG_GENERIC_GPIO is not set
# CONFIG_GENERIC_TIME is not set
+# CONFIG_GENERIC_CLOCKEVENTS is not set
CONFIG_MMU=y
+# CONFIG_NO_IOPORT is not set
CONFIG_GENERIC_HARDIRQS=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
CONFIG_TRACE_IRQFLAGS_SUPPORT=y
CONFIG_HARDIRQS_SW_RESEND=y
CONFIG_GENERIC_IRQ_PROBE=y
@@ -15,6 +21,7 @@
# CONFIG_ARCH_HAS_ILOG2_U64 is not set
CONFIG_GENERIC_HWEIGHT=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_ZONE_DMA=y
CONFIG_VECTORS_BASE=0xffff0000
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
@@ -32,16 +39,18 @@
CONFIG_LOCALVERSION_AUTO=y
CONFIG_SWAP=y
CONFIG_SYSVIPC=y
-# CONFIG_IPC_NS is not set
+CONFIG_SYSVIPC_SYSCTL=y
# CONFIG_POSIX_MQUEUE is not set
CONFIG_BSD_PROCESS_ACCT=y
# CONFIG_BSD_PROCESS_ACCT_V3 is not set
# CONFIG_TASKSTATS is not set
-# CONFIG_UTS_NS is not set
+# CONFIG_USER_NS is not set
# CONFIG_AUDIT is not set
# CONFIG_IKCONFIG is not set
+CONFIG_LOG_BUF_SHIFT=14
CONFIG_SYSFS_DEPRECATED=y
# CONFIG_RELAY is not set
+CONFIG_BLK_DEV_INITRD=y
CONFIG_INITRAMFS_SOURCE=""
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
CONFIG_SYSCTL=y
@@ -57,32 +66,30 @@
CONFIG_ELF_CORE=y
CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
+CONFIG_ANON_INODES=y
CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
CONFIG_SHMEM=y
-CONFIG_SLAB=y
CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_SLAB=y
+# CONFIG_SLUB is not set
+# CONFIG_SLOB is not set
CONFIG_RT_MUTEXES=y
# CONFIG_TINY_SHMEM is not set
CONFIG_BASE_SMALL=0
-# CONFIG_SLOB is not set
-
-#
-# Loadable module support
-#
CONFIG_MODULES=y
CONFIG_MODULE_UNLOAD=y
# CONFIG_MODULE_FORCE_UNLOAD is not set
# CONFIG_MODVERSIONS is not set
# CONFIG_MODULE_SRCVERSION_ALL is not set
CONFIG_KMOD=y
-
-#
-# Block layer
-#
CONFIG_BLOCK=y
# CONFIG_LBD is not set
# CONFIG_BLK_DEV_IO_TRACE is not set
# CONFIG_LSF is not set
+# CONFIG_BLK_DEV_BSG is not set
#
# IO Schedulers
@@ -114,13 +121,15 @@
# CONFIG_ARCH_NETX is not set
# CONFIG_ARCH_H720X is not set
# CONFIG_ARCH_IMX is not set
+# CONFIG_ARCH_IOP13XX is not set
CONFIG_ARCH_IOP32X=y
# CONFIG_ARCH_IOP33X is not set
-# CONFIG_ARCH_IOP13XX is not set
-# CONFIG_ARCH_IXP4XX is not set
-# CONFIG_ARCH_IXP2000 is not set
# CONFIG_ARCH_IXP23XX is not set
+# CONFIG_ARCH_IXP2000 is not set
+# CONFIG_ARCH_IXP4XX is not set
# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_KS8695 is not set
+# CONFIG_ARCH_NS9XXX is not set
# CONFIG_ARCH_PNX4008 is not set
# CONFIG_ARCH_PXA is not set
# CONFIG_ARCH_RPC is not set
@@ -128,6 +137,7 @@
# CONFIG_ARCH_S3C2410 is not set
# CONFIG_ARCH_SHARK is not set
# CONFIG_ARCH_LH7A40X is not set
+# CONFIG_ARCH_DAVINCI is not set
# CONFIG_ARCH_OMAP is not set
#
@@ -137,10 +147,12 @@
#
# IOP32x Platform Types
#
+CONFIG_MACH_EP80219=y
CONFIG_MACH_GLANTANK=y
CONFIG_ARCH_IQ80321=y
CONFIG_ARCH_IQ31244=y
CONFIG_MACH_N2100=y
+CONFIG_IOP3XX_ATU=y
CONFIG_PLAT_IOP=y
#
@@ -160,6 +172,7 @@
#
# CONFIG_ARM_THUMB is not set
# CONFIG_CPU_DCACHE_DISABLE is not set
+# CONFIG_OUTER_CACHE is not set
# CONFIG_IWMMXT is not set
CONFIG_XSCALE_PMU=y
@@ -167,7 +180,8 @@
# Bus support
#
CONFIG_PCI=y
-# CONFIG_PCI_MULTITHREAD_PROBE is not set
+CONFIG_PCI_SYSCALL=y
+# CONFIG_ARCH_SUPPORTS_MSI is not set
# CONFIG_PCI_DEBUG is not set
#
@@ -178,6 +192,7 @@
#
# Kernel Features
#
+# CONFIG_TICK_ONESHOT is not set
# CONFIG_PREEMPT is not set
# CONFIG_NO_IDLE_HZ is not set
CONFIG_HZ=100
@@ -192,6 +207,9 @@
# CONFIG_SPARSEMEM_STATIC is not set
CONFIG_SPLIT_PTLOCK_CPUS=4096
# CONFIG_RESOURCES_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=1
+CONFIG_BOUNCE=y
+CONFIG_VIRT_TO_BUS=y
CONFIG_ALIGNMENT_TRAP=y
#
@@ -199,8 +217,9 @@
#
CONFIG_ZBOOT_ROM_TEXT=0x0
CONFIG_ZBOOT_ROM_BSS=0x0
-CONFIG_CMDLINE="console=ttyS0,115200 root=/dev/nfs ip=bootp"
+CONFIG_CMDLINE="console=ttyS0,115200 root=/dev/nfs ip=bootp cachepolicy=writealloc"
# CONFIG_XIP_KERNEL is not set
+# CONFIG_KEXEC is not set
#
# Floating point emulation
@@ -225,7 +244,6 @@
# Power management options
#
# CONFIG_PM is not set
-# CONFIG_APM is not set
#
# Networking
@@ -235,13 +253,13 @@
#
# Networking options
#
-# CONFIG_NETDEBUG is not set
CONFIG_PACKET=y
CONFIG_PACKET_MMAP=y
CONFIG_UNIX=y
CONFIG_XFRM=y
# CONFIG_XFRM_USER is not set
# CONFIG_XFRM_SUB_POLICY is not set
+# CONFIG_XFRM_MIGRATE is not set
# CONFIG_NET_KEY is not set
CONFIG_INET=y
CONFIG_IP_MULTICAST=y
@@ -273,6 +291,7 @@
CONFIG_IPV6=y
# CONFIG_IPV6_PRIVACY is not set
# CONFIG_IPV6_ROUTER_PREF is not set
+# CONFIG_IPV6_OPTIMISTIC_DAD is not set
# CONFIG_INET6_AH is not set
# CONFIG_INET6_ESP is not set
# CONFIG_INET6_IPCOMP is not set
@@ -288,20 +307,8 @@
# CONFIG_IPV6_MULTIPLE_TABLES is not set
# CONFIG_NETWORK_SECMARK is not set
# CONFIG_NETFILTER is not set
-
-#
-# DCCP Configuration (EXPERIMENTAL)
-#
# CONFIG_IP_DCCP is not set
-
-#
-# SCTP Configuration (EXPERIMENTAL)
-#
# CONFIG_IP_SCTP is not set
-
-#
-# TIPC Configuration (EXPERIMENTAL)
-#
# CONFIG_TIPC is not set
# CONFIG_ATM is not set
# CONFIG_BRIDGE is not set
@@ -327,7 +334,17 @@
# CONFIG_HAMRADIO is not set
# CONFIG_IRDA is not set
# CONFIG_BT is not set
+# CONFIG_AF_RXRPC is not set
+
+#
+# Wireless
+#
+# CONFIG_CFG80211 is not set
+# CONFIG_WIRELESS_EXT is not set
+# CONFIG_MAC80211 is not set
# CONFIG_IEEE80211 is not set
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
#
# Device Drivers
@@ -340,16 +357,9 @@
CONFIG_PREVENT_FIRMWARE_BUILD=y
# CONFIG_FW_LOADER is not set
# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_DEBUG_DEVRES is not set
# CONFIG_SYS_HYPERVISOR is not set
-
-#
-# Connector - unified userspace <-> kernelspace linker
-#
# CONFIG_CONNECTOR is not set
-
-#
-# Memory Technology Devices (MTD)
-#
CONFIG_MTD=y
# CONFIG_MTD_DEBUG is not set
# CONFIG_MTD_CONCAT is not set
@@ -365,6 +375,7 @@
# User Modules And Translation Layers
#
CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLKDEVS=y
CONFIG_MTD_BLOCK=y
# CONFIG_FTL is not set
# CONFIG_NFTL is not set
@@ -396,7 +407,6 @@
# CONFIG_MTD_RAM is not set
# CONFIG_MTD_ROM is not set
# CONFIG_MTD_ABSENT is not set
-# CONFIG_MTD_OBSOLETE_CHIPS is not set
#
# Mapping drivers for chip access
@@ -424,29 +434,15 @@
# CONFIG_MTD_DOC2000 is not set
# CONFIG_MTD_DOC2001 is not set
# CONFIG_MTD_DOC2001PLUS is not set
-
-#
-# NAND Flash Device Drivers
-#
# CONFIG_MTD_NAND is not set
-
-#
-# OneNAND Flash Device Drivers
-#
# CONFIG_MTD_ONENAND is not set
#
-# Parallel port support
+# UBI - Unsorted block images
#
+# CONFIG_MTD_UBI is not set
# CONFIG_PARPORT is not set
-
-#
-# Plug and Play support
-#
-
-#
-# Block devices
-#
+CONFIG_BLK_DEV=y
# CONFIG_BLK_CPQ_DA is not set
# CONFIG_BLK_CPQ_CISS_DA is not set
# CONFIG_BLK_DEV_DAC960 is not set
@@ -461,13 +457,8 @@
CONFIG_BLK_DEV_RAM_COUNT=16
CONFIG_BLK_DEV_RAM_SIZE=8192
CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
-CONFIG_BLK_DEV_INITRD=y
# CONFIG_CDROM_PKTCDVD is not set
# CONFIG_ATA_OVER_ETH is not set
-
-#
-# ATA/ATAPI/MFM/RLL support
-#
# CONFIG_IDE is not set
#
@@ -475,6 +466,7 @@
#
# CONFIG_RAID_ATTRS is not set
CONFIG_SCSI=y
+CONFIG_SCSI_DMA=y
# CONFIG_SCSI_TGT is not set
# CONFIG_SCSI_NETLINK is not set
CONFIG_SCSI_PROC_FS=y
@@ -496,6 +488,7 @@
# CONFIG_SCSI_CONSTANTS is not set
# CONFIG_SCSI_LOGGING is not set
# CONFIG_SCSI_SCAN_ASYNC is not set
+CONFIG_SCSI_WAIT_SCAN=m
#
# SCSI Transports
@@ -541,11 +534,8 @@
# CONFIG_SCSI_NSP32 is not set
# CONFIG_SCSI_DEBUG is not set
# CONFIG_SCSI_SRP is not set
-
-#
-# Serial ATA (prod) and Parallel ATA (experimental) drivers
-#
CONFIG_ATA=y
+# CONFIG_ATA_NONSTANDARD is not set
# CONFIG_SATA_AHCI is not set
# CONFIG_SATA_SVW is not set
# CONFIG_ATA_PIIX is not set
@@ -560,11 +550,13 @@
# CONFIG_SATA_SIS is not set
# CONFIG_SATA_ULI is not set
# CONFIG_SATA_VIA is not set
-# CONFIG_SATA_VITESSE is not set
+CONFIG_SATA_VITESSE=y
+# CONFIG_SATA_INIC162X is not set
# CONFIG_PATA_ALI is not set
# CONFIG_PATA_AMD is not set
# CONFIG_PATA_ARTOP is not set
# CONFIG_PATA_ATIIXP is not set
+# CONFIG_PATA_CMD640_PCI is not set
# CONFIG_PATA_CMD64X is not set
# CONFIG_PATA_CS5520 is not set
# CONFIG_PATA_CS5530 is not set
@@ -576,6 +568,7 @@
# CONFIG_PATA_HPT3X2N is not set
# CONFIG_PATA_HPT3X3 is not set
# CONFIG_PATA_IT821X is not set
+# CONFIG_PATA_IT8213 is not set
# CONFIG_PATA_JMICRON is not set
# CONFIG_PATA_TRIFLEX is not set
# CONFIG_PATA_MARVELL is not set
@@ -595,17 +588,14 @@
# CONFIG_PATA_SIS is not set
# CONFIG_PATA_VIA is not set
# CONFIG_PATA_WINBOND is not set
-
-#
-# Multi-device support (RAID and LVM)
-#
CONFIG_MD=y
CONFIG_BLK_DEV_MD=y
# CONFIG_MD_LINEAR is not set
CONFIG_MD_RAID0=y
CONFIG_MD_RAID1=y
-# CONFIG_MD_RAID10 is not set
-# CONFIG_MD_RAID456 is not set
+CONFIG_MD_RAID10=y
+CONFIG_MD_RAID456=y
+# CONFIG_MD_RAID5_RESHAPE is not set
# CONFIG_MD_MULTIPATH is not set
# CONFIG_MD_FAULTY is not set
CONFIG_BLK_DEV_DM=y
@@ -615,6 +605,7 @@
# CONFIG_DM_MIRROR is not set
# CONFIG_DM_ZERO is not set
# CONFIG_DM_MULTIPATH is not set
+# CONFIG_DM_DELAY is not set
#
# Fusion MPT device support
@@ -627,47 +618,27 @@
#
# IEEE 1394 (FireWire) support
#
+# CONFIG_FIREWIRE is not set
# CONFIG_IEEE1394 is not set
-
-#
-# I2O device support
-#
# CONFIG_I2O is not set
-
-#
-# Network device support
-#
CONFIG_NETDEVICES=y
+# CONFIG_NETDEVICES_MULTIQUEUE is not set
# CONFIG_DUMMY is not set
# CONFIG_BONDING is not set
+# CONFIG_MACVLAN is not set
# CONFIG_EQUALIZER is not set
# CONFIG_TUN is not set
-
-#
-# ARCnet devices
-#
# CONFIG_ARCNET is not set
-
-#
-# PHY device support
-#
# CONFIG_PHYLIB is not set
-
-#
-# Ethernet (10 or 100Mbit)
-#
CONFIG_NET_ETHERNET=y
CONFIG_MII=y
+# CONFIG_AX88796 is not set
# CONFIG_HAPPYMEAL is not set
# CONFIG_SUNGEM is not set
# CONFIG_CASSINI is not set
# CONFIG_NET_VENDOR_3COM is not set
# CONFIG_SMC91X is not set
# CONFIG_DM9000 is not set
-
-#
-# Tulip family network device support
-#
# CONFIG_NET_TULIP is not set
# CONFIG_HP100 is not set
CONFIG_NET_PCI=y
@@ -689,10 +660,8 @@
# CONFIG_SUNDANCE is not set
# CONFIG_TLAN is not set
# CONFIG_VIA_RHINE is not set
-
-#
-# Ethernet (1000 Mbit)
-#
+# CONFIG_SC92031 is not set
+CONFIG_NETDEV_1000=y
# CONFIG_ACENIC is not set
# CONFIG_DL2K is not set
CONFIG_E1000=y
@@ -706,34 +675,36 @@
# CONFIG_SIS190 is not set
# CONFIG_SKGE is not set
# CONFIG_SKY2 is not set
-# CONFIG_SK98LIN is not set
# CONFIG_VIA_VELOCITY is not set
# CONFIG_TIGON3 is not set
# CONFIG_BNX2 is not set
# CONFIG_QLA3XXX is not set
-
-#
-# Ethernet (10000 Mbit)
-#
+# CONFIG_ATL1 is not set
+CONFIG_NETDEV_10000=y
# CONFIG_CHELSIO_T1 is not set
+# CONFIG_CHELSIO_T3 is not set
# CONFIG_IXGB is not set
# CONFIG_S2IO is not set
# CONFIG_MYRI10GE is not set
# CONFIG_NETXEN_NIC is not set
-
-#
-# Token Ring devices
-#
+# CONFIG_MLX4_CORE is not set
# CONFIG_TR is not set
#
-# Wireless LAN (non-hamradio)
+# Wireless LAN
#
-# CONFIG_NET_RADIO is not set
+# CONFIG_WLAN_PRE80211 is not set
+# CONFIG_WLAN_80211 is not set
#
-# Wan interfaces
+# USB Network Adapters
#
+# CONFIG_USB_CATC is not set
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_RTL8150 is not set
+# CONFIG_USB_USBNET_MII is not set
+# CONFIG_USB_USBNET is not set
# CONFIG_WAN is not set
# CONFIG_FDDI is not set
# CONFIG_HIPPI is not set
@@ -744,10 +715,6 @@
# CONFIG_NETCONSOLE is not set
# CONFIG_NETPOLL is not set
# CONFIG_NET_POLL_CONTROLLER is not set
-
-#
-# ISDN subsystem
-#
# CONFIG_ISDN is not set
#
@@ -755,6 +722,7 @@
#
CONFIG_INPUT=y
# CONFIG_INPUT_FF_MEMLESS is not set
+# CONFIG_INPUT_POLLDEV is not set
#
# Userland interfaces
@@ -774,6 +742,7 @@
# CONFIG_INPUT_KEYBOARD is not set
# CONFIG_INPUT_MOUSE is not set
# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
# CONFIG_INPUT_TOUCHSCREEN is not set
# CONFIG_INPUT_MISC is not set
@@ -811,33 +780,18 @@
CONFIG_UNIX98_PTYS=y
CONFIG_LEGACY_PTYS=y
CONFIG_LEGACY_PTY_COUNT=256
-
-#
-# IPMI
-#
# CONFIG_IPMI_HANDLER is not set
-
-#
-# Watchdog Cards
-#
# CONFIG_WATCHDOG is not set
CONFIG_HW_RANDOM=y
# CONFIG_NVRAM is not set
-# CONFIG_DTLK is not set
# CONFIG_R3964 is not set
# CONFIG_APPLICOM is not set
# CONFIG_DRM is not set
# CONFIG_RAW_DRIVER is not set
-
-#
-# TPM devices
-#
# CONFIG_TCG_TPM is not set
-
-#
-# I2C support
-#
+CONFIG_DEVPORT=y
CONFIG_I2C=y
+CONFIG_I2C_BOARDINFO=y
CONFIG_I2C_CHARDEV=y
#
@@ -864,25 +818,29 @@
# CONFIG_I2C_PARPORT_LIGHT is not set
# CONFIG_I2C_PROSAVAGE is not set
# CONFIG_I2C_SAVAGE4 is not set
+# CONFIG_I2C_SIMTEC is not set
# CONFIG_I2C_SIS5595 is not set
# CONFIG_I2C_SIS630 is not set
# CONFIG_I2C_SIS96X is not set
+# CONFIG_I2C_TAOS_EVM is not set
# CONFIG_I2C_STUB is not set
+# CONFIG_I2C_TINY_USB is not set
# CONFIG_I2C_VIA is not set
# CONFIG_I2C_VIAPRO is not set
# CONFIG_I2C_VOODOO3 is not set
-# CONFIG_I2C_PCA_ISA is not set
#
# Miscellaneous I2C Chip support
#
# CONFIG_SENSORS_DS1337 is not set
# CONFIG_SENSORS_DS1374 is not set
+# CONFIG_DS1682 is not set
# CONFIG_SENSORS_EEPROM is not set
# CONFIG_SENSORS_PCF8574 is not set
# CONFIG_SENSORS_PCA9539 is not set
# CONFIG_SENSORS_PCF8591 is not set
# CONFIG_SENSORS_MAX6875 is not set
+# CONFIG_SENSORS_TSL2550 is not set
# CONFIG_I2C_DEBUG_CORE is not set
# CONFIG_I2C_DEBUG_ALGO is not set
# CONFIG_I2C_DEBUG_BUS is not set
@@ -893,21 +851,15 @@
#
# CONFIG_SPI is not set
# CONFIG_SPI_MASTER is not set
-
-#
-# Dallas's 1-wire bus
-#
# CONFIG_W1 is not set
-
-#
-# Hardware Monitoring support
-#
CONFIG_HWMON=y
# CONFIG_HWMON_VID is not set
# CONFIG_SENSORS_ABITUGURU is not set
+# CONFIG_SENSORS_AD7418 is not set
# CONFIG_SENSORS_ADM1021 is not set
# CONFIG_SENSORS_ADM1025 is not set
# CONFIG_SENSORS_ADM1026 is not set
+# CONFIG_SENSORS_ADM1029 is not set
# CONFIG_SENSORS_ADM1031 is not set
# CONFIG_SENSORS_ADM9240 is not set
# CONFIG_SENSORS_ASB100 is not set
@@ -930,6 +882,7 @@
# CONFIG_SENSORS_LM90 is not set
# CONFIG_SENSORS_LM92 is not set
# CONFIG_SENSORS_MAX1619 is not set
+# CONFIG_SENSORS_MAX6650 is not set
# CONFIG_SENSORS_PC87360 is not set
# CONFIG_SENSORS_PC87427 is not set
# CONFIG_SENSORS_SIS5595 is not set
@@ -947,14 +900,18 @@
# CONFIG_SENSORS_W83627HF is not set
# CONFIG_SENSORS_W83627EHF is not set
# CONFIG_HWMON_DEBUG_CHIP is not set
-
-#
-# Misc devices
-#
+CONFIG_MISC_DEVICES=y
+# CONFIG_PHANTOM is not set
+# CONFIG_EEPROM_93CX6 is not set
# CONFIG_SGI_IOC4 is not set
# CONFIG_TIFM_CORE is not set
#
+# Multifunction device drivers
+#
+# CONFIG_MFD_SM501 is not set
+
+#
# LED devices
#
# CONFIG_NEW_LEDS is not set
@@ -971,17 +928,20 @@
# Multimedia devices
#
# CONFIG_VIDEO_DEV is not set
-
-#
-# Digital Video Broadcasting Devices
-#
-# CONFIG_DVB is not set
+# CONFIG_DVB_CORE is not set
+CONFIG_DAB=y
# CONFIG_USB_DABUSB is not set
#
# Graphics support
#
-CONFIG_FIRMWARE_EDID=y
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+# CONFIG_VGASTATE is not set
# CONFIG_FB is not set
#
@@ -989,21 +949,26 @@
#
# CONFIG_VGA_CONSOLE is not set
CONFIG_DUMMY_CONSOLE=y
-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
#
# Sound
#
# CONFIG_SOUND is not set
-
-#
-# HID Devices
-#
+CONFIG_HID_SUPPORT=y
CONFIG_HID=y
+# CONFIG_HID_DEBUG is not set
#
-# USB support
+# USB Input Devices
#
+# CONFIG_USB_HID is not set
+
+#
+# USB HID Boot Protocol drivers
+#
+# CONFIG_USB_KBD is not set
+# CONFIG_USB_MOUSE is not set
+CONFIG_USB_SUPPORT=y
CONFIG_USB_ARCH_HAS_HCD=y
CONFIG_USB_ARCH_HAS_OHCI=y
CONFIG_USB_ARCH_HAS_EHCI=y
@@ -1014,9 +979,8 @@
# Miscellaneous USB options
#
# CONFIG_USB_DEVICEFS is not set
-# CONFIG_USB_BANDWIDTH is not set
+CONFIG_USB_DEVICE_CLASS=y
# CONFIG_USB_DYNAMIC_MINORS is not set
-# CONFIG_USB_MULTITHREAD_PROBE is not set
# CONFIG_USB_OTG is not set
#
@@ -1030,6 +994,7 @@
# CONFIG_USB_OHCI_HCD is not set
CONFIG_USB_UHCI_HCD=y
# CONFIG_USB_SL811_HCD is not set
+# CONFIG_USB_R8A66597_HCD is not set
#
# USB Device Class drivers
@@ -1058,43 +1023,10 @@
# CONFIG_USB_LIBUSUAL is not set
#
-# USB Input Devices
-#
-# CONFIG_USB_HID is not set
-
-#
-# USB HID Boot Protocol drivers
-#
-# CONFIG_USB_KBD is not set
-# CONFIG_USB_MOUSE is not set
-# CONFIG_USB_AIPTEK is not set
-# CONFIG_USB_WACOM is not set
-# CONFIG_USB_ACECAD is not set
-# CONFIG_USB_KBTAB is not set
-# CONFIG_USB_POWERMATE is not set
-# CONFIG_USB_TOUCHSCREEN is not set
-# CONFIG_USB_YEALINK is not set
-# CONFIG_USB_XPAD is not set
-# CONFIG_USB_ATI_REMOTE is not set
-# CONFIG_USB_ATI_REMOTE2 is not set
-# CONFIG_USB_KEYSPAN_REMOTE is not set
-# CONFIG_USB_APPLETOUCH is not set
-
-#
# USB Imaging devices
#
# CONFIG_USB_MDC800 is not set
# CONFIG_USB_MICROTEK is not set
-
-#
-# USB Network Adapters
-#
-# CONFIG_USB_CATC is not set
-# CONFIG_USB_KAWETH is not set
-# CONFIG_USB_PEGASUS is not set
-# CONFIG_USB_RTL8150 is not set
-# CONFIG_USB_USBNET_MII is not set
-# CONFIG_USB_USBNET is not set
CONFIG_USB_MON=y
#
@@ -1116,6 +1048,7 @@
# CONFIG_USB_RIO500 is not set
# CONFIG_USB_LEGOTOWER is not set
# CONFIG_USB_LCD is not set
+# CONFIG_USB_BERRY_CHARGE is not set
# CONFIG_USB_LED is not set
# CONFIG_USB_CYPRESS_CY7C63 is not set
# CONFIG_USB_CYTHERM is not set
@@ -1126,6 +1059,7 @@
# CONFIG_USB_SISUSBVGA is not set
# CONFIG_USB_LD is not set
# CONFIG_USB_TRANCEVIBRATOR is not set
+# CONFIG_USB_IOWARRIOR is not set
#
# USB DSL modem support
@@ -1135,10 +1069,6 @@
# USB Gadget Support
#
# CONFIG_USB_GADGET is not set
-
-#
-# MMC/SD Card support
-#
# CONFIG_MMC is not set
#
@@ -1148,6 +1078,22 @@
# CONFIG_RTC_CLASS is not set
#
+# DMA Engine support
+#
+CONFIG_DMA_ENGINE=y
+
+#
+# DMA Clients
+#
+CONFIG_NET_DMA=y
+
+#
+# DMA Devices
+#
+# CONFIG_INTEL_IOATDMA is not set
+CONFIG_INTEL_IOP_ADMA=y
+
+#
# File systems
#
CONFIG_EXT2_FS=y
@@ -1164,11 +1110,7 @@
# CONFIG_REISERFS_FS is not set
# CONFIG_JFS_FS is not set
# CONFIG_FS_POSIX_ACL is not set
-CONFIG_XFS_FS=y
-# CONFIG_XFS_QUOTA is not set
-CONFIG_XFS_SECURITY=y
-CONFIG_XFS_POSIX_ACL=y
-# CONFIG_XFS_RT is not set
+# CONFIG_XFS_FS is not set
# CONFIG_GFS2_FS is not set
# CONFIG_OCFS2_FS is not set
# CONFIG_MINIX_FS is not set
@@ -1217,7 +1159,6 @@
# CONFIG_BEFS_FS is not set
# CONFIG_BFS_FS is not set
# CONFIG_EFS_FS is not set
-# CONFIG_JFFS_FS is not set
CONFIG_JFFS2_FS=y
CONFIG_JFFS2_FS_DEBUG=0
CONFIG_JFFS2_FS_WRITEBUFFER=y
@@ -1227,7 +1168,7 @@
CONFIG_JFFS2_ZLIB=y
CONFIG_JFFS2_RTIME=y
# CONFIG_JFFS2_RUBIN is not set
-# CONFIG_CRAMFS is not set
+CONFIG_CRAMFS=y
# CONFIG_VXFS_FS is not set
# CONFIG_HPFS_FS is not set
# CONFIG_QNX4FS_FS is not set
@@ -1253,6 +1194,7 @@
CONFIG_EXPORTFS=y
CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=y
+# CONFIG_SUNRPC_BIND34 is not set
# CONFIG_RPCSEC_GSS_KRB5 is not set
# CONFIG_RPCSEC_GSS_SPKM3 is not set
# CONFIG_SMB_FS is not set
@@ -1260,7 +1202,6 @@
# CONFIG_NCP_FS is not set
# CONFIG_CODA_FS is not set
# CONFIG_AFS_FS is not set
-# CONFIG_9P_FS is not set
#
# Partition Types
@@ -1282,6 +1223,7 @@
# CONFIG_SUN_PARTITION is not set
# CONFIG_KARMA_PARTITION is not set
# CONFIG_EFI_PARTITION is not set
+# CONFIG_SYSV68_PARTITION is not set
#
# Native Language Support
@@ -1308,15 +1250,19 @@
# CONFIG_DEBUG_FS is not set
# CONFIG_HEADERS_CHECK is not set
CONFIG_DEBUG_KERNEL=y
-CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_DEBUG_SHIRQ is not set
CONFIG_DETECT_SOFTLOCKUP=y
+CONFIG_SCHED_DEBUG=y
# CONFIG_SCHEDSTATS is not set
+# CONFIG_TIMER_STATS is not set
# CONFIG_DEBUG_SLAB is not set
# CONFIG_DEBUG_RT_MUTEXES is not set
# CONFIG_RT_MUTEX_TESTER is not set
# CONFIG_DEBUG_SPINLOCK is not set
# CONFIG_DEBUG_MUTEXES is not set
-# CONFIG_DEBUG_RWSEMS is not set
+# CONFIG_DEBUG_LOCK_ALLOC is not set
+# CONFIG_PROVE_LOCKING is not set
+# CONFIG_LOCK_STAT is not set
# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
# CONFIG_DEBUG_KOBJECT is not set
@@ -1327,6 +1273,7 @@
CONFIG_FRAME_POINTER=y
# CONFIG_FORCED_INLINING is not set
# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_FAULT_INJECTION is not set
CONFIG_DEBUG_USER=y
# CONFIG_DEBUG_ERRORS is not set
CONFIG_DEBUG_LL=y
@@ -1338,10 +1285,10 @@
CONFIG_KEYS=y
CONFIG_KEYS_DEBUG_PROC_KEYS=y
# CONFIG_SECURITY is not set
-
-#
-# Cryptographic options
-#
+CONFIG_XOR_BLOCKS=y
+CONFIG_ASYNC_CORE=y
+CONFIG_ASYNC_MEMCPY=y
+CONFIG_ASYNC_XOR=y
CONFIG_CRYPTO=y
CONFIG_CRYPTO_ALGAPI=y
CONFIG_CRYPTO_BLKCIPHER=y
@@ -1360,8 +1307,11 @@
CONFIG_CRYPTO_GF128MUL=y
CONFIG_CRYPTO_ECB=y
CONFIG_CRYPTO_CBC=y
+CONFIG_CRYPTO_PCBC=m
CONFIG_CRYPTO_LRW=y
+# CONFIG_CRYPTO_CRYPTD is not set
CONFIG_CRYPTO_DES=y
+# CONFIG_CRYPTO_FCRYPT is not set
CONFIG_CRYPTO_BLOWFISH=y
CONFIG_CRYPTO_TWOFISH=y
CONFIG_CRYPTO_TWOFISH_COMMON=y
@@ -1376,11 +1326,9 @@
CONFIG_CRYPTO_DEFLATE=y
CONFIG_CRYPTO_MICHAEL_MIC=y
CONFIG_CRYPTO_CRC32C=y
+# CONFIG_CRYPTO_CAMELLIA is not set
# CONFIG_CRYPTO_TEST is not set
-
-#
-# Hardware crypto devices
-#
+CONFIG_CRYPTO_HW=y
#
# Library routines
@@ -1388,9 +1336,13 @@
CONFIG_BITREVERSE=y
# CONFIG_CRC_CCITT is not set
# CONFIG_CRC16 is not set
+# CONFIG_CRC_ITU_T is not set
CONFIG_CRC32=y
+# CONFIG_CRC7 is not set
CONFIG_LIBCRC32C=y
CONFIG_ZLIB_INFLATE=y
CONFIG_ZLIB_DEFLATE=y
CONFIG_PLIST=y
-CONFIG_IOMAP_COPY=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
diff --git a/arch/arm/configs/iop33x_defconfig b/arch/arm/configs/iop33x_defconfig
index fa271bc..721ee64 100644
--- a/arch/arm/configs/iop33x_defconfig
+++ b/arch/arm/configs/iop33x_defconfig
@@ -1,12 +1,18 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.20-rc1
-# Sat Dec 16 06:05:34 2006
+# Linux kernel version: 2.6.22
+# Thu Jul 19 16:05:59 2007
#
CONFIG_ARM=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+# CONFIG_GENERIC_GPIO is not set
# CONFIG_GENERIC_TIME is not set
+# CONFIG_GENERIC_CLOCKEVENTS is not set
CONFIG_MMU=y
+# CONFIG_NO_IOPORT is not set
CONFIG_GENERIC_HARDIRQS=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
CONFIG_TRACE_IRQFLAGS_SUPPORT=y
CONFIG_HARDIRQS_SW_RESEND=y
CONFIG_GENERIC_IRQ_PROBE=y
@@ -15,6 +21,7 @@
# CONFIG_ARCH_HAS_ILOG2_U64 is not set
CONFIG_GENERIC_HWEIGHT=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_ZONE_DMA=y
CONFIG_VECTORS_BASE=0xffff0000
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
@@ -32,16 +39,18 @@
CONFIG_LOCALVERSION_AUTO=y
CONFIG_SWAP=y
CONFIG_SYSVIPC=y
-# CONFIG_IPC_NS is not set
+CONFIG_SYSVIPC_SYSCTL=y
# CONFIG_POSIX_MQUEUE is not set
CONFIG_BSD_PROCESS_ACCT=y
# CONFIG_BSD_PROCESS_ACCT_V3 is not set
# CONFIG_TASKSTATS is not set
-# CONFIG_UTS_NS is not set
+# CONFIG_USER_NS is not set
# CONFIG_AUDIT is not set
# CONFIG_IKCONFIG is not set
+CONFIG_LOG_BUF_SHIFT=14
CONFIG_SYSFS_DEPRECATED=y
# CONFIG_RELAY is not set
+CONFIG_BLK_DEV_INITRD=y
CONFIG_INITRAMFS_SOURCE=""
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
CONFIG_SYSCTL=y
@@ -57,32 +66,30 @@
CONFIG_ELF_CORE=y
CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
+CONFIG_ANON_INODES=y
CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
CONFIG_SHMEM=y
-CONFIG_SLAB=y
CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_SLAB=y
+# CONFIG_SLUB is not set
+# CONFIG_SLOB is not set
CONFIG_RT_MUTEXES=y
# CONFIG_TINY_SHMEM is not set
CONFIG_BASE_SMALL=0
-# CONFIG_SLOB is not set
-
-#
-# Loadable module support
-#
CONFIG_MODULES=y
CONFIG_MODULE_UNLOAD=y
# CONFIG_MODULE_FORCE_UNLOAD is not set
# CONFIG_MODVERSIONS is not set
# CONFIG_MODULE_SRCVERSION_ALL is not set
CONFIG_KMOD=y
-
-#
-# Block layer
-#
CONFIG_BLOCK=y
# CONFIG_LBD is not set
# CONFIG_BLK_DEV_IO_TRACE is not set
# CONFIG_LSF is not set
+# CONFIG_BLK_DEV_BSG is not set
#
# IO Schedulers
@@ -114,13 +121,15 @@
# CONFIG_ARCH_NETX is not set
# CONFIG_ARCH_H720X is not set
# CONFIG_ARCH_IMX is not set
+# CONFIG_ARCH_IOP13XX is not set
# CONFIG_ARCH_IOP32X is not set
CONFIG_ARCH_IOP33X=y
-# CONFIG_ARCH_IOP13XX is not set
-# CONFIG_ARCH_IXP4XX is not set
-# CONFIG_ARCH_IXP2000 is not set
# CONFIG_ARCH_IXP23XX is not set
+# CONFIG_ARCH_IXP2000 is not set
+# CONFIG_ARCH_IXP4XX is not set
# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_KS8695 is not set
+# CONFIG_ARCH_NS9XXX is not set
# CONFIG_ARCH_PNX4008 is not set
# CONFIG_ARCH_PXA is not set
# CONFIG_ARCH_RPC is not set
@@ -128,7 +137,9 @@
# CONFIG_ARCH_S3C2410 is not set
# CONFIG_ARCH_SHARK is not set
# CONFIG_ARCH_LH7A40X is not set
+# CONFIG_ARCH_DAVINCI is not set
# CONFIG_ARCH_OMAP is not set
+CONFIG_IOP3XX_ATU=y
#
# IOP33x Implementation Options
@@ -158,6 +169,7 @@
#
# CONFIG_ARM_THUMB is not set
# CONFIG_CPU_DCACHE_DISABLE is not set
+# CONFIG_OUTER_CACHE is not set
# CONFIG_IWMMXT is not set
CONFIG_XSCALE_PMU=y
@@ -165,7 +177,8 @@
# Bus support
#
CONFIG_PCI=y
-# CONFIG_PCI_MULTITHREAD_PROBE is not set
+CONFIG_PCI_SYSCALL=y
+# CONFIG_ARCH_SUPPORTS_MSI is not set
# CONFIG_PCI_DEBUG is not set
#
@@ -176,6 +189,7 @@
#
# Kernel Features
#
+# CONFIG_TICK_ONESHOT is not set
# CONFIG_PREEMPT is not set
# CONFIG_NO_IDLE_HZ is not set
CONFIG_HZ=100
@@ -190,6 +204,9 @@
# CONFIG_SPARSEMEM_STATIC is not set
CONFIG_SPLIT_PTLOCK_CPUS=4096
# CONFIG_RESOURCES_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=1
+CONFIG_BOUNCE=y
+CONFIG_VIRT_TO_BUS=y
CONFIG_ALIGNMENT_TRAP=y
#
@@ -197,8 +214,9 @@
#
CONFIG_ZBOOT_ROM_TEXT=0x0
CONFIG_ZBOOT_ROM_BSS=0x0
-CONFIG_CMDLINE="console=ttyS0,115200 root=/dev/nfs ip=bootp"
+CONFIG_CMDLINE="console=ttyS0,115200 root=/dev/nfs ip=bootp cachepolicy=writealloc"
# CONFIG_XIP_KERNEL is not set
+# CONFIG_KEXEC is not set
#
# Floating point emulation
@@ -223,7 +241,6 @@
# Power management options
#
# CONFIG_PM is not set
-# CONFIG_APM is not set
#
# Networking
@@ -233,13 +250,13 @@
#
# Networking options
#
-# CONFIG_NETDEBUG is not set
CONFIG_PACKET=y
CONFIG_PACKET_MMAP=y
CONFIG_UNIX=y
CONFIG_XFRM=y
# CONFIG_XFRM_USER is not set
# CONFIG_XFRM_SUB_POLICY is not set
+# CONFIG_XFRM_MIGRATE is not set
# CONFIG_NET_KEY is not set
CONFIG_INET=y
CONFIG_IP_MULTICAST=y
@@ -271,6 +288,7 @@
CONFIG_IPV6=y
# CONFIG_IPV6_PRIVACY is not set
# CONFIG_IPV6_ROUTER_PREF is not set
+# CONFIG_IPV6_OPTIMISTIC_DAD is not set
# CONFIG_INET6_AH is not set
# CONFIG_INET6_ESP is not set
# CONFIG_INET6_IPCOMP is not set
@@ -286,20 +304,8 @@
# CONFIG_IPV6_MULTIPLE_TABLES is not set
# CONFIG_NETWORK_SECMARK is not set
# CONFIG_NETFILTER is not set
-
-#
-# DCCP Configuration (EXPERIMENTAL)
-#
# CONFIG_IP_DCCP is not set
-
-#
-# SCTP Configuration (EXPERIMENTAL)
-#
# CONFIG_IP_SCTP is not set
-
-#
-# TIPC Configuration (EXPERIMENTAL)
-#
# CONFIG_TIPC is not set
# CONFIG_ATM is not set
# CONFIG_BRIDGE is not set
@@ -325,7 +331,17 @@
# CONFIG_HAMRADIO is not set
# CONFIG_IRDA is not set
# CONFIG_BT is not set
+# CONFIG_AF_RXRPC is not set
+
+#
+# Wireless
+#
+# CONFIG_CFG80211 is not set
+# CONFIG_WIRELESS_EXT is not set
+# CONFIG_MAC80211 is not set
# CONFIG_IEEE80211 is not set
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
#
# Device Drivers
@@ -338,16 +354,9 @@
CONFIG_PREVENT_FIRMWARE_BUILD=y
# CONFIG_FW_LOADER is not set
# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_DEBUG_DEVRES is not set
# CONFIG_SYS_HYPERVISOR is not set
-
-#
-# Connector - unified userspace <-> kernelspace linker
-#
# CONFIG_CONNECTOR is not set
-
-#
-# Memory Technology Devices (MTD)
-#
CONFIG_MTD=y
# CONFIG_MTD_DEBUG is not set
# CONFIG_MTD_CONCAT is not set
@@ -363,6 +372,7 @@
# User Modules And Translation Layers
#
CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLKDEVS=y
CONFIG_MTD_BLOCK=y
# CONFIG_FTL is not set
# CONFIG_NFTL is not set
@@ -399,7 +409,6 @@
# CONFIG_MTD_RAM is not set
# CONFIG_MTD_ROM is not set
# CONFIG_MTD_ABSENT is not set
-# CONFIG_MTD_OBSOLETE_CHIPS is not set
#
# Mapping drivers for chip access
@@ -427,29 +436,15 @@
# CONFIG_MTD_DOC2000 is not set
# CONFIG_MTD_DOC2001 is not set
# CONFIG_MTD_DOC2001PLUS is not set
-
-#
-# NAND Flash Device Drivers
-#
# CONFIG_MTD_NAND is not set
-
-#
-# OneNAND Flash Device Drivers
-#
# CONFIG_MTD_ONENAND is not set
#
-# Parallel port support
+# UBI - Unsorted block images
#
+# CONFIG_MTD_UBI is not set
# CONFIG_PARPORT is not set
-
-#
-# Plug and Play support
-#
-
-#
-# Block devices
-#
+CONFIG_BLK_DEV=y
# CONFIG_BLK_CPQ_DA is not set
# CONFIG_BLK_CPQ_CISS_DA is not set
# CONFIG_BLK_DEV_DAC960 is not set
@@ -462,13 +457,8 @@
CONFIG_BLK_DEV_RAM_COUNT=16
CONFIG_BLK_DEV_RAM_SIZE=8192
CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
-CONFIG_BLK_DEV_INITRD=y
# CONFIG_CDROM_PKTCDVD is not set
# CONFIG_ATA_OVER_ETH is not set
-
-#
-# ATA/ATAPI/MFM/RLL support
-#
# CONFIG_IDE is not set
#
@@ -476,6 +466,7 @@
#
# CONFIG_RAID_ATTRS is not set
CONFIG_SCSI=y
+CONFIG_SCSI_DMA=y
# CONFIG_SCSI_TGT is not set
# CONFIG_SCSI_NETLINK is not set
CONFIG_SCSI_PROC_FS=y
@@ -497,6 +488,7 @@
# CONFIG_SCSI_CONSTANTS is not set
# CONFIG_SCSI_LOGGING is not set
# CONFIG_SCSI_SCAN_ASYNC is not set
+CONFIG_SCSI_WAIT_SCAN=m
#
# SCSI Transports
@@ -541,22 +533,15 @@
# CONFIG_SCSI_NSP32 is not set
# CONFIG_SCSI_DEBUG is not set
# CONFIG_SCSI_SRP is not set
-
-#
-# Serial ATA (prod) and Parallel ATA (experimental) drivers
-#
# CONFIG_ATA is not set
-
-#
-# Multi-device support (RAID and LVM)
-#
CONFIG_MD=y
CONFIG_BLK_DEV_MD=y
CONFIG_MD_LINEAR=y
CONFIG_MD_RAID0=y
CONFIG_MD_RAID1=y
# CONFIG_MD_RAID10 is not set
-# CONFIG_MD_RAID456 is not set
+CONFIG_MD_RAID456=y
+# CONFIG_MD_RAID5_RESHAPE is not set
# CONFIG_MD_MULTIPATH is not set
# CONFIG_MD_FAULTY is not set
CONFIG_BLK_DEV_DM=y
@@ -566,6 +551,7 @@
# CONFIG_DM_MIRROR is not set
# CONFIG_DM_ZERO is not set
# CONFIG_DM_MULTIPATH is not set
+# CONFIG_DM_DELAY is not set
#
# Fusion MPT device support
@@ -578,39 +564,19 @@
#
# IEEE 1394 (FireWire) support
#
+# CONFIG_FIREWIRE is not set
# CONFIG_IEEE1394 is not set
-
-#
-# I2O device support
-#
# CONFIG_I2O is not set
-
-#
-# Network device support
-#
CONFIG_NETDEVICES=y
+# CONFIG_NETDEVICES_MULTIQUEUE is not set
# CONFIG_DUMMY is not set
# CONFIG_BONDING is not set
+# CONFIG_MACVLAN is not set
# CONFIG_EQUALIZER is not set
# CONFIG_TUN is not set
-
-#
-# ARCnet devices
-#
# CONFIG_ARCNET is not set
-
-#
-# PHY device support
-#
-
-#
-# Ethernet (10 or 100Mbit)
-#
# CONFIG_NET_ETHERNET is not set
-
-#
-# Ethernet (1000 Mbit)
-#
+CONFIG_NETDEV_1000=y
# CONFIG_ACENIC is not set
# CONFIG_DL2K is not set
CONFIG_E1000=y
@@ -623,33 +589,26 @@
# CONFIG_SIS190 is not set
# CONFIG_SKGE is not set
# CONFIG_SKY2 is not set
-# CONFIG_SK98LIN is not set
+# CONFIG_VIA_VELOCITY is not set
# CONFIG_TIGON3 is not set
# CONFIG_BNX2 is not set
# CONFIG_QLA3XXX is not set
-
-#
-# Ethernet (10000 Mbit)
-#
+# CONFIG_ATL1 is not set
+CONFIG_NETDEV_10000=y
# CONFIG_CHELSIO_T1 is not set
+# CONFIG_CHELSIO_T3 is not set
# CONFIG_IXGB is not set
# CONFIG_S2IO is not set
# CONFIG_MYRI10GE is not set
# CONFIG_NETXEN_NIC is not set
-
-#
-# Token Ring devices
-#
+# CONFIG_MLX4_CORE is not set
# CONFIG_TR is not set
#
-# Wireless LAN (non-hamradio)
+# Wireless LAN
#
-# CONFIG_NET_RADIO is not set
-
-#
-# Wan interfaces
-#
+# CONFIG_WLAN_PRE80211 is not set
+# CONFIG_WLAN_80211 is not set
# CONFIG_WAN is not set
# CONFIG_FDDI is not set
# CONFIG_HIPPI is not set
@@ -660,10 +619,6 @@
# CONFIG_NETCONSOLE is not set
# CONFIG_NETPOLL is not set
# CONFIG_NET_POLL_CONTROLLER is not set
-
-#
-# ISDN subsystem
-#
# CONFIG_ISDN is not set
#
@@ -671,6 +626,7 @@
#
CONFIG_INPUT=y
# CONFIG_INPUT_FF_MEMLESS is not set
+# CONFIG_INPUT_POLLDEV is not set
#
# Userland interfaces
@@ -690,6 +646,7 @@
# CONFIG_INPUT_KEYBOARD is not set
# CONFIG_INPUT_MOUSE is not set
# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
# CONFIG_INPUT_TOUCHSCREEN is not set
# CONFIG_INPUT_MISC is not set
@@ -727,33 +684,18 @@
CONFIG_UNIX98_PTYS=y
CONFIG_LEGACY_PTYS=y
CONFIG_LEGACY_PTY_COUNT=256
-
-#
-# IPMI
-#
# CONFIG_IPMI_HANDLER is not set
-
-#
-# Watchdog Cards
-#
# CONFIG_WATCHDOG is not set
CONFIG_HW_RANDOM=y
# CONFIG_NVRAM is not set
-# CONFIG_DTLK is not set
# CONFIG_R3964 is not set
# CONFIG_APPLICOM is not set
# CONFIG_DRM is not set
# CONFIG_RAW_DRIVER is not set
-
-#
-# TPM devices
-#
# CONFIG_TCG_TPM is not set
-
-#
-# I2C support
-#
+CONFIG_DEVPORT=y
CONFIG_I2C=y
+CONFIG_I2C_BOARDINFO=y
CONFIG_I2C_CHARDEV=y
#
@@ -780,25 +722,28 @@
# CONFIG_I2C_PARPORT_LIGHT is not set
# CONFIG_I2C_PROSAVAGE is not set
# CONFIG_I2C_SAVAGE4 is not set
+# CONFIG_I2C_SIMTEC is not set
# CONFIG_I2C_SIS5595 is not set
# CONFIG_I2C_SIS630 is not set
# CONFIG_I2C_SIS96X is not set
+# CONFIG_I2C_TAOS_EVM is not set
# CONFIG_I2C_STUB is not set
# CONFIG_I2C_VIA is not set
# CONFIG_I2C_VIAPRO is not set
# CONFIG_I2C_VOODOO3 is not set
-# CONFIG_I2C_PCA_ISA is not set
#
# Miscellaneous I2C Chip support
#
# CONFIG_SENSORS_DS1337 is not set
# CONFIG_SENSORS_DS1374 is not set
+# CONFIG_DS1682 is not set
# CONFIG_SENSORS_EEPROM is not set
# CONFIG_SENSORS_PCF8574 is not set
# CONFIG_SENSORS_PCA9539 is not set
# CONFIG_SENSORS_PCF8591 is not set
# CONFIG_SENSORS_MAX6875 is not set
+# CONFIG_SENSORS_TSL2550 is not set
# CONFIG_I2C_DEBUG_CORE is not set
# CONFIG_I2C_DEBUG_ALGO is not set
# CONFIG_I2C_DEBUG_BUS is not set
@@ -809,21 +754,15 @@
#
# CONFIG_SPI is not set
# CONFIG_SPI_MASTER is not set
-
-#
-# Dallas's 1-wire bus
-#
# CONFIG_W1 is not set
-
-#
-# Hardware Monitoring support
-#
CONFIG_HWMON=y
# CONFIG_HWMON_VID is not set
# CONFIG_SENSORS_ABITUGURU is not set
+# CONFIG_SENSORS_AD7418 is not set
# CONFIG_SENSORS_ADM1021 is not set
# CONFIG_SENSORS_ADM1025 is not set
# CONFIG_SENSORS_ADM1026 is not set
+# CONFIG_SENSORS_ADM1029 is not set
# CONFIG_SENSORS_ADM1031 is not set
# CONFIG_SENSORS_ADM9240 is not set
# CONFIG_SENSORS_ASB100 is not set
@@ -846,6 +785,7 @@
# CONFIG_SENSORS_LM90 is not set
# CONFIG_SENSORS_LM92 is not set
# CONFIG_SENSORS_MAX1619 is not set
+# CONFIG_SENSORS_MAX6650 is not set
# CONFIG_SENSORS_PC87360 is not set
# CONFIG_SENSORS_PC87427 is not set
# CONFIG_SENSORS_SIS5595 is not set
@@ -863,14 +803,18 @@
# CONFIG_SENSORS_W83627HF is not set
# CONFIG_SENSORS_W83627EHF is not set
# CONFIG_HWMON_DEBUG_CHIP is not set
-
-#
-# Misc devices
-#
+CONFIG_MISC_DEVICES=y
+# CONFIG_PHANTOM is not set
+# CONFIG_EEPROM_93CX6 is not set
# CONFIG_SGI_IOC4 is not set
# CONFIG_TIFM_CORE is not set
#
+# Multifunction device drivers
+#
+# CONFIG_MFD_SM501 is not set
+
+#
# LED devices
#
# CONFIG_NEW_LEDS is not set
@@ -887,16 +831,19 @@
# Multimedia devices
#
# CONFIG_VIDEO_DEV is not set
-
-#
-# Digital Video Broadcasting Devices
-#
-# CONFIG_DVB is not set
+# CONFIG_DVB_CORE is not set
+CONFIG_DAB=y
#
# Graphics support
#
-CONFIG_FIRMWARE_EDID=y
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+# CONFIG_VGASTATE is not set
# CONFIG_FB is not set
#
@@ -904,21 +851,15 @@
#
# CONFIG_VGA_CONSOLE is not set
CONFIG_DUMMY_CONSOLE=y
-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
#
# Sound
#
# CONFIG_SOUND is not set
-
-#
-# HID Devices
-#
+CONFIG_HID_SUPPORT=y
CONFIG_HID=y
-
-#
-# USB support
-#
+# CONFIG_HID_DEBUG is not set
+CONFIG_USB_SUPPORT=y
CONFIG_USB_ARCH_HAS_HCD=y
CONFIG_USB_ARCH_HAS_OHCI=y
CONFIG_USB_ARCH_HAS_EHCI=y
@@ -932,10 +873,6 @@
# USB Gadget Support
#
# CONFIG_USB_GADGET is not set
-
-#
-# MMC/SD Card support
-#
# CONFIG_MMC is not set
#
@@ -945,6 +882,22 @@
# CONFIG_RTC_CLASS is not set
#
+# DMA Engine support
+#
+CONFIG_DMA_ENGINE=y
+
+#
+# DMA Clients
+#
+CONFIG_NET_DMA=y
+
+#
+# DMA Devices
+#
+# CONFIG_INTEL_IOATDMA is not set
+CONFIG_INTEL_IOP_ADMA=y
+
+#
# File systems
#
CONFIG_EXT2_FS=y
@@ -961,11 +914,7 @@
# CONFIG_REISERFS_FS is not set
# CONFIG_JFS_FS is not set
# CONFIG_FS_POSIX_ACL is not set
-CONFIG_XFS_FS=y
-# CONFIG_XFS_QUOTA is not set
-CONFIG_XFS_SECURITY=y
-CONFIG_XFS_POSIX_ACL=y
-# CONFIG_XFS_RT is not set
+# CONFIG_XFS_FS is not set
# CONFIG_GFS2_FS is not set
# CONFIG_OCFS2_FS is not set
# CONFIG_MINIX_FS is not set
@@ -1013,9 +962,8 @@
# CONFIG_BEFS_FS is not set
# CONFIG_BFS_FS is not set
# CONFIG_EFS_FS is not set
-# CONFIG_JFFS_FS is not set
# CONFIG_JFFS2_FS is not set
-# CONFIG_CRAMFS is not set
+CONFIG_CRAMFS=y
# CONFIG_VXFS_FS is not set
# CONFIG_HPFS_FS is not set
# CONFIG_QNX4FS_FS is not set
@@ -1041,6 +989,7 @@
CONFIG_EXPORTFS=y
CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=y
+# CONFIG_SUNRPC_BIND34 is not set
# CONFIG_RPCSEC_GSS_KRB5 is not set
# CONFIG_RPCSEC_GSS_SPKM3 is not set
# CONFIG_SMB_FS is not set
@@ -1048,7 +997,6 @@
# CONFIG_NCP_FS is not set
# CONFIG_CODA_FS is not set
# CONFIG_AFS_FS is not set
-# CONFIG_9P_FS is not set
#
# Partition Types
@@ -1070,6 +1018,7 @@
# CONFIG_SUN_PARTITION is not set
# CONFIG_KARMA_PARTITION is not set
# CONFIG_EFI_PARTITION is not set
+# CONFIG_SYSV68_PARTITION is not set
#
# Native Language Support
@@ -1096,15 +1045,19 @@
# CONFIG_DEBUG_FS is not set
# CONFIG_HEADERS_CHECK is not set
CONFIG_DEBUG_KERNEL=y
-CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_DEBUG_SHIRQ is not set
CONFIG_DETECT_SOFTLOCKUP=y
+CONFIG_SCHED_DEBUG=y
# CONFIG_SCHEDSTATS is not set
+# CONFIG_TIMER_STATS is not set
# CONFIG_DEBUG_SLAB is not set
# CONFIG_DEBUG_RT_MUTEXES is not set
# CONFIG_RT_MUTEX_TESTER is not set
# CONFIG_DEBUG_SPINLOCK is not set
# CONFIG_DEBUG_MUTEXES is not set
-# CONFIG_DEBUG_RWSEMS is not set
+# CONFIG_DEBUG_LOCK_ALLOC is not set
+# CONFIG_PROVE_LOCKING is not set
+# CONFIG_LOCK_STAT is not set
# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
# CONFIG_DEBUG_KOBJECT is not set
@@ -1115,6 +1068,7 @@
CONFIG_FRAME_POINTER=y
# CONFIG_FORCED_INLINING is not set
# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_FAULT_INJECTION is not set
CONFIG_DEBUG_USER=y
# CONFIG_DEBUG_ERRORS is not set
CONFIG_DEBUG_LL=y
@@ -1125,10 +1079,10 @@
#
# CONFIG_KEYS is not set
# CONFIG_SECURITY is not set
-
-#
-# Cryptographic options
-#
+CONFIG_XOR_BLOCKS=y
+CONFIG_ASYNC_CORE=y
+CONFIG_ASYNC_MEMCPY=y
+CONFIG_ASYNC_XOR=y
# CONFIG_CRYPTO is not set
#
@@ -1136,7 +1090,12 @@
#
# CONFIG_CRC_CCITT is not set
# CONFIG_CRC16 is not set
+# CONFIG_CRC_ITU_T is not set
# CONFIG_CRC32 is not set
+# CONFIG_CRC7 is not set
# CONFIG_LIBCRC32C is not set
+CONFIG_ZLIB_INFLATE=y
CONFIG_PLIST=y
-CONFIG_IOMAP_COPY=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
diff --git a/arch/arm/configs/rpc_defconfig b/arch/arm/configs/rpc_defconfig
index 8452dc8..5ddecb9 100644
--- a/arch/arm/configs/rpc_defconfig
+++ b/arch/arm/configs/rpc_defconfig
@@ -1,87 +1,150 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.11
-# Wed Mar 9 14:41:48 2005
+# Linux kernel version: 2.6.23-rc2
+# Mon Aug 6 16:47:24 2007
#
CONFIG_ARM=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+# CONFIG_GENERIC_GPIO is not set
+# CONFIG_GENERIC_TIME is not set
+# CONFIG_GENERIC_CLOCKEVENTS is not set
CONFIG_MMU=y
-CONFIG_UID16=y
+CONFIG_NO_IOPORT=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_GENERIC_IRQ_PROBE=y
CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
+CONFIG_GENERIC_HWEIGHT=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
-CONFIG_GENERIC_IOMAP=y
+CONFIG_ARCH_MAY_HAVE_PC_FDC=y
+CONFIG_ZONE_DMA=y
CONFIG_FIQ=y
-
-#
-# Code maturity level options
-#
-CONFIG_EXPERIMENTAL=y
-CONFIG_CLEAN_COMPILE=y
-CONFIG_BROKEN_ON_SMP=y
+CONFIG_VECTORS_BASE=0xffff0000
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
#
# General setup
#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
CONFIG_LOCALVERSION=""
+# CONFIG_LOCALVERSION_AUTO is not set
CONFIG_SWAP=y
CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
# CONFIG_POSIX_MQUEUE is not set
# CONFIG_BSD_PROCESS_ACCT is not set
-CONFIG_SYSCTL=y
+# CONFIG_TASKSTATS is not set
+# CONFIG_USER_NS is not set
# CONFIG_AUDIT is not set
-CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_HOTPLUG is not set
-CONFIG_KOBJECT_UEVENT=y
# CONFIG_IKCONFIG is not set
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_SYSFS_DEPRECATED=y
+# CONFIG_RELAY is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
# CONFIG_EMBEDDED is not set
+CONFIG_UID16=y
+CONFIG_SYSCTL_SYSCALL=y
CONFIG_KALLSYMS=y
# CONFIG_KALLSYMS_ALL is not set
# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
+CONFIG_ANON_INODES=y
CONFIG_EPOLL=y
-CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
CONFIG_SHMEM=y
-CONFIG_CC_ALIGN_FUNCTIONS=0
-CONFIG_CC_ALIGN_LABELS=0
-CONFIG_CC_ALIGN_LOOPS=0
-CONFIG_CC_ALIGN_JUMPS=0
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_SLAB=y
+# CONFIG_SLUB is not set
+# CONFIG_SLOB is not set
+CONFIG_RT_MUTEXES=y
# CONFIG_TINY_SHMEM is not set
CONFIG_BASE_SMALL=0
-
-#
-# Loadable module support
-#
CONFIG_MODULES=y
CONFIG_MODULE_UNLOAD=y
# CONFIG_MODULE_FORCE_UNLOAD is not set
-CONFIG_OBSOLETE_MODPARM=y
# CONFIG_MODVERSIONS is not set
# CONFIG_MODULE_SRCVERSION_ALL is not set
CONFIG_KMOD=y
+CONFIG_BLOCK=y
+# CONFIG_LBD is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_LSF is not set
+# CONFIG_BLK_DEV_BSG is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_DEFAULT_AS is not set
+# CONFIG_DEFAULT_DEADLINE is not set
+CONFIG_DEFAULT_CFQ=y
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="cfq"
#
# System Type
#
+# CONFIG_ARCH_AAEC2000 is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_REALVIEW is not set
+# CONFIG_ARCH_VERSATILE is not set
+# CONFIG_ARCH_AT91 is not set
# CONFIG_ARCH_CLPS7500 is not set
# CONFIG_ARCH_CLPS711X is not set
# CONFIG_ARCH_CO285 is not set
# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_EP93XX is not set
# CONFIG_ARCH_FOOTBRIDGE is not set
-# CONFIG_ARCH_INTEGRATOR is not set
-# CONFIG_ARCH_IOP3XX is not set
-# CONFIG_ARCH_IXP4XX is not set
+# CONFIG_ARCH_NETX is not set
+# CONFIG_ARCH_H720X is not set
+# CONFIG_ARCH_IMX is not set
+# CONFIG_ARCH_IOP13XX is not set
+# CONFIG_ARCH_IOP32X is not set
+# CONFIG_ARCH_IOP33X is not set
+# CONFIG_ARCH_IXP23XX is not set
# CONFIG_ARCH_IXP2000 is not set
+# CONFIG_ARCH_IXP4XX is not set
# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_KS8695 is not set
+# CONFIG_ARCH_NS9XXX is not set
+# CONFIG_ARCH_MXC is not set
+# CONFIG_ARCH_PNX4008 is not set
# CONFIG_ARCH_PXA is not set
CONFIG_ARCH_RPC=y
# CONFIG_ARCH_SA1100 is not set
# CONFIG_ARCH_S3C2410 is not set
# CONFIG_ARCH_SHARK is not set
# CONFIG_ARCH_LH7A40X is not set
+# CONFIG_ARCH_DAVINCI is not set
# CONFIG_ARCH_OMAP is not set
-# CONFIG_ARCH_VERSATILE is not set
-# CONFIG_ARCH_IMX is not set
-# CONFIG_ARCH_H720X is not set
+
+#
+# Boot options
+#
+
+#
+# Power management
+#
CONFIG_ARCH_ACORN=y
#
@@ -100,15 +163,22 @@
CONFIG_CPU_COPY_V4WB=y
CONFIG_CPU_TLB_V3=y
CONFIG_CPU_TLB_V4WB=y
+CONFIG_CPU_CP15=y
+CONFIG_CPU_CP15_MMU=y
#
# Processor Features
#
+# CONFIG_CPU_DCACHE_DISABLE is not set
+# CONFIG_OUTER_CACHE is not set
CONFIG_TIMER_ACORN=y
#
# Bus support
#
+CONFIG_ISA_DMA_API=y
+# CONFIG_PCI_SYSCALL is not set
+# CONFIG_ARCH_SUPPORTS_MSI is not set
#
# PCCARD (PCMCIA/CardBus) support
@@ -116,13 +186,26 @@
# CONFIG_PCCARD is not set
#
-# PC-card bridges
-#
-
-#
# Kernel Features
#
+# CONFIG_TICK_ONESHOT is not set
# CONFIG_PREEMPT is not set
+# CONFIG_NO_IDLE_HZ is not set
+CONFIG_HZ=100
+# CONFIG_AEABI is not set
+# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+# CONFIG_SPARSEMEM_STATIC is not set
+CONFIG_SPLIT_PTLOCK_CPUS=4096
+# CONFIG_RESOURCES_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=1
+CONFIG_BOUNCE=y
+CONFIG_VIRT_TO_BUS=y
CONFIG_ALIGNMENT_TRAP=y
#
@@ -132,6 +215,7 @@
CONFIG_ZBOOT_ROM_BSS=0x0
CONFIG_CMDLINE=""
# CONFIG_XIP_KERNEL is not set
+# CONFIG_KEXEC is not set
#
# Floating point emulation
@@ -157,6 +241,100 @@
# CONFIG_PM is not set
#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=y
+CONFIG_UNIX=y
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+# CONFIG_IP_PNP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+CONFIG_INET_TUNNEL=m
+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_BEET is not set
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+CONFIG_IPV6=m
+# CONFIG_IPV6_PRIVACY is not set
+# CONFIG_IPV6_ROUTER_PREF is not set
+# CONFIG_IPV6_OPTIMISTIC_DAD is not set
+# CONFIG_INET6_AH is not set
+# CONFIG_INET6_ESP is not set
+# CONFIG_INET6_IPCOMP is not set
+# CONFIG_IPV6_MIP6 is not set
+# CONFIG_INET6_XFRM_TUNNEL is not set
+# CONFIG_INET6_TUNNEL is not set
+# CONFIG_INET6_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET6_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET6_XFRM_MODE_BEET is not set
+# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
+CONFIG_IPV6_SIT=m
+# CONFIG_IPV6_TUNNEL is not set
+# CONFIG_IPV6_MULTIPLE_TABLES is not set
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_IP_DCCP is not set
+# CONFIG_IP_SCTP is not set
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_AF_RXRPC is not set
+
+#
+# Wireless
+#
+# CONFIG_CFG80211 is not set
+# CONFIG_WIRELESS_EXT is not set
+# CONFIG_MAC80211 is not set
+# CONFIG_IEEE80211 is not set
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
+
+#
# Device Drivers
#
@@ -167,31 +345,18 @@
CONFIG_PREVENT_FIRMWARE_BUILD=y
# CONFIG_FW_LOADER is not set
# CONFIG_DEBUG_DRIVER is not set
-
-#
-# Memory Technology Devices (MTD)
-#
+# CONFIG_DEBUG_DEVRES is not set
+# CONFIG_SYS_HYPERVISOR is not set
+# CONFIG_CONNECTOR is not set
# CONFIG_MTD is not set
-
-#
-# Parallel port support
-#
CONFIG_PARPORT=y
CONFIG_PARPORT_PC=y
-CONFIG_PARPORT_PC_CML1=y
CONFIG_PARPORT_PC_FIFO=y
# CONFIG_PARPORT_PC_SUPERIO is not set
-# CONFIG_PARPORT_ARC is not set
-# CONFIG_PARPORT_OTHER is not set
+# CONFIG_PARPORT_GSC is not set
+# CONFIG_PARPORT_AX88796 is not set
# CONFIG_PARPORT_1284 is not set
-
-#
-# Plug and Play support
-#
-
-#
-# Block devices
-#
+CONFIG_BLK_DEV=y
CONFIG_BLK_DEV_FD=y
# CONFIG_PARIDE is not set
# CONFIG_BLK_DEV_COW_COMMON is not set
@@ -201,59 +366,19 @@
CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_RAM_COUNT=16
CONFIG_BLK_DEV_RAM_SIZE=4096
-CONFIG_BLK_DEV_INITRD=y
-CONFIG_INITRAMFS_SOURCE=""
+CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
# CONFIG_CDROM_PKTCDVD is not set
-
-#
-# IO Schedulers
-#
-CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
-CONFIG_IOSCHED_DEADLINE=y
-CONFIG_IOSCHED_CFQ=y
# CONFIG_ATA_OVER_ETH is not set
-
-#
-# Acorn-specific block devices
-#
-
-#
-# ATA/ATAPI/MFM/RLL support
-#
-CONFIG_IDE=y
-CONFIG_BLK_DEV_IDE=y
-
-#
-# Please see Documentation/ide.txt for help/info on IDE drives
-#
-# CONFIG_BLK_DEV_IDE_SATA is not set
-CONFIG_BLK_DEV_IDEDISK=y
-CONFIG_IDEDISK_MULTI_MODE=y
-CONFIG_BLK_DEV_IDECD=y
-# CONFIG_BLK_DEV_IDETAPE is not set
-# CONFIG_BLK_DEV_IDEFLOPPY is not set
-# CONFIG_BLK_DEV_IDESCSI is not set
-# CONFIG_IDE_TASK_IOCTL is not set
-
-#
-# IDE chipset support/bugfixes
-#
-CONFIG_IDE_GENERIC=y
-CONFIG_IDE_ARM=y
-CONFIG_BLK_DEV_IDE_ICSIDE=y
-CONFIG_BLK_DEV_IDEDMA_ICS=y
-CONFIG_IDEDMA_ICS_AUTO=y
-CONFIG_BLK_DEV_IDE_RAPIDE=y
-CONFIG_BLK_DEV_IDEDMA=y
-# CONFIG_IDEDMA_IVB is not set
-CONFIG_IDEDMA_AUTO=y
-# CONFIG_BLK_DEV_HD is not set
+# CONFIG_IDE is not set
#
# SCSI device support
#
+# CONFIG_RAID_ATTRS is not set
CONFIG_SCSI=y
+CONFIG_SCSI_DMA=y
+# CONFIG_SCSI_TGT is not set
+# CONFIG_SCSI_NETLINK is not set
CONFIG_SCSI_PROC_FS=y
#
@@ -265,6 +390,7 @@
CONFIG_BLK_DEV_SR=y
CONFIG_BLK_DEV_SR_VENDOR=y
CONFIG_CHR_DEV_SG=y
+# CONFIG_CHR_DEV_SCH is not set
#
# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
@@ -272,26 +398,23 @@
# CONFIG_SCSI_MULTI_LUN is not set
CONFIG_SCSI_CONSTANTS=y
CONFIG_SCSI_LOGGING=y
+# CONFIG_SCSI_SCAN_ASYNC is not set
+CONFIG_SCSI_WAIT_SCAN=m
#
-# SCSI Transport Attributes
+# SCSI Transports
#
-# CONFIG_SCSI_SPI_ATTRS is not set
+CONFIG_SCSI_SPI_ATTRS=m
# CONFIG_SCSI_FC_ATTRS is not set
# CONFIG_SCSI_ISCSI_ATTRS is not set
-
-#
-# SCSI low-level drivers
-#
-# CONFIG_SCSI_SATA is not set
-CONFIG_SCSI_PPA=m
-CONFIG_SCSI_IMM=m
+# CONFIG_SCSI_SAS_LIBSAS is not set
+CONFIG_SCSI_LOWLEVEL=y
+# CONFIG_ISCSI_TCP is not set
+# CONFIG_SCSI_PPA is not set
+# CONFIG_SCSI_IMM is not set
# CONFIG_SCSI_IZIP_EPP16 is not set
# CONFIG_SCSI_IZIP_SLOW_CTR is not set
# CONFIG_SCSI_DEBUG is not set
-CONFIG_SCSI_ACORNSCSI_3=m
-CONFIG_SCSI_ACORNSCSI_TAGGED_QUEUE=y
-CONFIG_SCSI_ACORNSCSI_SYNC=y
CONFIG_SCSI_ARXESCSI=m
CONFIG_SCSI_CUMANA_2=m
CONFIG_SCSI_EESOXSCSI=m
@@ -302,129 +425,36 @@
#
CONFIG_SCSI_CUMANA_1=m
CONFIG_SCSI_OAK1=m
-
-#
-# Multi-device support (RAID and LVM)
-#
+CONFIG_ATA=y
+# CONFIG_ATA_NONSTANDARD is not set
+CONFIG_PATA_PLATFORM=y
+CONFIG_PATA_ICSIDE=y
# CONFIG_MD is not set
-
-#
-# Fusion MPT device support
-#
-
-#
-# IEEE 1394 (FireWire) support
-#
-
-#
-# I2O device support
-#
-
-#
-# Networking support
-#
-CONFIG_NET=y
-
-#
-# Networking options
-#
-# CONFIG_PACKET is not set
-CONFIG_NETLINK_DEV=y
-CONFIG_UNIX=y
-# CONFIG_NET_KEY is not set
-CONFIG_INET=y
-CONFIG_IP_MULTICAST=y
-# CONFIG_IP_ADVANCED_ROUTER is not set
-# CONFIG_IP_PNP is not set
-# CONFIG_NET_IPIP is not set
-# CONFIG_NET_IPGRE is not set
-# CONFIG_IP_MROUTE is not set
-# CONFIG_ARPD is not set
-# CONFIG_SYN_COOKIES is not set
-# CONFIG_INET_AH is not set
-# CONFIG_INET_ESP is not set
-# CONFIG_INET_IPCOMP is not set
-# CONFIG_INET_TUNNEL is not set
-# CONFIG_IP_TCPDIAG is not set
-# CONFIG_IP_TCPDIAG_IPV6 is not set
-CONFIG_IPV6=m
-# CONFIG_IPV6_PRIVACY is not set
-# CONFIG_INET6_AH is not set
-# CONFIG_INET6_ESP is not set
-# CONFIG_INET6_IPCOMP is not set
-# CONFIG_INET6_TUNNEL is not set
-# CONFIG_IPV6_TUNNEL is not set
-# CONFIG_NETFILTER is not set
-
-#
-# SCTP Configuration (EXPERIMENTAL)
-#
-# CONFIG_IP_SCTP is not set
-# CONFIG_ATM is not set
-# CONFIG_BRIDGE is not set
-# CONFIG_VLAN_8021Q is not set
-# CONFIG_DECNET is not set
-# CONFIG_LLC2 is not set
-# CONFIG_IPX is not set
-# CONFIG_ATALK is not set
-# CONFIG_X25 is not set
-# CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
-# CONFIG_ECONET is not set
-# CONFIG_WAN_ROUTER is not set
-
-#
-# QoS and/or fair queueing
-#
-# CONFIG_NET_SCHED is not set
-# CONFIG_NET_CLS_ROUTE is not set
-
-#
-# Network testing
-#
-# CONFIG_NET_PKTGEN is not set
-# CONFIG_NETPOLL is not set
-# CONFIG_NET_POLL_CONTROLLER is not set
-# CONFIG_HAMRADIO is not set
-# CONFIG_IRDA is not set
-# CONFIG_BT is not set
CONFIG_NETDEVICES=y
+# CONFIG_NETDEVICES_MULTIQUEUE is not set
# CONFIG_DUMMY is not set
# CONFIG_BONDING is not set
+# CONFIG_MACVLAN is not set
# CONFIG_EQUALIZER is not set
# CONFIG_TUN is not set
-# CONFIG_ETHERTAP is not set
-
-#
-# Ethernet (10 or 100Mbit)
-#
+# CONFIG_PHYLIB is not set
CONFIG_NET_ETHERNET=y
# CONFIG_MII is not set
CONFIG_ARM_ETHER1=y
CONFIG_ARM_ETHER3=y
CONFIG_ARM_ETHERH=y
+# CONFIG_AX88796 is not set
# CONFIG_SMC91X is not set
+# CONFIG_DM9000 is not set
+# CONFIG_NET_POCKET is not set
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
#
-# Ethernet (1000 Mbit)
+# Wireless LAN
#
-
-#
-# Ethernet (10000 Mbit)
-#
-
-#
-# Token Ring devices
-#
-
-#
-# Wireless LAN (non-hamradio)
-#
-# CONFIG_NET_RADIO is not set
-
-#
-# Wan interfaces
-#
+# CONFIG_WLAN_PRE80211 is not set
+# CONFIG_WLAN_80211 is not set
# CONFIG_WAN is not set
# CONFIG_PLIP is not set
CONFIG_PPP=m
@@ -434,20 +464,23 @@
# CONFIG_PPP_SYNC_TTY is not set
# CONFIG_PPP_DEFLATE is not set
# CONFIG_PPP_BSDCOMP is not set
+# CONFIG_PPP_MPPE is not set
CONFIG_PPPOE=m
+# CONFIG_PPPOL2TP is not set
# CONFIG_SLIP is not set
+CONFIG_SLHC=m
# CONFIG_SHAPER is not set
# CONFIG_NETCONSOLE is not set
-
-#
-# ISDN subsystem
-#
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
# CONFIG_ISDN is not set
#
# Input device support
#
CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+# CONFIG_INPUT_POLLDEV is not set
#
# Userland interfaces
@@ -462,19 +495,6 @@
# CONFIG_INPUT_EVBUG is not set
#
-# Input I/O drivers
-#
-# CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
-CONFIG_SERIO=y
-# CONFIG_SERIO_SERPORT is not set
-# CONFIG_SERIO_CT82C710 is not set
-# CONFIG_SERIO_PARKBD is not set
-CONFIG_SERIO_RPCKBD=y
-CONFIG_SERIO_LIBPS2=y
-# CONFIG_SERIO_RAW is not set
-
-#
# Input Device Drivers
#
CONFIG_INPUT_KEYBOARD=y
@@ -483,21 +503,35 @@
# CONFIG_KEYBOARD_LKKBD is not set
# CONFIG_KEYBOARD_XTKBD is not set
# CONFIG_KEYBOARD_NEWTON is not set
+# CONFIG_KEYBOARD_STOWAWAY is not set
CONFIG_INPUT_MOUSE=y
# CONFIG_MOUSE_PS2 is not set
# CONFIG_MOUSE_SERIAL is not set
CONFIG_MOUSE_RISCPC=y
# CONFIG_MOUSE_VSXXXAA is not set
# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
# CONFIG_INPUT_TOUCHSCREEN is not set
# CONFIG_INPUT_MISC is not set
#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+# CONFIG_SERIO_SERPORT is not set
+# CONFIG_SERIO_PARKBD is not set
+CONFIG_SERIO_RPCKBD=y
+CONFIG_SERIO_LIBPS2=y
+# CONFIG_SERIO_RAW is not set
+# CONFIG_GAMEPORT is not set
+
+#
# Character devices
#
CONFIG_VT=y
CONFIG_VT_CONSOLE=y
CONFIG_HW_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
# CONFIG_SERIAL_NONSTANDARD is not set
#
@@ -506,12 +540,13 @@
CONFIG_SERIAL_8250=y
CONFIG_SERIAL_8250_CONSOLE=y
CONFIG_SERIAL_8250_NR_UARTS=16
+CONFIG_SERIAL_8250_RUNTIME_UARTS=8
# CONFIG_SERIAL_8250_EXTENDED is not set
+CONFIG_SERIAL_8250_ACORN=y
#
# Non-8250 serial port support
#
-CONFIG_SERIAL_8250_ACORN=y
CONFIG_SERIAL_CORE=y
CONFIG_SERIAL_CORE_CONSOLE=y
CONFIG_UNIX98_PTYS=y
@@ -521,31 +556,15 @@
# CONFIG_LP_CONSOLE is not set
# CONFIG_PPDEV is not set
# CONFIG_TIPAR is not set
-
-#
-# IPMI
-#
# CONFIG_IPMI_HANDLER is not set
-
-#
-# Watchdog Cards
-#
# CONFIG_WATCHDOG is not set
+# CONFIG_HW_RANDOM is not set
# CONFIG_NVRAM is not set
-# CONFIG_RTC is not set
-# CONFIG_DTLK is not set
# CONFIG_R3964 is not set
-
-#
-# Ftape, the floppy tape device driver
-#
-# CONFIG_DRM is not set
# CONFIG_RAW_DRIVER is not set
-
-#
-# I2C support
-#
+# CONFIG_TCG_TPM is not set
CONFIG_I2C=y
+CONFIG_I2C_BOARDINFO=y
CONFIG_I2C_CHARDEV=y
#
@@ -558,76 +577,87 @@
#
# I2C Hardware Bus support
#
+# CONFIG_I2C_OCORES is not set
# CONFIG_I2C_PARPORT is not set
# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_TAOS_EVM is not set
# CONFIG_I2C_STUB is not set
-# CONFIG_I2C_PCA_ISA is not set
+CONFIG_I2C_ACORN=y
#
-# Hardware Sensors Chip support
+# Miscellaneous I2C Chip support
#
-# CONFIG_I2C_SENSOR is not set
-# CONFIG_SENSORS_ADM1021 is not set
-# CONFIG_SENSORS_ADM1025 is not set
-# CONFIG_SENSORS_ADM1026 is not set
-# CONFIG_SENSORS_ADM1031 is not set
-# CONFIG_SENSORS_ASB100 is not set
-# CONFIG_SENSORS_DS1621 is not set
-# CONFIG_SENSORS_FSCHER is not set
-# CONFIG_SENSORS_FSCPOS is not set
-# CONFIG_SENSORS_GL518SM is not set
-# CONFIG_SENSORS_GL520SM is not set
-# CONFIG_SENSORS_IT87 is not set
-# CONFIG_SENSORS_LM63 is not set
-# CONFIG_SENSORS_LM75 is not set
-# CONFIG_SENSORS_LM77 is not set
-# CONFIG_SENSORS_LM78 is not set
-# CONFIG_SENSORS_LM80 is not set
-# CONFIG_SENSORS_LM83 is not set
-# CONFIG_SENSORS_LM85 is not set
-# CONFIG_SENSORS_LM87 is not set
-# CONFIG_SENSORS_LM90 is not set
-# CONFIG_SENSORS_MAX1619 is not set
-# CONFIG_SENSORS_PC87360 is not set
-# CONFIG_SENSORS_SMSC47B397 is not set
-# CONFIG_SENSORS_SMSC47M1 is not set
-# CONFIG_SENSORS_W83781D is not set
-# CONFIG_SENSORS_W83L785TS is not set
-# CONFIG_SENSORS_W83627HF is not set
-
-#
-# Other I2C Chip support
-#
+# CONFIG_SENSORS_DS1337 is not set
+# CONFIG_SENSORS_DS1374 is not set
+# CONFIG_DS1682 is not set
# CONFIG_SENSORS_EEPROM is not set
# CONFIG_SENSORS_PCF8574 is not set
+# CONFIG_SENSORS_PCA9539 is not set
# CONFIG_SENSORS_PCF8591 is not set
-# CONFIG_SENSORS_RTC8564 is not set
+# CONFIG_SENSORS_MAX6875 is not set
+# CONFIG_SENSORS_TSL2550 is not set
# CONFIG_I2C_DEBUG_CORE is not set
# CONFIG_I2C_DEBUG_ALGO is not set
# CONFIG_I2C_DEBUG_BUS is not set
# CONFIG_I2C_DEBUG_CHIP is not set
#
-# Misc devices
+# SPI support
#
+# CONFIG_SPI is not set
+# CONFIG_SPI_MASTER is not set
+# CONFIG_W1 is not set
+# CONFIG_HWMON is not set
+CONFIG_MISC_DEVICES=y
+# CONFIG_EEPROM_93CX6 is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_SM501 is not set
+# CONFIG_NEW_LEDS is not set
#
# Multimedia devices
#
# CONFIG_VIDEO_DEV is not set
-
-#
-# Digital Video Broadcasting Devices
-#
-# CONFIG_DVB is not set
+# CONFIG_DVB_CORE is not set
+# CONFIG_DAB is not set
#
# Graphics support
#
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
CONFIG_FB=y
+# CONFIG_FIRMWARE_EDID is not set
+# CONFIG_FB_DDC is not set
+CONFIG_FB_CFB_FILLRECT=y
+CONFIG_FB_CFB_COPYAREA=y
+CONFIG_FB_CFB_IMAGEBLIT=y
+# CONFIG_FB_SYS_FILLRECT is not set
+# CONFIG_FB_SYS_COPYAREA is not set
+# CONFIG_FB_SYS_IMAGEBLIT is not set
+# CONFIG_FB_SYS_FOPS is not set
+CONFIG_FB_DEFERRED_IO=y
+# CONFIG_FB_SVGALIB is not set
+# CONFIG_FB_MACMODES is not set
+# CONFIG_FB_BACKLIGHT is not set
# CONFIG_FB_MODE_HELPERS is not set
# CONFIG_FB_TILEBLITTING is not set
+
+#
+# Frame buffer hardware drivers
+#
CONFIG_FB_ACORN=y
+# CONFIG_FB_S1D13XXX is not set
# CONFIG_FB_VIRTUAL is not set
#
@@ -635,24 +665,23 @@
#
CONFIG_DUMMY_CONSOLE=y
CONFIG_FRAMEBUFFER_CONSOLE=y
+# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set
+# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
CONFIG_FONTS=y
# CONFIG_FONT_8x8 is not set
CONFIG_FONT_8x16=y
# CONFIG_FONT_6x11 is not set
+# CONFIG_FONT_7x14 is not set
# CONFIG_FONT_PEARL_8x8 is not set
CONFIG_FONT_ACORN_8x8=y
# CONFIG_FONT_MINI_4x6 is not set
# CONFIG_FONT_SUN8x16 is not set
# CONFIG_FONT_SUN12x22 is not set
-
-#
-# Logo configuration
-#
+# CONFIG_FONT_10x18 is not set
CONFIG_LOGO=y
CONFIG_LOGO_LINUX_MONO=y
CONFIG_LOGO_LINUX_VGA16=y
CONFIG_LOGO_LINUX_CLUT224=y
-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
#
# Sound
@@ -668,91 +697,115 @@
# Open Sound System
#
CONFIG_SOUND_PRIME=m
-# CONFIG_SOUND_BT878 is not set
-# CONFIG_SOUND_FUSION is not set
-# CONFIG_SOUND_CS4281 is not set
-# CONFIG_SOUND_SONICVIBES is not set
-# CONFIG_SOUND_TRIDENT is not set
# CONFIG_SOUND_MSNDCLAS is not set
# CONFIG_SOUND_MSNDPIN is not set
CONFIG_SOUND_OSS=m
# CONFIG_SOUND_TRACEINIT is not set
# CONFIG_SOUND_DMAP is not set
-# CONFIG_SOUND_AD1816 is not set
-# CONFIG_SOUND_AD1889 is not set
-# CONFIG_SOUND_SGALAXY is not set
-# CONFIG_SOUND_ADLIB is not set
-# CONFIG_SOUND_ACI_MIXER is not set
-# CONFIG_SOUND_CS4232 is not set
# CONFIG_SOUND_SSCAPE is not set
-# CONFIG_SOUND_GUS is not set
# CONFIG_SOUND_VMIDI is not set
# CONFIG_SOUND_TRIX is not set
# CONFIG_SOUND_MSS is not set
# CONFIG_SOUND_MPU401 is not set
-# CONFIG_SOUND_NM256 is not set
-# CONFIG_SOUND_MAD16 is not set
# CONFIG_SOUND_PAS is not set
# CONFIG_SOUND_PSS is not set
# CONFIG_SOUND_SB is not set
-# CONFIG_SOUND_AWE32_SYNTH is not set
-# CONFIG_SOUND_WAVEFRONT is not set
-# CONFIG_SOUND_MAUI is not set
# CONFIG_SOUND_YM3812 is not set
-# CONFIG_SOUND_OPL3SA1 is not set
-# CONFIG_SOUND_OPL3SA2 is not set
# CONFIG_SOUND_UART6850 is not set
# CONFIG_SOUND_AEDSP16 is not set
CONFIG_SOUND_VIDC=m
-# CONFIG_SOUND_TVMIXER is not set
-# CONFIG_SOUND_AD1980 is not set
-
-#
-# USB support
-#
-# CONFIG_USB is not set
-CONFIG_USB_ARCH_HAS_HCD=y
-# CONFIG_USB_ARCH_HAS_OHCI is not set
-
-#
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
-#
-
-#
-# USB Gadget Support
-#
-# CONFIG_USB_GADGET is not set
-
-#
-# MMC/SD Card support
-#
+# CONFIG_HID_SUPPORT is not set
+# CONFIG_USB_SUPPORT is not set
# CONFIG_MMC is not set
+CONFIG_RTC_LIB=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_HCTOSYS=y
+CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
+# CONFIG_RTC_DEBUG is not set
+
+#
+# RTC interfaces
+#
+CONFIG_RTC_INTF_SYSFS=y
+CONFIG_RTC_INTF_PROC=y
+CONFIG_RTC_INTF_DEV=y
+# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
+# CONFIG_RTC_DRV_TEST is not set
+
+#
+# I2C RTC drivers
+#
+# CONFIG_RTC_DRV_DS1307 is not set
+# CONFIG_RTC_DRV_DS1672 is not set
+# CONFIG_RTC_DRV_MAX6900 is not set
+# CONFIG_RTC_DRV_RS5C372 is not set
+# CONFIG_RTC_DRV_ISL1208 is not set
+# CONFIG_RTC_DRV_X1205 is not set
+# CONFIG_RTC_DRV_PCF8563 is not set
+CONFIG_RTC_DRV_PCF8583=y
+# CONFIG_RTC_DRV_M41T80 is not set
+
+#
+# SPI RTC drivers
+#
+
+#
+# Platform RTC drivers
+#
+# CONFIG_RTC_DRV_CMOS is not set
+# CONFIG_RTC_DRV_DS1553 is not set
+# CONFIG_RTC_DRV_STK17TA8 is not set
+# CONFIG_RTC_DRV_DS1742 is not set
+# CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_V3020 is not set
+
+#
+# on-CPU RTC drivers
+#
+
+#
+# DMA Engine support
+#
+# CONFIG_DMA_ENGINE is not set
+
+#
+# DMA Clients
+#
+
+#
+# DMA Devices
+#
#
# File systems
#
CONFIG_EXT2_FS=y
# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
CONFIG_EXT3_FS=y
CONFIG_EXT3_FS_XATTR=y
# CONFIG_EXT3_FS_POSIX_ACL is not set
# CONFIG_EXT3_FS_SECURITY is not set
+# CONFIG_EXT4DEV_FS is not set
CONFIG_JBD=y
# CONFIG_JBD_DEBUG is not set
CONFIG_FS_MBCACHE=y
# CONFIG_REISERFS_FS is not set
# CONFIG_JFS_FS is not set
-
-#
-# XFS support
-#
+# CONFIG_FS_POSIX_ACL is not set
# CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
+# CONFIG_OCFS2_FS is not set
# CONFIG_MINIX_FS is not set
# CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
# CONFIG_QUOTA is not set
CONFIG_DNOTIFY=y
# CONFIG_AUTOFS_FS is not set
CONFIG_AUTOFS4_FS=m
+# CONFIG_FUSE_FS is not set
#
# CD-ROM/DVD Filesystems
@@ -776,12 +829,12 @@
# Pseudo filesystems
#
CONFIG_PROC_FS=y
+CONFIG_PROC_SYSCTL=y
CONFIG_SYSFS=y
-# CONFIG_DEVFS_FS is not set
-# CONFIG_DEVPTS_FS_XATTR is not set
# CONFIG_TMPFS is not set
# CONFIG_HUGETLB_PAGE is not set
CONFIG_RAMFS=y
+# CONFIG_CONFIGFS_FS is not set
#
# Miscellaneous filesystems
@@ -810,7 +863,9 @@
# CONFIG_NFS_DIRECTIO is not set
# CONFIG_NFSD is not set
CONFIG_LOCKD=y
+CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=y
+# CONFIG_SUNRPC_BIND34 is not set
# CONFIG_RPCSEC_GSS_KRB5 is not set
# CONFIG_RPCSEC_GSS_SPKM3 is not set
# CONFIG_SMB_FS is not set
@@ -830,20 +885,22 @@
CONFIG_ACORN_PARTITION_ADFS=y
CONFIG_ACORN_PARTITION_POWERTEC=y
CONFIG_ACORN_PARTITION_RISCIX=y
-CONFIG_OSF_PARTITION=y
-CONFIG_AMIGA_PARTITION=y
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
# CONFIG_ATARI_PARTITION is not set
-CONFIG_MAC_PARTITION=y
+# CONFIG_MAC_PARTITION is not set
CONFIG_MSDOS_PARTITION=y
CONFIG_BSD_DISKLABEL=y
# CONFIG_MINIX_SUBPARTITION is not set
-CONFIG_SOLARIS_X86_PARTITION=y
+# CONFIG_SOLARIS_X86_PARTITION is not set
# CONFIG_UNIXWARE_DISKLABEL is not set
# CONFIG_LDM_PARTITION is not set
-CONFIG_SGI_PARTITION=y
+# CONFIG_SGI_PARTITION is not set
# CONFIG_ULTRIX_PARTITION is not set
-CONFIG_SUN_PARTITION=y
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_KARMA_PARTITION is not set
# CONFIG_EFI_PARTITION is not set
+# CONFIG_SYSV68_PARTITION is not set
#
# Native Language Support
@@ -890,6 +947,11 @@
# CONFIG_NLS_UTF8 is not set
#
+# Distributed Lock Manager
+#
+# CONFIG_DLM is not set
+
+#
# Profiling support
#
# CONFIG_PROFILING is not set
@@ -897,17 +959,37 @@
#
# Kernel hacking
#
-CONFIG_DEBUG_KERNEL=y
-CONFIG_MAGIC_SYSRQ=y
# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_MAGIC_SYSRQ=y
+# CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_SHIRQ is not set
+CONFIG_DETECT_SOFTLOCKUP=y
+CONFIG_SCHED_DEBUG=y
# CONFIG_SCHEDSTATS is not set
+# CONFIG_TIMER_STATS is not set
# CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_MUTEXES is not set
+# CONFIG_DEBUG_LOCK_ALLOC is not set
+# CONFIG_PROVE_LOCKING is not set
+# CONFIG_LOCK_STAT is not set
+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
# CONFIG_DEBUG_KOBJECT is not set
CONFIG_DEBUG_BUGVERBOSE=y
# CONFIG_DEBUG_INFO is not set
-# CONFIG_DEBUG_FS is not set
+# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_LIST is not set
CONFIG_FRAME_POINTER=y
+CONFIG_FORCED_INLINING=y
+# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_FAULT_INJECTION is not set
CONFIG_DEBUG_USER=y
CONFIG_DEBUG_ERRORS=y
CONFIG_DEBUG_LL=y
@@ -918,19 +1000,18 @@
#
# CONFIG_KEYS is not set
# CONFIG_SECURITY is not set
-
-#
-# Cryptographic options
-#
# CONFIG_CRYPTO is not set
#
-# Hardware crypto devices
-#
-
-#
# Library routines
#
+CONFIG_BITREVERSE=y
# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
+# CONFIG_CRC_ITU_T is not set
CONFIG_CRC32=y
+# CONFIG_CRC7 is not set
# CONFIG_LIBCRC32C is not set
+CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_DMA=y
diff --git a/arch/arm/mach-at91/at91sam9261_devices.c b/arch/arm/mach-at91/at91sam9261_devices.c
index 9db58da..3576595 100644
--- a/arch/arm/mach-at91/at91sam9261_devices.c
+++ b/arch/arm/mach-at91/at91sam9261_devices.c
@@ -15,6 +15,8 @@
#include <linux/platform_device.h>
+#include <video/atmel_lcdc.h>
+
#include <asm/arch/board.h>
#include <asm/arch/gpio.h>
#include <asm/arch/at91sam9261.h>
diff --git a/arch/arm/mach-at91/at91sam9263_devices.c b/arch/arm/mach-at91/at91sam9263_devices.c
index 6356957..f924bd5 100644
--- a/arch/arm/mach-at91/at91sam9263_devices.c
+++ b/arch/arm/mach-at91/at91sam9263_devices.c
@@ -14,6 +14,8 @@
#include <linux/platform_device.h>
+#include <video/atmel_lcdc.h>
+
#include <asm/arch/board.h>
#include <asm/arch/gpio.h>
#include <asm/arch/at91sam9263.h>
diff --git a/arch/arm/mach-ks8695/board-micrel.c b/arch/arm/mach-ks8695/board-micrel.c
index 8fc0edb..2feeef8 100644
--- a/arch/arm/mach-ks8695/board-micrel.c
+++ b/arch/arm/mach-ks8695/board-micrel.c
@@ -23,24 +23,24 @@
#include "generic.h"
#ifdef CONFIG_PCI
-static int __init micrel_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+static int micrel_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
{
return KS8695_IRQ_EXTERN0;
}
-static struct ks8695_pci_cfg micrel_pci = {
+static struct ks8695_pci_cfg __initdata micrel_pci = {
.mode = KS8695_MODE_MINIPCI,
.map_irq = micrel_pci_map_irq,
};
#endif
-static void micrel_init(void)
+static void __init micrel_init(void)
{
printk(KERN_INFO "Micrel KS8695 Development Board initializing\n");
#ifdef CONFIG_PCI
- ks8695_init_pci(&micrel_pci);
+// ks8695_init_pci(&micrel_pci);
#endif
/* Add devices */
diff --git a/arch/arm/mach-s3c2442/Kconfig b/arch/arm/mach-s3c2442/Kconfig
index 88d5fd3..26d131a 100644
--- a/arch/arm/mach-s3c2442/Kconfig
+++ b/arch/arm/mach-s3c2442/Kconfig
@@ -6,7 +6,7 @@
config CPU_S3C2442
bool
- depends on ARCH_S3C2420
+ depends on ARCH_S3C2410
select S3C2410_CLOCK
select S3C2410_GPIO
select S3C2410_PM if PM
diff --git a/arch/avr32/boards/atngw100/setup.c b/arch/avr32/boards/atngw100/setup.c
index 2edcecd..ef80156 100644
--- a/arch/avr32/boards/atngw100/setup.c
+++ b/arch/avr32/boards/atngw100/setup.c
@@ -9,6 +9,7 @@
*/
#include <linux/clk.h>
#include <linux/etherdevice.h>
+#include <linux/i2c-gpio.h>
#include <linux/init.h>
#include <linux/linkage.h>
#include <linux/platform_device.h>
@@ -123,6 +124,19 @@
}
};
+static struct i2c_gpio_platform_data i2c_gpio_data = {
+ .sda_pin = GPIO_PIN_PA(6),
+ .scl_pin = GPIO_PIN_PA(7),
+};
+
+static struct platform_device i2c_gpio_device = {
+ .name = "i2c-gpio",
+ .id = 0,
+ .dev = {
+ .platform_data = &i2c_gpio_data,
+ },
+};
+
static int __init atngw100_init(void)
{
unsigned i;
@@ -147,6 +161,10 @@
}
platform_device_register(&ngw_gpio_leds);
+ at32_select_gpio(i2c_gpio_data.sda_pin, 0);
+ at32_select_gpio(i2c_gpio_data.scl_pin, 0);
+ platform_device_register(&i2c_gpio_device);
+
return 0;
}
postcore_initcall(atngw100_init);
diff --git a/arch/avr32/boards/atstk1000/Kconfig b/arch/avr32/boards/atstk1000/Kconfig
index 71bc7d3..718578f 100644
--- a/arch/avr32/boards/atstk1000/Kconfig
+++ b/arch/avr32/boards/atstk1000/Kconfig
@@ -50,4 +50,30 @@
GPIO lines and accessed through the J1 jumper block. Say "y"
here to configure that SPI controller.
+config BOARD_ATSTK1002_J2_LED
+ bool
+ default BOARD_ATSTK1002_J2_LED8 || BOARD_ATSTK1002_J2_RGB
+
+choice
+ prompt "LEDs connected to J2:"
+ depends on LEDS_GPIO && !BOARD_ATSTK1002_SW4_CUSTOM
+ optional
+ help
+ Select this if you have jumpered the J2 jumper block to the
+ LED0..LED7 amber leds, or to the RGB leds, using a ten-pin
+ IDC cable. A default "heartbeat" trigger is provided, but
+ you can of course override this.
+
+config BOARD_ATSTK1002_J2_LED8
+ bool "LED0..LED7"
+ help
+ Select this if J2 is jumpered to LED0..LED7 amber leds.
+
+config BOARD_ATSTK1002_J2_RGB
+ bool "RGB leds"
+ help
+ Select this if J2 is jumpered to the RGB leds.
+
+endchoice
+
endif # stk 1002
diff --git a/arch/avr32/boards/atstk1000/atstk1002.c b/arch/avr32/boards/atstk1000/atstk1002.c
index cb93eab..c9981b7 100644
--- a/arch/avr32/boards/atstk1000/atstk1002.c
+++ b/arch/avr32/boards/atstk1000/atstk1002.c
@@ -11,6 +11,7 @@
#include <linux/etherdevice.h>
#include <linux/init.h>
#include <linux/kernel.h>
+#include <linux/leds.h>
#include <linux/platform_device.h>
#include <linux/string.h>
#include <linux/types.h>
@@ -120,6 +121,65 @@
clk_put(pclk);
}
+#ifdef CONFIG_BOARD_ATSTK1002_J2_LED
+
+static struct gpio_led stk_j2_led[] = {
+#ifdef CONFIG_BOARD_ATSTK1002_J2_LED8
+#define LEDSTRING "J2 jumpered to LED8"
+ { .name = "led0:amber", .gpio = GPIO_PIN_PB( 8), },
+ { .name = "led1:amber", .gpio = GPIO_PIN_PB( 9), },
+ { .name = "led2:amber", .gpio = GPIO_PIN_PB(10), },
+ { .name = "led3:amber", .gpio = GPIO_PIN_PB(13), },
+ { .name = "led4:amber", .gpio = GPIO_PIN_PB(14), },
+ { .name = "led5:amber", .gpio = GPIO_PIN_PB(15), },
+ { .name = "led6:amber", .gpio = GPIO_PIN_PB(16), },
+ { .name = "led7:amber", .gpio = GPIO_PIN_PB(30),
+ .default_trigger = "heartbeat", },
+#else /* RGB */
+#define LEDSTRING "J2 jumpered to RGB LEDs"
+ { .name = "r1:red", .gpio = GPIO_PIN_PB( 8), },
+ { .name = "g1:green", .gpio = GPIO_PIN_PB(10), },
+ { .name = "b1:blue", .gpio = GPIO_PIN_PB(14), },
+
+ { .name = "r2:red", .gpio = GPIO_PIN_PB( 9),
+ .default_trigger = "heartbeat", },
+ { .name = "g2:green", .gpio = GPIO_PIN_PB(13), },
+ { .name = "b2:blue", .gpio = GPIO_PIN_PB(15),
+ .default_trigger = "heartbeat", },
+ /* PB16, PB30 unused */
+#endif
+};
+
+static struct gpio_led_platform_data stk_j2_led_data = {
+ .num_leds = ARRAY_SIZE(stk_j2_led),
+ .leds = stk_j2_led,
+};
+
+static struct platform_device stk_j2_led_dev = {
+ .name = "leds-gpio",
+ .id = 2, /* gpio block J2 */
+ .dev = {
+ .platform_data = &stk_j2_led_data,
+ },
+};
+
+static void setup_j2_leds(void)
+{
+ unsigned i;
+
+ for (i = 0; i < ARRAY_SIZE(stk_j2_led); i++)
+ at32_select_gpio(stk_j2_led[i].gpio, AT32_GPIOF_OUTPUT);
+
+ printk("STK1002: " LEDSTRING "\n");
+ platform_device_register(&stk_j2_led_dev);
+}
+
+#else
+static void setup_j2_leds(void)
+{
+}
+#endif
+
void __init setup_board(void)
{
#ifdef CONFIG_BOARD_ATSTK1002_SW2_CUSTOM
@@ -185,6 +245,8 @@
at32_add_device_ssc(0, ATMEL_SSC_TX);
#endif
+ setup_j2_leds();
+
return 0;
}
postcore_initcall(atstk1002_init);
diff --git a/arch/blackfin/kernel/init_task.c b/arch/blackfin/kernel/init_task.c
index b45188f..673c860 100644
--- a/arch/blackfin/kernel/init_task.c
+++ b/arch/blackfin/kernel/init_task.c
@@ -31,6 +31,7 @@
#include <linux/module.h>
#include <linux/init_task.h>
#include <linux/mqueue.h>
+#include <linux/fs.h>
static struct fs_struct init_fs = INIT_FS;
static struct files_struct init_files = INIT_FILES;
diff --git a/arch/blackfin/kernel/process.c b/arch/blackfin/kernel/process.c
index 5a51dd6..6a7aefe 100644
--- a/arch/blackfin/kernel/process.c
+++ b/arch/blackfin/kernel/process.c
@@ -33,6 +33,8 @@
#include <linux/user.h>
#include <linux/a.out.h>
#include <linux/uaccess.h>
+#include <linux/fs.h>
+#include <linux/err.h>
#include <asm/blackfin.h>
#include <asm/fixed_code.h>
diff --git a/arch/blackfin/kernel/sys_bfin.c b/arch/blackfin/kernel/sys_bfin.c
index f5e1ae3..abcd148 100644
--- a/arch/blackfin/kernel/sys_bfin.c
+++ b/arch/blackfin/kernel/sys_bfin.c
@@ -37,6 +37,7 @@
#include <linux/syscalls.h>
#include <linux/mman.h>
#include <linux/file.h>
+#include <linux/fs.h>
#include <linux/uaccess.h>
#include <linux/ipc.h>
#include <linux/unistd.h>
diff --git a/arch/blackfin/kernel/traps.c b/arch/blackfin/kernel/traps.c
index 8766bd6..792a841 100644
--- a/arch/blackfin/kernel/traps.c
+++ b/arch/blackfin/kernel/traps.c
@@ -31,6 +31,7 @@
#include <linux/interrupt.h>
#include <linux/module.h>
#include <linux/kallsyms.h>
+#include <linux/fs.h>
#include <asm/traps.h>
#include <asm/cacheflush.h>
#include <asm/blackfin.h>
diff --git a/arch/cris/Kconfig b/arch/cris/Kconfig
index 4b41248..6b4d026 100644
--- a/arch/cris/Kconfig
+++ b/arch/cris/Kconfig
@@ -180,8 +180,6 @@
source "drivers/telephony/Kconfig"
-source "drivers/cdrom/Kconfig"
-
#
# input before char - char/joystick depends on it. As does USB.
#
diff --git a/arch/cris/arch-v10/drivers/Kconfig b/arch/cris/arch-v10/drivers/Kconfig
index e7e724bc..03e2e68 100644
--- a/arch/cris/arch-v10/drivers/Kconfig
+++ b/arch/cris/arch-v10/drivers/Kconfig
@@ -548,6 +548,7 @@
select BLK_DEV_IDEDISK
select BLK_DEV_IDECD
select BLK_DEV_IDEDMA
+ select IDE_GENERIC
help
Enable this to get support for ATA/IDE.
You can't use parallel ports or SCSI ports
diff --git a/arch/cris/arch-v32/drivers/Kconfig b/arch/cris/arch-v32/drivers/Kconfig
index 1d859c1..cc6ba54 100644
--- a/arch/cris/arch-v32/drivers/Kconfig
+++ b/arch/cris/arch-v32/drivers/Kconfig
@@ -592,6 +592,7 @@
select BLK_DEV_IDEDISK
select BLK_DEV_IDECD
select BLK_DEV_IDEDMA
+ select IDE_GENERIC
help
Enables the ETRAX IDE driver.
diff --git a/arch/frv/kernel/entry.S b/arch/frv/kernel/entry.S
index 275673c..1e74f3c 100644
--- a/arch/frv/kernel/entry.S
+++ b/arch/frv/kernel/entry.S
@@ -1496,6 +1496,7 @@
.long sys_signalfd
.long sys_timerfd
.long sys_eventfd
+ .long sys_fallocate
syscall_table_size = (. - sys_call_table)
diff --git a/arch/h8300/kernel/process.c b/arch/h8300/kernel/process.c
index e061b63..dfbe7ab 100644
--- a/arch/h8300/kernel/process.c
+++ b/arch/h8300/kernel/process.c
@@ -37,6 +37,7 @@
#include <linux/a.out.h>
#include <linux/interrupt.h>
#include <linux/reboot.h>
+#include <linux/fs.h>
#include <asm/uaccess.h>
#include <asm/system.h>
diff --git a/arch/h8300/kernel/sys_h8300.c b/arch/h8300/kernel/sys_h8300.c
index de7688c..ddc6272 100644
--- a/arch/h8300/kernel/sys_h8300.c
+++ b/arch/h8300/kernel/sys_h8300.c
@@ -18,6 +18,7 @@
#include <linux/mman.h>
#include <linux/file.h>
#include <linux/utsname.h>
+#include <linux/fs.h>
#include <asm/setup.h>
#include <asm/uaccess.h>
diff --git a/arch/i386/Kconfig b/arch/i386/Kconfig
index f952493..97b64d7 100644
--- a/arch/i386/Kconfig
+++ b/arch/i386/Kconfig
@@ -614,10 +614,14 @@
# Common NUMA Features
config NUMA
- bool "Numa Memory Allocation and Scheduler Support"
- depends on SMP && HIGHMEM64G && (X86_NUMAQ || (X86_SUMMIT || X86_GENERICARCH) && ACPI)
+ bool "Numa Memory Allocation and Scheduler Support (EXPERIMENTAL)"
+ depends on SMP && HIGHMEM64G && (X86_NUMAQ || (X86_SUMMIT || X86_GENERICARCH) && ACPI) && EXPERIMENTAL
default n if X86_PC
default y if (X86_NUMAQ || X86_SUMMIT)
+ help
+ NUMA support for i386. This is currently high experimental
+ and should be only used for kernel development. It might also
+ cause boot failures.
comment "NUMA (Summit) requires SMP, 64GB highmem support, ACPI"
depends on X86_SUMMIT && (!HIGHMEM64G || !ACPI)
@@ -1228,6 +1232,11 @@
bool "Instrumentation Support"
depends on EXPERIMENTAL
default y
+ ---help---
+ Say Y here to get to see options related to performance measurement,
+ debugging, and testing. This option alone does not add any kernel code.
+
+ If you say N, all options in this submenu will be skipped and disabled.
if INSTRUMENTATION
diff --git a/arch/i386/Makefile b/arch/i386/Makefile
index 01f0ff0..52b9324 100644
--- a/arch/i386/Makefile
+++ b/arch/i386/Makefile
@@ -51,8 +51,8 @@
CFLAGS += $(shell if [ $(call cc-version) -lt 0400 ] ; then echo $(call cc-option,-fno-unit-at-a-time); fi ;)
# do binutils support CFI?
-cflags-y += $(call as-instr,.cfi_startproc\n.cfi_endproc,-DCONFIG_AS_CFI=1,)
-AFLAGS += $(call as-instr,.cfi_startproc\n.cfi_endproc,-DCONFIG_AS_CFI=1,)
+cflags-y += $(call as-instr,.cfi_startproc\n.cfi_rel_offset esp${comma}0\n.cfi_endproc,-DCONFIG_AS_CFI=1,)
+AFLAGS += $(call as-instr,.cfi_startproc\n.cfi_rel_offset esp${comma}0\n.cfi_endproc,-DCONFIG_AS_CFI=1,)
# is .cfi_signal_frame supported too?
cflags-y += $(call as-instr,.cfi_startproc\n.cfi_signal_frame\n.cfi_endproc,-DCONFIG_AS_CFI_SIGNAL_FRAME=1,)
diff --git a/arch/i386/boot/boot.h b/arch/i386/boot/boot.h
index dec70c9..20bab94 100644
--- a/arch/i386/boot/boot.h
+++ b/arch/i386/boot/boot.h
@@ -87,7 +87,7 @@
static inline u16 fs(void)
{
u16 seg;
- asm("movw %%fs,%0" : "=rm" (seg));
+ asm volatile("movw %%fs,%0" : "=rm" (seg));
return seg;
}
@@ -98,7 +98,7 @@
static inline u16 gs(void)
{
u16 seg;
- asm("movw %%gs,%0" : "=rm" (seg));
+ asm volatile("movw %%gs,%0" : "=rm" (seg));
return seg;
}
@@ -107,19 +107,19 @@
static inline u8 rdfs8(addr_t addr)
{
u8 v;
- asm("movb %%fs:%1,%0" : "=r" (v) : "m" (*(u8 *)addr));
+ asm volatile("movb %%fs:%1,%0" : "=r" (v) : "m" (*(u8 *)addr));
return v;
}
static inline u16 rdfs16(addr_t addr)
{
u16 v;
- asm("movw %%fs:%1,%0" : "=r" (v) : "m" (*(u16 *)addr));
+ asm volatile("movw %%fs:%1,%0" : "=r" (v) : "m" (*(u16 *)addr));
return v;
}
static inline u32 rdfs32(addr_t addr)
{
u32 v;
- asm("movl %%fs:%1,%0" : "=r" (v) : "m" (*(u32 *)addr));
+ asm volatile("movl %%fs:%1,%0" : "=r" (v) : "m" (*(u32 *)addr));
return v;
}
@@ -139,19 +139,19 @@
static inline u8 rdgs8(addr_t addr)
{
u8 v;
- asm("movb %%gs:%1,%0" : "=r" (v) : "m" (*(u8 *)addr));
+ asm volatile("movb %%gs:%1,%0" : "=r" (v) : "m" (*(u8 *)addr));
return v;
}
static inline u16 rdgs16(addr_t addr)
{
u16 v;
- asm("movw %%gs:%1,%0" : "=r" (v) : "m" (*(u16 *)addr));
+ asm volatile("movw %%gs:%1,%0" : "=r" (v) : "m" (*(u16 *)addr));
return v;
}
static inline u32 rdgs32(addr_t addr)
{
u32 v;
- asm("movl %%gs:%1,%0" : "=r" (v) : "m" (*(u32 *)addr));
+ asm volatile("movl %%gs:%1,%0" : "=r" (v) : "m" (*(u32 *)addr));
return v;
}
@@ -180,15 +180,15 @@
static inline int memcmp_fs(const void *s1, addr_t s2, size_t len)
{
u8 diff;
- asm("fs; repe; cmpsb; setnz %0"
- : "=qm" (diff), "+D" (s1), "+S" (s2), "+c" (len));
+ asm volatile("fs; repe; cmpsb; setnz %0"
+ : "=qm" (diff), "+D" (s1), "+S" (s2), "+c" (len));
return diff;
}
static inline int memcmp_gs(const void *s1, addr_t s2, size_t len)
{
u8 diff;
- asm("gs; repe; cmpsb; setnz %0"
- : "=qm" (diff), "+D" (s1), "+S" (s2), "+c" (len));
+ asm volatile("gs; repe; cmpsb; setnz %0"
+ : "=qm" (diff), "+D" (s1), "+S" (s2), "+c" (len));
return diff;
}
diff --git a/arch/i386/boot/cpucheck.c b/arch/i386/boot/cpucheck.c
index 991e8ce..e655a89 100644
--- a/arch/i386/boot/cpucheck.c
+++ b/arch/i386/boot/cpucheck.c
@@ -96,7 +96,8 @@
asm volatile("movl %0,%%cr0" : : "r" (cr0));
}
- asm("fninit ; fnstsw %0 ; fnstcw %1" : "+m" (fsw), "+m" (fcw));
+ asm volatile("fninit ; fnstsw %0 ; fnstcw %1"
+ : "+m" (fsw), "+m" (fcw));
return fsw == 0 && (fcw & 0x103f) == 0x003f;
}
diff --git a/arch/i386/boot/edd.c b/arch/i386/boot/edd.c
index 658834d..bd138e4 100644
--- a/arch/i386/boot/edd.c
+++ b/arch/i386/boot/edd.c
@@ -19,57 +19,28 @@
#if defined(CONFIG_EDD) || defined(CONFIG_EDD_MODULE)
-struct edd_dapa {
- u8 pkt_size;
- u8 rsvd;
- u16 sector_cnt;
- u16 buf_off, buf_seg;
- u64 lba;
- u64 buf_lin_addr;
-};
-
/*
* Read the MBR (first sector) from a specific device.
*/
static int read_mbr(u8 devno, void *buf)
{
- struct edd_dapa dapa;
- u16 ax, bx, cx, dx, si;
-
- memset(&dapa, 0, sizeof dapa);
- dapa.pkt_size = sizeof(dapa);
- dapa.sector_cnt = 1;
- dapa.buf_off = (size_t)buf;
- dapa.buf_seg = ds();
- /* dapa.lba = 0; */
-
- ax = 0x4200; /* Extended Read */
- si = (size_t)&dapa;
- dx = devno;
- asm("pushfl; stc; int $0x13; setc %%al; popfl"
- : "+a" (ax), "+S" (si), "+d" (dx)
- : "m" (dapa)
- : "ebx", "ecx", "edi", "memory");
-
- if (!(u8)ax)
- return 0; /* OK */
+ u16 ax, bx, cx, dx;
ax = 0x0201; /* Legacy Read, one sector */
cx = 0x0001; /* Sector 0-0-1 */
dx = devno;
bx = (size_t)buf;
- asm("pushfl; stc; int $0x13; setc %%al; popfl"
- : "+a" (ax), "+c" (cx), "+d" (dx), "+b" (bx)
- : : "esi", "edi", "memory");
+ asm volatile("pushfl; stc; int $0x13; setc %%al; popfl"
+ : "+a" (ax), "+c" (cx), "+d" (dx), "+b" (bx)
+ : : "esi", "edi", "memory");
return -(u8)ax; /* 0 or -1 */
}
-static u32 read_mbr_sig(u8 devno, struct edd_info *ei)
+static u32 read_mbr_sig(u8 devno, struct edd_info *ei, u32 *mbrsig)
{
int sector_size;
char *mbrbuf_ptr, *mbrbuf_end;
- u32 mbrsig;
u32 buf_base, mbr_base;
extern char _end[];
@@ -85,15 +56,15 @@
/* Make sure we actually have space on the heap... */
if (!(boot_params.hdr.loadflags & CAN_USE_HEAP))
- return 0;
+ return -1;
if (mbrbuf_end > (char *)(size_t)boot_params.hdr.heap_end_ptr)
- return 0;
+ return -1;
if (read_mbr(devno, mbrbuf_ptr))
- return 0;
+ return -1;
- mbrsig = *(u32 *)&mbrbuf_ptr[EDD_MBR_SIG_OFFSET];
- return mbrsig;
+ *mbrsig = *(u32 *)&mbrbuf_ptr[EDD_MBR_SIG_OFFSET];
+ return 0;
}
static int get_edd_info(u8 devno, struct edd_info *ei)
@@ -160,6 +131,7 @@
int do_edd = 1;
int devno;
struct edd_info ei, *edp;
+ u32 *mbrptr;
if (cmdline_find_option("edd", eddarg, sizeof eddarg) > 0) {
if (!strcmp(eddarg, "skipmbr") || !strcmp(eddarg, "skip"))
@@ -168,7 +140,8 @@
do_edd = 0;
}
- edp = (struct edd_info *)boot_params.eddbuf;
+ edp = boot_params.eddbuf;
+ mbrptr = boot_params.edd_mbr_sig_buffer;
if (!do_edd)
return;
@@ -186,11 +159,8 @@
boot_params.eddbuf_entries++;
}
- if (do_mbr) {
- u32 mbr_sig;
- mbr_sig = read_mbr_sig(devno, &ei);
- boot_params.edd_mbr_sig_buffer[devno-0x80] = mbr_sig;
- }
+ if (do_mbr && !read_mbr_sig(devno, &ei, mbrptr++))
+ boot_params.edd_mbr_sig_buf_entries = devno-0x80+1;
}
}
diff --git a/arch/i386/boot/tty.c b/arch/i386/boot/tty.c
index 9c668aa..f3f14bd 100644
--- a/arch/i386/boot/tty.c
+++ b/arch/i386/boot/tty.c
@@ -54,9 +54,9 @@
u16 ax = 0x0200;
u16 cx, dx;
- asm("int $0x1a"
- : "+a" (ax), "=c" (cx), "=d" (dx)
- : : "ebx", "esi", "edi");
+ asm volatile("int $0x1a"
+ : "+a" (ax), "=c" (cx), "=d" (dx)
+ : : "ebx", "esi", "edi");
return dx >> 8;
}
@@ -67,7 +67,7 @@
int getchar(void)
{
u16 ax = 0;
- asm("int $0x16" : "+a" (ax));
+ asm volatile("int $0x16" : "+a" (ax));
return ax & 0xff;
}
@@ -75,9 +75,9 @@
static int kbd_pending(void)
{
u8 pending;
- asm("int $0x16; setnz %0"
- : "=rm" (pending)
- : "a" (0x0100));
+ asm volatile("int $0x16; setnz %0"
+ : "=rm" (pending)
+ : "a" (0x0100));
return pending;
}
diff --git a/arch/i386/boot/video-vga.c b/arch/i386/boot/video-vga.c
index 700d09a..aef02f9 100644
--- a/arch/i386/boot/video-vga.c
+++ b/arch/i386/boot/video-vga.c
@@ -47,16 +47,16 @@
#ifdef CONFIG_VIDEO_400_HACK
if (adapter >= ADAPTER_VGA) {
- asm(INT10
- : : "a" (0x1202), "b" (0x0030)
- : "ecx", "edx", "esi", "edi");
+ asm volatile(INT10
+ : : "a" (0x1202), "b" (0x0030)
+ : "ecx", "edx", "esi", "edi");
}
#endif
ax = 0x0f00;
- asm(INT10
- : "+a" (ax)
- : : "ebx", "ecx", "edx", "esi", "edi");
+ asm volatile(INT10
+ : "+a" (ax)
+ : : "ebx", "ecx", "edx", "esi", "edi");
mode = (u8)ax;
@@ -73,9 +73,10 @@
mode = 3;
/* Set the mode */
+ ax = mode;
asm volatile(INT10
- : : "a" (mode)
- : "ebx", "ecx", "edx", "esi", "edi");
+ : "+a" (ax)
+ : : "ebx", "ecx", "edx", "esi", "edi");
do_restore = 1;
return mode;
}
diff --git a/arch/i386/boot/video.c b/arch/i386/boot/video.c
index 958130e..693f20d 100644
--- a/arch/i386/boot/video.c
+++ b/arch/i386/boot/video.c
@@ -61,7 +61,7 @@
/* Not all BIOSes are clean with respect to the top bit */
boot_params.screen_info.orig_video_mode = ax & 0x7f;
- boot_params.screen_info.orig_video_page = page;
+ boot_params.screen_info.orig_video_page = page >> 8;
}
/*
diff --git a/arch/i386/kernel/alternative.c b/arch/i386/kernel/alternative.c
index c85598a..9f4ac8b 100644
--- a/arch/i386/kernel/alternative.c
+++ b/arch/i386/kernel/alternative.c
@@ -11,6 +11,8 @@
#include <asm/mce.h>
#include <asm/nmi.h>
+#define MAX_PATCH_LEN (255-1)
+
#ifdef CONFIG_HOTPLUG_CPU
static int smp_alt_once;
@@ -148,7 +150,8 @@
#endif /* CONFIG_X86_64 */
-static void nop_out(void *insns, unsigned int len)
+/* Use this to add nops to a buffer, then text_poke the whole buffer. */
+static void add_nops(void *insns, unsigned int len)
{
unsigned char **noptable = find_nop_table();
@@ -156,7 +159,7 @@
unsigned int noplen = len;
if (noplen > ASM_NOP_MAX)
noplen = ASM_NOP_MAX;
- text_poke(insns, noptable[noplen], noplen);
+ memcpy(insns, noptable[noplen], noplen);
insns += noplen;
len -= noplen;
}
@@ -174,15 +177,15 @@
void apply_alternatives(struct alt_instr *start, struct alt_instr *end)
{
struct alt_instr *a;
- u8 *instr;
- int diff;
+ char insnbuf[MAX_PATCH_LEN];
DPRINTK("%s: alt table %p -> %p\n", __FUNCTION__, start, end);
for (a = start; a < end; a++) {
+ u8 *instr = a->instr;
BUG_ON(a->replacementlen > a->instrlen);
+ BUG_ON(a->instrlen > sizeof(insnbuf));
if (!boot_cpu_has(a->cpuid))
continue;
- instr = a->instr;
#ifdef CONFIG_X86_64
/* vsyscall code is not mapped yet. resolve it manually. */
if (instr >= (u8 *)VSYSCALL_START && instr < (u8*)VSYSCALL_END) {
@@ -191,9 +194,10 @@
__FUNCTION__, a->instr, instr);
}
#endif
- memcpy(instr, a->replacement, a->replacementlen);
- diff = a->instrlen - a->replacementlen;
- nop_out(instr + a->replacementlen, diff);
+ memcpy(insnbuf, a->replacement, a->replacementlen);
+ add_nops(insnbuf + a->replacementlen,
+ a->instrlen - a->replacementlen);
+ text_poke(instr, insnbuf, a->instrlen);
}
}
@@ -215,16 +219,18 @@
static void alternatives_smp_unlock(u8 **start, u8 **end, u8 *text, u8 *text_end)
{
u8 **ptr;
+ char insn[1];
if (noreplace_smp)
return;
+ add_nops(insn, 1);
for (ptr = start; ptr < end; ptr++) {
if (*ptr < text)
continue;
if (*ptr > text_end)
continue;
- nop_out(*ptr, 1);
+ text_poke(*ptr, insn, 1);
};
}
@@ -351,6 +357,7 @@
struct paravirt_patch_site *end)
{
struct paravirt_patch_site *p;
+ char insnbuf[MAX_PATCH_LEN];
if (noreplace_paravirt)
return;
@@ -358,13 +365,17 @@
for (p = start; p < end; p++) {
unsigned int used;
- used = paravirt_ops.patch(p->instrtype, p->clobbers, p->instr,
- p->len);
+ BUG_ON(p->len > MAX_PATCH_LEN);
+ /* prep the buffer with the original instructions */
+ memcpy(insnbuf, p->instr, p->len);
+ used = paravirt_ops.patch(p->instrtype, p->clobbers, insnbuf,
+ (unsigned long)p->instr, p->len);
BUG_ON(used > p->len);
/* Pad the rest with nops */
- nop_out(p->instr + used, p->len - used);
+ add_nops(insnbuf + used, p->len - used);
+ text_poke(p->instr, insnbuf, p->len);
}
}
extern struct paravirt_patch_site __start_parainstructions[],
@@ -379,7 +390,7 @@
that might execute the to be patched code.
Other CPUs are not running. */
stop_nmi();
-#ifdef CONFIG_MCE
+#ifdef CONFIG_X86_MCE
stop_mce();
#endif
@@ -417,7 +428,7 @@
local_irq_restore(flags);
restart_nmi();
-#ifdef CONFIG_MCE
+#ifdef CONFIG_X86_MCE
restart_mce();
#endif
}
diff --git a/arch/i386/kernel/apic.c b/arch/i386/kernel/apic.c
index bfc6cb7..3d67ae1 100644
--- a/arch/i386/kernel/apic.c
+++ b/arch/i386/kernel/apic.c
@@ -61,8 +61,9 @@
/* Local APIC timer verification ok */
static int local_apic_timer_verify_ok;
-/* Disable local APIC timer from the kernel commandline or via dmi quirk */
-static int local_apic_timer_disabled;
+/* Disable local APIC timer from the kernel commandline or via dmi quirk
+ or using CPU MSR check */
+int local_apic_timer_disabled;
/* Local APIC timer works in C2 */
int local_apic_timer_c2_ok;
EXPORT_SYMBOL_GPL(local_apic_timer_c2_ok);
@@ -370,12 +371,9 @@
long delta, deltapm;
int pm_referenced = 0;
- if (boot_cpu_has(X86_FEATURE_LAPIC_TIMER_BROKEN))
- local_apic_timer_disabled = 1;
-
/*
* The local apic timer can be disabled via the kernel
- * commandline or from the test above. Register the lapic
+ * commandline or from the CPU detection code. Register the lapic
* timer as a dummy clock event source on SMP systems, so the
* broadcast mechanism is used. On UP systems simply ignore it.
*/
@@ -1087,7 +1085,7 @@
if (l & MSR_IA32_APICBASE_ENABLE)
mp_lapic_addr = l & MSR_IA32_APICBASE_BASE;
- if (nmi_watchdog != NMI_NONE)
+ if (nmi_watchdog != NMI_NONE && nmi_watchdog != NMI_DISABLED)
nmi_watchdog = NMI_LOCAL_APIC;
printk(KERN_INFO "Found and enabled local APIC!\n");
diff --git a/arch/i386/kernel/cpu/amd.c b/arch/i386/kernel/cpu/amd.c
index c7ba455..dcf6bbb 100644
--- a/arch/i386/kernel/cpu/amd.c
+++ b/arch/i386/kernel/cpu/amd.c
@@ -3,6 +3,7 @@
#include <linux/mm.h>
#include <asm/io.h>
#include <asm/processor.h>
+#include <asm/apic.h>
#include "cpu.h"
@@ -22,6 +23,7 @@
extern void vide(void);
__asm__(".align 4\nvide: ret");
+#ifdef CONFIG_X86_LOCAL_APIC
#define ENABLE_C1E_MASK 0x18000000
#define CPUID_PROCESSOR_SIGNATURE 1
#define CPUID_XFAM 0x0ff00000
@@ -52,6 +54,7 @@
}
return 0;
}
+#endif
int force_mwait __cpuinitdata;
@@ -282,8 +285,10 @@
num_cache_leaves = 3;
}
+#ifdef CONFIG_X86_LOCAL_APIC
if (amd_apic_timer_broken())
- set_bit(X86_FEATURE_LAPIC_TIMER_BROKEN, c->x86_capability);
+ local_apic_timer_disabled = 1;
+#endif
if (c->x86 == 0x10 && !force_mwait)
clear_bit(X86_FEATURE_MWAIT, c->x86_capability);
diff --git a/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c b/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c
index 32d04b0..705e13a 100644
--- a/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c
+++ b/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c
@@ -68,7 +68,8 @@
};
static struct acpi_cpufreq_data *drv_data[NR_CPUS];
-static struct acpi_processor_performance *acpi_perf_data[NR_CPUS];
+/* acpi_perf_data is a pointer to percpu data. */
+static struct acpi_processor_performance *acpi_perf_data;
static struct cpufreq_driver acpi_cpufreq_driver;
@@ -508,24 +509,14 @@
* do _PDC and _PSD and find out the processor dependency for the
* actual init that will happen later...
*/
-static int acpi_cpufreq_early_init(void)
+static int __init acpi_cpufreq_early_init(void)
{
- struct acpi_processor_performance *data;
- unsigned int i, j;
-
dprintk("acpi_cpufreq_early_init\n");
- for_each_possible_cpu(i) {
- data = kzalloc(sizeof(struct acpi_processor_performance),
- GFP_KERNEL);
- if (!data) {
- for_each_possible_cpu(j) {
- kfree(acpi_perf_data[j]);
- acpi_perf_data[j] = NULL;
- }
- return -ENOMEM;
- }
- acpi_perf_data[i] = data;
+ acpi_perf_data = alloc_percpu(struct acpi_processor_performance);
+ if (!acpi_perf_data) {
+ dprintk("Memory allocation error for acpi_perf_data.\n");
+ return -ENOMEM;
}
/* Do initialization in ACPI core */
@@ -574,14 +565,11 @@
dprintk("acpi_cpufreq_cpu_init\n");
- if (!acpi_perf_data[cpu])
- return -ENODEV;
-
data = kzalloc(sizeof(struct acpi_cpufreq_data), GFP_KERNEL);
if (!data)
return -ENOMEM;
- data->acpi_data = acpi_perf_data[cpu];
+ data->acpi_data = percpu_ptr(acpi_perf_data, cpu);
drv_data[cpu] = data;
if (cpu_has(c, X86_FEATURE_CONSTANT_TSC))
@@ -778,24 +766,25 @@
static int __init acpi_cpufreq_init(void)
{
+ int ret;
+
dprintk("acpi_cpufreq_init\n");
- acpi_cpufreq_early_init();
+ ret = acpi_cpufreq_early_init();
+ if (ret)
+ return ret;
return cpufreq_register_driver(&acpi_cpufreq_driver);
}
static void __exit acpi_cpufreq_exit(void)
{
- unsigned int i;
dprintk("acpi_cpufreq_exit\n");
cpufreq_unregister_driver(&acpi_cpufreq_driver);
- for_each_possible_cpu(i) {
- kfree(acpi_perf_data[i]);
- acpi_perf_data[i] = NULL;
- }
+ free_percpu(acpi_perf_data);
+
return;
}
diff --git a/arch/i386/kernel/doublefault.c b/arch/i386/kernel/doublefault.c
index 265c559..40978af 100644
--- a/arch/i386/kernel/doublefault.c
+++ b/arch/i386/kernel/doublefault.c
@@ -13,7 +13,7 @@
static unsigned long doublefault_stack[DOUBLEFAULT_STACKSIZE];
#define STACK_START (unsigned long)(doublefault_stack+DOUBLEFAULT_STACKSIZE)
-#define ptr_ok(x) ((x) > PAGE_OFFSET && (x) < PAGE_OFFSET + 0x1000000)
+#define ptr_ok(x) ((x) > PAGE_OFFSET && (x) < PAGE_OFFSET + MAXMEM)
static void doublefault_fn(void)
{
@@ -23,23 +23,23 @@
store_gdt(&gdt_desc);
gdt = gdt_desc.address;
- printk("double fault, gdt at %08lx [%d bytes]\n", gdt, gdt_desc.size);
+ printk(KERN_EMERG "PANIC: double fault, gdt at %08lx [%d bytes]\n", gdt, gdt_desc.size);
if (ptr_ok(gdt)) {
gdt += GDT_ENTRY_TSS << 3;
tss = *(u16 *)(gdt+2);
tss += *(u8 *)(gdt+4) << 16;
tss += *(u8 *)(gdt+7) << 24;
- printk("double fault, tss at %08lx\n", tss);
+ printk(KERN_EMERG "double fault, tss at %08lx\n", tss);
if (ptr_ok(tss)) {
struct i386_hw_tss *t = (struct i386_hw_tss *)tss;
- printk("eip = %08lx, esp = %08lx\n", t->eip, t->esp);
+ printk(KERN_EMERG "eip = %08lx, esp = %08lx\n", t->eip, t->esp);
- printk("eax = %08lx, ebx = %08lx, ecx = %08lx, edx = %08lx\n",
+ printk(KERN_EMERG "eax = %08lx, ebx = %08lx, ecx = %08lx, edx = %08lx\n",
t->eax, t->ebx, t->ecx, t->edx);
- printk("esi = %08lx, edi = %08lx\n",
+ printk(KERN_EMERG "esi = %08lx, edi = %08lx\n",
t->esi, t->edi);
}
}
@@ -63,6 +63,7 @@
.cs = __KERNEL_CS,
.ss = __KERNEL_DS,
.ds = __USER_DS,
+ .fs = __KERNEL_PERCPU,
.__cr3 = __pa(swapper_pg_dir)
}
diff --git a/arch/i386/kernel/head.S b/arch/i386/kernel/head.S
index 7c52b22..8f03821 100644
--- a/arch/i386/kernel/head.S
+++ b/arch/i386/kernel/head.S
@@ -162,9 +162,7 @@
* which will be freed later
*/
-#ifdef CONFIG_HOTPLUG_CPU
-.section .text,"ax",@progbits
-#else
+#ifndef CONFIG_HOTPLUG_CPU
.section .init.text,"ax",@progbits
#endif
diff --git a/arch/i386/kernel/io_apic.c b/arch/i386/kernel/io_apic.c
index 893df82..e2f4a1c 100644
--- a/arch/i386/kernel/io_apic.c
+++ b/arch/i386/kernel/io_apic.c
@@ -754,14 +754,6 @@
static int pirqs_enabled;
int skip_ioapic_setup;
-static int __init ioapic_setup(char *str)
-{
- skip_ioapic_setup = 1;
- return 1;
-}
-
-__setup("noapic", ioapic_setup);
-
static int __init ioapic_pirq_setup(char *str)
{
int i, max;
@@ -1256,12 +1248,15 @@
static void ioapic_register_intr(int irq, int vector, unsigned long trigger)
{
if ((trigger == IOAPIC_AUTO && IO_APIC_irq_trigger(irq)) ||
- trigger == IOAPIC_LEVEL)
+ trigger == IOAPIC_LEVEL) {
+ irq_desc[irq].status |= IRQ_LEVEL;
set_irq_chip_and_handler_name(irq, &ioapic_chip,
handle_fasteoi_irq, "fasteoi");
- else
+ } else {
+ irq_desc[irq].status &= ~IRQ_LEVEL;
set_irq_chip_and_handler_name(irq, &ioapic_chip,
handle_edge_irq, "edge");
+ }
set_intr_gate(vector, interrupt[irq]);
}
diff --git a/arch/i386/kernel/nmi.c b/arch/i386/kernel/nmi.c
index 99beac7..8c1c965 100644
--- a/arch/i386/kernel/nmi.c
+++ b/arch/i386/kernel/nmi.c
@@ -77,7 +77,7 @@
unsigned int *prev_nmi_count;
int cpu;
- if ((nmi_watchdog == NMI_NONE) || (nmi_watchdog == NMI_DEFAULT))
+ if ((nmi_watchdog == NMI_NONE) || (nmi_watchdog == NMI_DISABLED))
return 0;
if (!atomic_read(&nmi_active))
@@ -424,7 +424,7 @@
if (!!old_state == !!nmi_watchdog_enabled)
return 0;
- if (atomic_read(&nmi_active) < 0) {
+ if (atomic_read(&nmi_active) < 0 || nmi_watchdog == NMI_DISABLED) {
printk( KERN_WARNING "NMI watchdog is permanently disabled\n");
return -EIO;
}
diff --git a/arch/i386/kernel/paravirt.c b/arch/i386/kernel/paravirt.c
index ea962c0..739cfb2 100644
--- a/arch/i386/kernel/paravirt.c
+++ b/arch/i386/kernel/paravirt.c
@@ -69,7 +69,8 @@
DEF_NATIVE(ud2a, "ud2a");
-static unsigned native_patch(u8 type, u16 clobbers, void *insns, unsigned len)
+static unsigned native_patch(u8 type, u16 clobbers, void *ibuf,
+ unsigned long addr, unsigned len)
{
const unsigned char *start, *end;
unsigned ret;
@@ -90,7 +91,7 @@
#undef SITE
patch_site:
- ret = paravirt_patch_insns(insns, len, start, end);
+ ret = paravirt_patch_insns(ibuf, len, start, end);
break;
case PARAVIRT_PATCH(make_pgd):
@@ -107,7 +108,7 @@
break;
default:
- ret = paravirt_patch_default(type, clobbers, insns, len);
+ ret = paravirt_patch_default(type, clobbers, ibuf, addr, len);
break;
}
@@ -129,68 +130,67 @@
u32 delta;
} __attribute__((packed));
-unsigned paravirt_patch_call(void *target, u16 tgt_clobbers,
- void *site, u16 site_clobbers,
+unsigned paravirt_patch_call(void *insnbuf,
+ const void *target, u16 tgt_clobbers,
+ unsigned long addr, u16 site_clobbers,
unsigned len)
{
- unsigned char *call = site;
- unsigned long delta = (unsigned long)target - (unsigned long)(call+5);
- struct branch b;
+ struct branch *b = insnbuf;
+ unsigned long delta = (unsigned long)target - (addr+5);
if (tgt_clobbers & ~site_clobbers)
return len; /* target would clobber too much for this site */
if (len < 5)
return len; /* call too long for patch site */
- b.opcode = 0xe8; /* call */
- b.delta = delta;
- BUILD_BUG_ON(sizeof(b) != 5);
- text_poke(call, (unsigned char *)&b, 5);
+ b->opcode = 0xe8; /* call */
+ b->delta = delta;
+ BUILD_BUG_ON(sizeof(*b) != 5);
return 5;
}
-unsigned paravirt_patch_jmp(void *target, void *site, unsigned len)
+unsigned paravirt_patch_jmp(const void *target, void *insnbuf,
+ unsigned long addr, unsigned len)
{
- unsigned char *jmp = site;
- unsigned long delta = (unsigned long)target - (unsigned long)(jmp+5);
- struct branch b;
+ struct branch *b = insnbuf;
+ unsigned long delta = (unsigned long)target - (addr+5);
if (len < 5)
return len; /* call too long for patch site */
- b.opcode = 0xe9; /* jmp */
- b.delta = delta;
- text_poke(jmp, (unsigned char *)&b, 5);
+ b->opcode = 0xe9; /* jmp */
+ b->delta = delta;
return 5;
}
-unsigned paravirt_patch_default(u8 type, u16 clobbers, void *site, unsigned len)
+unsigned paravirt_patch_default(u8 type, u16 clobbers, void *insnbuf,
+ unsigned long addr, unsigned len)
{
void *opfunc = *((void **)¶virt_ops + type);
unsigned ret;
if (opfunc == NULL)
/* If there's no function, patch it with a ud2a (BUG) */
- ret = paravirt_patch_insns(site, len, start_ud2a, end_ud2a);
+ ret = paravirt_patch_insns(insnbuf, len, start_ud2a, end_ud2a);
else if (opfunc == paravirt_nop)
/* If the operation is a nop, then nop the callsite */
ret = paravirt_patch_nop();
else if (type == PARAVIRT_PATCH(iret) ||
type == PARAVIRT_PATCH(irq_enable_sysexit))
/* If operation requires a jmp, then jmp */
- ret = paravirt_patch_jmp(opfunc, site, len);
+ ret = paravirt_patch_jmp(opfunc, insnbuf, addr, len);
else
/* Otherwise call the function; assume target could
clobber any caller-save reg */
- ret = paravirt_patch_call(opfunc, CLBR_ANY,
- site, clobbers, len);
+ ret = paravirt_patch_call(insnbuf, opfunc, CLBR_ANY,
+ addr, clobbers, len);
return ret;
}
-unsigned paravirt_patch_insns(void *site, unsigned len,
+unsigned paravirt_patch_insns(void *insnbuf, unsigned len,
const char *start, const char *end)
{
unsigned insn_len = end - start;
@@ -198,7 +198,7 @@
if (insn_len > len || start == NULL)
insn_len = len;
else
- memcpy(site, start, insn_len);
+ memcpy(insnbuf, start, insn_len);
return insn_len;
}
diff --git a/arch/i386/kernel/tsc.c b/arch/i386/kernel/tsc.c
index debd7db..a39280b 100644
--- a/arch/i386/kernel/tsc.c
+++ b/arch/i386/kernel/tsc.c
@@ -292,7 +292,6 @@
void mark_tsc_unstable(char *reason)
{
- sched_clock_unstable_event();
if (!tsc_unstable) {
tsc_unstable = 1;
tsc_enabled = 0;
diff --git a/arch/i386/kernel/vmi.c b/arch/i386/kernel/vmi.c
index 72042bb..18673e0 100644
--- a/arch/i386/kernel/vmi.c
+++ b/arch/i386/kernel/vmi.c
@@ -87,12 +87,14 @@
#define IRQ_PATCH_INT_MASK 0
#define IRQ_PATCH_DISABLE 5
-static inline void patch_offset(unsigned char *eip, unsigned char *dest)
+static inline void patch_offset(void *insnbuf,
+ unsigned long eip, unsigned long dest)
{
- *(unsigned long *)(eip+1) = dest-eip-5;
+ *(unsigned long *)(insnbuf+1) = dest-eip-5;
}
-static unsigned patch_internal(int call, unsigned len, void *insns)
+static unsigned patch_internal(int call, unsigned len, void *insnbuf,
+ unsigned long eip)
{
u64 reloc;
struct vmi_relocation_info *const rel = (struct vmi_relocation_info *)&reloc;
@@ -100,14 +102,14 @@
switch(rel->type) {
case VMI_RELOCATION_CALL_REL:
BUG_ON(len < 5);
- *(char *)insns = MNEM_CALL;
- patch_offset(insns, rel->eip);
+ *(char *)insnbuf = MNEM_CALL;
+ patch_offset(insnbuf, eip, (unsigned long)rel->eip);
return 5;
case VMI_RELOCATION_JUMP_REL:
BUG_ON(len < 5);
- *(char *)insns = MNEM_JMP;
- patch_offset(insns, rel->eip);
+ *(char *)insnbuf = MNEM_JMP;
+ patch_offset(insnbuf, eip, (unsigned long)rel->eip);
return 5;
case VMI_RELOCATION_NOP:
@@ -128,21 +130,26 @@
* Apply patch if appropriate, return length of new instruction
* sequence. The callee does nop padding for us.
*/
-static unsigned vmi_patch(u8 type, u16 clobbers, void *insns, unsigned len)
+static unsigned vmi_patch(u8 type, u16 clobbers, void *insns,
+ unsigned long eip, unsigned len)
{
switch (type) {
case PARAVIRT_PATCH(irq_disable):
- return patch_internal(VMI_CALL_DisableInterrupts, len, insns);
+ return patch_internal(VMI_CALL_DisableInterrupts, len,
+ insns, eip);
case PARAVIRT_PATCH(irq_enable):
- return patch_internal(VMI_CALL_EnableInterrupts, len, insns);
+ return patch_internal(VMI_CALL_EnableInterrupts, len,
+ insns, eip);
case PARAVIRT_PATCH(restore_fl):
- return patch_internal(VMI_CALL_SetInterruptMask, len, insns);
+ return patch_internal(VMI_CALL_SetInterruptMask, len,
+ insns, eip);
case PARAVIRT_PATCH(save_fl):
- return patch_internal(VMI_CALL_GetInterruptMask, len, insns);
+ return patch_internal(VMI_CALL_GetInterruptMask, len,
+ insns, eip);
case PARAVIRT_PATCH(iret):
- return patch_internal(VMI_CALL_IRET, len, insns);
+ return patch_internal(VMI_CALL_IRET, len, insns, eip);
case PARAVIRT_PATCH(irq_enable_sysexit):
- return patch_internal(VMI_CALL_SYSEXIT, len, insns);
+ return patch_internal(VMI_CALL_SYSEXIT, len, insns, eip);
default:
break;
}
diff --git a/arch/i386/mm/fault.c b/arch/i386/mm/fault.c
index 01ffdd4..fcb38e7 100644
--- a/arch/i386/mm/fault.c
+++ b/arch/i386/mm/fault.c
@@ -249,9 +249,10 @@
pmd_k = pmd_offset(pud_k, address);
if (!pmd_present(*pmd_k))
return NULL;
- if (!pmd_present(*pmd))
+ if (!pmd_present(*pmd)) {
set_pmd(pmd, *pmd_k);
- else
+ arch_flush_lazy_mmu_mode();
+ } else
BUG_ON(pmd_page(*pmd) != pmd_page(*pmd_k));
return pmd_k;
}
diff --git a/arch/i386/mm/pageattr.c b/arch/i386/mm/pageattr.c
index 8927222..4241a74 100644
--- a/arch/i386/mm/pageattr.c
+++ b/arch/i386/mm/pageattr.c
@@ -82,7 +82,7 @@
struct page *p;
/* High level code is not ready for clflush yet */
- if (cpu_has_clflush) {
+ if (0 && cpu_has_clflush) {
list_for_each_entry (p, lh, lru)
cache_flush_page(p);
} else if (boot_cpu_data.x86_model >= 4)
diff --git a/arch/i386/pci/common.c b/arch/i386/pci/common.c
index 85503dee..ebc6f3c 100644
--- a/arch/i386/pci/common.c
+++ b/arch/i386/pci/common.c
@@ -455,3 +455,26 @@
if (!dev->msi_enabled && pcibios_disable_irq)
pcibios_disable_irq(dev);
}
+
+struct pci_bus *pci_scan_bus_with_sysdata(int busno)
+{
+ struct pci_bus *bus = NULL;
+ struct pci_sysdata *sd;
+
+ /*
+ * Allocate per-root-bus (not per bus) arch-specific data.
+ * TODO: leak; this memory is never freed.
+ * It's arguable whether it's worth the trouble to care.
+ */
+ sd = kzalloc(sizeof(*sd), GFP_KERNEL);
+ if (!sd) {
+ printk(KERN_ERR "PCI: OOM, skipping PCI bus %02x\n", busno);
+ return NULL;
+ }
+ sd->node = -1;
+ bus = pci_scan_bus(busno, &pci_root_ops, sd);
+ if (!bus)
+ kfree(sd);
+
+ return bus;
+}
diff --git a/arch/i386/pci/fixup.c b/arch/i386/pci/fixup.c
index e7306db..c82cbf4 100644
--- a/arch/i386/pci/fixup.c
+++ b/arch/i386/pci/fixup.c
@@ -25,9 +25,9 @@
pci_read_config_byte(d, reg++, &subb);
DBG("i450NX PXB %d: %02x/%02x/%02x\n", pxb, busno, suba, subb);
if (busno)
- pci_scan_bus(busno, &pci_root_ops, NULL); /* Bus A */
+ pci_scan_bus_with_sysdata(busno); /* Bus A */
if (suba < subb)
- pci_scan_bus(suba+1, &pci_root_ops, NULL); /* Bus B */
+ pci_scan_bus_with_sysdata(suba+1); /* Bus B */
}
pcibios_last_bus = -1;
}
@@ -42,7 +42,7 @@
u8 busno;
pci_read_config_byte(d, 0x4a, &busno);
printk(KERN_INFO "PCI: i440KX/GX host bridge %s: secondary bus %02x\n", pci_name(d), busno);
- pci_scan_bus(busno, &pci_root_ops, NULL);
+ pci_scan_bus_with_sysdata(busno);
pcibios_last_bus = -1;
}
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82454GX, pci_fixup_i450gx);
diff --git a/arch/i386/pci/irq.c b/arch/i386/pci/irq.c
index f2cb942..665db06 100644
--- a/arch/i386/pci/irq.c
+++ b/arch/i386/pci/irq.c
@@ -138,8 +138,9 @@
for(i = 1; i < 256; i++) {
if (!busmap[i] || pci_find_bus(0, i))
continue;
- if (pci_scan_bus(i, &pci_root_ops, NULL))
- printk(KERN_INFO "PCI: Discovered primary peer bus %02x [IRQ]\n", i);
+ if (pci_scan_bus_with_sysdata(i))
+ printk(KERN_INFO "PCI: Discovered primary peer "
+ "bus %02x [IRQ]\n", i);
}
pcibios_last_bus = -1;
}
diff --git a/arch/i386/pci/legacy.c b/arch/i386/pci/legacy.c
index 149a958..5565d70 100644
--- a/arch/i386/pci/legacy.c
+++ b/arch/i386/pci/legacy.c
@@ -26,7 +26,7 @@
l != 0x0000 && l != 0xffff) {
DBG("Found device at %02x:%02x [%04x]\n", n, devfn, l);
printk(KERN_INFO "PCI: Discovered peer bus %02x\n", n);
- pci_scan_bus(n, &pci_root_ops, NULL);
+ pci_scan_bus_with_sysdata(n);
break;
}
}
diff --git a/arch/i386/pci/mmconfig.c b/arch/i386/pci/mmconfig.c
index bb1afd9..1bf5816 100644
--- a/arch/i386/pci/mmconfig.c
+++ b/arch/i386/pci/mmconfig.c
@@ -82,16 +82,15 @@
switch (len) {
case 1:
- *value = readb(mmcfg_virt_addr + reg);
+ *value = mmio_config_readb(mmcfg_virt_addr + reg);
break;
case 2:
- *value = readw(mmcfg_virt_addr + reg);
+ *value = mmio_config_readw(mmcfg_virt_addr + reg);
break;
case 4:
- *value = readl(mmcfg_virt_addr + reg);
+ *value = mmio_config_readl(mmcfg_virt_addr + reg);
break;
}
-
spin_unlock_irqrestore(&pci_config_lock, flags);
return 0;
@@ -116,16 +115,15 @@
switch (len) {
case 1:
- writeb(value, mmcfg_virt_addr + reg);
+ mmio_config_writeb(mmcfg_virt_addr + reg, value);
break;
case 2:
- writew(value, mmcfg_virt_addr + reg);
+ mmio_config_writew(mmcfg_virt_addr + reg, value);
break;
case 4:
- writel(value, mmcfg_virt_addr + reg);
+ mmio_config_writel(mmcfg_virt_addr + reg, value);
break;
}
-
spin_unlock_irqrestore(&pci_config_lock, flags);
return 0;
diff --git a/arch/i386/pci/numa.c b/arch/i386/pci/numa.c
index adbe17a..f5f165f 100644
--- a/arch/i386/pci/numa.c
+++ b/arch/i386/pci/numa.c
@@ -96,10 +96,14 @@
pci_read_config_byte(d, reg++, &suba);
pci_read_config_byte(d, reg++, &subb);
DBG("i450NX PXB %d: %02x/%02x/%02x\n", pxb, busno, suba, subb);
- if (busno)
- pci_scan_bus(QUADLOCAL2BUS(quad,busno), &pci_root_ops, NULL); /* Bus A */
- if (suba < subb)
- pci_scan_bus(QUADLOCAL2BUS(quad,suba+1), &pci_root_ops, NULL); /* Bus B */
+ if (busno) {
+ /* Bus A */
+ pci_scan_bus_with_sysdata(QUADLOCAL2BUS(quad, busno));
+ }
+ if (suba < subb) {
+ /* Bus B */
+ pci_scan_bus_with_sysdata(QUADLOCAL2BUS(quad, suba+1));
+ }
}
pcibios_last_bus = -1;
}
@@ -123,8 +127,7 @@
continue;
printk("Scanning PCI bus %d for quad %d\n",
QUADLOCAL2BUS(quad,0), quad);
- pci_scan_bus(QUADLOCAL2BUS(quad,0),
- &pci_root_ops, NULL);
+ pci_scan_bus_with_sysdata(QUADLOCAL2BUS(quad, 0));
}
return 0;
}
diff --git a/arch/i386/pci/pci.h b/arch/i386/pci/pci.h
index e58bae2..8c66f27 100644
--- a/arch/i386/pci/pci.h
+++ b/arch/i386/pci/pci.h
@@ -104,3 +104,46 @@
extern int __init pci_mmcfg_arch_reachable(unsigned int seg, unsigned int bus,
unsigned int devfn);
extern int __init pci_mmcfg_arch_init(void);
+
+/*
+ * AMD Fam10h CPUs are buggy, and cannot access MMIO config space
+ * on their northbrige except through the * %eax register. As such, you MUST
+ * NOT use normal IOMEM accesses, you need to only use the magic mmio-config
+ * accessor functions.
+ * In fact just use pci_config_*, nothing else please.
+ */
+static inline unsigned char mmio_config_readb(void __iomem *pos)
+{
+ u8 val;
+ asm volatile("movb (%1),%%al" : "=a" (val) : "r" (pos));
+ return val;
+}
+
+static inline unsigned short mmio_config_readw(void __iomem *pos)
+{
+ u16 val;
+ asm volatile("movw (%1),%%ax" : "=a" (val) : "r" (pos));
+ return val;
+}
+
+static inline unsigned int mmio_config_readl(void __iomem *pos)
+{
+ u32 val;
+ asm volatile("movl (%1),%%eax" : "=a" (val) : "r" (pos));
+ return val;
+}
+
+static inline void mmio_config_writeb(void __iomem *pos, u8 val)
+{
+ asm volatile("movb %%al,(%1)" :: "a" (val), "r" (pos) : "memory");
+}
+
+static inline void mmio_config_writew(void __iomem *pos, u16 val)
+{
+ asm volatile("movw %%ax,(%1)" :: "a" (val), "r" (pos) : "memory");
+}
+
+static inline void mmio_config_writel(void __iomem *pos, u32 val)
+{
+ asm volatile("movl %%eax,(%1)" :: "a" (val), "r" (pos) : "memory");
+}
diff --git a/arch/i386/pci/visws.c b/arch/i386/pci/visws.c
index f1b486d..8ecb1c7 100644
--- a/arch/i386/pci/visws.c
+++ b/arch/i386/pci/visws.c
@@ -101,8 +101,8 @@
"bridge B (PIIX4) bus: %u\n", pci_bus1, pci_bus0);
raw_pci_ops = &pci_direct_conf1;
- pci_scan_bus(pci_bus0, &pci_root_ops, NULL);
- pci_scan_bus(pci_bus1, &pci_root_ops, NULL);
+ pci_scan_bus_with_sysdata(pci_bus0);
+ pci_scan_bus_with_sysdata(pci_bus1);
pci_fixup_irqs(visws_swizzle, visws_map_irq);
pcibios_resource_survey();
return 0;
diff --git a/arch/i386/xen/enlighten.c b/arch/i386/xen/enlighten.c
index 9a8c118..f0c3751 100644
--- a/arch/i386/xen/enlighten.c
+++ b/arch/i386/xen/enlighten.c
@@ -842,7 +842,8 @@
}
}
-static unsigned xen_patch(u8 type, u16 clobbers, void *insns, unsigned len)
+static unsigned xen_patch(u8 type, u16 clobbers, void *insnbuf,
+ unsigned long addr, unsigned len)
{
char *start, *end, *reloc;
unsigned ret;
@@ -869,7 +870,7 @@
if (start == NULL || (end-start) > len)
goto default_patch;
- ret = paravirt_patch_insns(insns, len, start, end);
+ ret = paravirt_patch_insns(insnbuf, len, start, end);
/* Note: because reloc is assigned from something that
appears to be an array, gcc assumes it's non-null,
@@ -877,8 +878,8 @@
end. */
if (reloc > start && reloc < end) {
int reloc_off = reloc - start;
- long *relocp = (long *)(insns + reloc_off);
- long delta = start - (char *)insns;
+ long *relocp = (long *)(insnbuf + reloc_off);
+ long delta = start - (char *)addr;
*relocp += delta;
}
@@ -886,7 +887,8 @@
default_patch:
default:
- ret = paravirt_patch_default(type, clobbers, insns, len);
+ ret = paravirt_patch_default(type, clobbers, insnbuf,
+ addr, len);
break;
}
diff --git a/arch/i386/xen/xen-head.S b/arch/i386/xen/xen-head.S
index bc71f3b..f8d6937 100644
--- a/arch/i386/xen/xen-head.S
+++ b/arch/i386/xen/xen-head.S
@@ -7,20 +7,20 @@
#include <asm/boot.h>
#include <xen/interface/elfnote.h>
- .section .init.text
+.pushsection .init.text
ENTRY(startup_xen)
movl %esi,xen_start_info
cld
movl $(init_thread_union+THREAD_SIZE),%esp
jmp xen_start_kernel
+.popsection
-.pushsection ".bss.page_aligned"
+.pushsection .bss.page_aligned
.align PAGE_SIZE_asm
ENTRY(hypercall_page)
.skip 0x1000
.popsection
- .section .text
ELFNOTE(Xen, XEN_ELFNOTE_GUEST_OS, .asciz "linux")
ELFNOTE(Xen, XEN_ELFNOTE_GUEST_VERSION, .asciz "2.6")
ELFNOTE(Xen, XEN_ELFNOTE_XEN_VERSION, .asciz "xen-3.0")
diff --git a/arch/ia64/Kconfig b/arch/ia64/Kconfig
index 21aa4fc..8c39913 100644
--- a/arch/ia64/Kconfig
+++ b/arch/ia64/Kconfig
@@ -327,17 +327,7 @@
This option it useful to enable this feature on older BIOS's as well.
You can also enable this by using boot command line option force_cpei=1.
-config PREEMPT
- bool "Preemptible Kernel"
- help
- This option reduces the latency of the kernel when reacting to
- real-time or interactive events by allowing a low priority process to
- be preempted even if it is in kernel mode executing a system call.
- This allows applications to run more reliably even when the system is
- under load.
-
- Say Y here if you are building a kernel for a desktop, embedded
- or real-time system. Say N if you are unsure.
+source "kernel/Kconfig.preempt"
source "mm/Kconfig"
diff --git a/arch/ia64/configs/bigsur_defconfig b/arch/ia64/configs/bigsur_defconfig
index 9eb48c0..6dd8655 100644
--- a/arch/ia64/configs/bigsur_defconfig
+++ b/arch/ia64/configs/bigsur_defconfig
@@ -42,7 +42,7 @@
CONFIG_CC_ALIGN_LABELS=0
CONFIG_CC_ALIGN_LOOPS=0
CONFIG_CC_ALIGN_JUMPS=0
-CONFIG_SLAB=y
+CONFIG_SLUB=y
# CONFIG_TINY_SHMEM is not set
CONFIG_BASE_SMALL=0
# CONFIG_SLOB is not set
diff --git a/arch/ia64/configs/gensparse_defconfig b/arch/ia64/configs/gensparse_defconfig
index 3a9ed95..e86fbd3 100644
--- a/arch/ia64/configs/gensparse_defconfig
+++ b/arch/ia64/configs/gensparse_defconfig
@@ -43,7 +43,7 @@
CONFIG_CC_ALIGN_LABELS=0
CONFIG_CC_ALIGN_LOOPS=0
CONFIG_CC_ALIGN_JUMPS=0
-CONFIG_SLAB=y
+CONFIG_SLUB=y
# CONFIG_TINY_SHMEM is not set
CONFIG_BASE_SMALL=0
# CONFIG_SLOB is not set
diff --git a/arch/ia64/configs/sim_defconfig b/arch/ia64/configs/sim_defconfig
index c420d9f..546a772 100644
--- a/arch/ia64/configs/sim_defconfig
+++ b/arch/ia64/configs/sim_defconfig
@@ -43,7 +43,7 @@
CONFIG_CC_ALIGN_LABELS=0
CONFIG_CC_ALIGN_LOOPS=0
CONFIG_CC_ALIGN_JUMPS=0
-CONFIG_SLAB=y
+CONFIG_SLUB=y
# CONFIG_TINY_SHMEM is not set
CONFIG_BASE_SMALL=0
# CONFIG_SLOB is not set
diff --git a/arch/ia64/configs/sn2_defconfig b/arch/ia64/configs/sn2_defconfig
index 4c9ffc4..9aecfce 100644
--- a/arch/ia64/configs/sn2_defconfig
+++ b/arch/ia64/configs/sn2_defconfig
@@ -46,7 +46,7 @@
CONFIG_FUTEX=y
CONFIG_EPOLL=y
CONFIG_SHMEM=y
-CONFIG_SLAB=y
+CONFIG_SLUB=y
CONFIG_VM_EVENT_COUNTERS=y
CONFIG_RT_MUTEXES=y
# CONFIG_TINY_SHMEM is not set
diff --git a/arch/ia64/configs/tiger_defconfig b/arch/ia64/configs/tiger_defconfig
index 3dbb398..797acf9 100644
--- a/arch/ia64/configs/tiger_defconfig
+++ b/arch/ia64/configs/tiger_defconfig
@@ -53,7 +53,7 @@
CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_VM_EVENT_COUNTERS=y
-CONFIG_SLAB=y
+CONFIG_SLUB=y
# CONFIG_SLUB is not set
# CONFIG_SLOB is not set
CONFIG_RT_MUTEXES=y
diff --git a/arch/ia64/configs/zx1_defconfig b/arch/ia64/configs/zx1_defconfig
index 4a060fc..0a06b13 100644
--- a/arch/ia64/configs/zx1_defconfig
+++ b/arch/ia64/configs/zx1_defconfig
@@ -48,7 +48,7 @@
CONFIG_FUTEX=y
CONFIG_EPOLL=y
CONFIG_SHMEM=y
-CONFIG_SLAB=y
+CONFIG_SLUB=y
CONFIG_VM_EVENT_COUNTERS=y
CONFIG_RT_MUTEXES=y
# CONFIG_TINY_SHMEM is not set
diff --git a/arch/ia64/defconfig b/arch/ia64/defconfig
index 03172dc..0210545 100644
--- a/arch/ia64/defconfig
+++ b/arch/ia64/defconfig
@@ -53,8 +53,7 @@
CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_VM_EVENT_COUNTERS=y
-CONFIG_SLAB=y
-# CONFIG_SLUB is not set
+CONFIG_SLUB=y
# CONFIG_SLOB is not set
CONFIG_RT_MUTEXES=y
# CONFIG_TINY_SHMEM is not set
diff --git a/arch/ia64/hp/sim/boot/boot_head.S b/arch/ia64/hp/sim/boot/boot_head.S
index a9bd71a..8808565 100644
--- a/arch/ia64/hp/sim/boot/boot_head.S
+++ b/arch/ia64/hp/sim/boot/boot_head.S
@@ -26,6 +26,7 @@
movl sp = stack_mem+16384-16
bsw.1
br.call.sptk.many rp=start_bootloader
+0: nop 0 /* dummy nop to make unwinding work */
END(_start)
/*
diff --git a/arch/ia64/kernel/cpufreq/acpi-cpufreq.c b/arch/ia64/kernel/cpufreq/acpi-cpufreq.c
index 15c08d5..8c6ec70 100644
--- a/arch/ia64/kernel/cpufreq/acpi-cpufreq.c
+++ b/arch/ia64/kernel/cpufreq/acpi-cpufreq.c
@@ -113,10 +113,8 @@
saved_mask = current->cpus_allowed;
set_cpus_allowed(current, cpumask_of_cpu(cpu));
- if (smp_processor_id() != cpu) {
- ret = -EAGAIN;
+ if (smp_processor_id() != cpu)
goto migrate_end;
- }
/* processor_get_pstate gets the instantaneous frequency */
ret = processor_get_pstate(&value);
@@ -125,7 +123,7 @@
set_cpus_allowed(current, saved_mask);
printk(KERN_WARNING "get performance failed with error %d\n",
ret);
- ret = -EAGAIN;
+ ret = 0;
goto migrate_end;
}
clock_freq = extract_clock(data, value, cpu);
diff --git a/arch/ia64/kernel/irq.c b/arch/ia64/kernel/irq.c
index cc3ee4e..44be1c95 100644
--- a/arch/ia64/kernel/irq.c
+++ b/arch/ia64/kernel/irq.c
@@ -33,6 +33,11 @@
}
#ifdef CONFIG_IA64_GENERIC
+ia64_vector __ia64_irq_to_vector(int irq)
+{
+ return irq_cfg[irq].vector;
+}
+
unsigned int __ia64_local_vector_to_irq (ia64_vector vec)
{
return __get_cpu_var(vector_irq)[vec];
diff --git a/arch/ia64/kernel/mca.c b/arch/ia64/kernel/mca.c
index ff28620..63b73f3 100644
--- a/arch/ia64/kernel/mca.c
+++ b/arch/ia64/kernel/mca.c
@@ -2018,22 +2018,26 @@
if (cpe_vector >= 0) {
/* If platform supports CPEI, enable the irq. */
- cpe_poll_enabled = 0;
- for (irq = 0; irq < NR_IRQS; ++irq)
- if (irq_to_vector(irq) == cpe_vector) {
- desc = irq_desc + irq;
- desc->status |= IRQ_PER_CPU;
- setup_irq(irq, &mca_cpe_irqaction);
- ia64_cpe_irq = irq;
- }
- ia64_mca_register_cpev(cpe_vector);
- IA64_MCA_DEBUG("%s: CPEI/P setup and enabled.\n", __FUNCTION__);
- } else {
- /* If platform doesn't support CPEI, get the timer going. */
- if (cpe_poll_enabled) {
- ia64_mca_cpe_poll(0UL);
- IA64_MCA_DEBUG("%s: CPEP setup and enabled.\n", __FUNCTION__);
+ irq = local_vector_to_irq(cpe_vector);
+ if (irq > 0) {
+ cpe_poll_enabled = 0;
+ desc = irq_desc + irq;
+ desc->status |= IRQ_PER_CPU;
+ setup_irq(irq, &mca_cpe_irqaction);
+ ia64_cpe_irq = irq;
+ ia64_mca_register_cpev(cpe_vector);
+ IA64_MCA_DEBUG("%s: CPEI/P setup and enabled.\n",
+ __FUNCTION__);
+ return 0;
}
+ printk(KERN_ERR "%s: Failed to find irq for CPE "
+ "interrupt handler, vector %d\n",
+ __FUNCTION__, cpe_vector);
+ }
+ /* If platform doesn't support CPEI, get the timer going. */
+ if (cpe_poll_enabled) {
+ ia64_mca_cpe_poll(0UL);
+ IA64_MCA_DEBUG("%s: CPEP setup and enabled.\n", __FUNCTION__);
}
}
#endif
diff --git a/arch/ia64/kernel/process.c b/arch/ia64/kernel/process.c
index 4158906..c613fc0 100644
--- a/arch/ia64/kernel/process.c
+++ b/arch/ia64/kernel/process.c
@@ -198,9 +198,13 @@
{
local_irq_enable();
while (!need_resched()) {
- if (can_do_pal_halt)
- safe_halt();
- else
+ if (can_do_pal_halt) {
+ local_irq_disable();
+ if (!need_resched()) {
+ safe_halt();
+ }
+ local_irq_enable();
+ } else
cpu_relax();
}
}
diff --git a/arch/ia64/kernel/ptrace.c b/arch/ia64/kernel/ptrace.c
index 00f8032..122444a 100644
--- a/arch/ia64/kernel/ptrace.c
+++ b/arch/ia64/kernel/ptrace.c
@@ -951,10 +951,14 @@
return 0;
case PT_CR_IPSR:
- if (write_access)
- pt->cr_ipsr = ((*data & IPSR_MASK)
+ if (write_access) {
+ unsigned long tmp = *data;
+ /* psr.ri==3 is a reserved value: SDM 2:25 */
+ if ((tmp & IA64_PSR_RI) == IA64_PSR_RI)
+ tmp &= ~IA64_PSR_RI;
+ pt->cr_ipsr = ((tmp & IPSR_MASK)
| (pt->cr_ipsr & ~IPSR_MASK));
- else
+ } else
*data = (pt->cr_ipsr & IPSR_MASK);
return 0;
diff --git a/arch/ia64/kernel/setup.c b/arch/ia64/kernel/setup.c
index cd9a37a..407efea 100644
--- a/arch/ia64/kernel/setup.c
+++ b/arch/ia64/kernel/setup.c
@@ -389,6 +389,13 @@
if (!efi_setup_pcdp_console(cmdline))
earlycons++;
#endif
+#ifdef CONFIG_HP_SIMSERIAL_CONSOLE
+ {
+ extern struct console hpsim_cons;
+ register_console(&hpsim_cons);
+ earlycons++;
+ }
+#endif
return (earlycons) ? 0 : -1;
}
diff --git a/arch/ia64/kernel/vmlinux.lds.S b/arch/ia64/kernel/vmlinux.lds.S
index 83e8067..00232b4 100644
--- a/arch/ia64/kernel/vmlinux.lds.S
+++ b/arch/ia64/kernel/vmlinux.lds.S
@@ -20,6 +20,8 @@
code PT_LOAD;
percpu PT_LOAD;
data PT_LOAD;
+ note PT_NOTE;
+ unwind 0x70000001; /* PT_IA_64_UNWIND, but ld doesn't match the name */
}
SECTIONS
{
@@ -62,6 +64,9 @@
/* Read-only data */
+ NOTES :code :note /* put .notes in text and mark in PT_NOTE */
+ code_continues : {} :code /* switch back to regular program... */
+
/* Exception table */
. = ALIGN(16);
__ex_table : AT(ADDR(__ex_table) - LOAD_OFFSET)
@@ -99,7 +104,8 @@
__start_unwind = .;
*(.IA_64.unwind*)
__end_unwind = .;
- }
+ } :code :unwind
+ code_continues2 : {} : code
RODATA
@@ -276,10 +282,6 @@
.debug_typenames 0 : { *(.debug_typenames) }
.debug_varnames 0 : { *(.debug_varnames) }
/* These must appear regardless of . */
- /* Discard them for now since Intel SoftSDV cannot handle them.
- .comment 0 : { *(.comment) }
- .note 0 : { *(.note) }
- */
/DISCARD/ : { *(.comment) }
/DISCARD/ : { *(.note) }
}
diff --git a/arch/ia64/mm/fault.c b/arch/ia64/mm/fault.c
index 73ccb60..9150ffa 100644
--- a/arch/ia64/mm/fault.c
+++ b/arch/ia64/mm/fault.c
@@ -112,11 +112,17 @@
down_read(&mm->mmap_sem);
vma = find_vma_prev(mm, address, &prev_vma);
- if (!vma)
+ if (!vma && !prev_vma )
goto bad_area;
- /* find_vma_prev() returns vma such that address < vma->vm_end or NULL */
- if (address < vma->vm_start)
+ /*
+ * find_vma_prev() returns vma such that address < vma->vm_end or NULL
+ *
+ * May find no vma, but could be that the last vm area is the
+ * register backing store that needs to expand upwards, in
+ * this case vma will be null, but prev_vma will ne non-null
+ */
+ if (( !vma && prev_vma ) || (address < vma->vm_start) )
goto check_expansion;
good_area:
@@ -172,6 +178,8 @@
check_expansion:
if (!(prev_vma && (prev_vma->vm_flags & VM_GROWSUP) && (address == prev_vma->vm_end))) {
+ if (!vma)
+ goto bad_area;
if (!(vma->vm_flags & VM_GROWSDOWN))
goto bad_area;
if (REGION_NUMBER(address) != REGION_NUMBER(vma->vm_start)
diff --git a/arch/ia64/sn/kernel/irq.c b/arch/ia64/sn/kernel/irq.c
index 7f6d236..3600473 100644
--- a/arch/ia64/sn/kernel/irq.c
+++ b/arch/ia64/sn/kernel/irq.c
@@ -256,6 +256,13 @@
.set_affinity = sn_set_affinity_irq
};
+ia64_vector sn_irq_to_vector(int irq)
+{
+ if (irq >= IA64_NUM_VECTORS)
+ return 0;
+ return (ia64_vector)irq;
+}
+
unsigned int sn_local_vector_to_irq(u8 vector)
{
return (CPU_VECTOR_TO_IRQ(smp_processor_id(), vector));
@@ -398,7 +405,10 @@
struct sn_pcibus_provider *pci_provider;
pci_provider = sn_pci_provider[sn_irq_info->irq_bridge_type];
- if (pci_provider && pci_provider->force_interrupt)
+
+ /* Don't force an interrupt if the irq has been disabled */
+ if (!(irq_desc[sn_irq_info->irq_irq].status & IRQ_DISABLED) &&
+ pci_provider && pci_provider->force_interrupt)
(*pci_provider->force_interrupt)(sn_irq_info);
}
diff --git a/arch/m68k/kernel/setup.c b/arch/m68k/kernel/setup.c
index 7e6d5fb..ed3a4ca 100644
--- a/arch/m68k/kernel/setup.c
+++ b/arch/m68k/kernel/setup.c
@@ -62,7 +62,6 @@
int m68k_realnum_memory;
EXPORT_SYMBOL(m68k_realnum_memory);
unsigned long m68k_memoffset;
-EXPORT_SYMBOL(m68k_memoffset);
struct mem_info m68k_memory[NUM_MEMINFO];
EXPORT_SYMBOL(m68k_memory);
@@ -200,7 +199,6 @@
(m68k_num_memory - 1));
m68k_num_memory = 1;
}
- m68k_memoffset = m68k_memory[0].addr-PAGE_OFFSET;
#endif
}
diff --git a/arch/m68k/kernel/vmlinux-std.lds b/arch/m68k/kernel/vmlinux-std.lds
index c422457..59fe285 100644
--- a/arch/m68k/kernel/vmlinux-std.lds
+++ b/arch/m68k/kernel/vmlinux-std.lds
@@ -19,6 +19,8 @@
*(.gnu.warning)
} :text = 0x4e75
+ _etext = .; /* End of text section */
+
. = ALIGN(16); /* Exception table */
__start___ex_table = .;
__ex_table : { *(__ex_table) }
@@ -26,8 +28,6 @@
RODATA
- _etext = .; /* End of text section */
-
.data : { /* Data */
DATA_DATA
CONSTRUCTORS
diff --git a/arch/m68k/mm/motorola.c b/arch/m68k/mm/motorola.c
index 7d571a2..30d34f2 100644
--- a/arch/m68k/mm/motorola.c
+++ b/arch/m68k/mm/motorola.c
@@ -210,11 +210,7 @@
int i;
#ifdef DEBUG
- {
- extern unsigned long availmem;
- printk ("start of paging_init (%p, %lx)\n",
- kernel_pg_dir, availmem);
- }
+ printk ("start of paging_init (%p, %lx)\n", kernel_pg_dir, availmem);
#endif
/* Fix the cache mode in the page descriptors for the 680[46]0. */
diff --git a/arch/m68knommu/kernel/process.c b/arch/m68knommu/kernel/process.c
index 846f975..47502d5 100644
--- a/arch/m68knommu/kernel/process.c
+++ b/arch/m68knommu/kernel/process.c
@@ -28,6 +28,7 @@
#include <linux/a.out.h>
#include <linux/interrupt.h>
#include <linux/reboot.h>
+#include <linux/fs.h>
#include <asm/uaccess.h>
#include <asm/system.h>
diff --git a/arch/m68knommu/kernel/sys_m68k.c b/arch/m68knommu/kernel/sys_m68k.c
index 48e6b33..15d62c5 100644
--- a/arch/m68knommu/kernel/sys_m68k.c
+++ b/arch/m68knommu/kernel/sys_m68k.c
@@ -18,6 +18,7 @@
#include <linux/mman.h>
#include <linux/file.h>
#include <linux/utsname.h>
+#include <linux/fs.h>
#include <asm/setup.h>
#include <asm/uaccess.h>
diff --git a/arch/powerpc/boot/dts/mpc8544ds.dts b/arch/powerpc/boot/dts/mpc8544ds.dts
index 4680e20..3e79bf0 100644
--- a/arch/powerpc/boot/dts/mpc8544ds.dts
+++ b/arch/powerpc/boot/dts/mpc8544ds.dts
@@ -44,8 +44,18 @@
#size-cells = <1>;
#interrupt-cells = <2>;
device_type = "soc";
- ranges = <0 e0000000 00100000>;
- reg = <e0000000 00100000>; // CCSRBAR 1M
+
+
+ ranges = <00001000 e0001000 000ff000
+ 80000000 80000000 20000000
+ a0000000 a0000000 10000000
+ b0000000 b0000000 00100000
+ c0000000 c0000000 20000000
+ b0100000 b0100000 00100000
+ e1000000 e1000000 00010000
+ e1010000 e1010000 00010000
+ e1020000 e1020000 00010000>;
+ reg = <e0000000 00001000>; // CCSRBAR 1M
bus-frequency = <0>; // Filled out by uboot.
memory-controller@2000 {
@@ -161,8 +171,8 @@
interrupt-parent = <&mpic>;
interrupts = <18 2>;
bus-range = <0 ff>;
- ranges = <02000000 0 80000000 80000000 0 10000000
- 01000000 0 00000000 e2000000 0 00800000>;
+ ranges = <02000000 0 c0000000 c0000000 0 20000000
+ 01000000 0 00000000 e1000000 0 00010000>;
clock-frequency = <3f940aa>;
#interrupt-cells = <1>;
#size-cells = <2>;
@@ -178,8 +188,8 @@
#address-cells = <3>;
reg = <9000 1000>;
bus-range = <0 ff>;
- ranges = <02000000 0 90000000 90000000 0 10000000
- 01000000 0 00000000 e3000000 0 00800000>;
+ ranges = <02000000 0 80000000 80000000 0 20000000
+ 01000000 0 00000000 e1010000 0 00010000>;
clock-frequency = <1fca055>;
interrupt-parent = <&mpic>;
interrupts = <1a 2>;
@@ -202,7 +212,7 @@
reg = <a000 1000>;
bus-range = <0 ff>;
ranges = <02000000 0 a0000000 a0000000 0 10000000
- 01000000 0 00000000 e2800000 0 00800000>;
+ 01000000 0 00000000 e1020000 0 00010000>;
clock-frequency = <1fca055>;
interrupt-parent = <&mpic>;
interrupts = <19 2>;
@@ -224,49 +234,29 @@
#address-cells = <3>;
reg = <b000 1000>;
bus-range = <0 ff>;
- ranges = <02000000 0 b0000000 b0000000 0 10000000
- 01000000 0 00000000 e3800000 0 00800000>;
+ ranges = <02000000 0 b0000000 b0000000 0 00100000
+ 01000000 0 00000000 b0100000 0 00100000>;
clock-frequency = <1fca055>;
interrupt-parent = <&mpic>;
interrupts = <1b 2>;
- interrupt-map-mask = <f800 0 0 7>;
+ interrupt-map-mask = <fb00 0 0 0>;
interrupt-map = <
-
- // IDSEL 0x1a
- d000 0 0 1 &i8259 6 2
- d000 0 0 2 &i8259 3 2
- d000 0 0 3 &i8259 4 2
- d000 0 0 4 &i8259 5 2
-
- // IDSEL 0x1b
- d800 0 0 1 &i8259 5 2
- d800 0 0 2 &i8259 0 0
- d800 0 0 3 &i8259 0 0
- d800 0 0 4 &i8259 0 0
-
// IDSEL 0x1c USB
- e000 0 0 1 &i8259 9 2
- e000 0 0 2 &i8259 a 2
- e000 0 0 3 &i8259 c 2
- e000 0 0 4 &i8259 7 2
+ e000 0 0 0 &i8259 c 2
+ e100 0 0 0 &i8259 9 2
+ e200 0 0 0 &i8259 a 2
+ e300 0 0 0 &i8259 b 2
// IDSEL 0x1d Audio
- e800 0 0 1 &i8259 9 2
- e800 0 0 2 &i8259 a 2
- e800 0 0 3 &i8259 b 2
- e800 0 0 4 &i8259 0 0
+ e800 0 0 0 &i8259 6 2
// IDSEL 0x1e Legacy
- f000 0 0 1 &i8259 c 2
- f000 0 0 2 &i8259 0 0
- f000 0 0 3 &i8259 0 0
- f000 0 0 4 &i8259 0 0
+ f000 0 0 0 &i8259 7 2
+ f100 0 0 0 &i8259 7 2
// IDSEL 0x1f IDE/SATA
- f800 0 0 1 &i8259 6 2
- f800 0 0 2 &i8259 0 0
- f800 0 0 3 &i8259 0 0
- f800 0 0 4 &i8259 0 0
+ f800 0 0 0 &i8259 e 2
+ f900 0 0 0 &i8259 5 2
>;
uli1575@0 {
reg = <0 0 0 0 0>;
@@ -274,10 +264,10 @@
#address-cells = <3>;
ranges = <02000000 0 b0000000
02000000 0 b0000000
- 0 10000000
+ 0 00100000
01000000 0 00000000
01000000 0 00000000
- 0 00080000>;
+ 0 00100000>;
pci_bridge@0 {
reg = <0 0 0 0 0>;
@@ -285,10 +275,10 @@
#address-cells = <3>;
ranges = <02000000 0 b0000000
02000000 0 b0000000
- 0 20000000
+ 0 00100000
01000000 0 00000000
01000000 0 00000000
- 0 00100000>;
+ 0 00100000>;
isa@1e {
device_type = "isa";
@@ -296,7 +286,8 @@
#size-cells = <1>;
#address-cells = <2>;
reg = <f000 0 0 0 0>;
- ranges = <1 0 01000000 0 0
+ ranges = <1 0
+ 01000000 0 0
00001000>;
interrupt-parent = <&i8259>;
@@ -312,8 +303,7 @@
built-in;
compatible = "chrp,iic";
interrupts = <9 2>;
- interrupt-parent =
- <&mpic>;
+ interrupt-parent = <&mpic>;
};
i8042@60 {
@@ -321,8 +311,7 @@
#address-cells = <1>;
reg = <1 60 1 1 64 1>;
interrupts = <1 3 c 3>;
- interrupt-parent =
- <&i8259>;
+ interrupt-parent = <&i8259>;
keyboard@0 {
reg = <0>;
@@ -336,8 +325,7 @@
};
rtc@70 {
- compatible =
- "pnpPNP,b00";
+ compatible = "pnpPNP,b00";
reg = <1 70 2>;
};
diff --git a/arch/powerpc/boot/dts/mpc8641_hpcn.dts b/arch/powerpc/boot/dts/mpc8641_hpcn.dts
index 5d82709..b0166e5 100644
--- a/arch/powerpc/boot/dts/mpc8641_hpcn.dts
+++ b/arch/powerpc/boot/dts/mpc8641_hpcn.dts
@@ -224,98 +224,36 @@
clock-frequency = <1fca055>;
interrupt-parent = <&mpic>;
interrupts = <18 2>;
- interrupt-map-mask = <f800 0 0 7>;
+ interrupt-map-mask = <fb00 0 0 0>;
interrupt-map = <
/* IDSEL 0x11 */
- 8800 0 0 1 &i8259 3 2
- 8800 0 0 2 &i8259 4 2
- 8800 0 0 3 &i8259 5 2
- 8800 0 0 4 &i8259 6 2
+ 8800 0 0 1 &i8259 9 2
+ 8800 0 0 2 &i8259 a 2
+ 8800 0 0 3 &i8259 b 2
+ 8800 0 0 4 &i8259 c 2
/* IDSEL 0x12 */
- 9000 0 0 1 &i8259 4 2
- 9000 0 0 2 &i8259 5 2
- 9000 0 0 3 &i8259 6 2
- 9000 0 0 4 &i8259 3 2
+ 9000 0 0 1 &i8259 a 2
+ 9000 0 0 2 &i8259 b 2
+ 9000 0 0 3 &i8259 c 2
+ 9000 0 0 4 &i8259 9 2
- /* IDSEL 0x13 */
- 9800 0 0 1 &i8259 0 0
- 9800 0 0 2 &i8259 0 0
- 9800 0 0 3 &i8259 0 0
- 9800 0 0 4 &i8259 0 0
+ // IDSEL 0x1c USB
+ e000 0 0 0 &i8259 c 2
+ e100 0 0 0 &i8259 9 2
+ e200 0 0 0 &i8259 a 2
+ e300 0 0 0 &i8259 b 2
- /* IDSEL 0x14 */
- a000 0 0 1 &i8259 0 0
- a000 0 0 2 &i8259 0 0
- a000 0 0 3 &i8259 0 0
- a000 0 0 4 &i8259 0 0
+ // IDSEL 0x1d Audio
+ e800 0 0 0 &i8259 6 2
- /* IDSEL 0x15 */
- a800 0 0 1 &i8259 0 0
- a800 0 0 2 &i8259 0 0
- a800 0 0 3 &i8259 0 0
- a800 0 0 4 &i8259 0 0
+ // IDSEL 0x1e Legacy
+ f000 0 0 0 &i8259 7 2
+ f100 0 0 0 &i8259 7 2
- /* IDSEL 0x16 */
- b000 0 0 1 &i8259 0 0
- b000 0 0 2 &i8259 0 0
- b000 0 0 3 &i8259 0 0
- b000 0 0 4 &i8259 0 0
-
- /* IDSEL 0x17 */
- b800 0 0 1 &i8259 0 0
- b800 0 0 2 &i8259 0 0
- b800 0 0 3 &i8259 0 0
- b800 0 0 4 &i8259 0 0
-
- /* IDSEL 0x18 */
- c000 0 0 1 &i8259 0 0
- c000 0 0 2 &i8259 0 0
- c000 0 0 3 &i8259 0 0
- c000 0 0 4 &i8259 0 0
-
- /* IDSEL 0x19 */
- c800 0 0 1 &i8259 0 0
- c800 0 0 2 &i8259 0 0
- c800 0 0 3 &i8259 0 0
- c800 0 0 4 &i8259 0 0
-
- /* IDSEL 0x1a */
- d000 0 0 1 &i8259 6 2
- d000 0 0 2 &i8259 3 2
- d000 0 0 3 &i8259 4 2
- d000 0 0 4 &i8259 5 2
-
-
- /* IDSEL 0x1b */
- d800 0 0 1 &i8259 5 2
- d800 0 0 2 &i8259 0 0
- d800 0 0 3 &i8259 0 0
- d800 0 0 4 &i8259 0 0
-
- /* IDSEL 0x1c */
- e000 0 0 1 &i8259 9 2
- e000 0 0 2 &i8259 a 2
- e000 0 0 3 &i8259 c 2
- e000 0 0 4 &i8259 7 2
-
- /* IDSEL 0x1d */
- e800 0 0 1 &i8259 9 2
- e800 0 0 2 &i8259 a 2
- e800 0 0 3 &i8259 b 2
- e800 0 0 4 &i8259 0 0
-
- /* IDSEL 0x1e */
- f000 0 0 1 &i8259 c 2
- f000 0 0 2 &i8259 0 0
- f000 0 0 3 &i8259 0 0
- f000 0 0 4 &i8259 0 0
-
- /* IDSEL 0x1f */
- f800 0 0 1 &i8259 6 2
- f800 0 0 2 &i8259 0 0
- f800 0 0 3 &i8259 0 0
- f800 0 0 4 &i8259 0 0
+ // IDSEL 0x1f IDE/SATA
+ f800 0 0 0 &i8259 e 2
+ f900 0 0 0 &i8259 5 2
>;
uli1575@0 {
reg = <0 0 0 0 0>;
diff --git a/arch/powerpc/boot/flatdevtree.c b/arch/powerpc/boot/flatdevtree.c
index b732644..13761bf 100644
--- a/arch/powerpc/boot/flatdevtree.c
+++ b/arch/powerpc/boot/flatdevtree.c
@@ -134,20 +134,6 @@
#define HDR_SIZE _ALIGN(sizeof(struct boot_param_header), 8)
#define EXPAND_INCR 1024 /* alloc this much extra when expanding */
-/* See if the regions are in the standard order and non-overlapping */
-static int ft_ordered(struct ft_cxt *cxt)
-{
- char *p = (char *)cxt->bph + HDR_SIZE;
- enum ft_rgn_id r;
-
- for (r = FT_RSVMAP; r <= FT_STRINGS; ++r) {
- if (p > cxt->rgn[r].start)
- return 0;
- p = cxt->rgn[r].start + cxt->rgn[r].size;
- }
- return p <= (char *)cxt->bph + cxt->max_size;
-}
-
/* Copy the tree to a newly-allocated region and put things in order */
static int ft_reorder(struct ft_cxt *cxt, int nextra)
{
@@ -573,10 +559,6 @@
cxt->rgn[FT_STRUCT].size = struct_size(cxt);
cxt->rgn[FT_STRINGS].start = blob + be32_to_cpu(bph->off_dt_strings);
cxt->rgn[FT_STRINGS].size = be32_to_cpu(bph->dt_strings_size);
- /* Leave as '0' to force first ft_make_space call to do a ft_reorder
- * and move dt to an area allocated by realloc.
- cxt->isordered = ft_ordered(cxt);
- */
cxt->p = cxt->rgn[FT_STRUCT].start;
cxt->str_anchor = cxt->rgn[FT_STRINGS].start;
diff --git a/arch/powerpc/configs/ps3_defconfig b/arch/powerpc/configs/ps3_defconfig
index d0b43df..ca7a197 100644
--- a/arch/powerpc/configs/ps3_defconfig
+++ b/arch/powerpc/configs/ps3_defconfig
@@ -1,9 +1,23 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.22-rc6
-# Tue Jun 26 14:15:19 2007
+# Linux kernel version: 2.6.23-rc2
+# Tue Aug 7 19:17:26 2007
#
CONFIG_PPC64=y
+
+#
+# Processor support
+#
+# CONFIG_POWER4_ONLY is not set
+CONFIG_POWER3=y
+CONFIG_POWER4=y
+CONFIG_PPC_FPU=y
+CONFIG_ALTIVEC=y
+CONFIG_PPC_STD_MMU=y
+# CONFIG_PPC_MM_SLICES is not set
+CONFIG_VIRT_CPU_ACCOUNTING=y
+CONFIG_SMP=y
+CONFIG_NR_CPUS=2
CONFIG_64BIT=y
CONFIG_PPC_MERGE=y
CONFIG_MMU=y
@@ -15,6 +29,7 @@
CONFIG_GENERIC_HWEIGHT=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
CONFIG_GENERIC_FIND_NEXT_BIT=y
+CONFIG_ARCH_NO_VIRT_TO_BUS=y
CONFIG_PPC=y
CONFIG_EARLY_PRINTK=y
CONFIG_COMPAT=y
@@ -22,50 +37,32 @@
CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
CONFIG_ARCH_MAY_HAVE_PC_FDC=y
CONFIG_PPC_OF=y
+CONFIG_OF=y
# CONFIG_PPC_UDBG_16550 is not set
# CONFIG_GENERIC_TBSYNC is not set
CONFIG_AUDIT_ARCH=y
CONFIG_GENERIC_BUG=y
# CONFIG_DEFAULT_UIMAGE is not set
-
-#
-# Processor support
-#
-# CONFIG_POWER4_ONLY is not set
-CONFIG_POWER3=y
-CONFIG_POWER4=y
-CONFIG_PPC_FPU=y
# CONFIG_PPC_DCR_NATIVE is not set
# CONFIG_PPC_DCR_MMIO is not set
# CONFIG_PPC_OF_PLATFORM_PCI is not set
-CONFIG_ALTIVEC=y
-CONFIG_PPC_STD_MMU=y
-# CONFIG_PPC_MM_SLICES is not set
-CONFIG_VIRT_CPU_ACCOUNTING=y
-CONFIG_SMP=y
-CONFIG_NR_CPUS=2
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
#
-# Code maturity level options
-#
-CONFIG_EXPERIMENTAL=y
-CONFIG_LOCK_KERNEL=y
-CONFIG_INIT_ENV_ARG_LIMIT=32
-
-#
# General setup
#
+CONFIG_EXPERIMENTAL=y
+CONFIG_LOCK_KERNEL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
CONFIG_LOCALVERSION=""
CONFIG_LOCALVERSION_AUTO=y
CONFIG_SWAP=y
CONFIG_SYSVIPC=y
-# CONFIG_IPC_NS is not set
CONFIG_SYSVIPC_SYSCTL=y
# CONFIG_POSIX_MQUEUE is not set
# CONFIG_BSD_PROCESS_ACCT is not set
# CONFIG_TASKSTATS is not set
-# CONFIG_UTS_NS is not set
+# CONFIG_USER_NS is not set
# CONFIG_AUDIT is not set
# CONFIG_IKCONFIG is not set
CONFIG_LOG_BUF_SHIFT=17
@@ -100,10 +97,6 @@
CONFIG_RT_MUTEXES=y
# CONFIG_TINY_SHMEM is not set
CONFIG_BASE_SMALL=0
-
-#
-# Loadable module support
-#
CONFIG_MODULES=y
CONFIG_MODULE_UNLOAD=y
# CONFIG_MODULE_FORCE_UNLOAD is not set
@@ -111,12 +104,9 @@
# CONFIG_MODULE_SRCVERSION_ALL is not set
CONFIG_KMOD=y
CONFIG_STOP_MACHINE=y
-
-#
-# Block layer
-#
CONFIG_BLOCK=y
# CONFIG_BLK_DEV_IO_TRACE is not set
+CONFIG_BLK_DEV_BSG=y
#
# IO Schedulers
@@ -136,7 +126,9 @@
#
CONFIG_PPC_MULTIPLATFORM=y
# CONFIG_EMBEDDED6xx is not set
-# CONFIG_APUS is not set
+# CONFIG_PPC_82xx is not set
+# CONFIG_PPC_83xx is not set
+# CONFIG_PPC_86xx is not set
# CONFIG_PPC_PSERIES is not set
# CONFIG_PPC_ISERIES is not set
# CONFIG_PPC_MPC52xx is not set
@@ -223,6 +215,7 @@
CONFIG_SPLIT_PTLOCK_CPUS=4
CONFIG_RESOURCES_64BIT=y
CONFIG_ZONE_DMA_FLAG=1
+CONFIG_BOUNCE=y
CONFIG_ARCH_MEMORY_PROBE=y
# CONFIG_PPC_HAS_HASH_64K is not set
# CONFIG_PPC_64K_PAGES is not set
@@ -241,6 +234,7 @@
CONFIG_GENERIC_ISA_DMA=y
# CONFIG_PCI is not set
# CONFIG_PCI_DOMAINS is not set
+# CONFIG_PCI_SYSCALL is not set
# CONFIG_ARCH_SUPPORTS_MSI is not set
#
@@ -365,6 +359,7 @@
# CONFIG_MAC80211 is not set
# CONFIG_IEEE80211 is not set
# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
#
# Device Drivers
@@ -379,26 +374,11 @@
# CONFIG_DEBUG_DRIVER is not set
# CONFIG_DEBUG_DEVRES is not set
# CONFIG_SYS_HYPERVISOR is not set
-
-#
-# Connector - unified userspace <-> kernelspace linker
-#
# CONFIG_CONNECTOR is not set
# CONFIG_MTD is not set
-
-#
-# Parallel port support
-#
+CONFIG_OF_DEVICE=y
# CONFIG_PARPORT is not set
-
-#
-# Plug and Play support
-#
-# CONFIG_PNPACPI is not set
-
-#
-# Block devices
-#
+CONFIG_BLK_DEV=y
# CONFIG_BLK_DEV_FD is not set
# CONFIG_BLK_DEV_COW_COMMON is not set
CONFIG_BLK_DEV_LOOP=y
@@ -411,11 +391,8 @@
CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
# CONFIG_CDROM_PKTCDVD is not set
# CONFIG_ATA_OVER_ETH is not set
-
-#
-# Misc devices
-#
-# CONFIG_BLINK is not set
+CONFIG_MISC_DEVICES=y
+# CONFIG_EEPROM_93CX6 is not set
# CONFIG_IDE is not set
#
@@ -423,6 +400,7 @@
#
# CONFIG_RAID_ATTRS is not set
CONFIG_SCSI=y
+CONFIG_SCSI_DMA=y
# CONFIG_SCSI_TGT is not set
# CONFIG_SCSI_NETLINK is not set
CONFIG_SCSI_PROC_FS=y
@@ -455,37 +433,22 @@
# CONFIG_SCSI_ISCSI_ATTRS is not set
# CONFIG_SCSI_SAS_ATTRS is not set
# CONFIG_SCSI_SAS_LIBSAS is not set
-
-#
-# SCSI low-level drivers
-#
-# CONFIG_ISCSI_TCP is not set
-# CONFIG_SCSI_DEBUG is not set
+# CONFIG_SCSI_LOWLEVEL is not set
# CONFIG_ATA is not set
-
-#
-# Multi-device support (RAID and LVM)
-#
# CONFIG_MD is not set
# CONFIG_MACINTOSH_DRIVERS is not set
-
-#
-# Network device support
-#
CONFIG_NETDEVICES=y
+# CONFIG_NETDEVICES_MULTIQUEUE is not set
# CONFIG_DUMMY is not set
# CONFIG_BONDING is not set
+# CONFIG_MACVLAN is not set
# CONFIG_EQUALIZER is not set
# CONFIG_TUN is not set
-
-#
-# Ethernet (10 or 100Mbit)
-#
# CONFIG_NET_ETHERNET is not set
CONFIG_MII=m
CONFIG_NETDEV_1000=y
-CONFIG_NETDEV_10000=y
CONFIG_GELIC_NET=y
+# CONFIG_NETDEV_10000 is not set
#
# Wireless LAN
@@ -518,15 +481,7 @@
# CONFIG_NETCONSOLE is not set
# CONFIG_NETPOLL is not set
# CONFIG_NET_POLL_CONTROLLER is not set
-
-#
-# ISDN subsystem
-#
# CONFIG_ISDN is not set
-
-#
-# Telephony Support
-#
# CONFIG_PHONE is not set
#
@@ -604,10 +559,6 @@
CONFIG_UNIX98_PTYS=y
CONFIG_LEGACY_PTYS=y
CONFIG_LEGACY_PTY_COUNT=16
-
-#
-# IPMI
-#
# CONFIG_IPMI_HANDLER is not set
# CONFIG_WATCHDOG is not set
# CONFIG_HW_RANDOM is not set
@@ -616,10 +567,6 @@
# CONFIG_R3964 is not set
# CONFIG_RAW_DRIVER is not set
# CONFIG_HANGCHECK_TIMER is not set
-
-#
-# TPM devices
-#
# CONFIG_TCG_TPM is not set
# CONFIG_I2C is not set
@@ -628,11 +575,8 @@
#
# CONFIG_SPI is not set
# CONFIG_SPI_MASTER is not set
-
-#
-# Dallas's 1-wire bus
-#
# CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
# CONFIG_HWMON is not set
#
@@ -657,6 +601,7 @@
#
# CONFIG_DISPLAY_SUPPORT is not set
# CONFIG_VGASTATE is not set
+CONFIG_VIDEO_OUTPUT_CONTROL=m
CONFIG_FB=y
# CONFIG_FIRMWARE_EDID is not set
# CONFIG_FB_DDC is not set
@@ -691,11 +636,13 @@
# CONFIG_VGA_CONSOLE is not set
CONFIG_DUMMY_CONSOLE=y
CONFIG_FRAMEBUFFER_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y
CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y
# CONFIG_FONTS is not set
CONFIG_FONT_8x8=y
CONFIG_FONT_8x16=y
CONFIG_LOGO=y
+CONFIG_FB_LOGO_EXTRA=y
# CONFIG_LOGO_LINUX_MONO is not set
# CONFIG_LOGO_LINUX_VGA16 is not set
CONFIG_LOGO_LINUX_CLUT224=y
@@ -709,6 +656,8 @@
# Advanced Linux Sound Architecture
#
CONFIG_SND=y
+CONFIG_SND_TIMER=y
+CONFIG_SND_PCM=y
# CONFIG_SND_SEQUENCER is not set
# CONFIG_SND_MIXER_OSS is not set
# CONFIG_SND_PCM_OSS is not set
@@ -735,6 +684,12 @@
#
#
+# ALSA PowerPC devices
+#
+CONFIG_SND_PS3=y
+CONFIG_SND_PS3_DEFAULT_START_DELAY=2000
+
+#
# USB devices
#
# CONFIG_SND_USB_AUDIO is not set
@@ -747,13 +702,14 @@
# CONFIG_SND_SOC is not set
#
+# SoC Audio support for SuperH
+#
+
+#
# Open Sound System
#
# CONFIG_SOUND_PRIME is not set
-
-#
-# HID Devices
-#
+CONFIG_HID_SUPPORT=y
CONFIG_HID=y
# CONFIG_HID_DEBUG is not set
@@ -770,10 +726,7 @@
#
# CONFIG_USB_KBD is not set
# CONFIG_USB_MOUSE is not set
-
-#
-# USB support
-#
+CONFIG_USB_SUPPORT=y
CONFIG_USB_ARCH_HAS_HCD=y
CONFIG_USB_ARCH_HAS_OHCI=y
CONFIG_USB_ARCH_HAS_EHCI=y
@@ -803,6 +756,7 @@
CONFIG_USB_OHCI_BIG_ENDIAN_MMIO=y
CONFIG_USB_OHCI_LITTLE_ENDIAN=y
# CONFIG_USB_SL811_HCD is not set
+# CONFIG_USB_R8A66597_HCD is not set
#
# USB Device Class drivers
@@ -879,31 +833,8 @@
#
# CONFIG_USB_GADGET is not set
# CONFIG_MMC is not set
-
-#
-# LED devices
-#
# CONFIG_NEW_LEDS is not set
-
-#
-# LED drivers
-#
-
-#
-# LED Triggers
-#
-
-#
-# InfiniBand support
-#
-
-#
-# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
-#
-
-#
-# Real Time Clock
-#
+# CONFIG_EDAC is not set
# CONFIG_RTC_CLASS is not set
#
@@ -920,6 +851,11 @@
#
#
+# Userspace I/O
+#
+# CONFIG_UIO is not set
+
+#
# File systems
#
CONFIG_EXT2_FS=m
@@ -948,8 +884,8 @@
CONFIG_QFMT_V2=y
CONFIG_QUOTACTL=y
CONFIG_DNOTIFY=y
-# CONFIG_AUTOFS_FS is not set
-CONFIG_AUTOFS4_FS=y
+CONFIG_AUTOFS_FS=m
+CONFIG_AUTOFS4_FS=m
# CONFIG_FUSE_FS is not set
#
@@ -1030,7 +966,6 @@
# CONFIG_NCP_FS is not set
# CONFIG_CODA_FS is not set
# CONFIG_AFS_FS is not set
-# CONFIG_9P_FS is not set
#
# Partition Types
@@ -1096,6 +1031,7 @@
# CONFIG_CRC16 is not set
# CONFIG_CRC_ITU_T is not set
CONFIG_CRC32=y
+# CONFIG_CRC7 is not set
# CONFIG_LIBCRC32C is not set
CONFIG_PLIST=y
CONFIG_HAS_IOMEM=y
@@ -1120,6 +1056,7 @@
CONFIG_DEBUG_KERNEL=y
# CONFIG_DEBUG_SHIRQ is not set
CONFIG_DETECT_SOFTLOCKUP=y
+CONFIG_SCHED_DEBUG=y
# CONFIG_SCHEDSTATS is not set
# CONFIG_TIMER_STATS is not set
# CONFIG_DEBUG_SLAB is not set
@@ -1150,10 +1087,6 @@
#
# CONFIG_KEYS is not set
# CONFIG_SECURITY is not set
-
-#
-# Cryptographic options
-#
CONFIG_CRYPTO=y
CONFIG_CRYPTO_ALGAPI=y
CONFIG_CRYPTO_BLKCIPHER=y
@@ -1191,7 +1124,4 @@
# CONFIG_CRYPTO_CRC32C is not set
# CONFIG_CRYPTO_CAMELLIA is not set
# CONFIG_CRYPTO_TEST is not set
-
-#
-# Hardware crypto devices
-#
+CONFIG_CRYPTO_HW=y
diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile
index f39a72f..b0cb2e6 100644
--- a/arch/powerpc/kernel/Makefile
+++ b/arch/powerpc/kernel/Makefile
@@ -81,6 +81,7 @@
endif
ifeq ($(CONFIG_PPC_ISERIES),y)
+CFLAGS_lparmap.s += -g0
extra-y += lparmap.s
$(obj)/head_64.o: $(obj)/lparmap.s
AFLAGS_head_64.o += -I$(obj)
diff --git a/arch/powerpc/kernel/head_64.S b/arch/powerpc/kernel/head_64.S
index 1448af9..1718000 100644
--- a/arch/powerpc/kernel/head_64.S
+++ b/arch/powerpc/kernel/head_64.S
@@ -1672,8 +1672,9 @@
* Are we booted from a PROM Of-type client-interface ?
*/
cmpldi cr0,r5,0
- bne .__boot_from_prom /* yes -> prom */
-
+ beq 1f
+ b .__boot_from_prom /* yes -> prom */
+1:
/* Save parameters */
mr r31,r3
mr r30,r4
@@ -1701,7 +1702,7 @@
bl .__mmu_off
b .__after_prom_start
-_STATIC(__boot_from_prom)
+_INIT_STATIC(__boot_from_prom)
/* Save parameters */
mr r31,r3
mr r30,r4
@@ -1768,9 +1769,10 @@
/* the source addr */
cmpdi r4,0 /* In some cases the loader may */
- beq .start_here_multiplatform /* have already put us at zero */
+ bne 1f
+ b .start_here_multiplatform /* have already put us at zero */
/* so we can skip the copy. */
- LOAD_REG_IMMEDIATE(r5,copy_to_here) /* # bytes of memory to copy */
+1: LOAD_REG_IMMEDIATE(r5,copy_to_here) /* # bytes of memory to copy */
sub r5,r5,r27
li r6,0x100 /* Start offset, the first 0x100 */
@@ -1957,7 +1959,7 @@
/*
* This is where the main kernel code starts.
*/
-_STATIC(start_here_multiplatform)
+_INIT_STATIC(start_here_multiplatform)
/* get a new offset, now that the kernel has moved. */
bl .reloc_offset
mr r26,r3
@@ -2019,7 +2021,7 @@
b . /* prevent speculative execution */
/* This is where all platforms converge execution */
-_STATIC(start_here_common)
+_INIT_STATIC(start_here_common)
/* relocation is on at this point */
/* The following code sets up the SP and TOC now that we are */
diff --git a/arch/powerpc/kernel/misc_32.S b/arch/powerpc/kernel/misc_32.S
index e708ab7..8533de5 100644
--- a/arch/powerpc/kernel/misc_32.S
+++ b/arch/powerpc/kernel/misc_32.S
@@ -301,9 +301,19 @@
mfspr r4,SPRN_MMUCR
mfspr r5,SPRN_PID /* Get PID */
rlwimi r4,r5,0,24,31 /* Set TID */
- mtspr SPRN_MMUCR,r4
+ /* We have to run the search with interrupts disabled, even critical
+ * and debug interrupts (in fact the only critical exceptions we have
+ * are debug and machine check). Otherwise an interrupt which causes
+ * a TLB miss can clobber the MMUCR between the mtspr and the tlbsx. */
+ mfmsr r5
+ lis r6,(MSR_EE|MSR_CE|MSR_ME|MSR_DE)@ha
+ addi r6,r6,(MSR_EE|MSR_CE|MSR_ME|MSR_DE)@l
+ andc r6,r5,r6
+ mtmsr r6
+ mtspr SPRN_MMUCR,r4
tlbsx. r3, 0, r3
+ mtmsr r5
bne 10f
sync
/* There are only 64 TLB entries, so r3 < 64,
diff --git a/arch/powerpc/kernel/pci_64.c b/arch/powerpc/kernel/pci_64.c
index a97e23a..291ffbc 100644
--- a/arch/powerpc/kernel/pci_64.c
+++ b/arch/powerpc/kernel/pci_64.c
@@ -313,6 +313,7 @@
dev->current_state = 4; /* unknown power state */
dev->error_state = pci_channel_io_normal;
+ dev->dma_mask = 0xffffffff;
if (!strcmp(type, "pci") || !strcmp(type, "pciex")) {
/* a PCI-PCI bridge */
diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c
index 2bb1cb9..d8502e3 100644
--- a/arch/powerpc/kernel/traps.c
+++ b/arch/powerpc/kernel/traps.c
@@ -299,7 +299,7 @@
#ifndef CONFIG_FSL_BOOKE
#define get_mc_reason(regs) ((regs)->dsisr)
#else
-#define get_mc_reason(regs) (mfspr(SPRN_MCSR))
+#define get_mc_reason(regs) (mfspr(SPRN_MCSR) & MCSR_MASK)
#endif
#define REASON_FP ESR_FP
#define REASON_ILLEGAL (ESR_PIL | ESR_PUO)
@@ -414,8 +414,6 @@
printk("Data Cache Push Parity Error\n");
if (reason & MCSR_DCPERR)
printk("Data Cache Parity Error\n");
- if (reason & MCSR_GL_CI)
- printk("Guarded Load or Cache-Inhibited stwcx.\n");
if (reason & MCSR_BUS_IAERR)
printk("Bus - Instruction Address Error\n");
if (reason & MCSR_BUS_RAERR)
diff --git a/arch/powerpc/mm/hash_utils_64.c b/arch/powerpc/mm/hash_utils_64.c
index f178957..a47151e 100644
--- a/arch/powerpc/mm/hash_utils_64.c
+++ b/arch/powerpc/mm/hash_utils_64.c
@@ -795,7 +795,7 @@
#ifdef CONFIG_PPC_MM_SLICES
/* We only prefault standard pages for now */
- if (unlikely(get_slice_psize(mm, ea) != mm->context.user_psize));
+ if (unlikely(get_slice_psize(mm, ea) != mm->context.user_psize))
return;
#endif
diff --git a/arch/powerpc/mm/slb.c b/arch/powerpc/mm/slb.c
index b069701..a73d2d7 100644
--- a/arch/powerpc/mm/slb.c
+++ b/arch/powerpc/mm/slb.c
@@ -69,20 +69,9 @@
smp_wmb();
}
-static inline void create_shadowed_slbe(unsigned long ea, unsigned long flags,
- unsigned long entry)
+static inline void slb_shadow_clear(unsigned long entry)
{
- /*
- * Updating the shadow buffer before writing the SLB ensures
- * we don't get a stale entry here if we get preempted by PHYP
- * between these two statements.
- */
- slb_shadow_update(ea, flags, entry);
-
- asm volatile("slbmte %0,%1" :
- : "r" (mk_vsid_data(ea, flags)),
- "r" (mk_esid_data(ea, entry))
- : "memory" );
+ get_slb_shadow()->save_area[entry].esid = 0;
}
void slb_flush_and_rebolt(void)
@@ -100,11 +89,13 @@
vflags = SLB_VSID_KERNEL | vmalloc_llp;
ksp_esid_data = mk_esid_data(get_paca()->kstack, 2);
- if ((ksp_esid_data & ESID_MASK) == PAGE_OFFSET)
+ if ((ksp_esid_data & ESID_MASK) == PAGE_OFFSET) {
ksp_esid_data &= ~SLB_ESID_V;
-
- /* Only third entry (stack) may change here so only resave that */
- slb_shadow_update(get_paca()->kstack, lflags, 2);
+ slb_shadow_clear(2);
+ } else {
+ /* Update stack entry; others don't change */
+ slb_shadow_update(get_paca()->kstack, lflags, 2);
+ }
/* We need to do this all in asm, so we're sure we don't touch
* the stack between the slbia and rebolting it. */
@@ -235,16 +226,12 @@
vflags = SLB_VSID_KERNEL | vmalloc_llp;
/* Invalidate the entire SLB (even slot 0) & all the ERATS */
- asm volatile("isync":::"memory");
- asm volatile("slbmte %0,%0"::"r" (0) : "memory");
- asm volatile("isync; slbia; isync":::"memory");
- create_shadowed_slbe(PAGE_OFFSET, lflags, 0);
+ slb_shadow_update(PAGE_OFFSET, lflags, 0);
+ asm volatile("isync; slbia; sync; slbmte %0,%1; isync" ::
+ "r" (get_slb_shadow()->save_area[0].vsid),
+ "r" (get_slb_shadow()->save_area[0].esid) : "memory");
- create_shadowed_slbe(VMALLOC_START, vflags, 1);
+ slb_shadow_update(VMALLOC_START, vflags, 1);
- /* We don't bolt the stack for the time being - we're in boot,
- * so the stack is in the bolted segment. By the time it goes
- * elsewhere, we'll call _switch() which will bolt in the new
- * one. */
- asm volatile("isync":::"memory");
+ slb_flush_and_rebolt();
}
diff --git a/arch/powerpc/mm/slice.c b/arch/powerpc/mm/slice.c
index f833dba..d5fd390 100644
--- a/arch/powerpc/mm/slice.c
+++ b/arch/powerpc/mm/slice.c
@@ -405,6 +405,8 @@
if (len > mm->task_size)
return -ENOMEM;
+ if (len & ((1ul << pshift) - 1))
+ return -EINVAL;
if (fixed && (addr & ((1ul << pshift) - 1)))
return -EINVAL;
if (fixed && addr > (mm->task_size - len))
diff --git a/arch/powerpc/platforms/83xx/mpc832x_mds.c b/arch/powerpc/platforms/83xx/mpc832x_mds.c
index b39cb52..2c8e641 100644
--- a/arch/powerpc/platforms/83xx/mpc832x_mds.c
+++ b/arch/powerpc/platforms/83xx/mpc832x_mds.c
@@ -106,7 +106,6 @@
{ .type = "soc", },
{ .compatible = "soc", },
{ .type = "qe", },
- { .type = "mdio", },
{},
};
diff --git a/arch/powerpc/platforms/83xx/mpc832x_rdb.c b/arch/powerpc/platforms/83xx/mpc832x_rdb.c
index b2b28a4..0909061 100644
--- a/arch/powerpc/platforms/83xx/mpc832x_rdb.c
+++ b/arch/powerpc/platforms/83xx/mpc832x_rdb.c
@@ -70,7 +70,6 @@
{ .type = "soc", },
{ .compatible = "soc", },
{ .type = "qe", },
- { .type = "mdio", },
{},
};
diff --git a/arch/powerpc/platforms/83xx/mpc836x_mds.c b/arch/powerpc/platforms/83xx/mpc836x_mds.c
index 0e615fd..84b5893 100644
--- a/arch/powerpc/platforms/83xx/mpc836x_mds.c
+++ b/arch/powerpc/platforms/83xx/mpc836x_mds.c
@@ -113,7 +113,6 @@
{ .type = "soc", },
{ .compatible = "soc", },
{ .type = "qe", },
- { .type = "mdio", },
{},
};
diff --git a/arch/powerpc/platforms/85xx/Kconfig b/arch/powerpc/platforms/85xx/Kconfig
index f581840..f620171 100644
--- a/arch/powerpc/platforms/85xx/Kconfig
+++ b/arch/powerpc/platforms/85xx/Kconfig
@@ -33,6 +33,7 @@
bool "Freescale MPC8544 DS"
select PPC_I8259
select DEFAULT_UIMAGE
+ select FSL_ULI1575
help
This option enables support for the MPC8544 DS board
diff --git a/arch/powerpc/platforms/85xx/mpc8544_ds.c b/arch/powerpc/platforms/85xx/mpc8544_ds.c
index 4905f6f..0f834d8 100644
--- a/arch/powerpc/platforms/85xx/mpc8544_ds.c
+++ b/arch/powerpc/platforms/85xx/mpc8544_ds.c
@@ -114,211 +114,25 @@
}
#ifdef CONFIG_PCI
-enum pirq { PIRQA = 8, PIRQB, PIRQC, PIRQD, PIRQE, PIRQF, PIRQG, PIRQH };
+extern int uses_fsl_uli_m1575;
+extern int uli_exclude_device(struct pci_controller *hose,
+ u_char bus, u_char devfn);
-/*
- * Value in table -- IRQ number
- */
-const unsigned char uli1575_irq_route_table[16] = {
- 0, /* 0: Reserved */
- 0x8,
- 0, /* 2: Reserved */
- 0x2,
- 0x4,
- 0x5,
- 0x7,
- 0x6,
- 0, /* 8: Reserved */
- 0x1,
- 0x3,
- 0x9,
- 0xb,
- 0, /* 13: Reserved */
- 0xd,
- 0xf,
-};
-
-static int __devinit
-get_pci_irq_from_of(struct pci_controller *hose, int slot, int pin)
+static int mpc85xx_exclude_device(struct pci_controller *hose,
+ u_char bus, u_char devfn)
{
- struct of_irq oirq;
- u32 laddr[3];
- struct device_node *hosenode = hose ? hose->arch_data : NULL;
+ struct device_node* node;
+ struct resource rsrc;
- if (!hosenode)
- return -EINVAL;
+ node = (struct device_node *)hose->arch_data;
+ of_address_to_resource(node, 0, &rsrc);
- laddr[0] = (hose->first_busno << 16) | (PCI_DEVFN(slot, 0) << 8);
- laddr[1] = laddr[2] = 0;
- of_irq_map_raw(hosenode, &pin, 1, laddr, &oirq);
- DBG("mpc8544_ds: pci irq addr %x, slot %d, pin %d, irq %d\n",
- laddr[0], slot, pin, oirq.specifier[0]);
- return oirq.specifier[0];
+ if ((rsrc.start & 0xfffff) == 0xb000) {
+ return uli_exclude_device(hose, bus, devfn);
+ }
+
+ return PCIBIOS_SUCCESSFUL;
}
-
-/*8259*/
-static void __devinit quirk_uli1575(struct pci_dev *dev)
-{
- unsigned short temp;
- struct pci_controller *hose = pci_bus_to_host(dev->bus);
- unsigned char irq2pin[16];
- unsigned long pirq_map_word = 0;
- u32 irq;
- int i;
-
- /*
- * ULI1575 interrupts route setup
- */
- memset(irq2pin, 0, 16); /* Initialize default value 0 */
-
- irq2pin[6]=PIRQA+3; /* enabled mapping for IRQ6 to PIRQD, used by SATA */
-
- /*
- * PIRQE -> PIRQF mapping set manually
- *
- * IRQ pin IRQ#
- * PIRQE ---- 9
- * PIRQF ---- 10
- * PIRQG ---- 11
- * PIRQH ---- 12
- */
- for (i = 0; i < 4; i++)
- irq2pin[i + 9] = PIRQE + i;
-
- /* Set IRQ-PIRQ Mapping to ULI1575 */
- for (i = 0; i < 16; i++)
- if (irq2pin[i])
- pirq_map_word |= (uli1575_irq_route_table[i] & 0xf)
- << ((irq2pin[i] - PIRQA) * 4);
-
- pirq_map_word |= 1<<26; /* disable INTx in EP mode*/
-
- /* ULI1575 IRQ mapping conf register default value is 0xb9317542 */
- DBG("Setup ULI1575 IRQ mapping configuration register value = 0x%x\n",
- (int)pirq_map_word);
- pci_write_config_dword(dev, 0x48, pirq_map_word);
-
-#define ULI1575_SET_DEV_IRQ(slot, pin, reg) \
- do { \
- int irq; \
- irq = get_pci_irq_from_of(hose, slot, pin); \
- if (irq > 0 && irq < 16) \
- pci_write_config_byte(dev, reg, irq2pin[irq]); \
- else \
- printk(KERN_WARNING "ULI1575 device" \
- "(slot %d, pin %d) irq %d is invalid.\n", \
- slot, pin, irq); \
- } while(0)
-
- /* USB 1.1 OHCI controller 1, slot 28, pin 1 */
- ULI1575_SET_DEV_IRQ(28, 1, 0x86);
-
- /* USB 1.1 OHCI controller 2, slot 28, pin 2 */
- ULI1575_SET_DEV_IRQ(28, 2, 0x87);
-
- /* USB 1.1 OHCI controller 3, slot 28, pin 3 */
- ULI1575_SET_DEV_IRQ(28, 3, 0x88);
-
- /* USB 2.0 controller, slot 28, pin 4 */
- irq = get_pci_irq_from_of(hose, 28, 4);
- if (irq >= 0 && irq <= 15)
- pci_write_config_dword(dev, 0x74, uli1575_irq_route_table[irq]);
-
- /* Audio controller, slot 29, pin 1 */
- ULI1575_SET_DEV_IRQ(29, 1, 0x8a);
-
- /* Modem controller, slot 29, pin 2 */
- ULI1575_SET_DEV_IRQ(29, 2, 0x8b);
-
- /* HD audio controller, slot 29, pin 3 */
- ULI1575_SET_DEV_IRQ(29, 3, 0x8c);
-
- /* SMB interrupt: slot 30, pin 1 */
- ULI1575_SET_DEV_IRQ(30, 1, 0x8e);
-
- /* PMU ACPI SCI interrupt: slot 30, pin 2 */
- ULI1575_SET_DEV_IRQ(30, 2, 0x8f);
-
- /* Serial ATA interrupt: slot 31, pin 1 */
- ULI1575_SET_DEV_IRQ(31, 1, 0x8d);
-
- /* Primary PATA IDE IRQ: 14
- * Secondary PATA IDE IRQ: 15
- */
- pci_write_config_byte(dev, 0x44, 0x30 | uli1575_irq_route_table[14]);
- pci_write_config_byte(dev, 0x75, uli1575_irq_route_table[15]);
-
- /* Set IRQ14 and IRQ15 to legacy IRQs */
- pci_read_config_word(dev, 0x46, &temp);
- temp |= 0xc000;
- pci_write_config_word(dev, 0x46, temp);
-
- /* Set i8259 interrupt trigger
- * IRQ 3: Level
- * IRQ 4: Level
- * IRQ 5: Level
- * IRQ 6: Level
- * IRQ 7: Level
- * IRQ 9: Level
- * IRQ 10: Level
- * IRQ 11: Level
- * IRQ 12: Level
- * IRQ 14: Edge
- * IRQ 15: Edge
- */
- outb(0xfa, 0x4d0);
- outb(0x1e, 0x4d1);
-
-#undef ULI1575_SET_DEV_IRQ
-}
-
-/* SATA */
-static void __devinit quirk_uli5288(struct pci_dev *dev)
-{
- unsigned char c;
-
- pci_read_config_byte(dev, 0x83, &c);
- c |= 0x80; /* read/write lock */
- pci_write_config_byte(dev, 0x83, c);
-
- pci_write_config_byte(dev, 0x09, 0x01); /* Base class code: storage */
- pci_write_config_byte(dev, 0x0a, 0x06); /* IDE disk */
-
- pci_read_config_byte(dev, 0x83, &c);
- c &= 0x7f;
- pci_write_config_byte(dev, 0x83, c);
-
- pci_read_config_byte(dev, 0x84, &c);
- c |= 0x01; /* emulated PATA mode enabled */
- pci_write_config_byte(dev, 0x84, c);
-}
-
-/* PATA */
-static void __devinit quirk_uli5229(struct pci_dev *dev)
-{
- unsigned short temp;
- pci_write_config_word(dev, 0x04, 0x0405); /* MEM IO MSI */
- pci_read_config_word(dev, 0x4a, &temp);
- temp |= 0x1000; /* Enable Native IRQ 14/15 */
- pci_write_config_word(dev, 0x4a, temp);
-}
-
-/*Bridge*/
-static void __devinit early_uli5249(struct pci_dev *dev)
-{
- unsigned char temp;
- pci_write_config_word(dev, 0x04, 0x0007); /* mem access */
- pci_read_config_byte(dev, 0x7c, &temp);
- pci_write_config_byte(dev, 0x7c, 0x80); /* R/W lock control */
- pci_write_config_byte(dev, 0x09, 0x01); /* set as pci-pci bridge */
- pci_write_config_byte(dev, 0x7c, temp); /* restore pci bus debug control */
- dev->class |= 0x1;
-}
-
-DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AL, 0x1575, quirk_uli1575);
-DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AL, 0x5288, quirk_uli5288);
-DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AL, 0x5229, quirk_uli5229);
-DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_AL, 0x5249, early_uli5249);
#endif /* CONFIG_PCI */
/*
@@ -342,6 +156,8 @@
else
fsl_add_bridge(np, 0);
}
+ uses_fsl_uli_m1575 = 1;
+ ppc_md.pci_exclude_device = mpc85xx_exclude_device;
#endif
printk("MPC8544 DS board from Freescale Semiconductor\n");
diff --git a/arch/powerpc/platforms/85xx/mpc85xx_mds.c b/arch/powerpc/platforms/85xx/mpc85xx_mds.c
index e8003bf..be25ecd 100644
--- a/arch/powerpc/platforms/85xx/mpc85xx_mds.c
+++ b/arch/powerpc/platforms/85xx/mpc85xx_mds.c
@@ -142,7 +142,6 @@
{ .type = "soc", },
{ .compatible = "soc", },
{ .type = "qe", },
- { .type = "mdio", },
{},
};
diff --git a/arch/powerpc/platforms/86xx/Kconfig b/arch/powerpc/platforms/86xx/Kconfig
index 343b76d..685b2fb 100644
--- a/arch/powerpc/platforms/86xx/Kconfig
+++ b/arch/powerpc/platforms/86xx/Kconfig
@@ -7,6 +7,7 @@
bool "Freescale MPC8641 HPCN"
select PPC_I8259
select DEFAULT_UIMAGE
+ select FSL_ULI1575
help
This option enables support for the MPC8641 HPCN board.
diff --git a/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c b/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c
index e9eaa07..56b27ca 100644
--- a/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c
+++ b/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c
@@ -107,220 +107,25 @@
}
#ifdef CONFIG_PCI
+extern int uses_fsl_uli_m1575;
+extern int uli_exclude_device(struct pci_controller *hose,
+ u_char bus, u_char devfn);
-enum pirq{PIRQA = 8, PIRQB, PIRQC, PIRQD, PIRQE, PIRQF, PIRQG, PIRQH};
-const unsigned char uli1575_irq_route_table[16] = {
- 0, /* 0: Reserved */
- 0x8, /* 1: 0b1000 */
- 0, /* 2: Reserved */
- 0x2, /* 3: 0b0010 */
- 0x4, /* 4: 0b0100 */
- 0x5, /* 5: 0b0101 */
- 0x7, /* 6: 0b0111 */
- 0x6, /* 7: 0b0110 */
- 0, /* 8: Reserved */
- 0x1, /* 9: 0b0001 */
- 0x3, /* 10: 0b0011 */
- 0x9, /* 11: 0b1001 */
- 0xb, /* 12: 0b1011 */
- 0, /* 13: Reserved */
- 0xd, /* 14, 0b1101 */
- 0xf, /* 15, 0b1111 */
-};
-
-static int __devinit
-get_pci_irq_from_of(struct pci_controller *hose, int slot, int pin)
+static int mpc86xx_exclude_device(struct pci_controller *hose,
+ u_char bus, u_char devfn)
{
- struct of_irq oirq;
- u32 laddr[3];
- struct device_node *hosenode = hose ? hose->arch_data : NULL;
+ struct device_node* node;
+ struct resource rsrc;
- if (!hosenode) return -EINVAL;
+ node = (struct device_node *)hose->arch_data;
+ of_address_to_resource(node, 0, &rsrc);
- laddr[0] = (hose->first_busno << 16) | (PCI_DEVFN(slot, 0) << 8);
- laddr[1] = laddr[2] = 0;
- of_irq_map_raw(hosenode, &pin, 1, laddr, &oirq);
- DBG("mpc86xx_hpcn: pci irq addr %x, slot %d, pin %d, irq %d\n",
- laddr[0], slot, pin, oirq.specifier[0]);
- return oirq.specifier[0];
-}
-
-static void __devinit quirk_uli1575(struct pci_dev *dev)
-{
- unsigned short temp;
- struct pci_controller *hose = pci_bus_to_host(dev->bus);
- unsigned char irq2pin[16], c;
- unsigned long pirq_map_word = 0;
- u32 irq;
- int i;
-
- /*
- * ULI1575 interrupts route setup
- */
- memset(irq2pin, 0, 16); /* Initialize default value 0 */
-
- /*
- * PIRQA -> PIRQD mapping read from OF-tree
- *
- * interrupts for PCI slot0 -- PIRQA / PIRQB / PIRQC / PIRQD
- * PCI slot1 -- PIRQB / PIRQC / PIRQD / PIRQA
- */
- for (i = 0; i < 4; i++){
- irq = get_pci_irq_from_of(hose, 17, i + 1);
- if (irq > 0 && irq < 16)
- irq2pin[irq] = PIRQA + i;
- else
- printk(KERN_WARNING "ULI1575 device"
- "(slot %d, pin %d) irq %d is invalid.\n",
- 17, i, irq);
+ if ((rsrc.start & 0xfffff) == 0x8000) {
+ return uli_exclude_device(hose, bus, devfn);
}
- /*
- * PIRQE -> PIRQF mapping set manually
- *
- * IRQ pin IRQ#
- * PIRQE ---- 9
- * PIRQF ---- 10
- * PIRQG ---- 11
- * PIRQH ---- 12
- */
- for (i = 0; i < 4; i++) irq2pin[i + 9] = PIRQE + i;
-
- /* Set IRQ-PIRQ Mapping to ULI1575 */
- for (i = 0; i < 16; i++)
- if (irq2pin[i])
- pirq_map_word |= (uli1575_irq_route_table[i] & 0xf)
- << ((irq2pin[i] - PIRQA) * 4);
-
- /* ULI1575 IRQ mapping conf register default value is 0xb9317542 */
- DBG("Setup ULI1575 IRQ mapping configuration register value = 0x%x\n",
- pirq_map_word);
- pci_write_config_dword(dev, 0x48, pirq_map_word);
-
-#define ULI1575_SET_DEV_IRQ(slot, pin, reg) \
- do { \
- int irq; \
- irq = get_pci_irq_from_of(hose, slot, pin); \
- if (irq > 0 && irq < 16) \
- pci_write_config_byte(dev, reg, irq2pin[irq]); \
- else \
- printk(KERN_WARNING "ULI1575 device" \
- "(slot %d, pin %d) irq %d is invalid.\n", \
- slot, pin, irq); \
- } while(0)
-
- /* USB 1.1 OHCI controller 1, slot 28, pin 1 */
- ULI1575_SET_DEV_IRQ(28, 1, 0x86);
-
- /* USB 1.1 OHCI controller 2, slot 28, pin 2 */
- ULI1575_SET_DEV_IRQ(28, 2, 0x87);
-
- /* USB 1.1 OHCI controller 3, slot 28, pin 3 */
- ULI1575_SET_DEV_IRQ(28, 3, 0x88);
-
- /* USB 2.0 controller, slot 28, pin 4 */
- irq = get_pci_irq_from_of(hose, 28, 4);
- if (irq >= 0 && irq <=15)
- pci_write_config_dword(dev, 0x74, uli1575_irq_route_table[irq]);
-
- /* Audio controller, slot 29, pin 1 */
- ULI1575_SET_DEV_IRQ(29, 1, 0x8a);
-
- /* Modem controller, slot 29, pin 2 */
- ULI1575_SET_DEV_IRQ(29, 2, 0x8b);
-
- /* HD audio controller, slot 29, pin 3 */
- ULI1575_SET_DEV_IRQ(29, 3, 0x8c);
-
- /* SMB interrupt: slot 30, pin 1 */
- ULI1575_SET_DEV_IRQ(30, 1, 0x8e);
-
- /* PMU ACPI SCI interrupt: slot 30, pin 2 */
- ULI1575_SET_DEV_IRQ(30, 2, 0x8f);
-
- /* Serial ATA interrupt: slot 31, pin 1 */
- ULI1575_SET_DEV_IRQ(31, 1, 0x8d);
-
- /* Primary PATA IDE IRQ: 14
- * Secondary PATA IDE IRQ: 15
- */
- pci_write_config_byte(dev, 0x44, 0x30 | uli1575_irq_route_table[14]);
- pci_write_config_byte(dev, 0x75, uli1575_irq_route_table[15]);
-
- /* Set IRQ14 and IRQ15 to legacy IRQs */
- pci_read_config_word(dev, 0x46, &temp);
- temp |= 0xc000;
- pci_write_config_word(dev, 0x46, temp);
-
- /* Set i8259 interrupt trigger
- * IRQ 3: Level
- * IRQ 4: Level
- * IRQ 5: Level
- * IRQ 6: Level
- * IRQ 7: Level
- * IRQ 9: Level
- * IRQ 10: Level
- * IRQ 11: Level
- * IRQ 12: Level
- * IRQ 14: Edge
- * IRQ 15: Edge
- */
- outb(0xfa, 0x4d0);
- outb(0x1e, 0x4d1);
-
-#undef ULI1575_SET_DEV_IRQ
-
- /* Disable the HD interface and enable the AC97 interface. */
- pci_read_config_byte(dev, 0xb8, &c);
- c &= 0x7f;
- pci_write_config_byte(dev, 0xb8, c);
+ return PCIBIOS_SUCCESSFUL;
}
-
-static void __devinit quirk_uli5288(struct pci_dev *dev)
-{
- unsigned char c;
-
- pci_read_config_byte(dev,0x83,&c);
- c |= 0x80;
- pci_write_config_byte(dev, 0x83, c);
-
- pci_write_config_byte(dev, 0x09, 0x01);
- pci_write_config_byte(dev, 0x0a, 0x06);
-
- pci_read_config_byte(dev,0x83,&c);
- c &= 0x7f;
- pci_write_config_byte(dev, 0x83, c);
-
- pci_read_config_byte(dev,0x84,&c);
- c |= 0x01;
- pci_write_config_byte(dev, 0x84, c);
-}
-
-static void __devinit quirk_uli5229(struct pci_dev *dev)
-{
- unsigned short temp;
- pci_write_config_word(dev, 0x04, 0x0405);
- dev->class &= ~0x5;
- pci_read_config_word(dev, 0x4a, &temp);
- temp |= 0x1000;
- pci_write_config_word(dev, 0x4a, temp);
-}
-
-static void __devinit early_uli5249(struct pci_dev *dev)
-{
- unsigned char temp;
- pci_write_config_word(dev, 0x04, 0x0007);
- pci_read_config_byte(dev, 0x7c, &temp);
- pci_write_config_byte(dev, 0x7c, 0x80);
- pci_write_config_byte(dev, 0x09, 0x01);
- pci_write_config_byte(dev, 0x7c, temp);
- dev->class |= 0x1;
-}
-
-DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AL, 0x1575, quirk_uli1575);
-DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AL, 0x5288, quirk_uli5288);
-DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AL, 0x5229, quirk_uli5229);
-DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_AL, 0x5249, early_uli5249);
#endif /* CONFIG_PCI */
@@ -353,6 +158,9 @@
else
fsl_add_bridge(np, 0);
}
+ uses_fsl_uli_m1575 = 1;
+ ppc_md.pci_exclude_device = mpc86xx_exclude_device;
+
#endif
printk("MPC86xx HPCN board from Freescale Semiconductor\n");
diff --git a/arch/powerpc/platforms/Kconfig b/arch/powerpc/platforms/Kconfig
index 932538a..cfc2497 100644
--- a/arch/powerpc/platforms/Kconfig
+++ b/arch/powerpc/platforms/Kconfig
@@ -282,4 +282,12 @@
minor numbers are available in /proc/devices, /proc/partitions or
in /sys/block/axonram?/dev.
+config FSL_ULI1575
+ bool
+ default n
+ help
+ Supports for the ULI1575 PCIe south bridge that exists on some
+ Freescale reference boards. The boards all use the ULI in pretty
+ much the same way.
+
endmenu
diff --git a/arch/powerpc/platforms/Makefile b/arch/powerpc/platforms/Makefile
index d6e041a..d44e832 100644
--- a/arch/powerpc/platforms/Makefile
+++ b/arch/powerpc/platforms/Makefile
@@ -1,3 +1,6 @@
+
+obj-$(CONFIG_FSL_ULI1575) += fsl_uli1575.o
+
ifeq ($(CONFIG_PPC_MERGE),y)
obj-$(CONFIG_PPC_PMAC) += powermac/
else
diff --git a/arch/powerpc/platforms/cell/spu_base.c b/arch/powerpc/platforms/cell/spu_base.c
index 9012422..095a303 100644
--- a/arch/powerpc/platforms/cell/spu_base.c
+++ b/arch/powerpc/platforms/cell/spu_base.c
@@ -36,7 +36,6 @@
#include <asm/spu_priv1.h>
#include <asm/xmon.h>
#include <asm/prom.h>
-#include "spu_priv1_mmio.h"
const struct spu_management_ops *spu_management_ops;
EXPORT_SYMBOL_GPL(spu_management_ops);
@@ -636,138 +635,6 @@
static SYSDEV_ATTR(stat, 0644, spu_stat_show, NULL);
-/* Hardcoded affinity idxs for QS20 */
-#define SPES_PER_BE 8
-static int QS20_reg_idxs[SPES_PER_BE] = { 0, 2, 4, 6, 7, 5, 3, 1 };
-static int QS20_reg_memory[SPES_PER_BE] = { 1, 1, 0, 0, 0, 0, 0, 0 };
-
-static struct spu *spu_lookup_reg(int node, u32 reg)
-{
- struct spu *spu;
-
- list_for_each_entry(spu, &cbe_spu_info[node].spus, cbe_list) {
- if (*(u32 *)get_property(spu_devnode(spu), "reg", NULL) == reg)
- return spu;
- }
- return NULL;
-}
-
-static void init_aff_QS20_harcoded(void)
-{
- int node, i;
- struct spu *last_spu, *spu;
- u32 reg;
-
- for (node = 0; node < MAX_NUMNODES; node++) {
- last_spu = NULL;
- for (i = 0; i < SPES_PER_BE; i++) {
- reg = QS20_reg_idxs[i];
- spu = spu_lookup_reg(node, reg);
- if (!spu)
- continue;
- spu->has_mem_affinity = QS20_reg_memory[reg];
- if (last_spu)
- list_add_tail(&spu->aff_list,
- &last_spu->aff_list);
- last_spu = spu;
- }
- }
-}
-
-static int of_has_vicinity(void)
-{
- struct spu* spu;
-
- spu = list_entry(cbe_spu_info[0].spus.next, struct spu, cbe_list);
- return of_find_property(spu_devnode(spu), "vicinity", NULL) != NULL;
-}
-
-static struct spu *aff_devnode_spu(int cbe, struct device_node *dn)
-{
- struct spu *spu;
-
- list_for_each_entry(spu, &cbe_spu_info[cbe].spus, cbe_list)
- if (spu_devnode(spu) == dn)
- return spu;
- return NULL;
-}
-
-static struct spu *
-aff_node_next_to(int cbe, struct device_node *target, struct device_node *avoid)
-{
- struct spu *spu;
- const phandle *vic_handles;
- int lenp, i;
-
- list_for_each_entry(spu, &cbe_spu_info[cbe].spus, cbe_list) {
- if (spu_devnode(spu) == avoid)
- continue;
- vic_handles = get_property(spu_devnode(spu), "vicinity", &lenp);
- for (i=0; i < (lenp / sizeof(phandle)); i++) {
- if (vic_handles[i] == target->linux_phandle)
- return spu;
- }
- }
- return NULL;
-}
-
-static void init_aff_fw_vicinity_node(int cbe)
-{
- struct spu *spu, *last_spu;
- struct device_node *vic_dn, *last_spu_dn;
- phandle avoid_ph;
- const phandle *vic_handles;
- const char *name;
- int lenp, i, added, mem_aff;
-
- last_spu = list_entry(cbe_spu_info[cbe].spus.next, struct spu, cbe_list);
- avoid_ph = 0;
- for (added = 1; added < cbe_spu_info[cbe].n_spus; added++) {
- last_spu_dn = spu_devnode(last_spu);
- vic_handles = get_property(last_spu_dn, "vicinity", &lenp);
-
- for (i = 0; i < (lenp / sizeof(phandle)); i++) {
- if (vic_handles[i] == avoid_ph)
- continue;
-
- vic_dn = of_find_node_by_phandle(vic_handles[i]);
- if (!vic_dn)
- continue;
-
- name = get_property(vic_dn, "name", NULL);
- if (strcmp(name, "spe") == 0) {
- spu = aff_devnode_spu(cbe, vic_dn);
- avoid_ph = last_spu_dn->linux_phandle;
- }
- else {
- mem_aff = strcmp(name, "mic-tm") == 0;
- spu = aff_node_next_to(cbe, vic_dn, last_spu_dn);
- if (!spu)
- continue;
- if (mem_aff) {
- last_spu->has_mem_affinity = 1;
- spu->has_mem_affinity = 1;
- }
- avoid_ph = vic_dn->linux_phandle;
- }
- list_add_tail(&spu->aff_list, &last_spu->aff_list);
- last_spu = spu;
- break;
- }
- }
-}
-
-static void init_aff_fw_vicinity(void)
-{
- int cbe;
-
- /* sets has_mem_affinity for each spu, as long as the
- * spu->aff_list list, linking each spu to its neighbors
- */
- for (cbe = 0; cbe < MAX_NUMNODES; cbe++)
- init_aff_fw_vicinity_node(cbe);
-}
-
static int __init init_spu_base(void)
{
int i, ret = 0;
@@ -811,13 +678,7 @@
mutex_unlock(&spu_full_list_mutex);
spu_add_sysdev_attr(&attr_stat);
- if (of_has_vicinity()) {
- init_aff_fw_vicinity();
- } else {
- long root = of_get_flat_dt_root();
- if (of_flat_dt_is_compatible(root, "IBM,CPBW-1.0"))
- init_aff_QS20_harcoded();
- }
+ spu_init_affinity();
return 0;
diff --git a/arch/powerpc/platforms/cell/spu_manage.c b/arch/powerpc/platforms/cell/spu_manage.c
index 75ed50f..5eb8834 100644
--- a/arch/powerpc/platforms/cell/spu_manage.c
+++ b/arch/powerpc/platforms/cell/spu_manage.c
@@ -361,8 +361,171 @@
return 0;
}
+/* Hardcoded affinity idxs for qs20 */
+#define QS20_SPES_PER_BE 8
+static int qs20_reg_idxs[QS20_SPES_PER_BE] = { 0, 2, 4, 6, 7, 5, 3, 1 };
+static int qs20_reg_memory[QS20_SPES_PER_BE] = { 1, 1, 0, 0, 0, 0, 0, 0 };
+
+static struct spu *spu_lookup_reg(int node, u32 reg)
+{
+ struct spu *spu;
+ u32 *spu_reg;
+
+ list_for_each_entry(spu, &cbe_spu_info[node].spus, cbe_list) {
+ spu_reg = (u32*)of_get_property(spu_devnode(spu), "reg", NULL);
+ if (*spu_reg == reg)
+ return spu;
+ }
+ return NULL;
+}
+
+static void init_affinity_qs20_harcoded(void)
+{
+ int node, i;
+ struct spu *last_spu, *spu;
+ u32 reg;
+
+ for (node = 0; node < MAX_NUMNODES; node++) {
+ last_spu = NULL;
+ for (i = 0; i < QS20_SPES_PER_BE; i++) {
+ reg = qs20_reg_idxs[i];
+ spu = spu_lookup_reg(node, reg);
+ if (!spu)
+ continue;
+ spu->has_mem_affinity = qs20_reg_memory[reg];
+ if (last_spu)
+ list_add_tail(&spu->aff_list,
+ &last_spu->aff_list);
+ last_spu = spu;
+ }
+ }
+}
+
+static int of_has_vicinity(void)
+{
+ struct spu* spu;
+
+ spu = list_first_entry(&cbe_spu_info[0].spus, struct spu, cbe_list);
+ return of_find_property(spu_devnode(spu), "vicinity", NULL) != NULL;
+}
+
+static struct spu *devnode_spu(int cbe, struct device_node *dn)
+{
+ struct spu *spu;
+
+ list_for_each_entry(spu, &cbe_spu_info[cbe].spus, cbe_list)
+ if (spu_devnode(spu) == dn)
+ return spu;
+ return NULL;
+}
+
+static struct spu *
+neighbour_spu(int cbe, struct device_node *target, struct device_node *avoid)
+{
+ struct spu *spu;
+ struct device_node *spu_dn;
+ const phandle *vic_handles;
+ int lenp, i;
+
+ list_for_each_entry(spu, &cbe_spu_info[cbe].spus, cbe_list) {
+ spu_dn = spu_devnode(spu);
+ if (spu_dn == avoid)
+ continue;
+ vic_handles = of_get_property(spu_dn, "vicinity", &lenp);
+ for (i=0; i < (lenp / sizeof(phandle)); i++) {
+ if (vic_handles[i] == target->linux_phandle)
+ return spu;
+ }
+ }
+ return NULL;
+}
+
+static void init_affinity_node(int cbe)
+{
+ struct spu *spu, *last_spu;
+ struct device_node *vic_dn, *last_spu_dn;
+ phandle avoid_ph;
+ const phandle *vic_handles;
+ const char *name;
+ int lenp, i, added;
+
+ last_spu = list_first_entry(&cbe_spu_info[cbe].spus, struct spu,
+ cbe_list);
+ avoid_ph = 0;
+ for (added = 1; added < cbe_spu_info[cbe].n_spus; added++) {
+ last_spu_dn = spu_devnode(last_spu);
+ vic_handles = of_get_property(last_spu_dn, "vicinity", &lenp);
+
+ /*
+ * Walk through each phandle in vicinity property of the spu
+ * (tipically two vicinity phandles per spe node)
+ */
+ for (i = 0; i < (lenp / sizeof(phandle)); i++) {
+ if (vic_handles[i] == avoid_ph)
+ continue;
+
+ vic_dn = of_find_node_by_phandle(vic_handles[i]);
+ if (!vic_dn)
+ continue;
+
+ /* a neighbour might be spe, mic-tm, or bif0 */
+ name = of_get_property(vic_dn, "name", NULL);
+ if (!name)
+ continue;
+
+ if (strcmp(name, "spe") == 0) {
+ spu = devnode_spu(cbe, vic_dn);
+ avoid_ph = last_spu_dn->linux_phandle;
+ } else {
+ /*
+ * "mic-tm" and "bif0" nodes do not have
+ * vicinity property. So we need to find the
+ * spe which has vic_dn as neighbour, but
+ * skipping the one we came from (last_spu_dn)
+ */
+ spu = neighbour_spu(cbe, vic_dn, last_spu_dn);
+ if (!spu)
+ continue;
+ if (!strcmp(name, "mic-tm")) {
+ last_spu->has_mem_affinity = 1;
+ spu->has_mem_affinity = 1;
+ }
+ avoid_ph = vic_dn->linux_phandle;
+ }
+
+ list_add_tail(&spu->aff_list, &last_spu->aff_list);
+ last_spu = spu;
+ break;
+ }
+ }
+}
+
+static void init_affinity_fw(void)
+{
+ int cbe;
+
+ for (cbe = 0; cbe < MAX_NUMNODES; cbe++)
+ init_affinity_node(cbe);
+}
+
+static int __init init_affinity(void)
+{
+ if (of_has_vicinity()) {
+ init_affinity_fw();
+ } else {
+ long root = of_get_flat_dt_root();
+ if (of_flat_dt_is_compatible(root, "IBM,CPBW-1.0"))
+ init_affinity_qs20_harcoded();
+ else
+ printk("No affinity configuration found");
+ }
+
+ return 0;
+}
+
const struct spu_management_ops spu_management_of_ops = {
.enumerate_spus = of_enumerate_spus,
.create_spu = of_create_spu,
.destroy_spu = of_destroy_spu,
+ .init_affinity = init_affinity,
};
diff --git a/arch/powerpc/platforms/cell/spu_syscalls.c b/arch/powerpc/platforms/cell/spu_syscalls.c
index dd2c668..027ac32 100644
--- a/arch/powerpc/platforms/cell/spu_syscalls.c
+++ b/arch/powerpc/platforms/cell/spu_syscalls.c
@@ -45,6 +45,7 @@
if (owner && try_module_get(owner)) {
if (flags & SPU_CREATE_AFFINITY_SPU) {
neighbor = fget_light(neighbor_fd, &fput_needed);
+ ret = -EBADF;
if (neighbor) {
ret = spufs_calls.create_thread(name, flags,
mode, neighbor);
diff --git a/arch/powerpc/platforms/fsl_uli1575.c b/arch/powerpc/platforms/fsl_uli1575.c
new file mode 100644
index 0000000..afc9141
--- /dev/null
+++ b/arch/powerpc/platforms/fsl_uli1575.c
@@ -0,0 +1,255 @@
+/*
+ * ULI M1575 setup code - specific to Freescale boards
+ *
+ * Copyright 2007 Freescale Semiconductor Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+#include <linux/stddef.h>
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/interrupt.h>
+#include <linux/mc146818rtc.h>
+
+#include <asm/system.h>
+#include <asm/pci-bridge.h>
+
+#define ULI_PIRQA 0x08
+#define ULI_PIRQB 0x09
+#define ULI_PIRQC 0x0a
+#define ULI_PIRQD 0x0b
+#define ULI_PIRQE 0x0c
+#define ULI_PIRQF 0x0d
+#define ULI_PIRQG 0x0e
+
+#define ULI_8259_NONE 0x00
+#define ULI_8259_IRQ1 0x08
+#define ULI_8259_IRQ3 0x02
+#define ULI_8259_IRQ4 0x04
+#define ULI_8259_IRQ5 0x05
+#define ULI_8259_IRQ6 0x07
+#define ULI_8259_IRQ7 0x06
+#define ULI_8259_IRQ9 0x01
+#define ULI_8259_IRQ10 0x03
+#define ULI_8259_IRQ11 0x09
+#define ULI_8259_IRQ12 0x0b
+#define ULI_8259_IRQ14 0x0d
+#define ULI_8259_IRQ15 0x0f
+
+u8 uli_pirq_to_irq[8] = {
+ ULI_8259_IRQ9, /* PIRQA */
+ ULI_8259_IRQ10, /* PIRQB */
+ ULI_8259_IRQ11, /* PIRQC */
+ ULI_8259_IRQ12, /* PIRQD */
+ ULI_8259_IRQ5, /* PIRQE */
+ ULI_8259_IRQ6, /* PIRQF */
+ ULI_8259_IRQ7, /* PIRQG */
+ ULI_8259_NONE, /* PIRQH */
+};
+
+/* set in board code if you want this quirks to do something */
+int uses_fsl_uli_m1575;
+
+/* Bridge */
+static void __devinit early_uli5249(struct pci_dev *dev)
+{
+ unsigned char temp;
+
+ if (!uses_fsl_uli_m1575)
+ return;
+
+ pci_write_config_word(dev, PCI_COMMAND, PCI_COMMAND_IO |
+ PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER);
+
+ /* read/write lock */
+ pci_read_config_byte(dev, 0x7c, &temp);
+ pci_write_config_byte(dev, 0x7c, 0x80);
+
+ /* set as P2P bridge */
+ pci_write_config_byte(dev, PCI_CLASS_PROG, 0x01);
+ dev->class |= 0x1;
+
+ /* restore lock */
+ pci_write_config_byte(dev, 0x7c, temp);
+}
+
+
+static void __devinit quirk_uli1575(struct pci_dev *dev)
+{
+ int i;
+
+ if (!uses_fsl_uli_m1575)
+ return;
+
+ /*
+ * ULI1575 interrupts route setup
+ */
+
+ /* ULI1575 IRQ mapping conf register maps PIRQx to IRQn */
+ for (i = 0; i < 4; i++) {
+ u8 val = uli_pirq_to_irq[i*2] | (uli_pirq_to_irq[i*2+1] << 4);
+ pci_write_config_byte(dev, 0x48 + i, val);
+ }
+
+ /* USB 1.1 OHCI controller 1: dev 28, func 0 - IRQ12 */
+ pci_write_config_byte(dev, 0x86, ULI_PIRQD);
+
+ /* USB 1.1 OHCI controller 2: dev 28, func 1 - IRQ9 */
+ pci_write_config_byte(dev, 0x87, ULI_PIRQA);
+
+ /* USB 1.1 OHCI controller 3: dev 28, func 2 - IRQ10 */
+ pci_write_config_byte(dev, 0x88, ULI_PIRQB);
+
+ /* Lan controller: dev 27, func 0 - IRQ6 */
+ pci_write_config_byte(dev, 0x89, ULI_PIRQF);
+
+ /* AC97 Audio controller: dev 29, func 0 - IRQ6 */
+ pci_write_config_byte(dev, 0x8a, ULI_PIRQF);
+
+ /* Modem controller: dev 29, func 1 - IRQ6 */
+ pci_write_config_byte(dev, 0x8b, ULI_PIRQF);
+
+ /* HD Audio controller: dev 29, func 2 - IRQ6 */
+ pci_write_config_byte(dev, 0x8c, ULI_PIRQF);
+
+ /* SATA controller: dev 31, func 1 - IRQ5 */
+ pci_write_config_byte(dev, 0x8d, ULI_PIRQE);
+
+ /* SMB interrupt: dev 30, func 1 - IRQ7 */
+ pci_write_config_byte(dev, 0x8e, ULI_PIRQG);
+
+ /* PMU ACPI SCI interrupt: dev 30, func 2 - IRQ7 */
+ pci_write_config_byte(dev, 0x8f, ULI_PIRQG);
+
+ /* USB 2.0 controller: dev 28, func 3 */
+ pci_write_config_byte(dev, 0x74, ULI_8259_IRQ11);
+
+ /* Primary PATA IDE IRQ: 14
+ * Secondary PATA IDE IRQ: 15
+ */
+ pci_write_config_byte(dev, 0x44, 0x30 | ULI_8259_IRQ14);
+ pci_write_config_byte(dev, 0x75, ULI_8259_IRQ15);
+}
+
+static void __devinit quirk_final_uli1575(struct pci_dev *dev)
+{
+ /* Set i8259 interrupt trigger
+ * IRQ 3: Level
+ * IRQ 4: Level
+ * IRQ 5: Level
+ * IRQ 6: Level
+ * IRQ 7: Level
+ * IRQ 9: Level
+ * IRQ 10: Level
+ * IRQ 11: Level
+ * IRQ 12: Level
+ * IRQ 14: Edge
+ * IRQ 15: Edge
+ */
+ if (!uses_fsl_uli_m1575)
+ return;
+
+ outb(0xfa, 0x4d0);
+ outb(0x1e, 0x4d1);
+
+ /* setup RTC */
+ CMOS_WRITE(RTC_SET, RTC_CONTROL);
+ CMOS_WRITE(RTC_24H, RTC_CONTROL);
+
+ /* ensure month, date, and week alarm fields are ignored */
+ CMOS_WRITE(0, RTC_VALID);
+
+ outb_p(0x7c, 0x72);
+ outb_p(RTC_ALARM_DONT_CARE, 0x73);
+
+ outb_p(0x7d, 0x72);
+ outb_p(RTC_ALARM_DONT_CARE, 0x73);
+}
+
+/* SATA */
+static void __devinit quirk_uli5288(struct pci_dev *dev)
+{
+ unsigned char c;
+ unsigned int d;
+
+ if (!uses_fsl_uli_m1575)
+ return;
+
+ /* read/write lock */
+ pci_read_config_byte(dev, 0x83, &c);
+ pci_write_config_byte(dev, 0x83, c|0x80);
+
+ pci_read_config_dword(dev, PCI_CLASS_REVISION, &d);
+ d = (d & 0xff) | (PCI_CLASS_STORAGE_SATA_AHCI << 8);
+ pci_write_config_dword(dev, PCI_CLASS_REVISION, d);
+
+ /* restore lock */
+ pci_write_config_byte(dev, 0x83, c);
+
+ /* disable emulated PATA mode enabled */
+ pci_read_config_byte(dev, 0x84, &c);
+ pci_write_config_byte(dev, 0x84, c & ~0x01);
+}
+
+/* PATA */
+static void __devinit quirk_uli5229(struct pci_dev *dev)
+{
+ unsigned short temp;
+
+ if (!uses_fsl_uli_m1575)
+ return;
+
+ pci_write_config_word(dev, PCI_COMMAND, PCI_COMMAND_INTX_DISABLE |
+ PCI_COMMAND_MASTER | PCI_COMMAND_IO);
+
+ /* Enable Native IRQ 14/15 */
+ pci_read_config_word(dev, 0x4a, &temp);
+ pci_write_config_word(dev, 0x4a, temp | 0x1000);
+}
+
+/* We have to do a dummy read on the P2P for the RTC to work, WTF */
+static void __devinit quirk_final_uli5249(struct pci_dev *dev)
+{
+ int i;
+ u8 *dummy;
+ struct pci_bus *bus = dev->bus;
+
+ for (i = 0; i < PCI_BUS_NUM_RESOURCES; i++) {
+ if ((bus->resource[i]) &&
+ (bus->resource[i]->flags & IORESOURCE_MEM)) {
+ dummy = ioremap(bus->resource[i]->start, 0x4);
+ if (dummy) {
+ in_8(dummy);
+ iounmap(dummy);
+ }
+ break;
+ }
+ }
+}
+
+DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_AL, 0x5249, early_uli5249);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AL, 0x1575, quirk_uli1575);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AL, 0x5288, quirk_uli5288);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AL, 0x5229, quirk_uli5229);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AL, 0x5249, quirk_final_uli5249);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AL, 0x1575, quirk_final_uli1575);
+
+int uli_exclude_device(struct pci_controller *hose,
+ u_char bus, u_char devfn)
+{
+ if (bus == (hose->first_busno + 2)) {
+ /* exclude Modem controller */
+ if ((PCI_SLOT(devfn) == 29) && (PCI_FUNC(devfn) == 1))
+ return PCIBIOS_DEVICE_NOT_FOUND;
+
+ /* exclude HD Audio controller */
+ if ((PCI_SLOT(devfn) == 29) && (PCI_FUNC(devfn) == 2))
+ return PCIBIOS_DEVICE_NOT_FOUND;
+ }
+
+ return PCIBIOS_SUCCESSFUL;
+}
diff --git a/arch/powerpc/platforms/ps3/Kconfig b/arch/powerpc/platforms/ps3/Kconfig
index d4fc74f..67144d1 100644
--- a/arch/powerpc/platforms/ps3/Kconfig
+++ b/arch/powerpc/platforms/ps3/Kconfig
@@ -1,5 +1,5 @@
config PPC_PS3
- bool "Sony PS3 (incomplete)"
+ bool "Sony PS3"
depends on PPC_MULTIPLATFORM && PPC64
select PPC_CELL
select USB_ARCH_HAS_OHCI
@@ -10,10 +10,10 @@
select MEMORY_HOTPLUG
help
This option enables support for the Sony PS3 game console
- and other platforms using the PS3 hypervisor.
- Support for this platform is not yet complete, so
- enabling this will not result in a bootable kernel on a
- PS3 system.
+ and other platforms using the PS3 hypervisor. Enabling this
+ option will allow building otheros.bld, a kernel image suitable
+ for programming into flash memory, and vmlinux, a kernel image
+ suitable for loading via kexec.
menu "PS3 Platform Options"
depends on PPC_PS3
diff --git a/arch/powerpc/platforms/ps3/device-init.c b/arch/powerpc/platforms/ps3/device-init.c
index 825ebb2..ce15cad 100644
--- a/arch/powerpc/platforms/ps3/device-init.c
+++ b/arch/powerpc/platforms/ps3/device-init.c
@@ -273,55 +273,58 @@
static int ps3_storage_wait_for_device(const struct ps3_repository_device *repo)
{
+ int error = -ENODEV;
int result;
const u64 notification_dev_id = (u64)-1LL;
const unsigned int timeout = HZ;
u64 lpar;
u64 tag;
+ void *buf;
+ enum ps3_notify_type {
+ notify_device_ready = 0,
+ notify_region_probe = 1,
+ notify_region_update = 2,
+ };
struct {
u64 operation_code; /* must be zero */
- u64 event_mask; /* 1 = device ready */
+ u64 event_mask; /* OR of 1UL << enum ps3_notify_type */
} *notify_cmd;
struct {
- u64 event_type; /* notify_device_ready */
+ u64 event_type; /* enum ps3_notify_type */
u64 bus_id;
u64 dev_id;
u64 dev_type;
u64 dev_port;
} *notify_event;
- enum {
- notify_device_ready = 1
- };
pr_debug(" -> %s:%u: bus_id %u, dev_id %u, dev_type %u\n", __func__,
__LINE__, repo->bus_id, repo->dev_id, repo->dev_type);
- notify_cmd = kzalloc(512, GFP_KERNEL);
- notify_event = (void *)notify_cmd;
- if (!notify_cmd)
+ buf = kzalloc(512, GFP_KERNEL);
+ if (!buf)
return -ENOMEM;
- lpar = ps3_mm_phys_to_lpar(__pa(notify_cmd));
+ lpar = ps3_mm_phys_to_lpar(__pa(buf));
+ notify_cmd = buf;
+ notify_event = buf;
result = lv1_open_device(repo->bus_id, notification_dev_id, 0);
if (result) {
printk(KERN_ERR "%s:%u: lv1_open_device %s\n", __func__,
__LINE__, ps3_result(result));
- result = -ENODEV;
goto fail_free;
}
/* Setup and write the request for device notification. */
- notify_cmd->operation_code = 0; /* must be zero */
- notify_cmd->event_mask = 0x01; /* device ready */
+ notify_cmd->operation_code = 0; /* must be zero */
+ notify_cmd->event_mask = 1UL << notify_region_probe;
result = lv1_storage_write(notification_dev_id, 0, 0, 1, 0, lpar,
&tag);
if (result) {
printk(KERN_ERR "%s:%u: write failed %s\n", __func__, __LINE__,
ps3_result(result));
- result = -ENODEV;
goto fail_close;
}
@@ -332,13 +335,11 @@
if (result) {
printk(KERN_ERR "%s:%u: write not completed %s\n", __func__,
__LINE__, ps3_result(result));
- result = -ENODEV;
goto fail_close;
}
/* Loop here processing the requested notification events. */
- result = -ENODEV;
while (1) {
memset(notify_event, 0, sizeof(*notify_event));
@@ -358,7 +359,7 @@
break;
}
- if (notify_event->event_type != notify_device_ready ||
+ if (notify_event->event_type != notify_region_probe ||
notify_event->bus_id != repo->bus_id) {
pr_debug("%s:%u: bad notify_event: event %lu, "
"dev_id %lu, dev_type %lu\n",
@@ -371,7 +372,7 @@
notify_event->dev_type == repo->dev_type) {
pr_debug("%s:%u: device ready: dev_id %u\n", __func__,
__LINE__, repo->dev_id);
- result = 0;
+ error = 0;
break;
}
@@ -386,9 +387,9 @@
fail_close:
lv1_close_device(repo->bus_id, notification_dev_id);
fail_free:
- kfree(notify_cmd);
+ kfree(buf);
pr_debug(" <- %s:%u\n", __func__, __LINE__);
- return result;
+ return error;
}
static int ps3_setup_storage_dev(const struct ps3_repository_device *repo,
diff --git a/arch/powerpc/platforms/ps3/spu.c b/arch/powerpc/platforms/ps3/spu.c
index 502d80e..ac2a4b8 100644
--- a/arch/powerpc/platforms/ps3/spu.c
+++ b/arch/powerpc/platforms/ps3/spu.c
@@ -414,10 +414,16 @@
return num_resource_id;
}
+static int ps3_init_affinity(void)
+{
+ return 0;
+}
+
const struct spu_management_ops spu_management_ps3_ops = {
.enumerate_spus = ps3_enumerate_spus,
.create_spu = ps3_create_spu,
.destroy_spu = ps3_destroy_spu,
+ .init_affinity = ps3_init_affinity,
};
/* spu_priv1_ops */
diff --git a/arch/powerpc/sysdev/fsl_pci.c b/arch/powerpc/sysdev/fsl_pci.c
index 9fb0ce5..114c90f 100644
--- a/arch/powerpc/sysdev/fsl_pci.c
+++ b/arch/powerpc/sysdev/fsl_pci.c
@@ -251,6 +251,8 @@
DECLARE_PCI_FIXUP_EARLY(0x1957, PCI_DEVICE_ID_MPC8568, quirk_fsl_pcie_transparent);
DECLARE_PCI_FIXUP_EARLY(0x1957, PCI_DEVICE_ID_MPC8567E, quirk_fsl_pcie_transparent);
DECLARE_PCI_FIXUP_EARLY(0x1957, PCI_DEVICE_ID_MPC8567, quirk_fsl_pcie_transparent);
+DECLARE_PCI_FIXUP_EARLY(0x1957, PCI_DEVICE_ID_MPC8533E, quirk_fsl_pcie_transparent);
+DECLARE_PCI_FIXUP_EARLY(0x1957, PCI_DEVICE_ID_MPC8533, quirk_fsl_pcie_transparent);
DECLARE_PCI_FIXUP_EARLY(0x1957, PCI_DEVICE_ID_MPC8544E, quirk_fsl_pcie_transparent);
DECLARE_PCI_FIXUP_EARLY(0x1957, PCI_DEVICE_ID_MPC8544, quirk_fsl_pcie_transparent);
DECLARE_PCI_FIXUP_EARLY(0x1957, PCI_DEVICE_ID_MPC8641, quirk_fsl_pcie_transparent);
diff --git a/arch/powerpc/sysdev/fsl_soc.c b/arch/powerpc/sysdev/fsl_soc.c
index 727453d..1cf29c9 100644
--- a/arch/powerpc/sysdev/fsl_soc.c
+++ b/arch/powerpc/sysdev/fsl_soc.c
@@ -22,6 +22,7 @@
#include <linux/module.h>
#include <linux/device.h>
#include <linux/platform_device.h>
+#include <linux/of_platform.h>
#include <linux/phy.h>
#include <linux/fsl_devices.h>
#include <linux/fs_enet_pd.h>
diff --git a/arch/powerpc/sysdev/rtc_cmos_setup.c b/arch/powerpc/sysdev/rtc_cmos_setup.c
index e276048..0c9ac7e 100644
--- a/arch/powerpc/sysdev/rtc_cmos_setup.c
+++ b/arch/powerpc/sysdev/rtc_cmos_setup.c
@@ -20,14 +20,16 @@
{
struct device_node *np;
struct platform_device *pd;
- struct resource res;
+ struct resource res[2];
int ret;
+ memset(&res, 0, sizeof(res));
+
np = of_find_compatible_node(NULL, NULL, "pnpPNP,b00");
if (!np)
return -ENODEV;
- ret = of_address_to_resource(np, 0, &res);
+ ret = of_address_to_resource(np, 0, &res[0]);
of_node_put(np);
if (ret)
return ret;
@@ -36,11 +38,18 @@
* RTC_PORT(x) is hardcoded in asm/mc146818rtc.h. Verify that the
* address provided by the device node matches.
*/
- if (res.start != RTC_PORT(0))
+ if (res[0].start != RTC_PORT(0))
return -EINVAL;
+ /* Use a fixed interrupt value of 8 since on PPC if we are using this
+ * its off an i8259 which we ensure has interrupt numbers 0..15. */
+ res[1].start = 8;
+ res[1].end = 8;
+ res[1].flags = IORESOURCE_IRQ;
+
pd = platform_device_register_simple("rtc_cmos", -1,
- &res, 1);
+ &res[0], 2);
+
if (IS_ERR(pd))
return PTR_ERR(pd);
diff --git a/arch/ppc/kernel/misc.S b/arch/ppc/kernel/misc.S
index 0da55368..a22e1f4 100644
--- a/arch/ppc/kernel/misc.S
+++ b/arch/ppc/kernel/misc.S
@@ -237,9 +237,19 @@
mfspr r4,SPRN_MMUCR
mfspr r5,SPRN_PID /* Get PID */
rlwimi r4,r5,0,24,31 /* Set TID */
- mtspr SPRN_MMUCR,r4
+ /* We have to run the search with interrupts disabled, even critical
+ * and debug interrupts (in fact the only critical exceptions we have
+ * are debug and machine check). Otherwise an interrupt which causes
+ * a TLB miss can clobber the MMUCR between the mtspr and the tlbsx. */
+ mfmsr r5
+ lis r6,(MSR_EE|MSR_CE|MSR_ME|MSR_DE)@ha
+ addi r6,r6,(MSR_EE|MSR_CE|MSR_ME|MSR_DE)@l
+ andc r6,r5,r6
+ mtmsr r6
+ mtspr SPRN_MMUCR,r4
tlbsx. r3, 0, r3
+ mtmsr r5
bne 10f
sync
/* There are only 64 TLB entries, so r3 < 64,
diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig
index 098c62c..b711321 100644
--- a/arch/s390/Kconfig
+++ b/arch/s390/Kconfig
@@ -109,10 +109,6 @@
can be controlled through /sys/devices/system/cpu/cpu#.
Say N if you want to disable CPU hotplug.
-config DEFAULT_MIGRATION_COST
- int
- default "1000000"
-
config MATHEMU
bool "IEEE FPU emulation"
depends on MARCH_G5
diff --git a/arch/s390/hypfs/inode.c b/arch/s390/hypfs/inode.c
index 8e1ea1c..5245717 100644
--- a/arch/s390/hypfs/inode.c
+++ b/arch/s390/hypfs/inode.c
@@ -17,6 +17,8 @@
#include <linux/parser.h>
#include <linux/sysfs.h>
#include <linux/module.h>
+#include <linux/seq_file.h>
+#include <linux/mount.h>
#include <asm/ebcdic.h>
#include "hypfs.h"
@@ -58,17 +60,28 @@
hypfs_last_dentry = dentry;
}
+static inline int hypfs_positive(struct dentry *dentry)
+{
+ return dentry->d_inode && !d_unhashed(dentry);
+}
+
static void hypfs_remove(struct dentry *dentry)
{
struct dentry *parent;
parent = dentry->d_parent;
- if (S_ISDIR(dentry->d_inode->i_mode))
- simple_rmdir(parent->d_inode, dentry);
- else
- simple_unlink(parent->d_inode, dentry);
+ if (!parent || !parent->d_inode)
+ return;
+ mutex_lock(&parent->d_inode->i_mutex);
+ if (hypfs_positive(dentry)) {
+ if (S_ISDIR(dentry->d_inode->i_mode))
+ simple_rmdir(parent->d_inode, dentry);
+ else
+ simple_unlink(parent->d_inode, dentry);
+ }
d_delete(dentry);
dput(dentry);
+ mutex_unlock(&parent->d_inode->i_mutex);
}
static void hypfs_delete_tree(struct dentry *root)
@@ -256,6 +269,15 @@
return 0;
}
+static int hypfs_show_options(struct seq_file *s, struct vfsmount *mnt)
+{
+ struct hypfs_sb_info *hypfs_info = mnt->mnt_sb->s_fs_info;
+
+ seq_printf(s, ",uid=%u", hypfs_info->uid);
+ seq_printf(s, ",gid=%u", hypfs_info->gid);
+ return 0;
+}
+
static int hypfs_fill_super(struct super_block *sb, void *data, int silent)
{
struct inode *root_inode;
@@ -304,6 +326,7 @@
}
hypfs_update_update(sb);
sb->s_root = root_dentry;
+ printk(KERN_INFO "hypfs: Hypervisor filesystem mounted\n");
return 0;
err_tree:
@@ -345,13 +368,17 @@
qname.name = name;
qname.len = strlen(name);
qname.hash = full_name_hash(name, qname.len);
+ mutex_lock(&parent->d_inode->i_mutex);
dentry = lookup_one_len(name, parent, strlen(name));
- if (IS_ERR(dentry))
- return ERR_PTR(-ENOMEM);
+ if (IS_ERR(dentry)) {
+ dentry = ERR_PTR(-ENOMEM);
+ goto fail;
+ }
inode = hypfs_make_inode(sb, mode);
if (!inode) {
dput(dentry);
- return ERR_PTR(-ENOMEM);
+ dentry = ERR_PTR(-ENOMEM);
+ goto fail;
}
if (mode & S_IFREG) {
inode->i_fop = &hypfs_file_ops;
@@ -368,6 +395,8 @@
inode->i_private = data;
d_instantiate(dentry, inode);
dget(dentry);
+fail:
+ mutex_unlock(&parent->d_inode->i_mutex);
return dentry;
}
@@ -380,7 +409,6 @@
if (IS_ERR(dentry))
return dentry;
hypfs_add_dentry(dentry);
- parent->d_inode->i_nlink++;
return dentry;
}
@@ -459,6 +487,7 @@
static struct super_operations hypfs_s_ops = {
.statfs = simple_statfs,
.drop_inode = hypfs_drop_inode,
+ .show_options = hypfs_show_options,
};
static decl_subsys(s390, NULL, NULL);
diff --git a/arch/s390/kernel/Makefile b/arch/s390/kernel/Makefile
index 3195d37..56cb710 100644
--- a/arch/s390/kernel/Makefile
+++ b/arch/s390/kernel/Makefile
@@ -6,7 +6,7 @@
obj-y := bitmap.o traps.o time.o process.o base.o early.o \
setup.o sys_s390.o ptrace.o signal.o cpcmd.o ebcdic.o \
- semaphore.o s390_ext.o debug.o irq.o ipl.o dis.o
+ semaphore.o s390_ext.o debug.o irq.o ipl.o dis.o diag.o
obj-y += $(if $(CONFIG_64BIT),entry64.o,entry.o)
obj-y += $(if $(CONFIG_64BIT),reipl64.o,reipl.o)
diff --git a/arch/s390/kernel/diag.c b/arch/s390/kernel/diag.c
new file mode 100644
index 0000000..c032d11
--- /dev/null
+++ b/arch/s390/kernel/diag.c
@@ -0,0 +1,102 @@
+/*
+ * Implementation of s390 diagnose codes
+ *
+ * Copyright IBM Corp. 2007
+ * Author(s): Michael Holzheu <holzheu@de.ibm.com>
+ */
+
+#include <linux/module.h>
+#include <asm/diag.h>
+
+/*
+ * Diagnose 10: Release pages
+ */
+void diag10(unsigned long addr)
+{
+ if (addr >= 0x7ff00000)
+ return;
+ asm volatile(
+#ifdef CONFIG_64BIT
+ " sam31\n"
+ " diag %0,%0,0x10\n"
+ "0: sam64\n"
+#else
+ " diag %0,%0,0x10\n"
+ "0:\n"
+#endif
+ EX_TABLE(0b, 0b)
+ : : "a" (addr));
+}
+EXPORT_SYMBOL(diag10);
+
+/*
+ * Diagnose 14: Input spool file manipulation
+ */
+int diag14(unsigned long rx, unsigned long ry1, unsigned long subcode)
+{
+ register unsigned long _ry1 asm("2") = ry1;
+ register unsigned long _ry2 asm("3") = subcode;
+ int rc = 0;
+
+ asm volatile(
+#ifdef CONFIG_64BIT
+ " sam31\n"
+ " diag %2,2,0x14\n"
+ " sam64\n"
+#else
+ " diag %2,2,0x14\n"
+#endif
+ " ipm %0\n"
+ " srl %0,28\n"
+ : "=d" (rc), "+d" (_ry2)
+ : "d" (rx), "d" (_ry1)
+ : "cc");
+
+ return rc;
+}
+EXPORT_SYMBOL(diag14);
+
+/*
+ * Diagnose 210: Get information about a virtual device
+ */
+int diag210(struct diag210 *addr)
+{
+ /*
+ * diag 210 needs its data below the 2GB border, so we
+ * use a static data area to be sure
+ */
+ static struct diag210 diag210_tmp;
+ static DEFINE_SPINLOCK(diag210_lock);
+ unsigned long flags;
+ int ccode;
+
+ spin_lock_irqsave(&diag210_lock, flags);
+ diag210_tmp = *addr;
+
+#ifdef CONFIG_64BIT
+ asm volatile(
+ " lhi %0,-1\n"
+ " sam31\n"
+ " diag %1,0,0x210\n"
+ "0: ipm %0\n"
+ " srl %0,28\n"
+ "1: sam64\n"
+ EX_TABLE(0b, 1b)
+ : "=&d" (ccode) : "a" (&diag210_tmp) : "cc", "memory");
+#else
+ asm volatile(
+ " lhi %0,-1\n"
+ " diag %1,0,0x210\n"
+ "0: ipm %0\n"
+ " srl %0,28\n"
+ "1:\n"
+ EX_TABLE(0b, 1b)
+ : "=&d" (ccode) : "a" (&diag210_tmp) : "cc", "memory");
+#endif
+
+ *addr = diag210_tmp;
+ spin_unlock_irqrestore(&diag210_lock, flags);
+
+ return ccode;
+}
+EXPORT_SYMBOL(diag210);
diff --git a/arch/s390/kernel/dis.c b/arch/s390/kernel/dis.c
index d305731..50d2235 100644
--- a/arch/s390/kernel/dis.c
+++ b/arch/s390/kernel/dis.c
@@ -577,7 +577,7 @@
{ "esta", 0x4a, INSTR_RRE_RR },
{ "lura", 0x4b, INSTR_RRE_RR },
{ "tar", 0x4c, INSTR_RRE_AR },
- { "cpya", INSTR_RRE_AA },
+ { "cpya", 0x4d, INSTR_RRE_AA },
{ "sar", 0x4e, INSTR_RRE_AR },
{ "ear", 0x4f, INSTR_RRE_RA },
{ "csp", 0x50, INSTR_RRE_RR },
diff --git a/arch/s390/kernel/kprobes.c b/arch/s390/kernel/kprobes.c
index 358d2bb..e40373d 100644
--- a/arch/s390/kernel/kprobes.c
+++ b/arch/s390/kernel/kprobes.c
@@ -85,7 +85,7 @@
ainsn->reg = (*ainsn->insn & 0xf0) >> 4;
/* save the instruction length (pop 5-5) in bytes */
- switch (*(__u8 *) (ainsn->insn) >> 4) {
+ switch (*(__u8 *) (ainsn->insn) >> 6) {
case 0:
ainsn->ilen = 2;
break;
diff --git a/arch/s390/kernel/s390_ksyms.c b/arch/s390/kernel/s390_ksyms.c
index 90b5ef5..7234c73 100644
--- a/arch/s390/kernel/s390_ksyms.c
+++ b/arch/s390/kernel/s390_ksyms.c
@@ -25,7 +25,6 @@
EXPORT_SYMBOL(_ni_bitmap);
EXPORT_SYMBOL(_zb_findmap);
EXPORT_SYMBOL(_sb_findmap);
-EXPORT_SYMBOL(diag10);
/*
* semaphore ops
diff --git a/arch/s390/mm/cmm.c b/arch/s390/mm/cmm.c
index c5b2f4f..fabc50a 100644
--- a/arch/s390/mm/cmm.c
+++ b/arch/s390/mm/cmm.c
@@ -20,6 +20,7 @@
#include <asm/pgalloc.h>
#include <asm/uaccess.h>
+#include <asm/diag.h>
static char *sender = "VMRMSVM";
module_param(sender, charp, 0400);
diff --git a/arch/s390/mm/init.c b/arch/s390/mm/init.c
index 9098531..3a25bbf 100644
--- a/arch/s390/mm/init.c
+++ b/arch/s390/mm/init.c
@@ -42,23 +42,6 @@
pgd_t swapper_pg_dir[PTRS_PER_PGD] __attribute__((__aligned__(PAGE_SIZE)));
char empty_zero_page[PAGE_SIZE] __attribute__((__aligned__(PAGE_SIZE)));
-void diag10(unsigned long addr)
-{
- if (addr >= 0x7ff00000)
- return;
- asm volatile(
-#ifdef CONFIG_64BIT
- " sam31\n"
- " diag %0,%0,0x10\n"
- "0: sam64\n"
-#else
- " diag %0,%0,0x10\n"
- "0:\n"
-#endif
- EX_TABLE(0b,0b)
- : : "a" (addr));
-}
-
void show_mem(void)
{
int i, total = 0, reserved = 0;
diff --git a/arch/sh/Makefile b/arch/sh/Makefile
index 3d211aa..97ac586 100644
--- a/arch/sh/Makefile
+++ b/arch/sh/Makefile
@@ -34,6 +34,8 @@
endif
endif
+isa-y := $(isa-y)-up
+
cflags-$(CONFIG_CPU_SH2) := $(call cc-option,-m2,)
cflags-$(CONFIG_CPU_SH2A) += $(call cc-option,-m2a,) \
$(call cc-option,-m2a-nofpu,)
@@ -46,7 +48,20 @@
cflags-$(CONFIG_CPU_BIG_ENDIAN) += -mb
cflags-$(CONFIG_CPU_LITTLE_ENDIAN) += -ml
-cflags-y += $(call as-option,-Wa$(comma)-isa=$(isa-y),) -ffreestanding
+#
+# -Wa,-isa= tuning implies -Wa,-dsp for the versions of binutils that
+# support it, while -Wa,-dsp by itself limits the range of usable opcodes
+# on certain CPU subtypes. Try the ISA variant first, and if that fails,
+# fall back on -Wa,-dsp for the old binutils versions. Even without DSP
+# opcodes, we always want the best ISA tuning the version of binutils
+# will provide.
+#
+isaflags-y := $(call as-option,-Wa$(comma)-isa=$(isa-y),)
+
+isaflags-$(CONFIG_SH_DSP) := \
+ $(call as-option,-Wa$(comma)-isa=$(isa-y),-Wa$(comma)-dsp)
+
+cflags-y += $(isaflags-y) -ffreestanding
cflags-$(CONFIG_MORE_COMPILE_OPTIONS) += \
$(shell echo $(CONFIG_COMPILE_OPTIONS) | sed -e 's/"//g')
diff --git a/arch/sh/kernel/cpu/sh4/setup-sh4-202.c b/arch/sh/kernel/cpu/sh4/setup-sh4-202.c
index 6e4e965..dab1932 100644
--- a/arch/sh/kernel/cpu/sh4/setup-sh4-202.c
+++ b/arch/sh/kernel/cpu/sh4/setup-sh4-202.c
@@ -41,3 +41,8 @@
ARRAY_SIZE(sh4202_devices));
}
__initcall(sh4202_devices_setup);
+
+void __init plat_irq_setup(void)
+{
+ /* do nothing - all IRL interrupts are handled by the board code */
+}
diff --git a/arch/sh/kernel/early_printk.c b/arch/sh/kernel/early_printk.c
index 9833493..80b637c 100644
--- a/arch/sh/kernel/early_printk.c
+++ b/arch/sh/kernel/early_printk.c
@@ -76,7 +76,7 @@
sci_in(&scif_port, SCxSR);
sci_out(&scif_port, SCxSR, 0xf3 & ~(0x20 | 0x40));
- while ((sci_in(&scif_port, SCxSR) & 0x40) == 0);
+ while ((sci_in(&scif_port, SCxSR) & 0x40) == 0)
;
if (c == '\n')
diff --git a/arch/sh/kernel/machvec.c b/arch/sh/kernel/machvec.c
index 23c5948..129b2cf 100644
--- a/arch/sh/kernel/machvec.c
+++ b/arch/sh/kernel/machvec.c
@@ -91,6 +91,13 @@
(unsigned long)&__machvec_start);
/*
+ * Sanity check for machvec section alignment. Ensure
+ * __initmv hasn't been misused.
+ */
+ if (machvec_size % sizeof(struct sh_machine_vector))
+ panic("machvec misaligned, invalid __initmv use?");
+
+ /*
* If the machvec hasn't been preselected, use the first
* vector (usually the only one) from .machvec.init.
*/
diff --git a/arch/sh/kernel/ptrace.c b/arch/sh/kernel/ptrace.c
index 891d1d4..f64a2d2 100644
--- a/arch/sh/kernel/ptrace.c
+++ b/arch/sh/kernel/ptrace.c
@@ -93,6 +93,7 @@
case PTRACE_PEEKTEXT: /* read word at location addr. */
case PTRACE_PEEKDATA:
ret = generic_ptrace_peekdata(child, addr, data);
+ break;
/* read the word at location addr in the USER area. */
case PTRACE_PEEKUSR: {
diff --git a/arch/sh64/kernel/setup.c b/arch/sh64/kernel/setup.c
index 53e9d20..2b7264c 100644
--- a/arch/sh64/kernel/setup.c
+++ b/arch/sh64/kernel/setup.c
@@ -59,10 +59,6 @@
#include <asm/setup.h>
#include <asm/smp.h>
-#ifdef CONFIG_VT
-#include <linux/console.h>
-#endif
-
struct screen_info screen_info;
#ifdef CONFIG_BLK_DEV_RAM
diff --git a/arch/sh64/kernel/signal.c b/arch/sh64/kernel/signal.c
index 0bb4a8f..79fc48c 100644
--- a/arch/sh64/kernel/signal.c
+++ b/arch/sh64/kernel/signal.c
@@ -25,7 +25,6 @@
#include <linux/ptrace.h>
#include <linux/unistd.h>
#include <linux/stddef.h>
-#include <linux/personality.h>
#include <asm/ucontext.h>
#include <asm/uaccess.h>
#include <asm/pgtable.h>
diff --git a/arch/sparc/kernel/ebus.c b/arch/sparc/kernel/ebus.c
index ac352eb..e2d02fd 100644
--- a/arch/sparc/kernel/ebus.c
+++ b/arch/sparc/kernel/ebus.c
@@ -238,6 +238,7 @@
sd = &dev->ofdev.dev.archdata;
sd->prom_node = dp;
sd->op = &dev->ofdev;
+ sd->iommu = dev->bus->ofdev.dev.parent->archdata.iommu;
dev->ofdev.node = dp;
dev->ofdev.dev.parent = &dev->bus->ofdev.dev;
diff --git a/arch/sparc/kernel/prom.c b/arch/sparc/kernel/prom.c
index 39fbd3c..cd4fb79 100644
--- a/arch/sparc/kernel/prom.c
+++ b/arch/sparc/kernel/prom.c
@@ -102,6 +102,21 @@
}
EXPORT_SYMBOL(of_set_property);
+int of_find_in_proplist(const char *list, const char *match, int len)
+{
+ while (len > 0) {
+ int l;
+
+ if (!strcmp(list, match))
+ return 1;
+ l = strlen(list) + 1;
+ list += l;
+ len -= l;
+ }
+ return 0;
+}
+EXPORT_SYMBOL(of_find_in_proplist);
+
static unsigned int prom_early_allocated;
static void * __init prom_early_alloc(unsigned long size)
diff --git a/arch/sparc/mm/io-unit.c b/arch/sparc/mm/io-unit.c
index 4ccda77..7c89893 100644
--- a/arch/sparc/mm/io-unit.c
+++ b/arch/sparc/mm/io-unit.c
@@ -66,7 +66,7 @@
}
if(!xpt) panic("Cannot map External Page Table.");
- sbus->iommu = (struct iommu_struct *)iounit;
+ sbus->ofdev.dev.archdata.iommu = iounit;
iounit->page_table = xpt;
spin_lock_init(&iounit->lock);
@@ -127,7 +127,7 @@
static __u32 iounit_get_scsi_one(char *vaddr, unsigned long len, struct sbus_bus *sbus)
{
unsigned long ret, flags;
- struct iounit_struct *iounit = (struct iounit_struct *)sbus->iommu;
+ struct iounit_struct *iounit = sbus->ofdev.dev.archdata.iommu;
spin_lock_irqsave(&iounit->lock, flags);
ret = iounit_get_area(iounit, (unsigned long)vaddr, len);
@@ -138,7 +138,7 @@
static void iounit_get_scsi_sgl(struct scatterlist *sg, int sz, struct sbus_bus *sbus)
{
unsigned long flags;
- struct iounit_struct *iounit = (struct iounit_struct *)sbus->iommu;
+ struct iounit_struct *iounit = sbus->ofdev.dev.archdata.iommu;
/* FIXME: Cache some resolved pages - often several sg entries are to the same page */
spin_lock_irqsave(&iounit->lock, flags);
@@ -153,7 +153,7 @@
static void iounit_release_scsi_one(__u32 vaddr, unsigned long len, struct sbus_bus *sbus)
{
unsigned long flags;
- struct iounit_struct *iounit = (struct iounit_struct *)sbus->iommu;
+ struct iounit_struct *iounit = sbus->ofdev.dev.archdata.iommu;
spin_lock_irqsave(&iounit->lock, flags);
len = ((vaddr & ~PAGE_MASK) + len + (PAGE_SIZE-1)) >> PAGE_SHIFT;
@@ -168,7 +168,7 @@
{
unsigned long flags;
unsigned long vaddr, len;
- struct iounit_struct *iounit = (struct iounit_struct *)sbus->iommu;
+ struct iounit_struct *iounit = sbus->ofdev.dev.archdata.iommu;
spin_lock_irqsave(&iounit->lock, flags);
while (sz != 0) {
@@ -211,7 +211,7 @@
i = ((addr - IOUNIT_DMA_BASE) >> PAGE_SHIFT);
for_each_sbus(sbus) {
- struct iounit_struct *iounit = (struct iounit_struct *)sbus->iommu;
+ struct iounit_struct *iounit = sbus->ofdev.dev.archdata.iommu;
iopte = (iopte_t *)(iounit->page_table + i);
*iopte = MKIOPTE(__pa(page));
@@ -235,7 +235,7 @@
static struct page *iounit_translate_dvma(unsigned long addr)
{
struct sbus_bus *sbus = sbus_root; /* They are all the same */
- struct iounit_struct *iounit = (struct iounit_struct *)sbus->iommu;
+ struct iounit_struct *iounit = sbus->ofdev.dev.archdata.iommu;
int i;
iopte_t *iopte;
@@ -279,7 +279,7 @@
unsigned long rotor, scan, limit;
unsigned long flags;
__u32 ret;
- struct iounit_struct *iounit = (struct iounit_struct *)sbus->iommu;
+ struct iounit_struct *iounit = sbus->ofdev.dev.archdata.iommu;
npages = (size + (PAGE_SIZE-1)) >> PAGE_SHIFT;
i = 0x0213;
@@ -315,7 +315,7 @@
__u32 iounit_map_dma_page(__u32 vaddr, void *addr, struct sbus_bus *sbus)
{
int scan = (vaddr - IOUNIT_DMA_BASE) >> PAGE_SHIFT;
- struct iounit_struct *iounit = (struct iounit_struct *)sbus->iommu;
+ struct iounit_struct *iounit = sbus->ofdev.dev.archdata.iommu;
iounit->page_table[scan] = MKIOPTE(__pa(((unsigned long)addr) & PAGE_MASK));
return vaddr + (((unsigned long)addr) & ~PAGE_MASK);
diff --git a/arch/sparc/mm/iommu.c b/arch/sparc/mm/iommu.c
index be042ef..52e907a 100644
--- a/arch/sparc/mm/iommu.c
+++ b/arch/sparc/mm/iommu.c
@@ -132,7 +132,7 @@
impl, vers, iommu->page_table,
(int)(IOMMU_NPTES*sizeof(iopte_t)), (int)IOMMU_NPTES);
- sbus->iommu = iommu;
+ sbus->ofdev.dev.archdata.iommu = iommu;
}
/* This begs to be btfixup-ed by srmmu. */
@@ -166,7 +166,7 @@
static u32 iommu_get_one(struct page *page, int npages, struct sbus_bus *sbus)
{
- struct iommu_struct *iommu = sbus->iommu;
+ struct iommu_struct *iommu = sbus->ofdev.dev.archdata.iommu;
int ioptex;
iopte_t *iopte, *iopte0;
unsigned int busa, busa0;
@@ -291,7 +291,7 @@
static void iommu_release_one(u32 busa, int npages, struct sbus_bus *sbus)
{
- struct iommu_struct *iommu = sbus->iommu;
+ struct iommu_struct *iommu = sbus->ofdev.dev.archdata.iommu;
int ioptex;
int i;
@@ -334,7 +334,7 @@
unsigned long addr, int len)
{
unsigned long page, end;
- struct iommu_struct *iommu = sbus_root->iommu;
+ struct iommu_struct *iommu = sbus_root->ofdev.dev.archdata.iommu;
iopte_t *iopte = iommu->page_table;
iopte_t *first;
int ioptex;
@@ -399,7 +399,7 @@
static void iommu_unmap_dma_area(unsigned long busa, int len)
{
- struct iommu_struct *iommu = sbus_root->iommu;
+ struct iommu_struct *iommu = sbus_root->ofdev.dev.archdata.iommu;
iopte_t *iopte = iommu->page_table;
unsigned long end;
int ioptex = (busa - iommu->start) >> PAGE_SHIFT;
@@ -420,7 +420,7 @@
static struct page *iommu_translate_dvma(unsigned long busa)
{
- struct iommu_struct *iommu = sbus_root->iommu;
+ struct iommu_struct *iommu = sbus_root->ofdev.dev.archdata.iommu;
iopte_t *iopte = iommu->page_table;
iopte += ((busa - iommu->start) >> PAGE_SHIFT);
diff --git a/arch/sparc/mm/sun4c.c b/arch/sparc/mm/sun4c.c
index 79d60d8..005a3e7 100644
--- a/arch/sparc/mm/sun4c.c
+++ b/arch/sparc/mm/sun4c.c
@@ -268,7 +268,6 @@
unsigned char savectx, ctx;
savectx = sun4c_get_context();
- kernel_end = SUN4C_REAL_PGDIR_ALIGN(kernel_end);
for (ctx = 0; ctx < num_contexts; ctx++) {
sun4c_set_context(ctx);
for (vaddr = 0; vaddr < 0x20000000; vaddr += SUN4C_REAL_PGDIR_SIZE)
@@ -2064,7 +2063,6 @@
unsigned long end_pfn, pages_avail;
kernel_end = (unsigned long) &end;
- kernel_end += (SUN4C_REAL_PGDIR_SIZE * 4);
kernel_end = SUN4C_REAL_PGDIR_ALIGN(kernel_end);
pages_avail = 0;
diff --git a/arch/sparc64/kernel/cpu.c b/arch/sparc64/kernel/cpu.c
index 7eb81d3..e43db73 100644
--- a/arch/sparc64/kernel/cpu.c
+++ b/arch/sparc64/kernel/cpu.c
@@ -1,7 +1,7 @@
/* cpu.c: Dinky routines to look for the kind of Sparc cpu
* we are on.
*
- * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
+ * Copyright (C) 1996, 2007 David S. Miller (davem@davemloft.net)
*/
#include <linux/kernel.h>
@@ -13,6 +13,7 @@
#include <asm/fpumacro.h>
#include <asm/cpudata.h>
#include <asm/spitfire.h>
+#include <asm/oplib.h>
DEFINE_PER_CPU(cpuinfo_sparc, __cpu_data) = { 0 };
@@ -61,21 +62,40 @@
#define NSPARCCHIPS ARRAY_SIZE(linux_sparc_chips)
-char *sparc_cpu_type = "cpu-oops";
-char *sparc_fpu_type = "fpu-oops";
+char *sparc_cpu_type;
+char *sparc_fpu_type;
unsigned int fsr_storage;
+static void __init sun4v_cpu_probe(void)
+{
+ switch (sun4v_chip_type) {
+ case SUN4V_CHIP_NIAGARA1:
+ sparc_cpu_type = "UltraSparc T1 (Niagara)";
+ sparc_fpu_type = "UltraSparc T1 integrated FPU";
+ break;
+
+ case SUN4V_CHIP_NIAGARA2:
+ sparc_cpu_type = "UltraSparc T2 (Niagara2)";
+ sparc_fpu_type = "UltraSparc T2 integrated FPU";
+ break;
+
+ default:
+ printk(KERN_WARNING "CPU: Unknown sun4v cpu type [%s]\n",
+ prom_cpu_compatible);
+ sparc_cpu_type = "Unknown SUN4V CPU";
+ sparc_fpu_type = "Unknown SUN4V FPU";
+ break;
+ }
+}
+
void __init cpu_probe(void)
{
unsigned long ver, fpu_vers, manuf, impl, fprs;
int i;
- if (tlb_type == hypervisor) {
- sparc_cpu_type = "UltraSparc T1 (Niagara)";
- sparc_fpu_type = "UltraSparc T1 integrated FPU";
- return;
- }
+ if (tlb_type == hypervisor)
+ return sun4v_cpu_probe();
fprs = fprs_read();
fprs_write(FPRS_FEF);
diff --git a/arch/sparc64/kernel/head.S b/arch/sparc64/kernel/head.S
index 9dbd833..63144ad 100644
--- a/arch/sparc64/kernel/head.S
+++ b/arch/sparc64/kernel/head.S
@@ -97,7 +97,8 @@
.globl prom_map_name, prom_unmap_name, prom_mmu_ihandle_cache
.globl prom_boot_mapped_pc, prom_boot_mapping_mode
.globl prom_boot_mapping_phys_high, prom_boot_mapping_phys_low
- .globl is_sun4v
+ .globl prom_compatible_name, prom_cpu_path, prom_cpu_compatible
+ .globl is_sun4v, sun4v_chip_type
prom_peer_name:
.asciz "peer"
prom_compatible_name:
@@ -106,6 +107,8 @@
.asciz "finddevice"
prom_chosen_path:
.asciz "/chosen"
+prom_cpu_path:
+ .asciz "/cpu"
prom_getprop_name:
.asciz "getprop"
prom_mmu_name:
@@ -120,9 +123,13 @@
.asciz "unmap"
prom_sun4v_name:
.asciz "sun4v"
+prom_niagara_prefix:
+ .asciz "SUNW,UltraSPARC-T"
.align 4
prom_root_compatible:
.skip 64
+prom_cpu_compatible:
+ .skip 64
prom_root_node:
.word 0
prom_mmu_ihandle_cache:
@@ -138,6 +145,8 @@
.xword 0
is_sun4v:
.word 0
+sun4v_chip_type:
+ .word SUN4V_CHIP_INVALID
1:
rd %pc, %l0
@@ -296,13 +305,13 @@
sethi %hi(prom_sun4v_name), %g7
or %g7, %lo(prom_sun4v_name), %g7
mov 5, %g3
-1: ldub [%g7], %g2
+90: ldub [%g7], %g2
ldub [%g1], %g4
cmp %g2, %g4
- bne,pn %icc, 2f
+ bne,pn %icc, 80f
add %g7, 1, %g7
subcc %g3, 1, %g3
- bne,pt %xcc, 1b
+ bne,pt %xcc, 90b
add %g1, 1, %g1
sethi %hi(is_sun4v), %g1
@@ -310,7 +319,80 @@
mov 1, %g7
stw %g7, [%g1]
-2:
+ /* cpu_node = prom_finddevice("/cpu") */
+ mov (1b - prom_finddev_name), %l1
+ mov (1b - prom_cpu_path), %l2
+ sub %l0, %l1, %l1
+ sub %l0, %l2, %l2
+ sub %sp, (192 + 128), %sp
+
+ stx %l1, [%sp + 2047 + 128 + 0x00] ! service, "finddevice"
+ mov 1, %l3
+ stx %l3, [%sp + 2047 + 128 + 0x08] ! num_args, 1
+ stx %l3, [%sp + 2047 + 128 + 0x10] ! num_rets, 1
+ stx %l2, [%sp + 2047 + 128 + 0x18] ! arg1, "/cpu"
+ stx %g0, [%sp + 2047 + 128 + 0x20] ! ret1
+ call %l7
+ add %sp, (2047 + 128), %o0 ! argument array
+
+ ldx [%sp + 2047 + 128 + 0x20], %l4 ! cpu device node
+
+ mov (1b - prom_getprop_name), %l1
+ mov (1b - prom_compatible_name), %l2
+ mov (1b - prom_cpu_compatible), %l5
+ sub %l0, %l1, %l1
+ sub %l0, %l2, %l2
+ sub %l0, %l5, %l5
+
+ /* prom_getproperty(cpu_node, "compatible",
+ * &prom_cpu_compatible, 64)
+ */
+ stx %l1, [%sp + 2047 + 128 + 0x00] ! service, "getprop"
+ mov 4, %l3
+ stx %l3, [%sp + 2047 + 128 + 0x08] ! num_args, 4
+ mov 1, %l3
+ stx %l3, [%sp + 2047 + 128 + 0x10] ! num_rets, 1
+ stx %l4, [%sp + 2047 + 128 + 0x18] ! arg1, cpu_node
+ stx %l2, [%sp + 2047 + 128 + 0x20] ! arg2, "compatible"
+ stx %l5, [%sp + 2047 + 128 + 0x28] ! arg3, &prom_cpu_compatible
+ mov 64, %l3
+ stx %l3, [%sp + 2047 + 128 + 0x30] ! arg4, size
+ stx %g0, [%sp + 2047 + 128 + 0x38] ! ret1
+ call %l7
+ add %sp, (2047 + 128), %o0 ! argument array
+
+ add %sp, (192 + 128), %sp
+
+ sethi %hi(prom_cpu_compatible), %g1
+ or %g1, %lo(prom_cpu_compatible), %g1
+ sethi %hi(prom_niagara_prefix), %g7
+ or %g7, %lo(prom_niagara_prefix), %g7
+ mov 17, %g3
+90: ldub [%g7], %g2
+ ldub [%g1], %g4
+ cmp %g2, %g4
+ bne,pn %icc, 4f
+ add %g7, 1, %g7
+ subcc %g3, 1, %g3
+ bne,pt %xcc, 90b
+ add %g1, 1, %g1
+
+ sethi %hi(prom_cpu_compatible), %g1
+ or %g1, %lo(prom_cpu_compatible), %g1
+ ldub [%g1 + 17], %g2
+ cmp %g2, '1'
+ be,pt %xcc, 5f
+ mov SUN4V_CHIP_NIAGARA1, %g4
+ cmp %g2, '2'
+ be,pt %xcc, 5f
+ mov SUN4V_CHIP_NIAGARA2, %g4
+4:
+ mov SUN4V_CHIP_UNKNOWN, %g4
+5: sethi %hi(sun4v_chip_type), %g2
+ or %g2, %lo(sun4v_chip_type), %g2
+ stw %g4, [%g2]
+
+80:
BRANCH_IF_SUN4V(g1, jump_to_sun4u_init)
BRANCH_IF_CHEETAH_BASE(g1,g7,cheetah_boot)
BRANCH_IF_CHEETAH_PLUS_OR_FOLLOWON(g1,g7,cheetah_plus_boot)
@@ -414,6 +496,33 @@
stw %g2, [%g1 + %lo(tlb_type)]
/* Patch copy/clear ops. */
+ sethi %hi(sun4v_chip_type), %g1
+ lduw [%g1 + %lo(sun4v_chip_type)], %g1
+ cmp %g1, SUN4V_CHIP_NIAGARA1
+ be,pt %xcc, niagara_patch
+ cmp %g1, SUN4V_CHIP_NIAGARA2
+ be,pt %xcc, niagara2_patch
+ nop
+
+ call generic_patch_copyops
+ nop
+ call generic_patch_bzero
+ nop
+ call generic_patch_pageops
+ nop
+
+ ba,a,pt %xcc, 80f
+niagara2_patch:
+ call niagara2_patch_copyops
+ nop
+ call niagara_patch_bzero
+ nop
+ call niagara2_patch_pageops
+ nop
+
+ ba,a,pt %xcc, 80f
+
+niagara_patch:
call niagara_patch_copyops
nop
call niagara_patch_bzero
@@ -421,6 +530,7 @@
call niagara_patch_pageops
nop
+80:
/* Patch TLB/cache ops. */
call hypervisor_patch_cachetlbops
nop
@@ -605,12 +715,13 @@
membar #Sync
+ BRANCH_IF_SUN4V(o2, 1f)
+
/* Kill PROM timer */
sethi %hi(0x80000000), %o2
sllx %o2, 32, %o2
wr %o2, 0, %tick_cmpr
- BRANCH_IF_SUN4V(o2, 1f)
BRANCH_IF_ANY_CHEETAH(o2, o3, 1f)
ba,pt %xcc, 2f
diff --git a/arch/sparc64/kernel/hvtramp.S b/arch/sparc64/kernel/hvtramp.S
index a55c252..b692e04 100644
--- a/arch/sparc64/kernel/hvtramp.S
+++ b/arch/sparc64/kernel/hvtramp.S
@@ -115,11 +115,8 @@
call hard_smp_processor_id
nop
- mov %o0, %o1
- mov 0, %o0
- mov 0, %o2
- call sun4v_init_mondo_queues
- mov 1, %o3
+ call sun4v_register_mondo_queues
+ nop
call init_cur_cpu_trap
mov %g6, %o0
diff --git a/arch/sparc64/kernel/irq.c b/arch/sparc64/kernel/irq.c
index db31bf6..384abf4 100644
--- a/arch/sparc64/kernel/irq.c
+++ b/arch/sparc64/kernel/irq.c
@@ -929,7 +929,7 @@
}
}
-static void __cpuinit sun4v_register_mondo_queues(int this_cpu)
+void __cpuinit sun4v_register_mondo_queues(int this_cpu)
{
struct trap_per_cpu *tb = &trap_block[this_cpu];
@@ -943,20 +943,10 @@
tb->nonresum_qmask);
}
-static void __cpuinit alloc_one_mondo(unsigned long *pa_ptr, unsigned long qmask, int use_bootmem)
+static void __init alloc_one_mondo(unsigned long *pa_ptr, unsigned long qmask)
{
unsigned long size = PAGE_ALIGN(qmask + 1);
- unsigned long order = get_order(size);
- void *p = NULL;
-
- if (use_bootmem) {
- p = __alloc_bootmem_low(size, size, 0);
- } else {
- struct page *page = alloc_pages(GFP_ATOMIC | __GFP_ZERO, order);
- if (page)
- p = page_address(page);
- }
-
+ void *p = __alloc_bootmem_low(size, size, 0);
if (!p) {
prom_printf("SUN4V: Error, cannot allocate mondo queue.\n");
prom_halt();
@@ -965,19 +955,10 @@
*pa_ptr = __pa(p);
}
-static void __cpuinit alloc_one_kbuf(unsigned long *pa_ptr, unsigned long qmask, int use_bootmem)
+static void __init alloc_one_kbuf(unsigned long *pa_ptr, unsigned long qmask)
{
unsigned long size = PAGE_ALIGN(qmask + 1);
- unsigned long order = get_order(size);
- void *p = NULL;
-
- if (use_bootmem) {
- p = __alloc_bootmem_low(size, size, 0);
- } else {
- struct page *page = alloc_pages(GFP_ATOMIC | __GFP_ZERO, order);
- if (page)
- p = page_address(page);
- }
+ void *p = __alloc_bootmem_low(size, size, 0);
if (!p) {
prom_printf("SUN4V: Error, cannot allocate kbuf page.\n");
@@ -987,18 +968,14 @@
*pa_ptr = __pa(p);
}
-static void __cpuinit init_cpu_send_mondo_info(struct trap_per_cpu *tb, int use_bootmem)
+static void __init init_cpu_send_mondo_info(struct trap_per_cpu *tb)
{
#ifdef CONFIG_SMP
void *page;
BUILD_BUG_ON((NR_CPUS * sizeof(u16)) > (PAGE_SIZE - 64));
- if (use_bootmem)
- page = alloc_bootmem_low_pages(PAGE_SIZE);
- else
- page = (void *) get_zeroed_page(GFP_ATOMIC);
-
+ page = alloc_bootmem_low_pages(PAGE_SIZE);
if (!page) {
prom_printf("SUN4V: Error, cannot allocate cpu mondo page.\n");
prom_halt();
@@ -1009,30 +986,27 @@
#endif
}
-/* Allocate and register the mondo and error queues for this cpu. */
-void __cpuinit sun4v_init_mondo_queues(int use_bootmem, int cpu, int alloc, int load)
+/* Allocate mondo and error queues for all possible cpus. */
+static void __init sun4v_init_mondo_queues(void)
{
- struct trap_per_cpu *tb = &trap_block[cpu];
+ int cpu;
- if (alloc) {
- alloc_one_mondo(&tb->cpu_mondo_pa, tb->cpu_mondo_qmask, use_bootmem);
- alloc_one_mondo(&tb->dev_mondo_pa, tb->dev_mondo_qmask, use_bootmem);
- alloc_one_mondo(&tb->resum_mondo_pa, tb->resum_qmask, use_bootmem);
- alloc_one_kbuf(&tb->resum_kernel_buf_pa, tb->resum_qmask, use_bootmem);
- alloc_one_mondo(&tb->nonresum_mondo_pa, tb->nonresum_qmask, use_bootmem);
- alloc_one_kbuf(&tb->nonresum_kernel_buf_pa, tb->nonresum_qmask, use_bootmem);
+ for_each_possible_cpu(cpu) {
+ struct trap_per_cpu *tb = &trap_block[cpu];
- init_cpu_send_mondo_info(tb, use_bootmem);
+ alloc_one_mondo(&tb->cpu_mondo_pa, tb->cpu_mondo_qmask);
+ alloc_one_mondo(&tb->dev_mondo_pa, tb->dev_mondo_qmask);
+ alloc_one_mondo(&tb->resum_mondo_pa, tb->resum_qmask);
+ alloc_one_kbuf(&tb->resum_kernel_buf_pa, tb->resum_qmask);
+ alloc_one_mondo(&tb->nonresum_mondo_pa, tb->nonresum_qmask);
+ alloc_one_kbuf(&tb->nonresum_kernel_buf_pa,
+ tb->nonresum_qmask);
+
+ init_cpu_send_mondo_info(tb);
}
- if (load) {
- if (cpu != hard_smp_processor_id()) {
- prom_printf("SUN4V: init mondo on cpu %d not %d\n",
- cpu, hard_smp_processor_id());
- prom_halt();
- }
- sun4v_register_mondo_queues(cpu);
- }
+ /* Load up the boot cpu's entries. */
+ sun4v_register_mondo_queues(hard_smp_processor_id());
}
static struct irqaction timer_irq_action = {
@@ -1047,7 +1021,7 @@
memset(&ivector_table[0], 0, sizeof(ivector_table));
if (tlb_type == hypervisor)
- sun4v_init_mondo_queues(1, hard_smp_processor_id(), 1, 1);
+ sun4v_init_mondo_queues();
/* We need to clear any IRQ's pending in the soft interrupt
* registers, a spurious one could be left around from the
diff --git a/arch/sparc64/kernel/mdesc.c b/arch/sparc64/kernel/mdesc.c
index cce4d0d..9f22e4f 100644
--- a/arch/sparc64/kernel/mdesc.c
+++ b/arch/sparc64/kernel/mdesc.c
@@ -9,6 +9,7 @@
#include <linux/list.h>
#include <linux/slab.h>
#include <linux/mm.h>
+#include <linux/miscdevice.h>
#include <asm/hypervisor.h>
#include <asm/mdesc.h>
@@ -568,20 +569,6 @@
mdesc_release(hp);
}
-static int inline find_in_proplist(const char *list, const char *match, int len)
-{
- while (len > 0) {
- int l;
-
- if (!strcmp(list, match))
- return 1;
- l = strlen(list) + 1;
- list += l;
- len -= l;
- }
- return 0;
-}
-
static void __devinit fill_in_one_cache(cpuinfo_sparc *c,
struct mdesc_handle *hp,
u64 mp)
@@ -596,10 +583,10 @@
switch (*level) {
case 1:
- if (find_in_proplist(type, "instn", type_len)) {
+ if (of_find_in_proplist(type, "instn", type_len)) {
c->icache_size = *size;
c->icache_line_size = *line_size;
- } else if (find_in_proplist(type, "data", type_len)) {
+ } else if (of_find_in_proplist(type, "data", type_len)) {
c->dcache_size = *size;
c->dcache_line_size = *line_size;
}
@@ -677,7 +664,7 @@
continue;
type = mdesc_get_property(hp, mp, "type", &len);
- if (!find_in_proplist(type, "instn", len))
+ if (!of_find_in_proplist(type, "instn", len))
continue;
mark_core_ids(hp, mp, idx);
@@ -718,8 +705,8 @@
int len;
type = mdesc_get_property(hp, mp, "type", &len);
- if (!find_in_proplist(type, "int", len) &&
- !find_in_proplist(type, "integer", len))
+ if (!of_find_in_proplist(type, "int", len) &&
+ !of_find_in_proplist(type, "integer", len))
continue;
mark_proc_ids(hp, mp, idx);
@@ -850,6 +837,43 @@
mdesc_release(hp);
}
+static ssize_t mdesc_read(struct file *file, char __user *buf,
+ size_t len, loff_t *offp)
+{
+ struct mdesc_handle *hp = mdesc_grab();
+ int err;
+
+ if (!hp)
+ return -ENODEV;
+
+ err = hp->handle_size;
+ if (len < hp->handle_size)
+ err = -EMSGSIZE;
+ else if (copy_to_user(buf, &hp->mdesc, hp->handle_size))
+ err = -EFAULT;
+ mdesc_release(hp);
+
+ return err;
+}
+
+static const struct file_operations mdesc_fops = {
+ .read = mdesc_read,
+ .owner = THIS_MODULE,
+};
+
+static struct miscdevice mdesc_misc = {
+ .minor = MISC_DYNAMIC_MINOR,
+ .name = "mdesc",
+ .fops = &mdesc_fops,
+};
+
+static int __init mdesc_misc_init(void)
+{
+ return misc_register(&mdesc_misc);
+}
+
+__initcall(mdesc_misc_init);
+
void __init sun4v_mdesc_init(void)
{
struct mdesc_handle *hp;
diff --git a/arch/sparc64/kernel/prom.c b/arch/sparc64/kernel/prom.c
index f4e0a9a..d1a78c9 100644
--- a/arch/sparc64/kernel/prom.c
+++ b/arch/sparc64/kernel/prom.c
@@ -107,6 +107,21 @@
}
EXPORT_SYMBOL(of_set_property);
+int of_find_in_proplist(const char *list, const char *match, int len)
+{
+ while (len > 0) {
+ int l;
+
+ if (!strcmp(list, match))
+ return 1;
+ l = strlen(list) + 1;
+ list += l;
+ len -= l;
+ }
+ return 0;
+}
+EXPORT_SYMBOL(of_find_in_proplist);
+
static unsigned int prom_early_allocated;
static void * __init prom_early_alloc(unsigned long size)
diff --git a/arch/sparc64/kernel/smp.c b/arch/sparc64/kernel/smp.c
index b448d33..b84c49e 100644
--- a/arch/sparc64/kernel/smp.c
+++ b/arch/sparc64/kernel/smp.c
@@ -334,8 +334,6 @@
}
#endif
-extern void sun4v_init_mondo_queues(int use_bootmem, int cpu, int alloc, int load);
-
extern unsigned long sparc64_cpu_startup;
/* The OBP cpu startup callback truncates the 3rd arg cookie to
@@ -359,9 +357,6 @@
cpu_new_thread = task_thread_info(p);
if (tlb_type == hypervisor) {
- /* Alloc the mondo queues, cpu will load them. */
- sun4v_init_mondo_queues(0, cpu, 1, 0);
-
#if defined(CONFIG_SUN_LDOMS) && defined(CONFIG_HOTPLUG_CPU)
if (ldom_domaining_enabled)
ldom_startcpu_cpuid(cpu,
diff --git a/arch/sparc64/kernel/sparc64_ksyms.c b/arch/sparc64/kernel/sparc64_ksyms.c
index d270c2f..23fad7e 100644
--- a/arch/sparc64/kernel/sparc64_ksyms.c
+++ b/arch/sparc64/kernel/sparc64_ksyms.c
@@ -168,6 +168,7 @@
EXPORT_SYMBOL(__flushw_user);
EXPORT_SYMBOL(tlb_type);
+EXPORT_SYMBOL(sun4v_chip_type);
EXPORT_SYMBOL(get_fb_unmapped_area);
EXPORT_SYMBOL(flush_icache_range);
diff --git a/arch/sparc64/kernel/trampoline.S b/arch/sparc64/kernel/trampoline.S
index a4dc01a..9533a25 100644
--- a/arch/sparc64/kernel/trampoline.S
+++ b/arch/sparc64/kernel/trampoline.S
@@ -95,14 +95,13 @@
membar #Sync
startup_continue:
+ mov %o0, %l0
+ BRANCH_IF_SUN4V(g1, niagara_lock_tlb)
+
sethi %hi(0x80000000), %g2
sllx %g2, 32, %g2
wr %g2, 0, %tick_cmpr
- mov %o0, %l0
-
- BRANCH_IF_SUN4V(g1, niagara_lock_tlb)
-
/* Call OBP by hand to lock KERNBASE into i/d tlbs.
* We lock 2 consequetive entries if we are 'bigkernel'.
*/
@@ -366,11 +365,8 @@
call hard_smp_processor_id
nop
- mov %o0, %o1
- mov 0, %o0
- mov 0, %o2
- call sun4v_init_mondo_queues
- mov 1, %o3
+ call sun4v_register_mondo_queues
+ nop
1: call init_cur_cpu_trap
ldx [%l0], %o0
diff --git a/arch/sparc64/kernel/vio.c b/arch/sparc64/kernel/vio.c
index 3685daf..1550ac5 100644
--- a/arch/sparc64/kernel/vio.c
+++ b/arch/sparc64/kernel/vio.c
@@ -16,21 +16,6 @@
#include <asm/mdesc.h>
#include <asm/vio.h>
-static inline int find_in_proplist(const char *list, const char *match,
- int len)
-{
- while (len > 0) {
- int l;
-
- if (!strcmp(list, match))
- return 1;
- l = strlen(list) + 1;
- list += l;
- len -= l;
- }
- return 0;
-}
-
static const struct vio_device_id *vio_match_device(
const struct vio_device_id *matches,
const struct vio_dev *dev)
@@ -49,7 +34,7 @@
if (matches->compat[0]) {
match &= len &&
- find_in_proplist(compat, matches->compat, len);
+ of_find_in_proplist(compat, matches->compat, len);
}
if (match)
return matches;
@@ -406,7 +391,7 @@
"property\n");
goto out_release;
}
- if (!find_in_proplist(compat, channel_devices_compat, len)) {
+ if (!of_find_in_proplist(compat, channel_devices_compat, len)) {
printk(KERN_ERR "VIO: Channel devices node lacks (%s) "
"compat entry.\n", channel_devices_compat);
goto out_release;
diff --git a/arch/sparc64/lib/GENbzero.S b/arch/sparc64/lib/GENbzero.S
new file mode 100644
index 0000000..f9c71d6
--- /dev/null
+++ b/arch/sparc64/lib/GENbzero.S
@@ -0,0 +1,160 @@
+/* GENbzero.S: Generic sparc64 memset/clear_user.
+ *
+ * Copyright (C) 2007 David S. Miller (davem@davemloft.net)
+ */
+#include <asm/asi.h>
+
+#define EX_ST(x,y) \
+98: x,y; \
+ .section .fixup; \
+ .align 4; \
+99: retl; \
+ mov %o1, %o0; \
+ .section __ex_table; \
+ .align 4; \
+ .word 98b, 99b; \
+ .text; \
+ .align 4;
+
+ .align 32
+ .text
+
+ .globl GENmemset
+ .type GENmemset, #function
+GENmemset: /* %o0=buf, %o1=pat, %o2=len */
+ and %o1, 0xff, %o3
+ mov %o2, %o1
+ sllx %o3, 8, %g1
+ or %g1, %o3, %o2
+ sllx %o2, 16, %g1
+ or %g1, %o2, %o2
+ sllx %o2, 32, %g1
+ ba,pt %xcc, 1f
+ or %g1, %o2, %o2
+
+ .globl GENbzero
+ .type GENbzero, #function
+GENbzero:
+ clr %o2
+1: brz,pn %o1, GENbzero_return
+ mov %o0, %o3
+
+ /* %o5: saved %asi, restored at GENbzero_done
+ * %o4: store %asi to use
+ */
+ rd %asi, %o5
+ mov ASI_P, %o4
+ wr %o4, 0x0, %asi
+
+GENbzero_from_clear_user:
+ cmp %o1, 15
+ bl,pn %icc, GENbzero_tiny
+ andcc %o0, 0x7, %g1
+ be,pt %xcc, 2f
+ mov 8, %g2
+ sub %g2, %g1, %g1
+ sub %o1, %g1, %o1
+1: EX_ST(stba %o2, [%o0 + 0x00] %asi)
+ subcc %g1, 1, %g1
+ bne,pt %xcc, 1b
+ add %o0, 1, %o0
+2: cmp %o1, 128
+ bl,pn %icc, GENbzero_medium
+ andcc %o0, (64 - 1), %g1
+ be,pt %xcc, GENbzero_pre_loop
+ mov 64, %g2
+ sub %g2, %g1, %g1
+ sub %o1, %g1, %o1
+1: EX_ST(stxa %o2, [%o0 + 0x00] %asi)
+ subcc %g1, 8, %g1
+ bne,pt %xcc, 1b
+ add %o0, 8, %o0
+
+GENbzero_pre_loop:
+ andn %o1, (64 - 1), %g1
+ sub %o1, %g1, %o1
+GENbzero_loop:
+ EX_ST(stxa %o2, [%o0 + 0x00] %asi)
+ EX_ST(stxa %o2, [%o0 + 0x08] %asi)
+ EX_ST(stxa %o2, [%o0 + 0x10] %asi)
+ EX_ST(stxa %o2, [%o0 + 0x18] %asi)
+ EX_ST(stxa %o2, [%o0 + 0x20] %asi)
+ EX_ST(stxa %o2, [%o0 + 0x28] %asi)
+ EX_ST(stxa %o2, [%o0 + 0x30] %asi)
+ EX_ST(stxa %o2, [%o0 + 0x38] %asi)
+ subcc %g1, 64, %g1
+ bne,pt %xcc, GENbzero_loop
+ add %o0, 64, %o0
+
+ membar #Sync
+ wr %o4, 0x0, %asi
+ brz,pn %o1, GENbzero_done
+GENbzero_medium:
+ andncc %o1, 0x7, %g1
+ be,pn %xcc, 2f
+ sub %o1, %g1, %o1
+1: EX_ST(stxa %o2, [%o0 + 0x00] %asi)
+ subcc %g1, 8, %g1
+ bne,pt %xcc, 1b
+ add %o0, 8, %o0
+2: brz,pt %o1, GENbzero_done
+ nop
+
+GENbzero_tiny:
+1: EX_ST(stba %o2, [%o0 + 0x00] %asi)
+ subcc %o1, 1, %o1
+ bne,pt %icc, 1b
+ add %o0, 1, %o0
+
+ /* fallthrough */
+
+GENbzero_done:
+ wr %o5, 0x0, %asi
+
+GENbzero_return:
+ retl
+ mov %o3, %o0
+ .size GENbzero, .-GENbzero
+ .size GENmemset, .-GENmemset
+
+ .globl GENclear_user
+ .type GENclear_user, #function
+GENclear_user: /* %o0=buf, %o1=len */
+ rd %asi, %o5
+ brz,pn %o1, GENbzero_done
+ clr %o3
+ cmp %o5, ASI_AIUS
+ bne,pn %icc, GENbzero
+ clr %o2
+ ba,pt %xcc, GENbzero_from_clear_user
+ mov ASI_AIUS, %o4
+ .size GENclear_user, .-GENclear_user
+
+#define BRANCH_ALWAYS 0x10680000
+#define NOP 0x01000000
+#define GEN_DO_PATCH(OLD, NEW) \
+ sethi %hi(NEW), %g1; \
+ or %g1, %lo(NEW), %g1; \
+ sethi %hi(OLD), %g2; \
+ or %g2, %lo(OLD), %g2; \
+ sub %g1, %g2, %g1; \
+ sethi %hi(BRANCH_ALWAYS), %g3; \
+ sll %g1, 11, %g1; \
+ srl %g1, 11 + 2, %g1; \
+ or %g3, %lo(BRANCH_ALWAYS), %g3; \
+ or %g3, %g1, %g3; \
+ stw %g3, [%g2]; \
+ sethi %hi(NOP), %g3; \
+ or %g3, %lo(NOP), %g3; \
+ stw %g3, [%g2 + 0x4]; \
+ flush %g2;
+
+ .globl generic_patch_bzero
+ .type generic_patch_bzero,#function
+generic_patch_bzero:
+ GEN_DO_PATCH(memset, GENmemset)
+ GEN_DO_PATCH(__bzero, GENbzero)
+ GEN_DO_PATCH(__clear_user, GENclear_user)
+ retl
+ nop
+ .size generic_patch_bzero,.-generic_patch_bzero
diff --git a/arch/sparc64/lib/GENcopy_from_user.S b/arch/sparc64/lib/GENcopy_from_user.S
new file mode 100644
index 0000000..2b9df99
--- /dev/null
+++ b/arch/sparc64/lib/GENcopy_from_user.S
@@ -0,0 +1,34 @@
+/* GENcopy_from_user.S: Generic sparc64 copy from userspace.
+ *
+ * Copyright (C) 2007 David S. Miller (davem@davemloft.net)
+ */
+
+#define EX_LD(x) \
+98: x; \
+ .section .fixup; \
+ .align 4; \
+99: retl; \
+ mov 1, %o0; \
+ .section __ex_table,"a";\
+ .align 4; \
+ .word 98b, 99b; \
+ .text; \
+ .align 4;
+
+#ifndef ASI_AIUS
+#define ASI_AIUS 0x11
+#endif
+
+#define FUNC_NAME GENcopy_from_user
+#define LOAD(type,addr,dest) type##a [addr] ASI_AIUS, dest
+#define EX_RETVAL(x) 0
+
+#ifdef __KERNEL__
+#define PREAMBLE \
+ rd %asi, %g1; \
+ cmp %g1, ASI_AIUS; \
+ bne,pn %icc, memcpy_user_stub; \
+ nop
+#endif
+
+#include "GENmemcpy.S"
diff --git a/arch/sparc64/lib/GENcopy_to_user.S b/arch/sparc64/lib/GENcopy_to_user.S
new file mode 100644
index 0000000..bb3f708
--- /dev/null
+++ b/arch/sparc64/lib/GENcopy_to_user.S
@@ -0,0 +1,38 @@
+/* GENcopy_to_user.S: Generic sparc64 copy to userspace.
+ *
+ * Copyright (C) 2007 David S. Miller (davem@davemloft.net)
+ */
+
+#define EX_ST(x) \
+98: x; \
+ .section .fixup; \
+ .align 4; \
+99: retl; \
+ mov 1, %o0; \
+ .section __ex_table,"a";\
+ .align 4; \
+ .word 98b, 99b; \
+ .text; \
+ .align 4;
+
+#ifndef ASI_AIUS
+#define ASI_AIUS 0x11
+#endif
+
+#define FUNC_NAME GENcopy_to_user
+#define STORE(type,src,addr) type##a src, [addr] ASI_AIUS
+#define EX_RETVAL(x) 0
+
+#ifdef __KERNEL__
+ /* Writing to %asi is _expensive_ so we hardcode it.
+ * Reading %asi to check for KERNEL_DS is comparatively
+ * cheap.
+ */
+#define PREAMBLE \
+ rd %asi, %g1; \
+ cmp %g1, ASI_AIUS; \
+ bne,pn %icc, memcpy_user_stub; \
+ nop
+#endif
+
+#include "GENmemcpy.S"
diff --git a/arch/sparc64/lib/GENmemcpy.S b/arch/sparc64/lib/GENmemcpy.S
new file mode 100644
index 0000000..89358ee
--- /dev/null
+++ b/arch/sparc64/lib/GENmemcpy.S
@@ -0,0 +1,121 @@
+/* GENmemcpy.S: Generic sparc64 memcpy.
+ *
+ * Copyright (C) 2007 David S. Miller (davem@davemloft.net)
+ */
+
+#ifdef __KERNEL__
+#define GLOBAL_SPARE %g7
+#else
+#define GLOBAL_SPARE %g5
+#endif
+
+#ifndef EX_LD
+#define EX_LD(x) x
+#endif
+
+#ifndef EX_ST
+#define EX_ST(x) x
+#endif
+
+#ifndef EX_RETVAL
+#define EX_RETVAL(x) x
+#endif
+
+#ifndef LOAD
+#define LOAD(type,addr,dest) type [addr], dest
+#endif
+
+#ifndef STORE
+#define STORE(type,src,addr) type src, [addr]
+#endif
+
+#ifndef FUNC_NAME
+#define FUNC_NAME GENmemcpy
+#endif
+
+#ifndef PREAMBLE
+#define PREAMBLE
+#endif
+
+#ifndef XCC
+#define XCC xcc
+#endif
+
+ .register %g2,#scratch
+ .register %g3,#scratch
+
+ .text
+ .align 64
+
+ .globl FUNC_NAME
+ .type FUNC_NAME,#function
+FUNC_NAME: /* %o0=dst, %o1=src, %o2=len */
+ srlx %o2, 31, %g2
+ cmp %g2, 0
+ tne %XCC, 5
+ PREAMBLE
+ mov %o0, GLOBAL_SPARE
+
+ cmp %o2, 0
+ be,pn %XCC, 85f
+ or %o0, %o1, %o3
+ cmp %o2, 16
+ blu,a,pn %XCC, 80f
+ or %o3, %o2, %o3
+
+ xor %o0, %o1, %o4
+ andcc %o4, 0x7, %g0
+ bne,a,pn %XCC, 90f
+ sub %o0, %o1, %o3
+
+ and %o0, 0x7, %o4
+ sub %o4, 0x8, %o4
+ sub %g0, %o4, %o4
+ sub %o2, %o4, %o2
+1: subcc %o4, 1, %o4
+ EX_LD(LOAD(ldub, %o1, %g1))
+ EX_ST(STORE(stb, %g1, %o0))
+ add %o1, 1, %o1
+ bne,pt %XCC, 1b
+ add %o0, 1, %o0
+
+ andn %o2, 0x7, %g1
+ sub %o2, %g1, %o2
+1: subcc %g1, 0x8, %g1
+ EX_LD(LOAD(ldx, %o1, %g2))
+ EX_ST(STORE(stx, %g2, %o0))
+ add %o1, 0x8, %o1
+ bne,pt %XCC, 1b
+ add %o0, 0x8, %o0
+
+ brz,pt %o2, 85f
+ sub %o0, %o1, %o3
+ ba,a,pt %XCC, 90f
+
+ .align 64
+80: /* 0 < len <= 16 */
+ andcc %o3, 0x3, %g0
+ bne,pn %XCC, 90f
+ sub %o0, %o1, %o3
+
+1:
+ subcc %o2, 4, %o2
+ EX_LD(LOAD(lduw, %o1, %g1))
+ EX_ST(STORE(stw, %g1, %o1 + %o3))
+ bgu,pt %XCC, 1b
+ add %o1, 4, %o1
+
+85: retl
+ mov EX_RETVAL(GLOBAL_SPARE), %o0
+
+ .align 32
+90:
+ subcc %o2, 1, %o2
+ EX_LD(LOAD(ldub, %o1, %g1))
+ EX_ST(STORE(stb, %g1, %o1 + %o3))
+ bgu,pt %XCC, 90b
+ add %o1, 1, %o1
+ retl
+ mov EX_RETVAL(GLOBAL_SPARE), %o0
+
+ .size FUNC_NAME, .-FUNC_NAME
diff --git a/arch/sparc64/lib/GENpage.S b/arch/sparc64/lib/GENpage.S
new file mode 100644
index 0000000..2ef9d05
--- /dev/null
+++ b/arch/sparc64/lib/GENpage.S
@@ -0,0 +1,77 @@
+/* GENpage.S: Generic clear and copy page.
+ *
+ * Copyright (C) 2007 (davem@davemloft.net)
+ */
+#include <asm/page.h>
+
+ .text
+ .align 32
+
+GENcopy_user_page:
+ set PAGE_SIZE, %g7
+1: ldx [%o1 + 0x00], %o2
+ ldx [%o1 + 0x08], %o3
+ ldx [%o1 + 0x10], %o4
+ ldx [%o1 + 0x18], %o5
+ stx %o2, [%o0 + 0x00]
+ stx %o3, [%o0 + 0x08]
+ stx %o4, [%o0 + 0x10]
+ stx %o5, [%o0 + 0x18]
+ ldx [%o1 + 0x20], %o2
+ ldx [%o1 + 0x28], %o3
+ ldx [%o1 + 0x30], %o4
+ ldx [%o1 + 0x38], %o5
+ stx %o2, [%o0 + 0x20]
+ stx %o3, [%o0 + 0x28]
+ stx %o4, [%o0 + 0x30]
+ stx %o5, [%o0 + 0x38]
+ subcc %g7, 64, %g7
+ add %o1, 64, %o1
+ bne,pt %xcc, 1b
+ add %o0, 64, %o0
+ retl
+ nop
+
+GENclear_page:
+GENclear_user_page:
+ set PAGE_SIZE, %g7
+1: stx %g0, [%o0 + 0x00]
+ stx %g0, [%o0 + 0x08]
+ stx %g0, [%o0 + 0x10]
+ stx %g0, [%o0 + 0x18]
+ stx %g0, [%o0 + 0x20]
+ stx %g0, [%o0 + 0x28]
+ stx %g0, [%o0 + 0x30]
+ stx %g0, [%o0 + 0x38]
+ subcc %g7, 64, %g7
+ bne,pt %xcc, 1b
+ add %o0, 64, %o0
+
+#define BRANCH_ALWAYS 0x10680000
+#define NOP 0x01000000
+#define GEN_DO_PATCH(OLD, NEW) \
+ sethi %hi(NEW), %g1; \
+ or %g1, %lo(NEW), %g1; \
+ sethi %hi(OLD), %g2; \
+ or %g2, %lo(OLD), %g2; \
+ sub %g1, %g2, %g1; \
+ sethi %hi(BRANCH_ALWAYS), %g3; \
+ sll %g1, 11, %g1; \
+ srl %g1, 11 + 2, %g1; \
+ or %g3, %lo(BRANCH_ALWAYS), %g3; \
+ or %g3, %g1, %g3; \
+ stw %g3, [%g2]; \
+ sethi %hi(NOP), %g3; \
+ or %g3, %lo(NOP), %g3; \
+ stw %g3, [%g2 + 0x4]; \
+ flush %g2;
+
+ .globl generic_patch_pageops
+ .type generic_patch_pageops,#function
+generic_patch_pageops:
+ GEN_DO_PATCH(copy_user_page, GENcopy_user_page)
+ GEN_DO_PATCH(_clear_page, GENclear_page)
+ GEN_DO_PATCH(clear_user_page, GENclear_user_page)
+ retl
+ nop
+ .size generic_patch_pageops,.-generic_patch_pageops
diff --git a/arch/sparc64/lib/GENpatch.S b/arch/sparc64/lib/GENpatch.S
new file mode 100644
index 0000000..fab9e89
--- /dev/null
+++ b/arch/sparc64/lib/GENpatch.S
@@ -0,0 +1,33 @@
+/* GENpatch.S: Patch Ultra-I routines with generic variant.
+ *
+ * Copyright (C) 2007 David S. Miller <davem@davemloft.net>
+ */
+
+#define BRANCH_ALWAYS 0x10680000
+#define NOP 0x01000000
+#define GEN_DO_PATCH(OLD, NEW) \
+ sethi %hi(NEW), %g1; \
+ or %g1, %lo(NEW), %g1; \
+ sethi %hi(OLD), %g2; \
+ or %g2, %lo(OLD), %g2; \
+ sub %g1, %g2, %g1; \
+ sethi %hi(BRANCH_ALWAYS), %g3; \
+ sll %g1, 11, %g1; \
+ srl %g1, 11 + 2, %g1; \
+ or %g3, %lo(BRANCH_ALWAYS), %g3; \
+ or %g3, %g1, %g3; \
+ stw %g3, [%g2]; \
+ sethi %hi(NOP), %g3; \
+ or %g3, %lo(NOP), %g3; \
+ stw %g3, [%g2 + 0x4]; \
+ flush %g2;
+
+ .globl generic_patch_copyops
+ .type generic_patch_copyops,#function
+generic_patch_copyops:
+ GEN_DO_PATCH(memcpy, GENmemcpy)
+ GEN_DO_PATCH(___copy_from_user, GENcopy_from_user)
+ GEN_DO_PATCH(___copy_to_user, GENcopy_to_user)
+ retl
+ nop
+ .size generic_patch_copyops,.-generic_patch_copyops
diff --git a/arch/sparc64/lib/Makefile b/arch/sparc64/lib/Makefile
index c4a6d6e..f095e13 100644
--- a/arch/sparc64/lib/Makefile
+++ b/arch/sparc64/lib/Makefile
@@ -1,4 +1,4 @@
-# $Id: Makefile,v 1.25 2000/12/14 22:57:25 davem Exp $
+#
# Makefile for Sparc64 library files..
#
@@ -13,6 +13,10 @@
U3memcpy.o U3copy_from_user.o U3copy_to_user.o U3patch.o \
NGmemcpy.o NGcopy_from_user.o NGcopy_to_user.o NGpatch.o \
NGpage.o NGbzero.o \
+ NG2memcpy.o NG2copy_from_user.o NG2copy_to_user.o NG2patch.o \
+ NG2page.o \
+ GENmemcpy.o GENcopy_from_user.o GENcopy_to_user.o GENpatch.o \
+ GENpage.o GENbzero.o \
copy_in_user.o user_fixup.o memmove.o \
mcount.o ipcsum.o rwsem.o xor.o
diff --git a/arch/sparc64/lib/NG2copy_from_user.S b/arch/sparc64/lib/NG2copy_from_user.S
new file mode 100644
index 0000000..c77ef5f
--- /dev/null
+++ b/arch/sparc64/lib/NG2copy_from_user.S
@@ -0,0 +1,40 @@
+/* NG2copy_from_user.S: Niagara-2 optimized copy from userspace.
+ *
+ * Copyright (C) 2007 David S. Miller (davem@davemloft.net)
+ */
+
+#define EX_LD(x) \
+98: x; \
+ .section .fixup; \
+ .align 4; \
+99: wr %g0, ASI_AIUS, %asi;\
+ retl; \
+ mov 1, %o0; \
+ .section __ex_table,"a";\
+ .align 4; \
+ .word 98b, 99b; \
+ .text; \
+ .align 4;
+
+#ifndef ASI_AIUS
+#define ASI_AIUS 0x11
+#endif
+
+#ifndef ASI_BLK_AIUS_4V
+#define ASI_BLK_AIUS_4V 0x17
+#endif
+
+#define FUNC_NAME NG2copy_from_user
+#define LOAD(type,addr,dest) type##a [addr] %asi, dest
+#define LOAD_BLK(addr,dest) ldda [addr] ASI_BLK_AIUS_4V, dest
+#define EX_RETVAL(x) 0
+
+#ifdef __KERNEL__
+#define PREAMBLE \
+ rd %asi, %g1; \
+ cmp %g1, ASI_AIUS; \
+ bne,pn %icc, memcpy_user_stub; \
+ nop
+#endif
+
+#include "NG2memcpy.S"
diff --git a/arch/sparc64/lib/NG2copy_to_user.S b/arch/sparc64/lib/NG2copy_to_user.S
new file mode 100644
index 0000000..4bd4093
--- /dev/null
+++ b/arch/sparc64/lib/NG2copy_to_user.S
@@ -0,0 +1,49 @@
+/* NG2copy_to_user.S: Niagara-2 optimized copy to userspace.
+ *
+ * Copyright (C) 2007 David S. Miller (davem@davemloft.net)
+ */
+
+#define EX_ST(x) \
+98: x; \
+ .section .fixup; \
+ .align 4; \
+99: wr %g0, ASI_AIUS, %asi;\
+ retl; \
+ mov 1, %o0; \
+ .section __ex_table,"a";\
+ .align 4; \
+ .word 98b, 99b; \
+ .text; \
+ .align 4;
+
+#ifndef ASI_AIUS
+#define ASI_AIUS 0x11
+#endif
+
+#ifndef ASI_BLK_AIUS_4V
+#define ASI_BLK_AIUS_4V 0x17
+#endif
+
+#ifndef ASI_BLK_INIT_QUAD_LDD_AIUS
+#define ASI_BLK_INIT_QUAD_LDD_AIUS 0x23
+#endif
+
+#define FUNC_NAME NG2copy_to_user
+#define STORE(type,src,addr) type##a src, [addr] ASI_AIUS
+#define STORE_ASI ASI_BLK_INIT_QUAD_LDD_AIUS
+#define STORE_BLK(src,addr) stda src, [addr] ASI_BLK_AIUS_4V
+#define EX_RETVAL(x) 0
+
+#ifdef __KERNEL__
+ /* Writing to %asi is _expensive_ so we hardcode it.
+ * Reading %asi to check for KERNEL_DS is comparatively
+ * cheap.
+ */
+#define PREAMBLE \
+ rd %asi, %g1; \
+ cmp %g1, ASI_AIUS; \
+ bne,pn %icc, memcpy_user_stub; \
+ nop
+#endif
+
+#include "NG2memcpy.S"
diff --git a/arch/sparc64/lib/NG2memcpy.S b/arch/sparc64/lib/NG2memcpy.S
new file mode 100644
index 0000000..0aed756
--- /dev/null
+++ b/arch/sparc64/lib/NG2memcpy.S
@@ -0,0 +1,520 @@
+/* NG2memcpy.S: Niagara-2 optimized memcpy.
+ *
+ * Copyright (C) 2007 David S. Miller (davem@davemloft.net)
+ */
+
+#ifdef __KERNEL__
+#include <asm/visasm.h>
+#include <asm/asi.h>
+#define GLOBAL_SPARE %g7
+#else
+#define ASI_PNF 0x82
+#define ASI_BLK_P 0xf0
+#define ASI_BLK_INIT_QUAD_LDD_P 0xe2
+#define FPRS_FEF 0x04
+#ifdef MEMCPY_DEBUG
+#define VISEntryHalf rd %fprs, %o5; wr %g0, FPRS_FEF, %fprs; \
+ clr %g1; clr %g2; clr %g3; subcc %g0, %g0, %g0;
+#define VISExitHalf and %o5, FPRS_FEF, %o5; wr %o5, 0x0, %fprs
+#else
+#define VISEntryHalf rd %fprs, %o5; wr %g0, FPRS_FEF, %fprs
+#define VISExitHalf and %o5, FPRS_FEF, %o5; wr %o5, 0x0, %fprs
+#endif
+#define GLOBAL_SPARE %g5
+#endif
+
+#ifndef STORE_ASI
+#ifndef SIMULATE_NIAGARA_ON_NON_NIAGARA
+#define STORE_ASI ASI_BLK_INIT_QUAD_LDD_P
+#else
+#define STORE_ASI 0x80 /* ASI_P */
+#endif
+#endif
+
+#ifndef EX_LD
+#define EX_LD(x) x
+#endif
+
+#ifndef EX_ST
+#define EX_ST(x) x
+#endif
+
+#ifndef EX_RETVAL
+#define EX_RETVAL(x) x
+#endif
+
+#ifndef LOAD
+#define LOAD(type,addr,dest) type [addr], dest
+#endif
+
+#ifndef LOAD_BLK
+#define LOAD_BLK(addr,dest) ldda [addr] ASI_BLK_P, dest
+#endif
+
+#ifndef STORE
+#ifndef MEMCPY_DEBUG
+#define STORE(type,src,addr) type src, [addr]
+#else
+#define STORE(type,src,addr) type##a src, [addr] 0x80
+#endif
+#endif
+
+#ifndef STORE_BLK
+#define STORE_BLK(src,addr) stda src, [addr] ASI_BLK_P
+#endif
+
+#ifndef STORE_INIT
+#define STORE_INIT(src,addr) stxa src, [addr] STORE_ASI
+#endif
+
+#ifndef FUNC_NAME
+#define FUNC_NAME NG2memcpy
+#endif
+
+#ifndef PREAMBLE
+#define PREAMBLE
+#endif
+
+#ifndef XCC
+#define XCC xcc
+#endif
+
+#define FREG_FROB(x0, x1, x2, x3, x4, x5, x6, x7, x8) \
+ faligndata %x0, %x1, %f0; \
+ faligndata %x1, %x2, %f2; \
+ faligndata %x2, %x3, %f4; \
+ faligndata %x3, %x4, %f6; \
+ faligndata %x4, %x5, %f8; \
+ faligndata %x5, %x6, %f10; \
+ faligndata %x6, %x7, %f12; \
+ faligndata %x7, %x8, %f14;
+
+#define FREG_MOVE_1(x0) \
+ fmovd %x0, %f0;
+#define FREG_MOVE_2(x0, x1) \
+ fmovd %x0, %f0; \
+ fmovd %x1, %f2;
+#define FREG_MOVE_3(x0, x1, x2) \
+ fmovd %x0, %f0; \
+ fmovd %x1, %f2; \
+ fmovd %x2, %f4;
+#define FREG_MOVE_4(x0, x1, x2, x3) \
+ fmovd %x0, %f0; \
+ fmovd %x1, %f2; \
+ fmovd %x2, %f4; \
+ fmovd %x3, %f6;
+#define FREG_MOVE_5(x0, x1, x2, x3, x4) \
+ fmovd %x0, %f0; \
+ fmovd %x1, %f2; \
+ fmovd %x2, %f4; \
+ fmovd %x3, %f6; \
+ fmovd %x4, %f8;
+#define FREG_MOVE_6(x0, x1, x2, x3, x4, x5) \
+ fmovd %x0, %f0; \
+ fmovd %x1, %f2; \
+ fmovd %x2, %f4; \
+ fmovd %x3, %f6; \
+ fmovd %x4, %f8; \
+ fmovd %x5, %f10;
+#define FREG_MOVE_7(x0, x1, x2, x3, x4, x5, x6) \
+ fmovd %x0, %f0; \
+ fmovd %x1, %f2; \
+ fmovd %x2, %f4; \
+ fmovd %x3, %f6; \
+ fmovd %x4, %f8; \
+ fmovd %x5, %f10; \
+ fmovd %x6, %f12;
+#define FREG_MOVE_8(x0, x1, x2, x3, x4, x5, x6, x7) \
+ fmovd %x0, %f0; \
+ fmovd %x1, %f2; \
+ fmovd %x2, %f4; \
+ fmovd %x3, %f6; \
+ fmovd %x4, %f8; \
+ fmovd %x5, %f10; \
+ fmovd %x6, %f12; \
+ fmovd %x7, %f14;
+#define FREG_LOAD_1(base, x0) \
+ EX_LD(LOAD(ldd, base + 0x00, %x0))
+#define FREG_LOAD_2(base, x0, x1) \
+ EX_LD(LOAD(ldd, base + 0x00, %x0)); \
+ EX_LD(LOAD(ldd, base + 0x08, %x1));
+#define FREG_LOAD_3(base, x0, x1, x2) \
+ EX_LD(LOAD(ldd, base + 0x00, %x0)); \
+ EX_LD(LOAD(ldd, base + 0x08, %x1)); \
+ EX_LD(LOAD(ldd, base + 0x10, %x2));
+#define FREG_LOAD_4(base, x0, x1, x2, x3) \
+ EX_LD(LOAD(ldd, base + 0x00, %x0)); \
+ EX_LD(LOAD(ldd, base + 0x08, %x1)); \
+ EX_LD(LOAD(ldd, base + 0x10, %x2)); \
+ EX_LD(LOAD(ldd, base + 0x18, %x3));
+#define FREG_LOAD_5(base, x0, x1, x2, x3, x4) \
+ EX_LD(LOAD(ldd, base + 0x00, %x0)); \
+ EX_LD(LOAD(ldd, base + 0x08, %x1)); \
+ EX_LD(LOAD(ldd, base + 0x10, %x2)); \
+ EX_LD(LOAD(ldd, base + 0x18, %x3)); \
+ EX_LD(LOAD(ldd, base + 0x20, %x4));
+#define FREG_LOAD_6(base, x0, x1, x2, x3, x4, x5) \
+ EX_LD(LOAD(ldd, base + 0x00, %x0)); \
+ EX_LD(LOAD(ldd, base + 0x08, %x1)); \
+ EX_LD(LOAD(ldd, base + 0x10, %x2)); \
+ EX_LD(LOAD(ldd, base + 0x18, %x3)); \
+ EX_LD(LOAD(ldd, base + 0x20, %x4)); \
+ EX_LD(LOAD(ldd, base + 0x28, %x5));
+#define FREG_LOAD_7(base, x0, x1, x2, x3, x4, x5, x6) \
+ EX_LD(LOAD(ldd, base + 0x00, %x0)); \
+ EX_LD(LOAD(ldd, base + 0x08, %x1)); \
+ EX_LD(LOAD(ldd, base + 0x10, %x2)); \
+ EX_LD(LOAD(ldd, base + 0x18, %x3)); \
+ EX_LD(LOAD(ldd, base + 0x20, %x4)); \
+ EX_LD(LOAD(ldd, base + 0x28, %x5)); \
+ EX_LD(LOAD(ldd, base + 0x30, %x6));
+
+ .register %g2,#scratch
+ .register %g3,#scratch
+
+ .text
+ .align 64
+
+ .globl FUNC_NAME
+ .type FUNC_NAME,#function
+FUNC_NAME: /* %o0=dst, %o1=src, %o2=len */
+ srlx %o2, 31, %g2
+ cmp %g2, 0
+ tne %xcc, 5
+ PREAMBLE
+ mov %o0, GLOBAL_SPARE
+ cmp %o2, 0
+ be,pn %XCC, 85f
+ or %o0, %o1, %o3
+ cmp %o2, 16
+ blu,a,pn %XCC, 80f
+ or %o3, %o2, %o3
+
+ /* 2 blocks (128 bytes) is the minimum we can do the block
+ * copy with. We need to ensure that we'll iterate at least
+ * once in the block copy loop. At worst we'll need to align
+ * the destination to a 64-byte boundary which can chew up
+ * to (64 - 1) bytes from the length before we perform the
+ * block copy loop.
+ *
+ * However, the cut-off point, performance wise, is around
+ * 4 64-byte blocks.
+ */
+ cmp %o2, (4 * 64)
+ blu,pt %XCC, 75f
+ andcc %o3, 0x7, %g0
+
+ /* %o0: dst
+ * %o1: src
+ * %o2: len (known to be >= 128)
+ *
+ * The block copy loops can use %o4, %g2, %g3 as
+ * temporaries while copying the data. %o5 must
+ * be preserved between VISEntryHalf and VISExitHalf
+ */
+
+ LOAD(prefetch, %o1 + 0x000, #one_read)
+ LOAD(prefetch, %o1 + 0x040, #one_read)
+ LOAD(prefetch, %o1 + 0x080, #one_read)
+
+ /* Align destination on 64-byte boundary. */
+ andcc %o0, (64 - 1), %o4
+ be,pt %XCC, 2f
+ sub %o4, 64, %o4
+ sub %g0, %o4, %o4 ! bytes to align dst
+ sub %o2, %o4, %o2
+1: subcc %o4, 1, %o4
+ EX_LD(LOAD(ldub, %o1, %g1))
+ EX_ST(STORE(stb, %g1, %o0))
+ add %o1, 1, %o1
+ bne,pt %XCC, 1b
+ add %o0, 1, %o0
+
+2:
+ /* Clobbers o5/g1/g2/g3/g7/icc/xcc. We must preserve
+ * o5 from here until we hit VISExitHalf.
+ */
+ VISEntryHalf
+
+ alignaddr %o1, %g0, %g0
+
+ add %o1, (64 - 1), %o4
+ andn %o4, (64 - 1), %o4
+ andn %o2, (64 - 1), %g1
+ sub %o2, %g1, %o2
+
+ and %o1, (64 - 1), %g2
+ add %o1, %g1, %o1
+ sub %o0, %o4, %g3
+ brz,pt %g2, 190f
+ cmp %g2, 32
+ blu,a 5f
+ cmp %g2, 16
+ cmp %g2, 48
+ blu,a 4f
+ cmp %g2, 40
+ cmp %g2, 56
+ blu 170f
+ nop
+ ba,a,pt %xcc, 180f
+
+4: /* 32 <= low bits < 48 */
+ blu 150f
+ nop
+ ba,a,pt %xcc, 160f
+5: /* 0 < low bits < 32 */
+ blu,a 6f
+ cmp %g2, 8
+ cmp %g2, 24
+ blu 130f
+ nop
+ ba,a,pt %xcc, 140f
+6: /* 0 < low bits < 16 */
+ bgeu 120f
+ nop
+ /* fall through for 0 < low bits < 8 */
+110: sub %o4, 64, %g2
+ EX_LD(LOAD_BLK(%g2, %f0))
+1: EX_ST(STORE_INIT(%g0, %o4 + %g3))
+ EX_LD(LOAD_BLK(%o4, %f16))
+ FREG_FROB(f0, f2, f4, f6, f8, f10, f12, f14, f16)
+ EX_ST(STORE_BLK(%f0, %o4 + %g3))
+ FREG_MOVE_8(f16, f18, f20, f22, f24, f26, f28, f30)
+ subcc %g1, 64, %g1
+ add %o4, 64, %o4
+ bne,pt %xcc, 1b
+ LOAD(prefetch, %o4 + 64, #one_read)
+ ba,pt %xcc, 195f
+ nop
+
+120: sub %o4, 56, %g2
+ FREG_LOAD_7(%g2, f0, f2, f4, f6, f8, f10, f12)
+1: EX_ST(STORE_INIT(%g0, %o4 + %g3))
+ EX_LD(LOAD_BLK(%o4, %f16))
+ FREG_FROB(f0, f2, f4, f6, f8, f10, f12, f16, f18)
+ EX_ST(STORE_BLK(%f0, %o4 + %g3))
+ FREG_MOVE_7(f18, f20, f22, f24, f26, f28, f30)
+ subcc %g1, 64, %g1
+ add %o4, 64, %o4
+ bne,pt %xcc, 1b
+ LOAD(prefetch, %o4 + 64, #one_read)
+ ba,pt %xcc, 195f
+ nop
+
+130: sub %o4, 48, %g2
+ FREG_LOAD_6(%g2, f0, f2, f4, f6, f8, f10)
+1: EX_ST(STORE_INIT(%g0, %o4 + %g3))
+ EX_LD(LOAD_BLK(%o4, %f16))
+ FREG_FROB(f0, f2, f4, f6, f8, f10, f16, f18, f20)
+ EX_ST(STORE_BLK(%f0, %o4 + %g3))
+ FREG_MOVE_6(f20, f22, f24, f26, f28, f30)
+ subcc %g1, 64, %g1
+ add %o4, 64, %o4
+ bne,pt %xcc, 1b
+ LOAD(prefetch, %o4 + 64, #one_read)
+ ba,pt %xcc, 195f
+ nop
+
+140: sub %o4, 40, %g2
+ FREG_LOAD_5(%g2, f0, f2, f4, f6, f8)
+1: EX_ST(STORE_INIT(%g0, %o4 + %g3))
+ EX_LD(LOAD_BLK(%o4, %f16))
+ FREG_FROB(f0, f2, f4, f6, f8, f16, f18, f20, f22)
+ EX_ST(STORE_BLK(%f0, %o4 + %g3))
+ FREG_MOVE_5(f22, f24, f26, f28, f30)
+ subcc %g1, 64, %g1
+ add %o4, 64, %o4
+ bne,pt %xcc, 1b
+ LOAD(prefetch, %o4 + 64, #one_read)
+ ba,pt %xcc, 195f
+ nop
+
+150: sub %o4, 32, %g2
+ FREG_LOAD_4(%g2, f0, f2, f4, f6)
+1: EX_ST(STORE_INIT(%g0, %o4 + %g3))
+ EX_LD(LOAD_BLK(%o4, %f16))
+ FREG_FROB(f0, f2, f4, f6, f16, f18, f20, f22, f24)
+ EX_ST(STORE_BLK(%f0, %o4 + %g3))
+ FREG_MOVE_4(f24, f26, f28, f30)
+ subcc %g1, 64, %g1
+ add %o4, 64, %o4
+ bne,pt %xcc, 1b
+ LOAD(prefetch, %o4 + 64, #one_read)
+ ba,pt %xcc, 195f
+ nop
+
+160: sub %o4, 24, %g2
+ FREG_LOAD_3(%g2, f0, f2, f4)
+1: EX_ST(STORE_INIT(%g0, %o4 + %g3))
+ EX_LD(LOAD_BLK(%o4, %f16))
+ FREG_FROB(f0, f2, f4, f16, f18, f20, f22, f24, f26)
+ EX_ST(STORE_BLK(%f0, %o4 + %g3))
+ FREG_MOVE_3(f26, f28, f30)
+ subcc %g1, 64, %g1
+ add %o4, 64, %o4
+ bne,pt %xcc, 1b
+ LOAD(prefetch, %o4 + 64, #one_read)
+ ba,pt %xcc, 195f
+ nop
+
+170: sub %o4, 16, %g2
+ FREG_LOAD_2(%g2, f0, f2)
+1: EX_ST(STORE_INIT(%g0, %o4 + %g3))
+ EX_LD(LOAD_BLK(%o4, %f16))
+ FREG_FROB(f0, f2, f16, f18, f20, f22, f24, f26, f28)
+ EX_ST(STORE_BLK(%f0, %o4 + %g3))
+ FREG_MOVE_2(f28, f30)
+ subcc %g1, 64, %g1
+ add %o4, 64, %o4
+ bne,pt %xcc, 1b
+ LOAD(prefetch, %o4 + 64, #one_read)
+ ba,pt %xcc, 195f
+ nop
+
+180: sub %o4, 8, %g2
+ FREG_LOAD_1(%g2, f0)
+1: EX_ST(STORE_INIT(%g0, %o4 + %g3))
+ EX_LD(LOAD_BLK(%o4, %f16))
+ FREG_FROB(f0, f16, f18, f20, f22, f24, f26, f28, f30)
+ EX_ST(STORE_BLK(%f0, %o4 + %g3))
+ FREG_MOVE_1(f30)
+ subcc %g1, 64, %g1
+ add %o4, 64, %o4
+ bne,pt %xcc, 1b
+ LOAD(prefetch, %o4 + 64, #one_read)
+ ba,pt %xcc, 195f
+ nop
+
+190:
+1: EX_ST(STORE_INIT(%g0, %o4 + %g3))
+ subcc %g1, 64, %g1
+ EX_LD(LOAD_BLK(%o4, %f0))
+ EX_ST(STORE_BLK(%f0, %o4 + %g3))
+ add %o4, 64, %o4
+ bne,pt %xcc, 1b
+ LOAD(prefetch, %o4 + 64, #one_read)
+
+195:
+ add %o4, %g3, %o0
+ membar #Sync
+
+ VISExitHalf
+
+ /* %o2 contains any final bytes still needed to be copied
+ * over. If anything is left, we copy it one byte at a time.
+ */
+ brz,pt %o2, 85f
+ sub %o0, %o1, %o3
+ ba,a,pt %XCC, 90f
+
+ .align 64
+75: /* 16 < len <= 64 */
+ bne,pn %XCC, 75f
+ sub %o0, %o1, %o3
+
+72:
+ andn %o2, 0xf, %o4
+ and %o2, 0xf, %o2
+1: subcc %o4, 0x10, %o4
+ EX_LD(LOAD(ldx, %o1, %o5))
+ add %o1, 0x08, %o1
+ EX_LD(LOAD(ldx, %o1, %g1))
+ sub %o1, 0x08, %o1
+ EX_ST(STORE(stx, %o5, %o1 + %o3))
+ add %o1, 0x8, %o1
+ EX_ST(STORE(stx, %g1, %o1 + %o3))
+ bgu,pt %XCC, 1b
+ add %o1, 0x8, %o1
+73: andcc %o2, 0x8, %g0
+ be,pt %XCC, 1f
+ nop
+ sub %o2, 0x8, %o2
+ EX_LD(LOAD(ldx, %o1, %o5))
+ EX_ST(STORE(stx, %o5, %o1 + %o3))
+ add %o1, 0x8, %o1
+1: andcc %o2, 0x4, %g0
+ be,pt %XCC, 1f
+ nop
+ sub %o2, 0x4, %o2
+ EX_LD(LOAD(lduw, %o1, %o5))
+ EX_ST(STORE(stw, %o5, %o1 + %o3))
+ add %o1, 0x4, %o1
+1: cmp %o2, 0
+ be,pt %XCC, 85f
+ nop
+ ba,pt %xcc, 90f
+ nop
+
+75:
+ andcc %o0, 0x7, %g1
+ sub %g1, 0x8, %g1
+ be,pn %icc, 2f
+ sub %g0, %g1, %g1
+ sub %o2, %g1, %o2
+
+1: subcc %g1, 1, %g1
+ EX_LD(LOAD(ldub, %o1, %o5))
+ EX_ST(STORE(stb, %o5, %o1 + %o3))
+ bgu,pt %icc, 1b
+ add %o1, 1, %o1
+
+2: add %o1, %o3, %o0
+ andcc %o1, 0x7, %g1
+ bne,pt %icc, 8f
+ sll %g1, 3, %g1
+
+ cmp %o2, 16
+ bgeu,pt %icc, 72b
+ nop
+ ba,a,pt %xcc, 73b
+
+8: mov 64, %o3
+ andn %o1, 0x7, %o1
+ EX_LD(LOAD(ldx, %o1, %g2))
+ sub %o3, %g1, %o3
+ andn %o2, 0x7, %o4
+ sllx %g2, %g1, %g2
+1: add %o1, 0x8, %o1
+ EX_LD(LOAD(ldx, %o1, %g3))
+ subcc %o4, 0x8, %o4
+ srlx %g3, %o3, %o5
+ or %o5, %g2, %o5
+ EX_ST(STORE(stx, %o5, %o0))
+ add %o0, 0x8, %o0
+ bgu,pt %icc, 1b
+ sllx %g3, %g1, %g2
+
+ srl %g1, 3, %g1
+ andcc %o2, 0x7, %o2
+ be,pn %icc, 85f
+ add %o1, %g1, %o1
+ ba,pt %xcc, 90f
+ sub %o0, %o1, %o3
+
+ .align 64
+80: /* 0 < len <= 16 */
+ andcc %o3, 0x3, %g0
+ bne,pn %XCC, 90f
+ sub %o0, %o1, %o3
+
+1:
+ subcc %o2, 4, %o2
+ EX_LD(LOAD(lduw, %o1, %g1))
+ EX_ST(STORE(stw, %g1, %o1 + %o3))
+ bgu,pt %XCC, 1b
+ add %o1, 4, %o1
+
+85: retl
+ mov EX_RETVAL(GLOBAL_SPARE), %o0
+
+ .align 32
+90:
+ subcc %o2, 1, %o2
+ EX_LD(LOAD(ldub, %o1, %g1))
+ EX_ST(STORE(stb, %g1, %o1 + %o3))
+ bgu,pt %XCC, 90b
+ add %o1, 1, %o1
+ retl
+ mov EX_RETVAL(GLOBAL_SPARE), %o0
+
+ .size FUNC_NAME, .-FUNC_NAME
diff --git a/arch/sparc64/lib/NG2page.S b/arch/sparc64/lib/NG2page.S
new file mode 100644
index 0000000..73b6b7c
--- /dev/null
+++ b/arch/sparc64/lib/NG2page.S
@@ -0,0 +1,61 @@
+/* NG2page.S: Niagara-2 optimized clear and copy page.
+ *
+ * Copyright (C) 2007 (davem@davemloft.net)
+ */
+
+#include <asm/asi.h>
+#include <asm/page.h>
+#include <asm/visasm.h>
+
+ .text
+ .align 32
+
+ /* This is heavily simplified from the sun4u variants
+ * because Niagara-2 does not have any D-cache aliasing issues.
+ */
+NG2copy_user_page: /* %o0=dest, %o1=src, %o2=vaddr */
+ prefetch [%o1 + 0x00], #one_read
+ prefetch [%o1 + 0x40], #one_read
+ VISEntryHalf
+ set PAGE_SIZE, %g7
+ sub %o0, %o1, %g3
+1: stxa %g0, [%o1 + %g3] ASI_BLK_INIT_QUAD_LDD_P
+ subcc %g7, 64, %g7
+ ldda [%o1] ASI_BLK_P, %f0
+ stda %f0, [%o1 + %g3] ASI_BLK_P
+ add %o1, 64, %o1
+ bne,pt %xcc, 1b
+ prefetch [%o1 + 0x40], #one_read
+ membar #Sync
+ VISExitHalf
+ retl
+ nop
+
+#define BRANCH_ALWAYS 0x10680000
+#define NOP 0x01000000
+#define NG_DO_PATCH(OLD, NEW) \
+ sethi %hi(NEW), %g1; \
+ or %g1, %lo(NEW), %g1; \
+ sethi %hi(OLD), %g2; \
+ or %g2, %lo(OLD), %g2; \
+ sub %g1, %g2, %g1; \
+ sethi %hi(BRANCH_ALWAYS), %g3; \
+ sll %g1, 11, %g1; \
+ srl %g1, 11 + 2, %g1; \
+ or %g3, %lo(BRANCH_ALWAYS), %g3; \
+ or %g3, %g1, %g3; \
+ stw %g3, [%g2]; \
+ sethi %hi(NOP), %g3; \
+ or %g3, %lo(NOP), %g3; \
+ stw %g3, [%g2 + 0x4]; \
+ flush %g2;
+
+ .globl niagara2_patch_pageops
+ .type niagara2_patch_pageops,#function
+niagara2_patch_pageops:
+ NG_DO_PATCH(copy_user_page, NG2copy_user_page)
+ NG_DO_PATCH(_clear_page, NGclear_page)
+ NG_DO_PATCH(clear_user_page, NGclear_user_page)
+ retl
+ nop
+ .size niagara2_patch_pageops,.-niagara2_patch_pageops
diff --git a/arch/sparc64/lib/NG2patch.S b/arch/sparc64/lib/NG2patch.S
new file mode 100644
index 0000000..28c36f0
--- /dev/null
+++ b/arch/sparc64/lib/NG2patch.S
@@ -0,0 +1,33 @@
+/* NG2patch.S: Patch Ultra-I routines with Niagara-2 variant.
+ *
+ * Copyright (C) 2007 David S. Miller <davem@davemloft.net>
+ */
+
+#define BRANCH_ALWAYS 0x10680000
+#define NOP 0x01000000
+#define NG_DO_PATCH(OLD, NEW) \
+ sethi %hi(NEW), %g1; \
+ or %g1, %lo(NEW), %g1; \
+ sethi %hi(OLD), %g2; \
+ or %g2, %lo(OLD), %g2; \
+ sub %g1, %g2, %g1; \
+ sethi %hi(BRANCH_ALWAYS), %g3; \
+ sll %g1, 11, %g1; \
+ srl %g1, 11 + 2, %g1; \
+ or %g3, %lo(BRANCH_ALWAYS), %g3; \
+ or %g3, %g1, %g3; \
+ stw %g3, [%g2]; \
+ sethi %hi(NOP), %g3; \
+ or %g3, %lo(NOP), %g3; \
+ stw %g3, [%g2 + 0x4]; \
+ flush %g2;
+
+ .globl niagara2_patch_copyops
+ .type niagara2_patch_copyops,#function
+niagara2_patch_copyops:
+ NG_DO_PATCH(memcpy, NG2memcpy)
+ NG_DO_PATCH(___copy_from_user, NG2copy_from_user)
+ NG_DO_PATCH(___copy_to_user, NG2copy_to_user)
+ retl
+ nop
+ .size niagara2_patch_copyops,.-niagara2_patch_copyops
diff --git a/arch/sparc64/lib/NGpage.S b/arch/sparc64/lib/NGpage.S
index 8ce3a0c..428920d 100644
--- a/arch/sparc64/lib/NGpage.S
+++ b/arch/sparc64/lib/NGpage.S
@@ -45,6 +45,7 @@
retl
nop
+ .globl NGclear_page, NGclear_user_page
NGclear_page: /* %o0=dest */
NGclear_user_page: /* %o0=dest, %o1=vaddr */
mov 8, %g1
diff --git a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c
index aff661f..0eabe73 100644
--- a/arch/um/drivers/ubd_kern.c
+++ b/arch/um/drivers/ubd_kern.c
@@ -612,6 +612,8 @@
ubd_dev->fd = fd;
if(ubd_dev->cow.file != NULL){
+ blk_queue_max_sectors(ubd_dev->queue, 8 * sizeof(long));
+
err = -ENOMEM;
ubd_dev->cow.bitmap = (void *) vmalloc(ubd_dev->cow.bitmap_len);
if(ubd_dev->cow.bitmap == NULL){
@@ -712,8 +714,6 @@
ubd_dev->queue->queuedata = ubd_dev;
blk_queue_max_hw_segments(ubd_dev->queue, MAX_SG);
- if(ubd_dev->cow.file != NULL)
- blk_queue_max_sectors(ubd_dev->queue, 8 * sizeof(long));
err = ubd_disk_register(MAJOR_NR, ubd_dev->size, n, &ubd_gendisk[n]);
if(err){
*error_out = "Failed to register device";
diff --git a/arch/x86_64/Makefile b/arch/x86_64/Makefile
index 128561d..b024e4a 100644
--- a/arch/x86_64/Makefile
+++ b/arch/x86_64/Makefile
@@ -57,8 +57,8 @@
cflags-y += -maccumulate-outgoing-args
# do binutils support CFI?
-cflags-y += $(call as-instr,.cfi_startproc\n.cfi_endproc,-DCONFIG_AS_CFI=1,)
-AFLAGS += $(call as-instr,.cfi_startproc\n.cfi_endproc,-DCONFIG_AS_CFI=1,)
+cflags-y += $(call as-instr,.cfi_startproc\n.cfi_rel_offset rsp${comma}0\n.cfi_endproc,-DCONFIG_AS_CFI=1,)
+AFLAGS += $(call as-instr,.cfi_startproc\n.cfi_rel_offset rsp${comma}0\n.cfi_endproc,-DCONFIG_AS_CFI=1,)
# is .cfi_signal_frame supported too?
cflags-y += $(call as-instr,.cfi_startproc\n.cfi_signal_frame\n.cfi_endproc,-DCONFIG_AS_CFI_SIGNAL_FRAME=1,)
diff --git a/arch/x86_64/boot/compressed/head.S b/arch/x86_64/boot/compressed/head.S
index 1312bfa..9fd8030 100644
--- a/arch/x86_64/boot/compressed/head.S
+++ b/arch/x86_64/boot/compressed/head.S
@@ -195,6 +195,11 @@
movl %eax, %ds
movl %eax, %es
movl %eax, %ss
+ movl %eax, %fs
+ movl %eax, %gs
+ lldt %ax
+ movl $0x20, %eax
+ ltr %ax
/* Compute the decompressed kernel start address. It is where
* we were loaded at aligned to a 2M boundary. %rbp contains the
@@ -295,6 +300,8 @@
.quad 0x0000000000000000 /* NULL descriptor */
.quad 0x00af9a000000ffff /* __KERNEL_CS */
.quad 0x00cf92000000ffff /* __KERNEL_DS */
+ .quad 0x0080890000000000 /* TS descriptor */
+ .quad 0x0000000000000000 /* TS continued */
gdt_end:
.bss
/* Stack for uncompression */
diff --git a/arch/x86_64/kernel/apic.c b/arch/x86_64/kernel/apic.c
index 900ff38..925758d 100644
--- a/arch/x86_64/kernel/apic.c
+++ b/arch/x86_64/kernel/apic.c
@@ -791,10 +791,8 @@
/* wait for irq slice */
if (hpet_address && hpet_use_timer) {
- int trigger = hpet_readl(HPET_T0_CMP);
- while (hpet_readl(HPET_COUNTER) >= trigger)
- /* do nothing */ ;
- while (hpet_readl(HPET_COUNTER) < trigger)
+ u32 trigger = hpet_readl(HPET_T0_CMP);
+ while (hpet_readl(HPET_T0_CMP) == trigger)
/* do nothing */ ;
} else {
int c1, c2;
diff --git a/arch/x86_64/kernel/head.S b/arch/x86_64/kernel/head.S
index e89abcd..b6167fe 100644
--- a/arch/x86_64/kernel/head.S
+++ b/arch/x86_64/kernel/head.S
@@ -345,8 +345,7 @@
/* 40MB kernel mapping. The kernel code cannot be bigger than that.
When you change this change KERNEL_TEXT_SIZE in page.h too. */
/* (2^48-(2*1024*1024*1024)-((2^39)*511)-((2^30)*510)) = 0 */
- PMDS(0x0000000000000000, __PAGE_KERNEL_LARGE_EXEC|_PAGE_GLOBAL,
- KERNEL_TEXT_SIZE/PMD_SIZE)
+ PMDS(0x0000000000000000, __PAGE_KERNEL_LARGE_EXEC|_PAGE_GLOBAL, KERNEL_TEXT_SIZE/PMD_SIZE)
/* Module mapping starts here */
.fill (PTRS_PER_PMD - (KERNEL_TEXT_SIZE/PMD_SIZE)),8,0
diff --git a/arch/x86_64/kernel/io_apic.c b/arch/x86_64/kernel/io_apic.c
index 050141c..966fa10 100644
--- a/arch/x86_64/kernel/io_apic.c
+++ b/arch/x86_64/kernel/io_apic.c
@@ -397,14 +397,12 @@
int skip_ioapic_setup;
int ioapic_force;
-/* dummy parsing: see setup.c */
-
-static int __init disable_ioapic_setup(char *str)
+static int __init parse_noapic(char *str)
{
- skip_ioapic_setup = 1;
+ disable_ioapic_setup();
return 0;
}
-early_param("noapic", disable_ioapic_setup);
+early_param("noapic", parse_noapic);
/* Actually the next is obsolete, but keep it for paranoid reasons -AK */
static int __init disable_timer_pin_setup(char *arg)
@@ -800,12 +798,15 @@
static void ioapic_register_intr(int irq, unsigned long trigger)
{
- if (trigger)
+ if (trigger) {
+ irq_desc[irq].status |= IRQ_LEVEL;
set_irq_chip_and_handler_name(irq, &ioapic_chip,
handle_fasteoi_irq, "fasteoi");
- else
+ } else {
+ irq_desc[irq].status &= ~IRQ_LEVEL;
set_irq_chip_and_handler_name(irq, &ioapic_chip,
handle_edge_irq, "edge");
+ }
}
static void setup_IO_APIC_irq(int apic, int pin, unsigned int irq,
diff --git a/arch/x86_64/kernel/nmi.c b/arch/x86_64/kernel/nmi.c
index cb8ee9d..0ec6d2d 100644
--- a/arch/x86_64/kernel/nmi.c
+++ b/arch/x86_64/kernel/nmi.c
@@ -85,7 +85,7 @@
int *counts;
int cpu;
- if ((nmi_watchdog == NMI_NONE) || (nmi_watchdog == NMI_DEFAULT))
+ if ((nmi_watchdog == NMI_NONE) || (nmi_watchdog == NMI_DISABLED))
return 0;
if (!atomic_read(&nmi_active))
@@ -442,7 +442,7 @@
if (!!old_state == !!nmi_watchdog_enabled)
return 0;
- if (atomic_read(&nmi_active) < 0) {
+ if (atomic_read(&nmi_active) < 0 || nmi_watchdog == NMI_DISABLED) {
printk( KERN_WARNING "NMI watchdog is permanently disabled\n");
return -EIO;
}
diff --git a/arch/x86_64/kernel/pci-calgary.c b/arch/x86_64/kernel/pci-calgary.c
index ba16c96..71da01e 100644
--- a/arch/x86_64/kernel/pci-calgary.c
+++ b/arch/x86_64/kernel/pci-calgary.c
@@ -367,16 +367,15 @@
pdev = to_pci_dev(dev);
- /* is the device behind a bridge? */
- if (unlikely(pdev->bus->parent))
- pbus = pdev->bus->parent;
- else
- pbus = pdev->bus;
+ pbus = pdev->bus;
+
+ /* is the device behind a bridge? Look for the root bus */
+ while (pbus->parent)
+ pbus = pbus->parent;
tbl = pci_iommu(pbus);
- BUG_ON(pdev->bus->parent &&
- (tbl->it_busno != pdev->bus->parent->number));
+ BUG_ON(tbl && (tbl->it_busno != pbus->number));
return tbl;
}
diff --git a/arch/x86_64/kernel/pci-dma.c b/arch/x86_64/kernel/pci-dma.c
index 05d745e..2971144 100644
--- a/arch/x86_64/kernel/pci-dma.c
+++ b/arch/x86_64/kernel/pci-dma.c
@@ -82,6 +82,10 @@
if (dma_mask == 0)
dma_mask = DMA_32BIT_MASK;
+ /* Device not DMA able */
+ if (dev->dma_mask == NULL)
+ return NULL;
+
/* Don't invoke OOM killer */
gfp |= __GFP_NORETRY;
diff --git a/arch/x86_64/lib/memcpy.S b/arch/x86_64/lib/memcpy.S
index 0ea0ddc..c22981f 100644
--- a/arch/x86_64/lib/memcpy.S
+++ b/arch/x86_64/lib/memcpy.S
@@ -124,6 +124,8 @@
.quad memcpy
.quad 1b
.byte X86_FEATURE_REP_GOOD
- .byte .Lfinal - memcpy
+ /* Replace only beginning, memcpy is used to apply alternatives, so it
+ * is silly to overwrite itself with nops - reboot is only outcome... */
+ .byte 2b - 1b
.byte 2b - 1b
.previous
diff --git a/arch/x86_64/mm/pageattr.c b/arch/x86_64/mm/pageattr.c
index 7e161c6..10b9809 100644
--- a/arch/x86_64/mm/pageattr.c
+++ b/arch/x86_64/mm/pageattr.c
@@ -75,7 +75,8 @@
/* When clflush is available always use it because it is
much cheaper than WBINVD. */
- if (!cpu_has_clflush)
+ /* clflush is still broken. Disable for now. */
+ if (1 || !cpu_has_clflush)
asm volatile("wbinvd" ::: "memory");
else list_for_each_entry(pg, l, lru) {
void *adr = page_address(pg);
diff --git a/arch/x86_64/pci/mmconfig.c b/arch/x86_64/pci/mmconfig.c
index 65d8273..4095e4d 100644
--- a/arch/x86_64/pci/mmconfig.c
+++ b/arch/x86_64/pci/mmconfig.c
@@ -66,13 +66,13 @@
switch (len) {
case 1:
- *value = readb(addr + reg);
+ *value = mmio_config_readb(addr + reg);
break;
case 2:
- *value = readw(addr + reg);
+ *value = mmio_config_readw(addr + reg);
break;
case 4:
- *value = readl(addr + reg);
+ *value = mmio_config_readl(addr + reg);
break;
}
@@ -94,13 +94,13 @@
switch (len) {
case 1:
- writeb(value, addr + reg);
+ mmio_config_writeb(addr + reg, value);
break;
case 2:
- writew(value, addr + reg);
+ mmio_config_writew(addr + reg, value);
break;
case 4:
- writel(value, addr + reg);
+ mmio_config_writel(addr + reg, value);
break;
}
diff --git a/arch/x86_64/vdso/.gitignore b/arch/x86_64/vdso/.gitignore
new file mode 100644
index 0000000..f8b69d8
--- /dev/null
+++ b/arch/x86_64/vdso/.gitignore
@@ -0,0 +1 @@
+vdso.lds
diff --git a/block/bsg.c b/block/bsg.c
index d60eee5..ed26468 100644
--- a/block/bsg.c
+++ b/block/bsg.c
@@ -1,5 +1,5 @@
/*
- * bsg.c - block layer implementation of the sg v3 interface
+ * bsg.c - block layer implementation of the sg v4 interface
*
* Copyright (C) 2004 Jens Axboe <axboe@suse.de> SUSE Labs
* Copyright (C) 2004 Peter M. Jones <pjones@redhat.com>
@@ -421,7 +421,6 @@
hdr->info = 0;
if (hdr->device_status || hdr->transport_status || hdr->driver_status)
hdr->info |= SG_INFO_CHECK;
- hdr->din_resid = rq->data_len;
hdr->response_len = 0;
if (rq->sense_len && hdr->response) {
@@ -437,9 +436,14 @@
}
if (rq->next_rq) {
+ hdr->dout_resid = rq->data_len;
+ hdr->din_resid = rq->next_rq->data_len;
blk_rq_unmap_user(bidi_bio);
blk_put_request(rq->next_rq);
- }
+ } else if (rq_data_dir(rq) == READ)
+ hdr->din_resid = rq->data_len;
+ else
+ hdr->dout_resid = rq->data_len;
blk_rq_unmap_user(bio);
blk_put_request(rq);
diff --git a/block/ll_rw_blk.c b/block/ll_rw_blk.c
index 8c2caff..a15845c 100644
--- a/block/ll_rw_blk.c
+++ b/block/ll_rw_blk.c
@@ -3047,6 +3047,10 @@
bio->bi_sector += p->start_sect;
bio->bi_bdev = bdev->bd_contains;
+
+ blk_add_trace_remap(bdev_get_queue(bio->bi_bdev), bio,
+ bdev->bd_dev, bio->bi_sector,
+ bio->bi_sector - p->start_sect);
}
}
diff --git a/crypto/ablkcipher.c b/crypto/ablkcipher.c
index 1c166b4..3dbb1cc 100644
--- a/crypto/ablkcipher.c
+++ b/crypto/ablkcipher.c
@@ -35,7 +35,7 @@
alignbuffer = (u8 *)ALIGN((unsigned long)buffer, alignmask + 1);
memcpy(alignbuffer, key, keylen);
ret = cipher->setkey(tfm, alignbuffer, keylen);
- memset(alignbuffer, 0, absize);
+ memset(alignbuffer, 0, keylen);
kfree(buffer);
return ret;
}
diff --git a/crypto/blkcipher.c b/crypto/blkcipher.c
index 40a3dcf..7755834 100644
--- a/crypto/blkcipher.c
+++ b/crypto/blkcipher.c
@@ -352,7 +352,7 @@
alignbuffer = (u8 *)ALIGN((unsigned long)buffer, alignmask + 1);
memcpy(alignbuffer, key, keylen);
ret = cipher->setkey(tfm, alignbuffer, keylen);
- memset(alignbuffer, 0, absize);
+ memset(alignbuffer, 0, keylen);
kfree(buffer);
return ret;
}
diff --git a/crypto/cipher.c b/crypto/cipher.c
index 0b2650c..fc6b46f 100644
--- a/crypto/cipher.c
+++ b/crypto/cipher.c
@@ -36,7 +36,7 @@
alignbuffer = (u8 *)ALIGN((unsigned long)buffer, alignmask + 1);
memcpy(alignbuffer, key, keylen);
ret = cia->cia_setkey(tfm, alignbuffer, keylen);
- memset(alignbuffer, 0, absize);
+ memset(alignbuffer, 0, keylen);
kfree(buffer);
return ret;
diff --git a/crypto/hash.c b/crypto/hash.c
index 4d75ca7..4fd470b 100644
--- a/crypto/hash.c
+++ b/crypto/hash.c
@@ -40,7 +40,7 @@
alignbuffer = (u8 *)ALIGN((unsigned long)buffer, alignmask + 1);
memcpy(alignbuffer, key, keylen);
ret = alg->setkey(crt, alignbuffer, keylen);
- memset(alignbuffer, 0, absize);
+ memset(alignbuffer, 0, keylen);
kfree(buffer);
return ret;
}
diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig
index f1372de..5742594 100644
--- a/drivers/acpi/Kconfig
+++ b/drivers/acpi/Kconfig
@@ -68,6 +68,20 @@
Say N to delete /proc/acpi/ files that have moved to /sys/
+config ACPI_PROC_EVENT
+ bool "Deprecated /proc/acpi/event support"
+ depends on PROC_FS
+ ---help---
+ A user-space daemon, acpi, typically read /proc/acpi/event
+ and handled all ACPI sub-system generated events.
+
+ These events are now delivered to user-space via
+ either the input layer, or as netlink events.
+
+ This build option enables the old code for for legacy
+ user-space implementation. After some time, this will
+ be moved under CONFIG_ACPI_PROCFS, and then deleted.
+
config ACPI_AC
tristate "AC Adapter"
depends on X86
diff --git a/drivers/acpi/ac.c b/drivers/acpi/ac.c
index d8b3509..26d7070 100644
--- a/drivers/acpi/ac.c
+++ b/drivers/acpi/ac.c
@@ -204,7 +204,10 @@
case ACPI_NOTIFY_BUS_CHECK:
case ACPI_NOTIFY_DEVICE_CHECK:
acpi_ac_get_state(ac);
- acpi_bus_generate_event(device, event, (u32) ac->state);
+ acpi_bus_generate_proc_event(device, event, (u32) ac->state);
+ acpi_bus_generate_netlink_event(device->pnp.device_class,
+ device->dev.bus_id, event,
+ (u32) ac->state);
break;
default:
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
diff --git a/drivers/acpi/asus_acpi.c b/drivers/acpi/asus_acpi.c
index 9c4bd22..d915fec 100644
--- a/drivers/acpi/asus_acpi.c
+++ b/drivers/acpi/asus_acpi.c
@@ -1069,7 +1069,7 @@
hotk->brightness = (event & ~((u32) BR_DOWN));
}
- acpi_bus_generate_event(hotk->device, event,
+ acpi_bus_generate_proc_event(hotk->device, event,
hotk->event_count[event % 128]++);
return;
@@ -1192,6 +1192,7 @@
break;
default:
kfree(model);
+ model = NULL;
break;
}
}
diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c
index 8165103..9b2c0f7 100644
--- a/drivers/acpi/battery.c
+++ b/drivers/acpi/battery.c
@@ -872,8 +872,11 @@
case ACPI_NOTIFY_DEVICE_CHECK:
device = battery->device;
acpi_battery_notify_update(battery);
- acpi_bus_generate_event(device, event,
+ acpi_bus_generate_proc_event(device, event,
acpi_battery_present(battery));
+ acpi_bus_generate_netlink_event(device->pnp.device_class,
+ device->dev.bus_id, event,
+ acpi_battery_present(battery));
break;
default:
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
diff --git a/drivers/acpi/bay.c b/drivers/acpi/bay.c
index 56a5b3f..6daf6088 100644
--- a/drivers/acpi/bay.c
+++ b/drivers/acpi/bay.c
@@ -337,7 +337,7 @@
char *envp[] = { event_string, NULL };
bay_dprintk(handle, "Bay event");
- sprintf(event_string, "BAY_EVENT=%d\n", event);
+ sprintf(event_string, "BAY_EVENT=%d", event);
kobject_uevent_env(&dev->kobj, KOBJ_CHANGE, envp);
}
diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c
index 6b2658c..9ba778a 100644
--- a/drivers/acpi/bus.c
+++ b/drivers/acpi/bus.c
@@ -276,6 +276,7 @@
Event Management
-------------------------------------------------------------------------- */
+#ifdef CONFIG_ACPI_PROC_EVENT
static DEFINE_SPINLOCK(acpi_bus_event_lock);
LIST_HEAD(acpi_bus_event_list);
@@ -283,7 +284,7 @@
extern int event_is_open;
-int acpi_bus_generate_event(struct acpi_device *device, u8 type, int data)
+int acpi_bus_generate_proc_event(struct acpi_device *device, u8 type, int data)
{
struct acpi_bus_event *event = NULL;
unsigned long flags = 0;
@@ -292,10 +293,6 @@
if (!device)
return -EINVAL;
- if (acpi_bus_generate_genetlink_event(device, type, data))
- printk(KERN_WARNING PREFIX
- "Failed to generate an ACPI event via genetlink!\n");
-
/* drop event on the floor if no one's listening */
if (!event_is_open)
return 0;
@@ -318,7 +315,7 @@
return 0;
}
-EXPORT_SYMBOL(acpi_bus_generate_event);
+EXPORT_SYMBOL(acpi_bus_generate_proc_event);
int acpi_bus_receive_event(struct acpi_bus_event *event)
{
@@ -364,6 +361,7 @@
}
EXPORT_SYMBOL(acpi_bus_receive_event);
+#endif /* CONFIG_ACPI_PROC_EVENT */
/* --------------------------------------------------------------------------
Notification Handling
diff --git a/drivers/acpi/button.c b/drivers/acpi/button.c
index 5405813..2e79a33 100644
--- a/drivers/acpi/button.c
+++ b/drivers/acpi/button.c
@@ -284,7 +284,7 @@
}
input_sync(input);
- acpi_bus_generate_event(button->device, event,
+ acpi_bus_generate_proc_event(button->device, event,
++button->pushed);
break;
default:
diff --git a/drivers/acpi/dock.c b/drivers/acpi/dock.c
index 6192c8b..1dabdf4 100644
--- a/drivers/acpi/dock.c
+++ b/drivers/acpi/dock.c
@@ -336,13 +336,13 @@
static void dock_event(struct dock_station *ds, u32 event, int num)
{
struct device *dev = &dock_device->dev;
- char event_string[7];
+ char event_string[13];
char *envp[] = { event_string, NULL };
if (num == UNDOCK_EVENT)
- sprintf(event_string, "UNDOCK");
+ sprintf(event_string, "EVENT=undock");
else
- sprintf(event_string, "DOCK");
+ sprintf(event_string, "EVENT=dock");
/*
* Indicate that the status of the dock station has
diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c
index 469f3f5..43749c8 100644
--- a/drivers/acpi/ec.c
+++ b/drivers/acpi/ec.c
@@ -471,7 +471,6 @@
}
}
mutex_unlock(&ec->lock);
- printk(KERN_ERR PREFIX "Handler for query 0x%x is not found!\n", value);
}
static u32 acpi_ec_gpe_handler(void *data)
@@ -665,30 +664,36 @@
return AE_OK;
}
-static int ec_parse_device(struct acpi_ec *ec, acpi_handle handle)
+static acpi_status
+ec_parse_device(acpi_handle handle, u32 Level, void *context, void **retval)
{
- if (ACPI_FAILURE(acpi_walk_resources(handle, METHOD_NAME__CRS,
- ec_parse_io_ports, ec)))
- return -EINVAL;
+ acpi_status status;
+
+ struct acpi_ec *ec = context;
+ status = acpi_walk_resources(handle, METHOD_NAME__CRS,
+ ec_parse_io_ports, ec);
+ if (ACPI_FAILURE(status))
+ return status;
/* Get GPE bit assignment (EC events). */
/* TODO: Add support for _GPE returning a package */
- if (ACPI_FAILURE(acpi_evaluate_integer(handle, "_GPE", NULL, &ec->gpe)))
- return -EINVAL;
-
- /* Use the global lock for all EC transactions? */
- acpi_evaluate_integer(handle, "_GLK", NULL, &ec->global_lock);
+ status = acpi_evaluate_integer(handle, "_GPE", NULL, &ec->gpe);
+ if (ACPI_FAILURE(status))
+ return status;
/* Find and register all query methods */
acpi_walk_namespace(ACPI_TYPE_METHOD, handle, 1,
acpi_ec_register_query_methods, ec, NULL);
+ /* Use the global lock for all EC transactions? */
+ acpi_evaluate_integer(handle, "_GLK", NULL, &ec->global_lock);
+
ec->handle = handle;
- printk(KERN_INFO PREFIX "GPE = 0x%lx, I/O: command/status = 0x%lx, data = 0x%lx",
+ printk(KERN_INFO PREFIX "GPE = 0x%lx, I/O: command/status = 0x%lx, data = 0x%lx\n",
ec->gpe, ec->command_addr, ec->data_addr);
- return 0;
+ return AE_CTRL_TERMINATE;
}
static int acpi_ec_add(struct acpi_device *device)
@@ -705,7 +710,8 @@
if (!ec)
return -ENOMEM;
- if (ec_parse_device(ec, device->handle)) {
+ if (ec_parse_device(device->handle, 0, ec, NULL) !=
+ AE_CTRL_TERMINATE) {
kfree(ec);
return -EINVAL;
}
@@ -734,14 +740,14 @@
static int acpi_ec_remove(struct acpi_device *device, int type)
{
struct acpi_ec *ec;
- struct acpi_ec_query_handler *handler;
+ struct acpi_ec_query_handler *handler, *tmp;
if (!device)
return -EINVAL;
ec = acpi_driver_data(device);
mutex_lock(&ec->lock);
- list_for_each_entry(handler, &ec->list, node) {
+ list_for_each_entry_safe(handler, tmp, &ec->list, node) {
list_del(&handler->node);
kfree(handler);
}
@@ -868,18 +874,21 @@
/*
* Generate a boot ec context
*/
-
status = acpi_get_table(ACPI_SIG_ECDT, 1,
(struct acpi_table_header **)&ecdt_ptr);
- if (ACPI_FAILURE(status))
- goto error;
-
- printk(KERN_INFO PREFIX "EC description table is found, configuring boot EC\n");
-
- boot_ec->command_addr = ecdt_ptr->control.address;
- boot_ec->data_addr = ecdt_ptr->data.address;
- boot_ec->gpe = ecdt_ptr->gpe;
- boot_ec->handle = ACPI_ROOT_OBJECT;
+ if (ACPI_SUCCESS(status)) {
+ printk(KERN_INFO PREFIX "EC description table is found, configuring boot EC\n\n");
+ boot_ec->command_addr = ecdt_ptr->control.address;
+ boot_ec->data_addr = ecdt_ptr->data.address;
+ boot_ec->gpe = ecdt_ptr->gpe;
+ boot_ec->handle = ACPI_ROOT_OBJECT;
+ } else {
+ printk(KERN_DEBUG PREFIX "Look up EC in DSDT\n");
+ status = acpi_get_devices(ec_device_ids[0].id, ec_parse_device,
+ boot_ec, NULL);
+ if (ACPI_FAILURE(status))
+ goto error;
+ }
ret = ec_install_handlers(boot_ec);
if (!ret) {
diff --git a/drivers/acpi/event.c b/drivers/acpi/event.c
index dfa5853..a2b9304 100644
--- a/drivers/acpi/event.c
+++ b/drivers/acpi/event.c
@@ -17,6 +17,7 @@
#define _COMPONENT ACPI_SYSTEM_COMPONENT
ACPI_MODULE_NAME("event");
+#ifdef CONFIG_ACPI_PROC_EVENT
/* Global vars for handling event proc entry */
static DEFINE_SPINLOCK(acpi_system_event_lock);
int event_is_open = 0;
@@ -106,9 +107,10 @@
.release = acpi_system_close_event,
.poll = acpi_system_poll_event,
};
+#endif /* CONFIG_ACPI_PROC_EVENT */
#ifdef CONFIG_NET
-unsigned int acpi_event_seqnum;
+static unsigned int acpi_event_seqnum;
struct acpi_genl_event {
acpi_device_class device_class;
char bus_id[15];
@@ -147,7 +149,8 @@
.name = ACPI_GENL_MCAST_GROUP_NAME,
};
-int acpi_bus_generate_genetlink_event(struct acpi_device *device,
+int acpi_bus_generate_netlink_event(const char *device_class,
+ const char *bus_id,
u8 type, int data)
{
struct sk_buff *skb;
@@ -191,8 +194,8 @@
memset(event, 0, sizeof(struct acpi_genl_event));
- strcpy(event->device_class, device->pnp.device_class);
- strcpy(event->bus_id, device->dev.bus_id);
+ strcpy(event->device_class, device_class);
+ strcpy(event->bus_id, bus_id);
event->type = type;
event->data = data;
@@ -211,6 +214,8 @@
return 0;
}
+EXPORT_SYMBOL(acpi_bus_generate_netlink_event);
+
static int acpi_event_genetlink_init(void)
{
int result;
@@ -228,12 +233,15 @@
}
#else
-int acpi_bus_generate_genetlink_event(struct acpi_device *device, u8 type,
- int data)
+int acpi_bus_generate_netlink_event(const char *device_class,
+ const char *bus_id,
+ u8 type, int data)
{
return 0;
}
+EXPORT_SYMBOL(acpi_generate_netlink_event);
+
static int acpi_event_genetlink_init(void)
{
return -ENODEV;
@@ -242,7 +250,9 @@
static int __init acpi_event_init(void)
{
+#ifdef CONFIG_ACPI_PROC_EVENT
struct proc_dir_entry *entry;
+#endif
int error = 0;
if (acpi_disabled)
@@ -254,12 +264,14 @@
printk(KERN_WARNING PREFIX
"Failed to create genetlink family for ACPI event\n");
+#ifdef CONFIG_ACPI_PROC_EVENT
/* 'event' [R] */
entry = create_proc_entry("event", S_IRUSR, acpi_root_dir);
if (entry)
entry->proc_fops = &acpi_system_event_ops;
else
return -ENODEV;
+#endif
return 0;
}
diff --git a/drivers/acpi/hardware/hwsleep.c b/drivers/acpi/hardware/hwsleep.c
index 76c525d..cf69c00 100644
--- a/drivers/acpi/hardware/hwsleep.c
+++ b/drivers/acpi/hardware/hwsleep.c
@@ -576,13 +576,10 @@
ACPI_EXCEPTION((AE_INFO, status, "During Method _BFS"));
}
- status = acpi_evaluate_object(NULL, METHOD_NAME__WAK, &arg_list, NULL);
- if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) {
- ACPI_EXCEPTION((AE_INFO, status, "During Method _WAK"));
- }
- /* TBD: _WAK "sometimes" returns stuff - do we want to look at it? */
-
/*
+ * GPEs must be enabled before _WAK is called as GPEs
+ * might get fired there
+ *
* Restore the GPEs:
* 1) Disable/Clear all GPEs
* 2) Enable all runtime GPEs
@@ -591,13 +588,19 @@
if (ACPI_FAILURE(status)) {
return_ACPI_STATUS(status);
}
- acpi_gbl_system_awake_and_running = TRUE;
-
status = acpi_hw_enable_all_runtime_gpes();
if (ACPI_FAILURE(status)) {
return_ACPI_STATUS(status);
}
+ status = acpi_evaluate_object(NULL, METHOD_NAME__WAK, &arg_list, NULL);
+ if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) {
+ ACPI_EXCEPTION((AE_INFO, status, "During Method _WAK"));
+ }
+ /* TBD: _WAK "sometimes" returns stuff - do we want to look at it? */
+
+ acpi_gbl_system_awake_and_running = TRUE;
+
/* Enable power button */
(void)
diff --git a/drivers/acpi/namespace/nsxfeval.c b/drivers/acpi/namespace/nsxfeval.c
index ab65b2c..f39fbc6 100644
--- a/drivers/acpi/namespace/nsxfeval.c
+++ b/drivers/acpi/namespace/nsxfeval.c
@@ -540,7 +540,7 @@
******************************************************************************/
acpi_status
-acpi_get_devices(char *HID,
+acpi_get_devices(const char *HID,
acpi_walk_callback user_function,
void *context, void **return_value)
{
diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c
index 4984223..e944aae 100644
--- a/drivers/acpi/processor_core.c
+++ b/drivers/acpi/processor_core.c
@@ -698,16 +698,23 @@
switch (event) {
case ACPI_PROCESSOR_NOTIFY_PERFORMANCE:
acpi_processor_ppc_has_changed(pr);
- acpi_bus_generate_event(device, event,
+ acpi_bus_generate_proc_event(device, event,
pr->performance_platform_limit);
+ acpi_bus_generate_netlink_event(device->pnp.device_class,
+ device->dev.bus_id, event,
+ pr->performance_platform_limit);
break;
case ACPI_PROCESSOR_NOTIFY_POWER:
acpi_processor_cst_has_changed(pr);
- acpi_bus_generate_event(device, event, 0);
+ acpi_bus_generate_proc_event(device, event, 0);
+ acpi_bus_generate_netlink_event(device->pnp.device_class,
+ device->dev.bus_id, event, 0);
break;
case ACPI_PROCESSOR_NOTIFY_THROTTLING:
acpi_processor_tstate_has_changed(pr);
- acpi_bus_generate_event(device, event, 0);
+ acpi_bus_generate_proc_event(device, event, 0);
+ acpi_bus_generate_netlink_event(device->pnp.device_class,
+ device->dev.bus_id, event, 0);
default:
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
"Unsupported event [0x%x]\n", event));
diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c
index a898991..d9b8af7 100644
--- a/drivers/acpi/processor_idle.c
+++ b/drivers/acpi/processor_idle.c
@@ -63,6 +63,7 @@
ACPI_MODULE_NAME("processor_idle");
#define ACPI_PROCESSOR_FILE_POWER "power"
#define US_TO_PM_TIMER_TICKS(t) ((t * (PM_TIMER_FREQUENCY/1000)) / 1000)
+#define PM_TIMER_TICK_NS (1000000000ULL/PM_TIMER_FREQUENCY)
#define C2_OVERHEAD 4 /* 1us (3.579 ticks per us) */
#define C3_OVERHEAD 4 /* 1us (3.579 ticks per us) */
static void (*pm_idle_save) (void) __read_mostly;
@@ -462,6 +463,9 @@
* TBD: Can't get time duration while in C1, as resumes
* go to an ISR rather than here. Need to instrument
* base interrupt handler.
+ *
+ * Note: the TSC better not stop in C1, sched_clock() will
+ * skew otherwise.
*/
sleep_ticks = 0xFFFFFFFF;
break;
@@ -469,6 +473,8 @@
case ACPI_STATE_C2:
/* Get start time (ticks) */
t1 = inl(acpi_gbl_FADT.xpm_timer_block.address);
+ /* Tell the scheduler that we are going deep-idle: */
+ sched_clock_idle_sleep_event();
/* Invoke C2 */
acpi_state_timer_broadcast(pr, cx, 1);
acpi_cstate_enter(cx);
@@ -479,17 +485,22 @@
/* TSC halts in C2, so notify users */
mark_tsc_unstable("possible TSC halt in C2");
#endif
+ /* Compute time (ticks) that we were actually asleep */
+ sleep_ticks = ticks_elapsed(t1, t2);
+
+ /* Tell the scheduler how much we idled: */
+ sched_clock_idle_wakeup_event(sleep_ticks*PM_TIMER_TICK_NS);
+
/* Re-enable interrupts */
local_irq_enable();
+ /* Do not account our idle-switching overhead: */
+ sleep_ticks -= cx->latency_ticks + C2_OVERHEAD;
+
current_thread_info()->status |= TS_POLLING;
- /* Compute time (ticks) that we were actually asleep */
- sleep_ticks =
- ticks_elapsed(t1, t2) - cx->latency_ticks - C2_OVERHEAD;
acpi_state_timer_broadcast(pr, cx, 0);
break;
case ACPI_STATE_C3:
-
/*
* disable bus master
* bm_check implies we need ARB_DIS
@@ -518,6 +529,8 @@
t1 = inl(acpi_gbl_FADT.xpm_timer_block.address);
/* Invoke C3 */
acpi_state_timer_broadcast(pr, cx, 1);
+ /* Tell the scheduler that we are going deep-idle: */
+ sched_clock_idle_sleep_event();
acpi_cstate_enter(cx);
/* Get end time (ticks) */
t2 = inl(acpi_gbl_FADT.xpm_timer_block.address);
@@ -531,12 +544,17 @@
/* TSC halts in C3, so notify users */
mark_tsc_unstable("TSC halts in C3");
#endif
+ /* Compute time (ticks) that we were actually asleep */
+ sleep_ticks = ticks_elapsed(t1, t2);
+ /* Tell the scheduler how much we idled: */
+ sched_clock_idle_wakeup_event(sleep_ticks*PM_TIMER_TICK_NS);
+
/* Re-enable interrupts */
local_irq_enable();
+ /* Do not account our idle-switching overhead: */
+ sleep_ticks -= cx->latency_ticks + C3_OVERHEAD;
+
current_thread_info()->status |= TS_POLLING;
- /* Compute time (ticks) that we were actually asleep */
- sleep_ticks =
- ticks_elapsed(t1, t2) - cx->latency_ticks - C3_OVERHEAD;
acpi_state_timer_broadcast(pr, cx, 0);
break;
@@ -969,11 +987,17 @@
}
if (pr->flags.bm_check) {
- /* bus mastering control is necessary */
if (!pr->flags.bm_control) {
- /* In this case we enter C3 without bus mastering */
- ACPI_DEBUG_PRINT((ACPI_DB_INFO,
- "C3 support without bus mastering control\n"));
+ if (pr->flags.has_cst != 1) {
+ /* bus mastering control is necessary */
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+ "C3 support requires BM control\n"));
+ return;
+ } else {
+ /* Here we enter C3 without bus mastering */
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+ "C3 support without BM control\n"));
+ }
}
} else {
/*
diff --git a/drivers/acpi/processor_perflib.c b/drivers/acpi/processor_perflib.c
index c4efc0c..463b024 100644
--- a/drivers/acpi/processor_perflib.c
+++ b/drivers/acpi/processor_perflib.c
@@ -539,7 +539,7 @@
}
int acpi_processor_preregister_performance(
- struct acpi_processor_performance **performance)
+ struct acpi_processor_performance *performance)
{
int count, count_target;
int retval = 0;
@@ -567,12 +567,12 @@
continue;
}
- if (!performance || !performance[i]) {
+ if (!performance || !percpu_ptr(performance, i)) {
retval = -EINVAL;
continue;
}
- pr->performance = performance[i];
+ pr->performance = percpu_ptr(performance, i);
cpu_set(i, pr->performance->shared_cpu_map);
if (acpi_processor_get_psd(pr)) {
retval = -EINVAL;
diff --git a/drivers/acpi/resources/rsxface.c b/drivers/acpi/resources/rsxface.c
index f63813a..4c3fd4c 100644
--- a/drivers/acpi/resources/rsxface.c
+++ b/drivers/acpi/resources/rsxface.c
@@ -474,8 +474,6 @@
return (AE_CTRL_TERMINATE);
}
-ACPI_EXPORT_SYMBOL(acpi_rs_match_vendor_resource)
-
/*******************************************************************************
*
* FUNCTION: acpi_walk_resources
diff --git a/drivers/acpi/sbs.c b/drivers/acpi/sbs.c
index 7d8e78e..a578986 100644
--- a/drivers/acpi/sbs.c
+++ b/drivers/acpi/sbs.c
@@ -440,11 +440,12 @@
strcpy(acpi_device_bid(device), bid);
strcpy(acpi_device_class(device), class);
- result = acpi_bus_generate_event(device, event, state);
+ result = acpi_bus_generate_proc_event(device, event, state);
strcpy(acpi_device_bid(device), bid_saved);
strcpy(acpi_device_class(device), class_saved);
+ acpi_bus_generate_netlink_event(class, bid, event, state);
return result;
}
@@ -1415,7 +1416,7 @@
char dir_name[32];
int do_battery_init = 0, do_ac_init = 0;
int old_remaining_capacity = 0;
- int update_ac = 1, update_battery = 1;
+ int update_battery = 1;
int up_tm = update_time;
if (sbs_zombie(sbs)) {
@@ -1435,10 +1436,6 @@
sbs->run_cnt++;
- if (!update_ac && !update_battery) {
- goto end;
- }
-
old_ac_present = sbs->ac.ac_present;
result = acpi_ac_get_present(sbs);
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index be74347..64620d6 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -35,8 +35,9 @@
* e.g. on a device with hid:IBM0001 and cid:ACPI0001 you get:
* char *modalias: "acpi:IBM0001:ACPI0001"
*/
-int create_modalias(struct acpi_device *acpi_dev, char *modalias, int size){
-
+static int create_modalias(struct acpi_device *acpi_dev, char *modalias,
+ int size)
+{
int len;
if (!acpi_dev->flags.hardware_id)
diff --git a/drivers/acpi/sleep/main.c b/drivers/acpi/sleep/main.c
index e8cff5d..c52ade8 100644
--- a/drivers/acpi/sleep/main.c
+++ b/drivers/acpi/sleep/main.c
@@ -305,7 +305,7 @@
unsigned long d_min, d_max;
if (!handle || ACPI_FAILURE(acpi_bus_get_device(handle, &adev))) {
- printk(KERN_ERR "ACPI handle has no context!\n");
+ printk(KERN_DEBUG "ACPI handle has no context!\n");
return -ENODEV;
}
diff --git a/drivers/acpi/tables/tbutils.c b/drivers/acpi/tables/tbutils.c
index 1da64b4..8cc9492 100644
--- a/drivers/acpi/tables/tbutils.c
+++ b/drivers/acpi/tables/tbutils.c
@@ -51,6 +51,65 @@
static acpi_physical_address
acpi_tb_get_root_table_entry(u8 * table_entry,
acpi_native_uint table_entry_size);
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_tb_check_xsdt
+ *
+ * PARAMETERS: address - Pointer to the XSDT
+ *
+ * RETURN: status
+ * AE_OK - XSDT is okay
+ * AE_NO_MEMORY - can't map XSDT
+ * AE_INVALID_TABLE_LENGTH - invalid table length
+ * AE_NULL_ENTRY - XSDT has NULL entry
+ *
+ * DESCRIPTION: validate XSDT
+******************************************************************************/
+
+static acpi_status
+acpi_tb_check_xsdt(acpi_physical_address address)
+{
+ struct acpi_table_header *table;
+ u32 length;
+ u64 xsdt_entry_address;
+ u8 *table_entry;
+ u32 table_count;
+ int i;
+
+ table = acpi_os_map_memory(address, sizeof(struct acpi_table_header));
+ if (!table)
+ return AE_NO_MEMORY;
+
+ length = table->length;
+ acpi_os_unmap_memory(table, sizeof(struct acpi_table_header));
+ if (length < sizeof(struct acpi_table_header))
+ return AE_INVALID_TABLE_LENGTH;
+
+ table = acpi_os_map_memory(address, length);
+ if (!table)
+ return AE_NO_MEMORY;
+
+ /* Calculate the number of tables described in XSDT */
+ table_count =
+ (u32) ((table->length -
+ sizeof(struct acpi_table_header)) / sizeof(u64));
+ table_entry =
+ ACPI_CAST_PTR(u8, table) + sizeof(struct acpi_table_header);
+ for (i = 0; i < table_count; i++) {
+ ACPI_MOVE_64_TO_64(&xsdt_entry_address, table_entry);
+ if (!xsdt_entry_address) {
+ /* XSDT has NULL entry */
+ break;
+ }
+ table_entry += sizeof(u64);
+ }
+ acpi_os_unmap_memory(table, length);
+
+ if (i < table_count)
+ return AE_NULL_ENTRY;
+ else
+ return AE_OK;
+}
/*******************************************************************************
*
@@ -341,6 +400,7 @@
u32 table_count;
struct acpi_table_header *table;
acpi_physical_address address;
+ acpi_physical_address rsdt_address;
u32 length;
u8 *table_entry;
acpi_status status;
@@ -369,6 +429,8 @@
*/
address = (acpi_physical_address) rsdp->xsdt_physical_address;
table_entry_size = sizeof(u64);
+ rsdt_address = (acpi_physical_address)
+ rsdp->rsdt_physical_address;
} else {
/* Root table is an RSDT (32-bit physical addresses) */
@@ -382,6 +444,15 @@
*/
acpi_os_unmap_memory(rsdp, sizeof(struct acpi_table_rsdp));
+ if (table_entry_size == sizeof(u64)) {
+ if (acpi_tb_check_xsdt(address) == AE_NULL_ENTRY) {
+ /* XSDT has NULL entry, RSDT is used */
+ address = rsdt_address;
+ table_entry_size = sizeof(u32);
+ ACPI_WARNING((AE_INFO, "BIOS XSDT has NULL entry,"
+ "using RSDT"));
+ }
+ }
/* Map the RSDT/XSDT table header to get the full table length */
table = acpi_os_map_memory(address, sizeof(struct acpi_table_header));
diff --git a/drivers/acpi/tables/tbxface.c b/drivers/acpi/tables/tbxface.c
index 5b302c4..a9e3331 100644
--- a/drivers/acpi/tables/tbxface.c
+++ b/drivers/acpi/tables/tbxface.c
@@ -52,6 +52,8 @@
/* Local prototypes */
static acpi_status acpi_tb_load_namespace(void);
+static int no_auto_ssdt;
+
/*******************************************************************************
*
* FUNCTION: acpi_allocate_root_table
@@ -536,6 +538,10 @@
ACPI_INFO((AE_INFO, "Table DSDT replaced by host OS"));
acpi_tb_print_table_header(0, table);
+
+ if (no_auto_ssdt == 0) {
+ printk(KERN_WARNING "ACPI: DSDT override uses original SSDTs unless \"acpi_no_auto_ssdt\"");
+ }
}
status =
@@ -577,6 +583,11 @@
continue;
}
+ if (no_auto_ssdt) {
+ printk(KERN_WARNING "ACPI: SSDT ignored due to \"acpi_no_auto_ssdt\"\n");
+ continue;
+ }
+
/* Ignore errors while loading tables, get as many as possible */
(void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
@@ -622,3 +633,15 @@
}
ACPI_EXPORT_SYMBOL(acpi_load_tables)
+
+
+static int __init acpi_no_auto_ssdt_setup(char *s) {
+
+ printk(KERN_NOTICE "ACPI: SSDT auto-load disabled\n");
+
+ no_auto_ssdt = 1;
+
+ return 1;
+}
+
+__setup("acpi_no_auto_ssdt", acpi_no_auto_ssdt_setup);
diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c
index 5a62de1..bc6d586 100644
--- a/drivers/acpi/thermal.c
+++ b/drivers/acpi/thermal.c
@@ -33,6 +33,7 @@
#include <linux/kernel.h>
#include <linux/module.h>
+#include <linux/dmi.h>
#include <linux/init.h>
#include <linux/types.h>
#include <linux/proc_fs.h>
@@ -74,9 +75,29 @@
MODULE_DESCRIPTION("ACPI Thermal Zone Driver");
MODULE_LICENSE("GPL");
+static int act;
+module_param(act, int, 0644);
+MODULE_PARM_DESC(act, "Disable or override all lowest active trip points.");
+
+static int crt;
+module_param(crt, int, 0644);
+MODULE_PARM_DESC(crt, "Disable or lower all critical trip points.");
+
static int tzp;
-module_param(tzp, int, 0);
-MODULE_PARM_DESC(tzp, "Thermal zone polling frequency, in 1/10 seconds.\n");
+module_param(tzp, int, 0444);
+MODULE_PARM_DESC(tzp, "Thermal zone polling frequency, in 1/10 seconds.");
+
+static int nocrt;
+module_param(nocrt, int, 0);
+MODULE_PARM_DESC(nocrt, "Set to take no action upon ACPI thermal zone critical trips points.");
+
+static int off;
+module_param(off, int, 0);
+MODULE_PARM_DESC(off, "Set to disable ACPI thermal support.");
+
+static int psv;
+module_param(psv, int, 0644);
+MODULE_PARM_DESC(psv, "Disable or override all passive trip points.");
static int acpi_thermal_add(struct acpi_device *device);
static int acpi_thermal_remove(struct acpi_device *device, int type);
@@ -323,6 +344,20 @@
tz->trips.critical.temperature));
}
+ if (tz->trips.critical.flags.valid == 1) {
+ if (crt == -1) {
+ tz->trips.critical.flags.valid = 0;
+ } else if (crt > 0) {
+ unsigned long crt_k = CELSIUS_TO_KELVIN(crt);
+
+ /*
+ * Allow override to lower critical threshold
+ */
+ if (crt_k < tz->trips.critical.temperature)
+ tz->trips.critical.temperature = crt_k;
+ }
+ }
+
/* Critical Sleep (optional) */
status =
@@ -339,9 +374,16 @@
/* Passive: Processors (optional) */
- status =
- acpi_evaluate_integer(tz->device->handle, "_PSV", NULL,
- &tz->trips.passive.temperature);
+ if (psv == -1) {
+ status = AE_SUPPORT;
+ } else if (psv > 0) {
+ tz->trips.passive.temperature = CELSIUS_TO_KELVIN(psv);
+ status = AE_OK;
+ } else {
+ status = acpi_evaluate_integer(tz->device->handle,
+ "_PSV", NULL, &tz->trips.passive.temperature);
+ }
+
if (ACPI_FAILURE(status)) {
tz->trips.passive.flags.valid = 0;
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "No passive threshold\n"));
@@ -386,11 +428,33 @@
char name[5] = { '_', 'A', 'C', ('0' + i), '\0' };
- status =
- acpi_evaluate_integer(tz->device->handle, name, NULL,
- &tz->trips.active[i].temperature);
- if (ACPI_FAILURE(status))
+ if (act == -1)
+ break; /* disable all active trip points */
+
+ status = acpi_evaluate_integer(tz->device->handle,
+ name, NULL, &tz->trips.active[i].temperature);
+
+ if (ACPI_FAILURE(status)) {
+ if (i == 0) /* no active trip points */
+ break;
+ if (act <= 0) /* no override requested */
+ break;
+ if (i == 1) { /* 1 trip point */
+ tz->trips.active[0].temperature =
+ CELSIUS_TO_KELVIN(act);
+ } else { /* multiple trips */
+ /*
+ * Don't allow override higher than
+ * the next higher trip point
+ */
+ tz->trips.active[i - 1].temperature =
+ (tz->trips.active[i - 2].temperature <
+ CELSIUS_TO_KELVIN(act) ?
+ tz->trips.active[i - 2].temperature :
+ CELSIUS_TO_KELVIN(act));
+ }
break;
+ }
name[2] = 'L';
status =
@@ -427,7 +491,7 @@
static int acpi_thermal_critical(struct acpi_thermal *tz)
{
- if (!tz || !tz->trips.critical.flags.valid)
+ if (!tz || !tz->trips.critical.flags.valid || nocrt)
return -EINVAL;
if (tz->temperature >= tz->trips.critical.temperature) {
@@ -439,8 +503,12 @@
printk(KERN_EMERG
"Critical temperature reached (%ld C), shutting down.\n",
KELVIN_TO_CELSIUS(tz->temperature));
- acpi_bus_generate_event(tz->device, ACPI_THERMAL_NOTIFY_CRITICAL,
+ acpi_bus_generate_proc_event(tz->device, ACPI_THERMAL_NOTIFY_CRITICAL,
tz->trips.critical.flags.enabled);
+ acpi_bus_generate_netlink_event(tz->device->pnp.device_class,
+ tz->device->dev.bus_id,
+ ACPI_THERMAL_NOTIFY_CRITICAL,
+ tz->trips.critical.flags.enabled);
orderly_poweroff(true);
@@ -449,7 +517,7 @@
static int acpi_thermal_hot(struct acpi_thermal *tz)
{
- if (!tz || !tz->trips.hot.flags.valid)
+ if (!tz || !tz->trips.hot.flags.valid || nocrt)
return -EINVAL;
if (tz->temperature >= tz->trips.hot.temperature) {
@@ -458,8 +526,12 @@
} else if (tz->trips.hot.flags.enabled)
tz->trips.hot.flags.enabled = 0;
- acpi_bus_generate_event(tz->device, ACPI_THERMAL_NOTIFY_HOT,
+ acpi_bus_generate_proc_event(tz->device, ACPI_THERMAL_NOTIFY_HOT,
tz->trips.hot.flags.enabled);
+ acpi_bus_generate_netlink_event(tz->device->pnp.device_class,
+ tz->device->dev.bus_id,
+ ACPI_THERMAL_NOTIFY_HOT,
+ tz->trips.hot.flags.enabled);
/* TBD: Call user-mode "sleep(S4)" function */
@@ -824,12 +896,14 @@
goto end;
if (tz->trips.critical.flags.valid)
- seq_printf(seq, "critical (S5): %ld C\n",
- KELVIN_TO_CELSIUS(tz->trips.critical.temperature));
+ seq_printf(seq, "critical (S5): %ld C%s",
+ KELVIN_TO_CELSIUS(tz->trips.critical.temperature),
+ nocrt ? " <disabled>\n" : "\n");
if (tz->trips.hot.flags.valid)
- seq_printf(seq, "hot (S4): %ld C\n",
- KELVIN_TO_CELSIUS(tz->trips.hot.temperature));
+ seq_printf(seq, "hot (S4): %ld C%s",
+ KELVIN_TO_CELSIUS(tz->trips.hot.temperature),
+ nocrt ? " <disabled>\n" : "\n");
if (tz->trips.passive.flags.valid) {
seq_printf(seq,
@@ -1019,9 +1093,9 @@
entry->owner = THIS_MODULE;
}
- /* 'trip_points' [R/W] */
+ /* 'trip_points' [R] */
entry = create_proc_entry(ACPI_THERMAL_FILE_TRIP_POINTS,
- S_IFREG | S_IRUGO | S_IWUSR,
+ S_IRUGO,
acpi_device_dir(device));
if (!entry)
return -ENODEV;
@@ -1101,12 +1175,16 @@
case ACPI_THERMAL_NOTIFY_THRESHOLDS:
acpi_thermal_get_trip_points(tz);
acpi_thermal_check(tz);
- acpi_bus_generate_event(device, event, 0);
+ acpi_bus_generate_proc_event(device, event, 0);
+ acpi_bus_generate_netlink_event(device->pnp.device_class,
+ device->dev.bus_id, event, 0);
break;
case ACPI_THERMAL_NOTIFY_DEVICES:
if (tz->flags.devices)
acpi_thermal_get_devices(tz);
- acpi_bus_generate_event(device, event, 0);
+ acpi_bus_generate_proc_event(device, event, 0);
+ acpi_bus_generate_netlink_event(device->pnp.device_class,
+ device->dev.bus_id, event, 0);
break;
default:
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
@@ -1281,11 +1359,93 @@
return AE_OK;
}
+#ifdef CONFIG_DMI
+static int thermal_act(struct dmi_system_id *d) {
+
+ if (act == 0) {
+ printk(KERN_NOTICE "ACPI: %s detected: "
+ "disabling all active thermal trip points\n", d->ident);
+ act = -1;
+ }
+ return 0;
+}
+static int thermal_nocrt(struct dmi_system_id *d) {
+
+ printk(KERN_NOTICE "ACPI: %s detected: "
+ "disabling all critical thermal trip point actions.\n", d->ident);
+ nocrt = 1;
+ return 0;
+}
+static int thermal_tzp(struct dmi_system_id *d) {
+
+ if (tzp == 0) {
+ printk(KERN_NOTICE "ACPI: %s detected: "
+ "enabling thermal zone polling\n", d->ident);
+ tzp = 300; /* 300 dS = 30 Seconds */
+ }
+ return 0;
+}
+static int thermal_psv(struct dmi_system_id *d) {
+
+ if (psv == 0) {
+ printk(KERN_NOTICE "ACPI: %s detected: "
+ "disabling all passive thermal trip points\n", d->ident);
+ psv = -1;
+ }
+ return 0;
+}
+
+static struct dmi_system_id thermal_dmi_table[] __initdata = {
+ /*
+ * Award BIOS on this AOpen makes thermal control almost worthless.
+ * http://bugzilla.kernel.org/show_bug.cgi?id=8842
+ */
+ {
+ .callback = thermal_act,
+ .ident = "AOpen i915GMm-HFS",
+ .matches = {
+ DMI_MATCH(DMI_BOARD_VENDOR, "AOpen"),
+ DMI_MATCH(DMI_BOARD_NAME, "i915GMm-HFS"),
+ },
+ },
+ {
+ .callback = thermal_psv,
+ .ident = "AOpen i915GMm-HFS",
+ .matches = {
+ DMI_MATCH(DMI_BOARD_VENDOR, "AOpen"),
+ DMI_MATCH(DMI_BOARD_NAME, "i915GMm-HFS"),
+ },
+ },
+ {
+ .callback = thermal_tzp,
+ .ident = "AOpen i915GMm-HFS",
+ .matches = {
+ DMI_MATCH(DMI_BOARD_VENDOR, "AOpen"),
+ DMI_MATCH(DMI_BOARD_NAME, "i915GMm-HFS"),
+ },
+ },
+ {
+ .callback = thermal_nocrt,
+ .ident = "Gigabyte GA-7ZX",
+ .matches = {
+ DMI_MATCH(DMI_BOARD_VENDOR, "Gigabyte Technology Co., Ltd."),
+ DMI_MATCH(DMI_BOARD_NAME, "7ZX"),
+ },
+ },
+ {}
+};
+#endif /* CONFIG_DMI */
+
static int __init acpi_thermal_init(void)
{
int result = 0;
+ dmi_check_system(thermal_dmi_table);
+ if (off) {
+ printk(KERN_NOTICE "ACPI: thermal control disabled\n");
+ return -ENODEV;
+ }
acpi_thermal_dir = proc_mkdir(ACPI_THERMAL_CLASS, acpi_root_dir);
if (!acpi_thermal_dir)
return -ENODEV;
diff --git a/drivers/acpi/utilities/utglobal.c b/drivers/acpi/utilities/utglobal.c
index 1621655..93ea829 100644
--- a/drivers/acpi/utilities/utglobal.c
+++ b/drivers/acpi/utilities/utglobal.c
@@ -126,6 +126,7 @@
"Unknown exception code: 0x%8.8X", status));
exception = "UNKNOWN_STATUS_CODE";
+ dump_stack();
}
return (ACPI_CAST_PTR(const char, exception));
diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c
index d987019..3c9bb85 100644
--- a/drivers/acpi/video.c
+++ b/drivers/acpi/video.c
@@ -31,7 +31,7 @@
#include <linux/list.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
-
+#include <linux/input.h>
#include <linux/backlight.h>
#include <linux/video_output.h>
#include <asm/uaccess.h>
@@ -138,6 +138,8 @@
struct semaphore sem;
struct list_head video_device_list;
struct proc_dir_entry *dir;
+ struct input_dev *input;
+ char phys[32]; /* for input device */
};
struct acpi_video_device_flags {
@@ -1764,6 +1766,9 @@
{
struct acpi_video_bus *video = data;
struct acpi_device *device = NULL;
+ struct input_dev *input;
+ int keycode;
+
printk("video bus notify\n");
@@ -1771,11 +1776,13 @@
return;
device = video->device;
+ input = video->input;
switch (event) {
case ACPI_VIDEO_NOTIFY_SWITCH: /* User requested a switch,
* most likely via hotkey. */
- acpi_bus_generate_event(device, event, 0);
+ acpi_bus_generate_proc_event(device, event, 0);
+ keycode = KEY_SWITCHVIDEOMODE;
break;
case ACPI_VIDEO_NOTIFY_PROBE: /* User plugged in or removed a video
@@ -1783,22 +1790,38 @@
acpi_video_device_enumerate(video);
acpi_video_device_rebind(video);
acpi_video_switch_output(video, event);
- acpi_bus_generate_event(device, event, 0);
+ acpi_bus_generate_proc_event(device, event, 0);
+ keycode = KEY_SWITCHVIDEOMODE;
break;
case ACPI_VIDEO_NOTIFY_CYCLE: /* Cycle Display output hotkey pressed. */
+ acpi_video_switch_output(video, event);
+ acpi_bus_generate_proc_event(device, event, 0);
+ keycode = KEY_SWITCHVIDEOMODE;
+ break;
case ACPI_VIDEO_NOTIFY_NEXT_OUTPUT: /* Next Display output hotkey pressed. */
+ acpi_video_switch_output(video, event);
+ acpi_bus_generate_proc_event(device, event, 0);
+ keycode = KEY_VIDEO_NEXT;
+ break;
case ACPI_VIDEO_NOTIFY_PREV_OUTPUT: /* previous Display output hotkey pressed. */
acpi_video_switch_output(video, event);
- acpi_bus_generate_event(device, event, 0);
+ acpi_bus_generate_proc_event(device, event, 0);
+ keycode = KEY_VIDEO_PREV;
break;
default:
+ keycode = KEY_UNKNOWN;
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
"Unsupported event [0x%x]\n", event));
break;
}
+ input_report_key(input, keycode, 1);
+ input_sync(input);
+ input_report_key(input, keycode, 0);
+ input_sync(input);
+
return;
}
@@ -1806,38 +1829,65 @@
{
struct acpi_video_device *video_device = data;
struct acpi_device *device = NULL;
+ struct acpi_video_bus *bus;
+ struct input_dev *input;
+ int keycode;
if (!video_device)
return;
device = video_device->dev;
+ bus = video_device->video;
+ input = bus->input;
switch (event) {
- case ACPI_VIDEO_NOTIFY_SWITCH: /* change in status (cycle output device) */
- case ACPI_VIDEO_NOTIFY_PROBE: /* change in status (output device status) */
- acpi_bus_generate_event(device, event, 0);
- break;
case ACPI_VIDEO_NOTIFY_CYCLE_BRIGHTNESS: /* Cycle brightness */
+ acpi_video_switch_brightness(video_device, event);
+ acpi_bus_generate_proc_event(device, event, 0);
+ keycode = KEY_BRIGHTNESS_CYCLE;
+ break;
case ACPI_VIDEO_NOTIFY_INC_BRIGHTNESS: /* Increase brightness */
+ acpi_video_switch_brightness(video_device, event);
+ acpi_bus_generate_proc_event(device, event, 0);
+ keycode = KEY_BRIGHTNESSUP;
+ break;
case ACPI_VIDEO_NOTIFY_DEC_BRIGHTNESS: /* Decrease brightness */
+ acpi_video_switch_brightness(video_device, event);
+ acpi_bus_generate_proc_event(device, event, 0);
+ keycode = KEY_BRIGHTNESSDOWN;
+ break;
case ACPI_VIDEO_NOTIFY_ZERO_BRIGHTNESS: /* zero brightnesss */
+ acpi_video_switch_brightness(video_device, event);
+ acpi_bus_generate_proc_event(device, event, 0);
+ keycode = KEY_BRIGHTNESS_ZERO;
+ break;
case ACPI_VIDEO_NOTIFY_DISPLAY_OFF: /* display device off */
acpi_video_switch_brightness(video_device, event);
- acpi_bus_generate_event(device, event, 0);
+ acpi_bus_generate_proc_event(device, event, 0);
+ keycode = KEY_DISPLAY_OFF;
break;
default:
+ keycode = KEY_UNKNOWN;
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
"Unsupported event [0x%x]\n", event));
break;
}
+
+ input_report_key(input, keycode, 1);
+ input_sync(input);
+ input_report_key(input, keycode, 0);
+ input_sync(input);
+
return;
}
+static int instance;
static int acpi_video_bus_add(struct acpi_device *device)
{
int result = 0;
acpi_status status = 0;
struct acpi_video_bus *video = NULL;
+ struct input_dev *input;
if (!device)
@@ -1847,6 +1897,13 @@
if (!video)
return -ENOMEM;
+ /* a hack to fix the duplicate name "VID" problem on T61 */
+ if (!strcmp(device->pnp.bus_id, "VID")) {
+ if (instance)
+ device->pnp.bus_id[3] = '0' + instance;
+ instance ++;
+ }
+
video->device = device;
strcpy(acpi_device_name(device), ACPI_VIDEO_BUS_NAME);
strcpy(acpi_device_class(device), ACPI_VIDEO_CLASS);
@@ -1881,6 +1938,39 @@
goto end;
}
+
+ video->input = input = input_allocate_device();
+
+ snprintf(video->phys, sizeof(video->phys),
+ "%s/video/input0", acpi_device_hid(video->device));
+
+ input->name = acpi_device_name(video->device);
+ input->phys = video->phys;
+ input->id.bustype = BUS_HOST;
+ input->id.product = 0x06;
+ input->evbit[0] = BIT(EV_KEY);
+ set_bit(KEY_SWITCHVIDEOMODE, input->keybit);
+ set_bit(KEY_VIDEO_NEXT, input->keybit);
+ set_bit(KEY_VIDEO_PREV, input->keybit);
+ set_bit(KEY_BRIGHTNESS_CYCLE, input->keybit);
+ set_bit(KEY_BRIGHTNESSUP, input->keybit);
+ set_bit(KEY_BRIGHTNESSDOWN, input->keybit);
+ set_bit(KEY_BRIGHTNESS_ZERO, input->keybit);
+ set_bit(KEY_DISPLAY_OFF, input->keybit);
+ set_bit(KEY_UNKNOWN, input->keybit);
+ result = input_register_device(input);
+ if (result) {
+ acpi_remove_notify_handler(video->device->handle,
+ ACPI_DEVICE_NOTIFY,
+ acpi_video_bus_notify);
+ acpi_video_bus_stop_devices(video);
+ acpi_video_bus_put_devices(video);
+ kfree(video->attached_array);
+ acpi_video_bus_remove_fs(device);
+ goto end;
+ }
+
+
printk(KERN_INFO PREFIX "%s [%s] (multi-head: %s rom: %s post: %s)\n",
ACPI_VIDEO_DEVICE_NAME, acpi_device_bid(device),
video->flags.multihead ? "yes" : "no",
@@ -1914,6 +2004,7 @@
acpi_video_bus_put_devices(video);
acpi_video_bus_remove_fs(device);
+ input_unregister_device(video->input);
kfree(video->attached_array);
kfree(video);
diff --git a/drivers/ata/ata_piix.c b/drivers/ata/ata_piix.c
index a78832e..071d274 100644
--- a/drivers/ata/ata_piix.c
+++ b/drivers/ata/ata_piix.c
@@ -436,7 +436,7 @@
/* PM PS SM SS MAP */
{ P0, P2, P1, P3 }, /* 00b (hardwired when in AHCI) */
{ RV, RV, RV, RV },
- { IDE, IDE, NA, NA }, /* 10b (IDE mode) */
+ { P0, P2, IDE, IDE }, /* 10b (IDE mode) */
{ RV, RV, RV, RV },
},
};
@@ -901,6 +901,13 @@
},
},
{
+ .ident = "TECRA M7",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "TECRA M7"),
+ },
+ },
+ {
.ident = "Satellite U205",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index 60e78be..2ad4dda 100644
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -1723,7 +1723,7 @@
tf.protocol = ATA_PROT_NODATA;
tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE;
err_mask = ata_exec_internal(dev, &tf, NULL, DMA_NONE, NULL, 0);
- if (err_mask) {
+ if (err_mask && id[2] != 0x738c) {
rc = -EIO;
reason = "SPINUP failed";
goto err_out;
@@ -3700,11 +3700,16 @@
goto fail;
/* verify n_sectors hasn't changed */
- if (dev->class == ATA_DEV_ATA && dev->n_sectors != n_sectors) {
+ if (dev->class == ATA_DEV_ATA && n_sectors &&
+ dev->n_sectors != n_sectors) {
ata_dev_printk(dev, KERN_INFO, "n_sectors mismatch "
"%llu != %llu\n",
(unsigned long long)n_sectors,
(unsigned long long)dev->n_sectors);
+
+ /* restore original n_sectors */
+ dev->n_sectors = n_sectors;
+
rc = -ENODEV;
goto fail;
}
diff --git a/drivers/ata/pata_artop.c b/drivers/ata/pata_artop.c
index ce589d9..b5352eb 100644
--- a/drivers/ata/pata_artop.c
+++ b/drivers/ata/pata_artop.c
@@ -2,6 +2,7 @@
* pata_artop.c - ARTOP ATA controller driver
*
* (C) 2006 Red Hat <alan@redhat.com>
+ * (C) 2007 Bartlomiej Zolnierkiewicz
*
* Based in part on drivers/ide/pci/aec62xx.c
* Copyright (C) 1999-2002 Andre Hedrick <andre@linux-ide.org>
@@ -28,7 +29,7 @@
#include <linux/ata.h>
#define DRV_NAME "pata_artop"
-#define DRV_VERSION "0.4.3"
+#define DRV_VERSION "0.4.4"
/*
* The ARTOP has 33 Mhz and "over clocked" timing tables. Until we
@@ -430,7 +431,7 @@
.udma_mask = ATA_UDMA4,
.port_ops = &artop6260_ops,
};
- static const struct ata_port_info info_626x_fast = {
+ static const struct ata_port_info info_628x = {
.sht = &artop_sht,
.flags = ATA_FLAG_SLAVE_POSS,
.pio_mask = 0x1f, /* pio0-4 */
@@ -438,6 +439,14 @@
.udma_mask = ATA_UDMA5,
.port_ops = &artop6260_ops,
};
+ static const struct ata_port_info info_628x_fast = {
+ .sht = &artop_sht,
+ .flags = ATA_FLAG_SLAVE_POSS,
+ .pio_mask = 0x1f, /* pio0-4 */
+ .mwdma_mask = 0x07, /* mwdma0-2 */
+ .udma_mask = ATA_UDMA6,
+ .port_ops = &artop6260_ops,
+ };
const struct ata_port_info *ppi[] = { NULL, NULL };
if (!printed_version++)
@@ -455,13 +464,13 @@
}
else if (id->driver_data == 1) /* 6260 */
ppi[0] = &info_626x;
- else if (id->driver_data == 2) { /* 6260 or 6260 + fast */
+ else if (id->driver_data == 2) { /* 6280 or 6280 + fast */
unsigned long io = pci_resource_start(pdev, 4);
u8 reg;
- ppi[0] = &info_626x;
+ ppi[0] = &info_628x;
if (inb(io) & 0x10)
- ppi[0] = &info_626x_fast;
+ ppi[0] = &info_628x_fast;
/* Mac systems come up with some registers not set as we
will need them */
diff --git a/drivers/ata/pata_hpt37x.c b/drivers/ata/pata_hpt37x.c
index 84d9c55..c5ddd93 100644
--- a/drivers/ata/pata_hpt37x.c
+++ b/drivers/ata/pata_hpt37x.c
@@ -8,12 +8,10 @@
* Copyright (C) 1999-2003 Andre Hedrick <andre@linux-ide.org>
* Portions Copyright (C) 2001 Sun Microsystems, Inc.
* Portions Copyright (C) 2003 Red Hat Inc
- * Portions Copyright (C) 2005-2006 MontaVista Software, Inc.
+ * Portions Copyright (C) 2005-2007 MontaVista Software, Inc.
*
* TODO
- * PLL mode
- * Look into engine reset on timeout errors. Should not be
- * required.
+ * Look into engine reset on timeout errors. Should not be required.
*/
#include <linux/kernel.h>
@@ -26,7 +24,7 @@
#include <linux/libata.h>
#define DRV_NAME "pata_hpt37x"
-#define DRV_VERSION "0.6.7"
+#define DRV_VERSION "0.6.9"
struct hpt_clock {
u8 xfer_speed;
@@ -1092,9 +1090,7 @@
int dpll, adjust;
/* Compute DPLL */
- dpll = 2;
- if (port->udma_mask & 0xE0)
- dpll = 3;
+ dpll = (port->udma_mask & 0xC0) ? 3 : 2;
f_low = (MHz[clock_slot] * 48) / MHz[dpll];
f_high = f_low + 2;
@@ -1116,7 +1112,7 @@
pci_write_config_dword(dev, 0x5C, (f_high << 16) | f_low | 0x100);
}
if (adjust == 8) {
- printk(KERN_WARNING "hpt37x: DPLL did not stabilize.\n");
+ printk(KERN_ERR "pata_hpt37x: DPLL did not stabilize!\n");
return -ENODEV;
}
if (dpll == 3)
@@ -1124,7 +1120,8 @@
else
private_data = (void *)hpt37x_timings_50;
- printk(KERN_INFO "hpt37x: Bus clock %dMHz, using DPLL.\n", MHz[dpll]);
+ printk(KERN_INFO "pata_hpt37x: bus clock %dMHz, using %dMHz DPLL.\n",
+ MHz[clock_slot], MHz[dpll]);
} else {
private_data = (void *)chip_table->clocks[clock_slot];
/*
@@ -1137,7 +1134,8 @@
port = &info_hpt370_33;
if (clock_slot < 2 && port == &info_hpt370a)
port = &info_hpt370a_33;
- printk(KERN_INFO "hpt37x: %s: Bus clock %dMHz.\n", chip_table->name, MHz[clock_slot]);
+ printk(KERN_INFO "pata_hpt37x: %s using %dMHz bus clock.\n",
+ chip_table->name, MHz[clock_slot]);
}
/* Now kick off ATA set up */
diff --git a/drivers/ata/pata_hpt3x2n.c b/drivers/ata/pata_hpt3x2n.c
index aa29cde..f8f234b 100644
--- a/drivers/ata/pata_hpt3x2n.c
+++ b/drivers/ata/pata_hpt3x2n.c
@@ -8,7 +8,7 @@
* Copyright (C) 1999-2003 Andre Hedrick <andre@linux-ide.org>
* Portions Copyright (C) 2001 Sun Microsystems, Inc.
* Portions Copyright (C) 2003 Red Hat Inc
- * Portions Copyright (C) 2005-2006 MontaVista Software, Inc.
+ * Portions Copyright (C) 2005-2007 MontaVista Software, Inc.
*
*
* TODO
@@ -25,7 +25,7 @@
#include <linux/libata.h>
#define DRV_NAME "pata_hpt3x2n"
-#define DRV_VERSION "0.3.3"
+#define DRV_VERSION "0.3.4"
enum {
HPT_PCI_FAST = (1 << 31),
@@ -579,10 +579,12 @@
pci_write_config_dword(dev, 0x5C, (f_high << 16) | f_low);
}
if (adjust == 8) {
- printk(KERN_WARNING "hpt3x2n: DPLL did not stabilize.\n");
+ printk(KERN_ERR "pata_hpt3x2n: DPLL did not stabilize!\n");
return -ENODEV;
}
+ printk(KERN_INFO "pata_hpt37x: bus clock %dMHz, using 66MHz DPLL.\n",
+ pci_mhz);
/* Set our private data up. We only need a few flags so we use
it directly */
port.private_data = NULL;
diff --git a/drivers/ata/pata_icside.c b/drivers/ata/pata_icside.c
index 321d98b..64a7117 100644
--- a/drivers/ata/pata_icside.c
+++ b/drivers/ata/pata_icside.c
@@ -330,17 +330,12 @@
{
}
-/*
- * We need to shut down unused ports to prevent spurious interrupts.
- * FIXME: the libata core doesn't call this function for PATA interfaces.
- */
-static void pata_icside_port_disable(struct ata_port *ap)
+static void pata_icside_postreset(struct ata_port *ap, unsigned int *classes)
{
struct pata_icside_state *state = ap->host->private_data;
- ata_port_printk(ap, KERN_ERR, "disabling icside port\n");
-
- ata_port_disable(ap);
+ if (classes[0] != ATA_DEV_NONE || classes[1] != ATA_DEV_NONE)
+ return ata_std_postreset(ap, classes);
state->port[ap->port_no].disabled = 1;
@@ -356,6 +351,12 @@
}
}
+static void pata_icside_error_handler(struct ata_port *ap)
+{
+ ata_bmdma_drive_eh(ap, ata_std_prereset, ata_std_softreset, NULL,
+ pata_icside_postreset);
+}
+
static u8 pata_icside_irq_ack(struct ata_port *ap, unsigned int chk_drq)
{
unsigned int bits = chk_drq ? ATA_BUSY | ATA_DRQ : ATA_BUSY;
@@ -374,7 +375,7 @@
}
static struct ata_port_operations pata_icside_port_ops = {
- .port_disable = pata_icside_port_disable,
+ .port_disable = ata_port_disable,
.set_dmamode = pata_icside_set_dmamode,
@@ -397,7 +398,7 @@
.freeze = ata_bmdma_freeze,
.thaw = ata_bmdma_thaw,
- .error_handler = ata_bmdma_error_handler,
+ .error_handler = pata_icside_error_handler,
.post_internal_cmd = pata_icside_bmdma_stop,
.irq_clear = ata_dummy_noret,
@@ -484,13 +485,6 @@
state->port[0].port_sel = sel;
state->port[1].port_sel = sel | 1;
- /*
- * FIXME: work around libata's aversion to calling port_disable.
- * This permanently disables interrupts on port 0 - bad luck if
- * you have a drive on that port.
- */
- state->port[0].disabled = 1;
-
info->base = easi_base;
info->irqops = &pata_icside_ops_arcin_v6;
info->nr_ports = 2;
diff --git a/drivers/ata/pata_isapnp.c b/drivers/ata/pata_isapnp.c
index 5525518..91a396f 100644
--- a/drivers/ata/pata_isapnp.c
+++ b/drivers/ata/pata_isapnp.c
@@ -139,6 +139,8 @@
{.id = ""}
};
+MODULE_DEVICE_TABLE(pnp, isapnp_devices);
+
static struct pnp_driver isapnp_driver = {
.name = DRV_NAME,
.id_table = isapnp_devices,
diff --git a/drivers/ata/pata_it821x.c b/drivers/ata/pata_it821x.c
index 430673b..7225124 100644
--- a/drivers/ata/pata_it821x.c
+++ b/drivers/ata/pata_it821x.c
@@ -587,7 +587,7 @@
itdev->want[1][1] = ATA_ANY;
itdev->last_device = -1;
- if (pdev->revision == 0x11) {
+ if (pdev->revision == 0x10) {
itdev->timing10 = 1;
/* Need to disable ATAPI DMA for this case */
if (!itdev->smart)
diff --git a/drivers/ata/pata_pdc2027x.c b/drivers/ata/pata_pdc2027x.c
index 69a5aa4..e3245b3 100644
--- a/drivers/ata/pata_pdc2027x.c
+++ b/drivers/ata/pata_pdc2027x.c
@@ -563,13 +563,13 @@
u32 bccrl, bccrh, bccrlv, bccrhv;
retry:
- bccrl = readl(mmio_base + PDC_BYTE_COUNT) & 0xffff;
- bccrh = readl(mmio_base + PDC_BYTE_COUNT + 0x100) & 0xffff;
+ bccrl = readl(mmio_base + PDC_BYTE_COUNT) & 0x7fff;
+ bccrh = readl(mmio_base + PDC_BYTE_COUNT + 0x100) & 0x7fff;
rmb();
/* Read the counter values again for verification */
- bccrlv = readl(mmio_base + PDC_BYTE_COUNT) & 0xffff;
- bccrhv = readl(mmio_base + PDC_BYTE_COUNT + 0x100) & 0xffff;
+ bccrlv = readl(mmio_base + PDC_BYTE_COUNT) & 0x7fff;
+ bccrhv = readl(mmio_base + PDC_BYTE_COUNT + 0x100) & 0x7fff;
rmb();
counter = (bccrh << 15) | bccrl;
@@ -692,16 +692,16 @@
struct timeval start_time, end_time;
long pll_clock, usec_elapsed;
- /* Read current counter value */
- start_count = pdc_read_counter(host);
- do_gettimeofday(&start_time);
-
/* Start the test mode */
scr = readl(mmio_base + PDC_SYS_CTL);
PDPRINTK("scr[%X]\n", scr);
writel(scr | (0x01 << 14), mmio_base + PDC_SYS_CTL);
readl(mmio_base + PDC_SYS_CTL); /* flush */
+ /* Read current counter value */
+ start_count = pdc_read_counter(host);
+ do_gettimeofday(&start_time);
+
/* Let the counter run for 100 ms. */
mdelay(100);
@@ -719,7 +719,7 @@
usec_elapsed = (end_time.tv_sec - start_time.tv_sec) * 1000000 +
(end_time.tv_usec - start_time.tv_usec);
- pll_clock = (start_count - end_count) / 100 *
+ pll_clock = ((start_count - end_count) & 0x3fffffff) / 100 *
(100000000 / usec_elapsed);
PDPRINTK("start[%ld] end[%ld] \n", start_count, end_count);
diff --git a/drivers/ata/pata_sis.c b/drivers/ata/pata_sis.c
index 66bd0e8..2bd7645 100644
--- a/drivers/ata/pata_sis.c
+++ b/drivers/ata/pata_sis.c
@@ -54,6 +54,7 @@
static const struct sis_laptop sis_laptop[] = {
/* devid, subvendor, subdev */
{ 0x5513, 0x1043, 0x1107 }, /* ASUS A6K */
+ { 0x5513, 0x1734, 0x105F }, /* FSC Amilo A1630 */
/* end marker */
{ 0, }
};
diff --git a/drivers/ata/pata_via.c b/drivers/ata/pata_via.c
index f645fe2..ea18e33 100644
--- a/drivers/ata/pata_via.c
+++ b/drivers/ata/pata_via.c
@@ -63,7 +63,7 @@
#include <linux/dmi.h>
#define DRV_NAME "pata_via"
-#define DRV_VERSION "0.3.1"
+#define DRV_VERSION "0.3.2"
/*
* The following comes directly from Vojtech Pavlik's ide/pci/via82cxxx
@@ -144,6 +144,9 @@
/* Systems by DMI */
if (dmi_check_system(cable_dmi_table))
return 1;
+ /* Arima W730-K8/Targa Visionary 811/... */
+ if (pdev->subsystem_vendor == 0x161F && pdev->subsystem_device == 0x2032)
+ return 1;
return 0;
}
diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c
index 8ec5208..3acf65e 100644
--- a/drivers/ata/sata_mv.c
+++ b/drivers/ata/sata_mv.c
@@ -621,6 +621,9 @@
{ PCI_VDEVICE(MARVELL, 0x5041), chip_504x },
{ PCI_VDEVICE(MARVELL, 0x5080), chip_5080 },
{ PCI_VDEVICE(MARVELL, 0x5081), chip_508x },
+ /* RocketRAID 1740/174x have different identifiers */
+ { PCI_VDEVICE(TTI, 0x1740), chip_508x },
+ { PCI_VDEVICE(TTI, 0x1742), chip_508x },
{ PCI_VDEVICE(MARVELL, 0x6040), chip_604x },
{ PCI_VDEVICE(MARVELL, 0x6041), chip_604x },
diff --git a/drivers/atm/Kconfig b/drivers/atm/Kconfig
index bed9f58..b554eda 100644
--- a/drivers/atm/Kconfig
+++ b/drivers/atm/Kconfig
@@ -6,6 +6,11 @@
bool "ATM drivers"
depends on NETDEVICES && ATM
default y
+ ---help---
+ Say Y here to get to see options for Asynchronous Transfer Mode
+ device drivers. This option alone does not add any kernel code.
+
+ If you say N, all options in this submenu will be skipped and disabled.
if ATM_DRIVERS && NETDEVICES && ATM
diff --git a/drivers/atm/fore200e.c b/drivers/atm/fore200e.c
index 405ee5e..8b12925 100644
--- a/drivers/atm/fore200e.c
+++ b/drivers/atm/fore200e.c
@@ -2435,7 +2435,7 @@
}
-static void __init
+static void __devinit
fore200e_param_bs_queue(struct fore200e* fore200e,
enum buffer_scheme scheme, enum buffer_magn magn,
int queue_length, int pool_size, int supply_blksize)
diff --git a/drivers/atm/iphase.c b/drivers/atm/iphase.c
index a3b605a..ef52452 100644
--- a/drivers/atm/iphase.c
+++ b/drivers/atm/iphase.c
@@ -1601,14 +1601,14 @@
skb_queue_head_init(&iadev->rx_dma_q);
iadev->rx_free_desc_qhead = NULL;
- iadev->rx_open = kmalloc(4*iadev->num_vc,GFP_KERNEL);
- if (!iadev->rx_open)
- {
+
+ iadev->rx_open = kzalloc(4 * iadev->num_vc, GFP_KERNEL);
+ if (!iadev->rx_open) {
printk(KERN_ERR DEV_LABEL "itf %d couldn't get free page\n",
dev->number);
goto err_free_dle;
}
- memset(iadev->rx_open, 0, 4*iadev->num_vc);
+
iadev->rxing = 1;
iadev->rx_pkt_cnt = 0;
/* Mode Register */
@@ -3171,12 +3171,12 @@
unsigned long flags;
int ret;
- iadev = kmalloc(sizeof(*iadev), GFP_KERNEL);
+ iadev = kzalloc(sizeof(*iadev), GFP_KERNEL);
if (!iadev) {
ret = -ENOMEM;
goto err_out;
}
- memset(iadev, 0, sizeof(*iadev));
+
iadev->pci = pdev;
IF_INIT(printk("ia detected at bus:%d dev: %d function:%d\n",
diff --git a/drivers/atm/lanai.c b/drivers/atm/lanai.c
index 55fd1b4..144a49f 100644
--- a/drivers/atm/lanai.c
+++ b/drivers/atm/lanai.c
@@ -65,7 +65,6 @@
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
-#include <linux/dma-mapping.h>
/* -------------------- TUNABLE PARAMATERS: */
diff --git a/drivers/auxdisplay/Kconfig b/drivers/auxdisplay/Kconfig
index de2fcce..043353b 100644
--- a/drivers/auxdisplay/Kconfig
+++ b/drivers/auxdisplay/Kconfig
@@ -8,6 +8,11 @@
menuconfig AUXDISPLAY
depends on PARPORT
bool "Auxiliary Display support"
+ ---help---
+ Say Y here to get to see options for auxiliary display drivers.
+ This option alone does not add any kernel code.
+
+ If you say N, all options in this submenu will be skipped and disabled.
if AUXDISPLAY && PARPORT
diff --git a/drivers/auxdisplay/cfag12864b.c b/drivers/auxdisplay/cfag12864b.c
index cb44cb4..80bb061 100644
--- a/drivers/auxdisplay/cfag12864b.c
+++ b/drivers/auxdisplay/cfag12864b.c
@@ -355,7 +355,7 @@
cfag12864b_cache = kmalloc(sizeof(unsigned char) *
CFAG12864B_SIZE, GFP_KERNEL);
- if (cfag12864b_buffer == NULL) {
+ if (cfag12864b_cache == NULL) {
printk(KERN_ERR CFAG12864B_NAME ": ERROR: "
"can't alloc cache buffer (%i bytes)\n",
CFAG12864B_SIZE);
diff --git a/drivers/block/Kconfig b/drivers/block/Kconfig
index a4a3119..4245b7f 100644
--- a/drivers/block/Kconfig
+++ b/drivers/block/Kconfig
@@ -6,6 +6,12 @@
bool "Block devices"
depends on BLOCK
default y
+ ---help---
+ Say Y here to get to see options for various different block device
+ drivers. This option alone does not add any kernel code.
+
+ If you say N, all options in this submenu will be skipped and disabled;
+ only do this if you know what you are doing.
if BLK_DEV
@@ -62,6 +68,7 @@
config BLK_DEV_XD
tristate "XT hard disk support"
depends on ISA && ISA_DMA_API
+ select CHECK_SIGNATURE
help
Very old 8 bit hard disk controllers used in the IBM XT computer
will be supported if you say Y here.
diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c
index a11b2bd..084358a 100644
--- a/drivers/block/cciss.c
+++ b/drivers/block/cciss.c
@@ -1977,12 +1977,13 @@
{
ReadCapdata_struct *buf;
int return_code;
- buf = kmalloc(sizeof(ReadCapdata_struct), GFP_KERNEL);
- if (buf == NULL) {
+
+ buf = kzalloc(sizeof(ReadCapdata_struct), GFP_KERNEL);
+ if (!buf) {
printk(KERN_WARNING "cciss: out of memory\n");
return;
}
- memset(buf, 0, sizeof(ReadCapdata_struct));
+
if (withirq)
return_code = sendcmd_withirq(CCISS_READ_CAPACITY,
ctlr, buf, sizeof(ReadCapdata_struct),
@@ -2003,7 +2004,6 @@
printk(KERN_INFO " blocks= %llu block_size= %d\n",
(unsigned long long)*total_size+1, *block_size);
kfree(buf);
- return;
}
static void
@@ -2011,12 +2011,13 @@
{
ReadCapdata_struct_16 *buf;
int return_code;
- buf = kmalloc(sizeof(ReadCapdata_struct_16), GFP_KERNEL);
- if (buf == NULL) {
+
+ buf = kzalloc(sizeof(ReadCapdata_struct_16), GFP_KERNEL);
+ if (!buf) {
printk(KERN_WARNING "cciss: out of memory\n");
return;
}
- memset(buf, 0, sizeof(ReadCapdata_struct_16));
+
if (withirq) {
return_code = sendcmd_withirq(CCISS_READ_CAPACITY_16,
ctlr, buf, sizeof(ReadCapdata_struct_16),
@@ -2038,7 +2039,6 @@
printk(KERN_INFO " blocks= %llu block_size= %d\n",
(unsigned long long)*total_size+1, *block_size);
kfree(buf);
- return;
}
static int cciss_revalidate(struct gendisk *disk)
diff --git a/drivers/block/cpqarray.c b/drivers/block/cpqarray.c
index be4e3477d..eb9799a 100644
--- a/drivers/block/cpqarray.c
+++ b/drivers/block/cpqarray.c
@@ -420,18 +420,17 @@
goto Enomem2;
}
- hba[i]->cmd_pool = (cmdlist_t *)pci_alloc_consistent(
+ hba[i]->cmd_pool = pci_alloc_consistent(
hba[i]->pci_dev, NR_CMDS * sizeof(cmdlist_t),
&(hba[i]->cmd_pool_dhandle));
- hba[i]->cmd_pool_bits = kmalloc(
- ((NR_CMDS+BITS_PER_LONG-1)/BITS_PER_LONG)*sizeof(unsigned long),
+ hba[i]->cmd_pool_bits = kcalloc(
+ (NR_CMDS+BITS_PER_LONG-1)/BITS_PER_LONG, sizeof(unsigned long),
GFP_KERNEL);
if (!hba[i]->cmd_pool_bits || !hba[i]->cmd_pool)
goto Enomem1;
memset(hba[i]->cmd_pool, 0, NR_CMDS * sizeof(cmdlist_t));
- memset(hba[i]->cmd_pool_bits, 0, ((NR_CMDS+BITS_PER_LONG-1)/BITS_PER_LONG)*sizeof(unsigned long));
printk(KERN_INFO "cpqarray: Finding drives on %s",
hba[i]->devname);
@@ -1660,45 +1659,30 @@
info_p->log_drv_map = 0;
- id_ldrive = kmalloc(sizeof(id_log_drv_t), GFP_KERNEL);
- if(id_ldrive == NULL)
- {
+ id_ldrive = kzalloc(sizeof(id_log_drv_t), GFP_KERNEL);
+ if (!id_ldrive) {
printk( KERN_ERR "cpqarray: out of memory.\n");
- return;
+ goto err_0;
}
- id_ctlr_buf = kmalloc(sizeof(id_ctlr_t), GFP_KERNEL);
- if(id_ctlr_buf == NULL)
- {
- kfree(id_ldrive);
+ id_ctlr_buf = kzalloc(sizeof(id_ctlr_t), GFP_KERNEL);
+ if (!id_ctlr_buf) {
printk( KERN_ERR "cpqarray: out of memory.\n");
- return;
+ goto err_1;
}
- id_lstatus_buf = kmalloc(sizeof(sense_log_drv_stat_t), GFP_KERNEL);
- if(id_lstatus_buf == NULL)
- {
- kfree(id_ctlr_buf);
- kfree(id_ldrive);
+ id_lstatus_buf = kzalloc(sizeof(sense_log_drv_stat_t), GFP_KERNEL);
+ if (!id_lstatus_buf) {
printk( KERN_ERR "cpqarray: out of memory.\n");
- return;
+ goto err_2;
}
- sense_config_buf = kmalloc(sizeof(config_t), GFP_KERNEL);
- if(sense_config_buf == NULL)
- {
- kfree(id_lstatus_buf);
- kfree(id_ctlr_buf);
- kfree(id_ldrive);
+ sense_config_buf = kzalloc(sizeof(config_t), GFP_KERNEL);
+ if (!sense_config_buf) {
printk( KERN_ERR "cpqarray: out of memory.\n");
- return;
+ goto err_3;
}
- memset(id_ldrive, 0, sizeof(id_log_drv_t));
- memset(id_ctlr_buf, 0, sizeof(id_ctlr_t));
- memset(id_lstatus_buf, 0, sizeof(sense_log_drv_stat_t));
- memset(sense_config_buf, 0, sizeof(config_t));
-
info_p->phys_drives = 0;
info_p->log_drv_map = 0;
info_p->drv_assign_map = 0;
@@ -1712,13 +1696,8 @@
* so the idastubopen will fail on all logical drives
* on the controller.
*/
- /* Free all the buffers and return */
printk(KERN_ERR "cpqarray: error sending ID controller\n");
- kfree(sense_config_buf);
- kfree(id_lstatus_buf);
- kfree(id_ctlr_buf);
- kfree(id_ldrive);
- return;
+ goto err_4;
}
info_p->log_drives = id_ctlr_buf->nr_drvs;
@@ -1764,12 +1743,7 @@
" failed to report status of logical drive %d\n"
"Access to this controller has been disabled\n",
ctlr, log_unit);
- /* Free all the buffers and return */
- kfree(sense_config_buf);
- kfree(id_lstatus_buf);
- kfree(id_ctlr_buf);
- kfree(id_ldrive);
- return;
+ goto err_4;
}
/*
Make sure the logical drive is configured
@@ -1798,14 +1772,8 @@
sizeof(config_t), 0, 0, log_unit);
if (ret_code == IO_ERROR) {
info_p->log_drv_map = 0;
- /* Free all the buffers and return */
printk(KERN_ERR "cpqarray: error sending sense config\n");
- kfree(sense_config_buf);
- kfree(id_lstatus_buf);
- kfree(id_ctlr_buf);
- kfree(id_ldrive);
- return;
-
+ goto err_4;
}
info_p->phys_drives =
@@ -1820,12 +1788,18 @@
log_index = log_index + 1;
} /* end of if logical drive configured */
} /* end of for log_unit */
- kfree(sense_config_buf);
- kfree(id_ldrive);
- kfree(id_lstatus_buf);
- kfree(id_ctlr_buf);
- return;
+ /* Free all the buffers and return */
+err_4:
+ kfree(sense_config_buf);
+err_3:
+ kfree(id_lstatus_buf);
+err_2:
+ kfree(id_ctlr_buf);
+err_1:
+ kfree(id_ldrive);
+err_0:
+ return;
}
static void __exit cpqarray_exit(void)
diff --git a/drivers/block/lguest_blk.c b/drivers/block/lguest_blk.c
index 93e3c40..160cf14 100644
--- a/drivers/block/lguest_blk.c
+++ b/drivers/block/lguest_blk.c
@@ -308,9 +308,12 @@
}
/* This allocates a "struct gendisk" where we pack all the information
- * about the disk which the rest of Linux sees. We ask for one minor
- * number; I do wonder if we should be asking for more. */
- bd->disk = alloc_disk(1);
+ * about the disk which the rest of Linux sees. The argument is the
+ * number of minor devices desired: we need one minor for the main
+ * disk, and one for each partition. Of course, we can't possibly know
+ * how many partitions are on the disk (add_disk does that).
+ */
+ bd->disk = alloc_disk(16);
if (!bd->disk) {
err = -ENOMEM;
goto out_unregister_blkdev;
diff --git a/drivers/block/viodasd.c b/drivers/block/viodasd.c
index 85916e2..af3969a 100644
--- a/drivers/block/viodasd.c
+++ b/drivers/block/viodasd.c
@@ -41,7 +41,6 @@
#include <linux/dma-mapping.h>
#include <linux/completion.h>
#include <linux/device.h>
-#include <linux/kernel.h>
#include <asm/uaccess.h>
#include <asm/vio.h>
diff --git a/drivers/block/xsysace.c b/drivers/block/xsysace.c
index cb27e88..3ede0b6 100644
--- a/drivers/block/xsysace.c
+++ b/drivers/block/xsysace.c
@@ -902,26 +902,17 @@
return 0;
}
-static int ace_ioctl(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg)
+static int ace_getgeo(struct block_device *bdev, struct hd_geometry *geo)
{
- struct ace_device *ace = inode->i_bdev->bd_disk->private_data;
- struct hd_geometry __user *geo = (struct hd_geometry __user *)arg;
- struct hd_geometry g;
- dev_dbg(ace->dev, "ace_ioctl()\n");
+ struct ace_device *ace = bdev->bd_disk->private_data;
- switch (cmd) {
- case HDIO_GETGEO:
- g.heads = ace->cf_id.heads;
- g.sectors = ace->cf_id.sectors;
- g.cylinders = ace->cf_id.cyls;
- g.start = 0;
- return copy_to_user(geo, &g, sizeof(g)) ? -EFAULT : 0;
+ dev_dbg(ace->dev, "ace_getgeo()\n");
- default:
- return -ENOTTY;
- }
- return -ENOTTY;
+ geo->heads = ace->cf_id.heads;
+ geo->sectors = ace->cf_id.sectors;
+ geo->cylinders = ace->cf_id.cyls;
+
+ return 0;
}
static struct block_device_operations ace_fops = {
@@ -930,7 +921,7 @@
.release = ace_release,
.media_changed = ace_media_changed,
.revalidate_disk = ace_revalidate_disk,
- .ioctl = ace_ioctl,
+ .getgeo = ace_getgeo,
};
/* --------------------------------------------------------------------
diff --git a/drivers/char/drm/drm_bufs.c b/drivers/char/drm/drm_bufs.c
index 923174c..c115b39 100644
--- a/drivers/char/drm/drm_bufs.c
+++ b/drivers/char/drm/drm_bufs.c
@@ -177,8 +177,14 @@
MTRR_TYPE_WRCOMB, 1);
}
}
- if (map->type == _DRM_REGISTERS)
+ if (map->type == _DRM_REGISTERS) {
map->handle = ioremap(map->offset, map->size);
+ if (!map->handle) {
+ drm_free(map, sizeof(*map), DRM_MEM_MAPS);
+ return -ENOMEM;
+ }
+ }
+
break;
case _DRM_SHM:
list = drm_find_matching_map(dev, map);
@@ -479,11 +485,6 @@
return -EINVAL;
}
- if (!map) {
- mutex_unlock(&dev->struct_mutex);
- return -EINVAL;
- }
-
/* Register and framebuffer maps are permanent */
if ((map->type == _DRM_REGISTERS) || (map->type == _DRM_FRAME_BUFFER)) {
mutex_unlock(&dev->struct_mutex);
diff --git a/drivers/char/drm/i915_dma.c b/drivers/char/drm/i915_dma.c
index 3359cc2..8e7d713 100644
--- a/drivers/char/drm/i915_dma.c
+++ b/drivers/char/drm/i915_dma.c
@@ -184,6 +184,8 @@
* private backbuffer/depthbuffer usage.
*/
dev_priv->use_mi_batchbuffer_start = 0;
+ if (IS_I965G(dev)) /* 965 doesn't support older method */
+ dev_priv->use_mi_batchbuffer_start = 1;
/* Allow hardware batchbuffers unless told otherwise.
*/
@@ -517,8 +519,13 @@
if (dev_priv->use_mi_batchbuffer_start) {
BEGIN_LP_RING(2);
- OUT_RING(MI_BATCH_BUFFER_START | (2 << 6));
- OUT_RING(batch->start | MI_BATCH_NON_SECURE);
+ if (IS_I965G(dev)) {
+ OUT_RING(MI_BATCH_BUFFER_START | (2 << 6) | MI_BATCH_NON_SECURE_I965);
+ OUT_RING(batch->start);
+ } else {
+ OUT_RING(MI_BATCH_BUFFER_START | (2 << 6));
+ OUT_RING(batch->start | MI_BATCH_NON_SECURE);
+ }
ADVANCE_LP_RING();
} else {
BEGIN_LP_RING(4);
@@ -735,7 +742,8 @@
switch (param.param) {
case I915_SETPARAM_USE_MI_BATCHBUFFER_START:
- dev_priv->use_mi_batchbuffer_start = param.value;
+ if (!IS_I965G(dev))
+ dev_priv->use_mi_batchbuffer_start = param.value;
break;
case I915_SETPARAM_TEX_LRU_LOG_GRANULARITY:
dev_priv->tex_lru_log_granularity = param.value;
diff --git a/drivers/char/drm/i915_drv.h b/drivers/char/drm/i915_drv.h
index fd91856..737088b 100644
--- a/drivers/char/drm/i915_drv.h
+++ b/drivers/char/drm/i915_drv.h
@@ -282,6 +282,7 @@
#define MI_BATCH_BUFFER_START (0x31<<23)
#define MI_BATCH_BUFFER_END (0xA<<23)
#define MI_BATCH_NON_SECURE (1)
+#define MI_BATCH_NON_SECURE_I965 (1<<8)
#define MI_WAIT_FOR_EVENT ((0x3<<23))
#define MI_WAIT_FOR_PLANE_A_FLIP (1<<2)
diff --git a/drivers/char/drm/via_dmablit.c b/drivers/char/drm/via_dmablit.c
index 832de1d..3dd1ed3 100644
--- a/drivers/char/drm/via_dmablit.c
+++ b/drivers/char/drm/via_dmablit.c
@@ -560,7 +560,7 @@
blitq->head = 0;
blitq->cur = 0;
blitq->serviced = 0;
- blitq->num_free = VIA_NUM_BLIT_SLOTS;
+ blitq->num_free = VIA_NUM_BLIT_SLOTS - 1;
blitq->num_outstanding = 0;
blitq->is_active = 0;
blitq->aborting = 0;
diff --git a/drivers/char/hvc_lguest.c b/drivers/char/hvc_lguest.c
index feeccba..3d6bd0b 100644
--- a/drivers/char/hvc_lguest.c
+++ b/drivers/char/hvc_lguest.c
@@ -35,6 +35,7 @@
#include <linux/err.h>
#include <linux/init.h>
#include <linux/lguest_bus.h>
+#include <asm/paravirt.h>
#include "hvc_console.h"
/*D:340 This is our single console input buffer, with associated "struct
diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c
index 96d2f9e..9b07f785 100644
--- a/drivers/char/ipmi/ipmi_si_intf.c
+++ b/drivers/char/ipmi/ipmi_si_intf.c
@@ -2292,7 +2292,7 @@
info->irq = irq_of_parse_and_map(dev->node, 0);
info->dev = &dev->dev;
- dev_dbg(&dev->dev, "addr 0x%lx regsize %ld spacing %ld irq %x\n",
+ dev_dbg(&dev->dev, "addr 0x%lx regsize %d spacing %d irq %x\n",
info->io.addr_data, info->io.regsize, info->io.regspacing,
info->irq);
diff --git a/drivers/char/keyboard.c b/drivers/char/keyboard.c
index 2ce0af1..d95f316 100644
--- a/drivers/char/keyboard.c
+++ b/drivers/char/keyboard.c
@@ -1022,10 +1022,6 @@
308,310,313,314,315,317,318,319,320,357,322,323,324,325,276,330,
332,340,365,342,343,344,345,346,356,270,341,368,369,370,371,372 };
-#ifdef CONFIG_MAC_EMUMOUSEBTN
-extern int mac_hid_mouse_emulate_buttons(int, int, int);
-#endif /* CONFIG_MAC_EMUMOUSEBTN */
-
#ifdef CONFIG_SPARC
static int sparc_l1_a_state = 0;
extern void sun_do_break(void);
diff --git a/drivers/char/pcmcia/cm4000_cs.c b/drivers/char/pcmcia/cm4000_cs.c
index fee58e0..4177f6d 100644
--- a/drivers/char/pcmcia/cm4000_cs.c
+++ b/drivers/char/pcmcia/cm4000_cs.c
@@ -1629,7 +1629,7 @@
{
struct cm4000_dev *dev;
struct pcmcia_device *link;
- int rc, minor = iminor(inode);
+ int minor = iminor(inode);
if (minor >= CM4000_MAX_DEV)
return -ENODEV;
@@ -1668,7 +1668,6 @@
start_monitor(dev);
link->open = 1; /* only one open per device */
- rc = 0;
DEBUGP(2, dev, "<- cmm_open\n");
return nonseekable_open(inode, filp);
@@ -1824,7 +1823,7 @@
static void cm4000_release(struct pcmcia_device *link)
{
- cmm_cm4000_release(link->priv); /* delay release until device closed */
+ cmm_cm4000_release(link); /* delay release until device closed */
pcmcia_disable_device(link);
}
diff --git a/drivers/char/pcmcia/cm4040_cs.c b/drivers/char/pcmcia/cm4040_cs.c
index af88181..b24a3e7 100644
--- a/drivers/char/pcmcia/cm4040_cs.c
+++ b/drivers/char/pcmcia/cm4040_cs.c
@@ -599,7 +599,7 @@
static void reader_release(struct pcmcia_device *link)
{
- cm4040_reader_release(link->priv);
+ cm4040_reader_release(link);
pcmcia_disable_device(link);
}
diff --git a/drivers/char/sonypi.c b/drivers/char/sonypi.c
index 73037a4..8598585 100644
--- a/drivers/char/sonypi.c
+++ b/drivers/char/sonypi.c
@@ -875,7 +875,7 @@
#ifdef CONFIG_ACPI
if (sonypi_acpi_device)
- acpi_bus_generate_event(sonypi_acpi_device, 1, event);
+ acpi_bus_generate_proc_event(sonypi_acpi_device, 1, event);
#endif
kfifo_put(sonypi_device.fifo, (unsigned char *)&event, sizeof(event));
@@ -1147,10 +1147,15 @@
return 0;
}
+const static struct acpi_device_id sonypi_device_ids[] = {
+ {"SNY6001", 0},
+ {"", 0},
+};
+
static struct acpi_driver sonypi_acpi_driver = {
.name = "sonypi",
.class = "hkey",
- .ids = "SNY6001",
+ .ids = sonypi_device_ids,
.ops = {
.add = sonypi_acpi_add,
.remove = sonypi_acpi_remove,
diff --git a/drivers/char/synclink_gt.c b/drivers/char/synclink_gt.c
index bbb7f12..2f97d2f 100644
--- a/drivers/char/synclink_gt.c
+++ b/drivers/char/synclink_gt.c
@@ -1565,6 +1565,9 @@
int rc;
unsigned long flags;
+ if (!try_module_get(THIS_MODULE))
+ return -EBUSY;
+
DBGINFO(("%s hdlcdev_open\n", dev->name));
/* generic HDLC layer open processing */
@@ -1634,6 +1637,7 @@
info->netcount=0;
spin_unlock_irqrestore(&info->netlock, flags);
+ module_put(THIS_MODULE);
return 0;
}
diff --git a/drivers/char/tpm/tpm.c b/drivers/char/tpm/tpm.c
index 9bb5429..39564b7 100644
--- a/drivers/char/tpm/tpm.c
+++ b/drivers/char/tpm/tpm.c
@@ -7,7 +7,7 @@
* Reiner Sailer <sailer@watson.ibm.com>
* Kylene Hall <kjhall@us.ibm.com>
*
- * Maintained by: <tpmdd_devel@lists.sourceforge.net>
+ * Maintained by: <tpmdd-devel@lists.sourceforge.net>
*
* Device driver for TCG/TCPA TPM (trusted platform module).
* Specifications at www.trustedcomputinggroup.org
diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h
index b2e2b00..d15ccdd 100644
--- a/drivers/char/tpm/tpm.h
+++ b/drivers/char/tpm/tpm.h
@@ -7,7 +7,7 @@
* Reiner Sailer <sailer@watson.ibm.com>
* Kylene Hall <kjhall@us.ibm.com>
*
- * Maintained by: <tpmdd_devel@lists.sourceforge.net>
+ * Maintained by: <tpmdd-devel@lists.sourceforge.net>
*
* Device driver for TCG/TCPA TPM (trusted platform module).
* Specifications at www.trustedcomputinggroup.org
diff --git a/drivers/char/tpm/tpm_atmel.c b/drivers/char/tpm/tpm_atmel.c
index 1ab0896..d0e7926 100644
--- a/drivers/char/tpm/tpm_atmel.c
+++ b/drivers/char/tpm/tpm_atmel.c
@@ -7,7 +7,7 @@
* Reiner Sailer <sailer@watson.ibm.com>
* Kylene Hall <kjhall@us.ibm.com>
*
- * Maintained by: <tpmdd_devel@lists.sourceforge.net>
+ * Maintained by: <tpmdd-devel@lists.sourceforge.net>
*
* Device driver for TCG/TCPA TPM (trusted platform module).
* Specifications at www.trustedcomputinggroup.org
diff --git a/drivers/char/tpm/tpm_atmel.h b/drivers/char/tpm/tpm_atmel.h
index 9363bcf..6c831f9 100644
--- a/drivers/char/tpm/tpm_atmel.h
+++ b/drivers/char/tpm/tpm_atmel.h
@@ -4,7 +4,7 @@
* Authors:
* Kylene Hall <kjhall@us.ibm.com>
*
- * Maintained by: <tpmdd_devel@lists.sourceforge.net>
+ * Maintained by: <tpmdd-devel@lists.sourceforge.net>
*
* Device driver for TCG/TCPA TPM (trusted platform module).
* Specifications at www.trustedcomputinggroup.org
diff --git a/drivers/char/tpm/tpm_bios.c b/drivers/char/tpm/tpm_bios.c
index 8677fc6..60a2d26 100644
--- a/drivers/char/tpm/tpm_bios.c
+++ b/drivers/char/tpm/tpm_bios.c
@@ -7,6 +7,8 @@
* Reiner Sailer <sailer@watson.ibm.com>
* Kylene Hall <kjhall@us.ibm.com>
*
+ * Maintained by: <tpmdd-devel@lists.sourceforge.net>
+ *
* Access to the eventlog extended by the TCG BIOS of PC platform
*
* This program is free software; you can redistribute it and/or
diff --git a/drivers/char/tpm/tpm_nsc.c b/drivers/char/tpm/tpm_nsc.c
index 608f730..6313326 100644
--- a/drivers/char/tpm/tpm_nsc.c
+++ b/drivers/char/tpm/tpm_nsc.c
@@ -7,7 +7,7 @@
* Reiner Sailer <sailer@watson.ibm.com>
* Kylene Hall <kjhall@us.ibm.com>
*
- * Maintained by: <tpmdd_devel@lists.sourceforge.net>
+ * Maintained by: <tpmdd-devel@lists.sourceforge.net>
*
* Device driver for TCG/TCPA TPM (trusted platform module).
* Specifications at www.trustedcomputinggroup.org
diff --git a/drivers/char/tpm/tpm_tis.c b/drivers/char/tpm/tpm_tis.c
index 483f3f6..23fa18a 100644
--- a/drivers/char/tpm/tpm_tis.c
+++ b/drivers/char/tpm/tpm_tis.c
@@ -5,6 +5,8 @@
* Leendert van Doorn <leendert@watson.ibm.com>
* Kylene Hall <kjhall@us.ibm.com>
*
+ * Maintained by: <tpmdd-devel@lists.sourceforge.net>
+ *
* Device driver for TCG/TCPA TPM (trusted platform module).
* Specifications at www.trustedcomputinggroup.org
*
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c
index de37ebc..9c867cf 100644
--- a/drivers/char/tty_io.c
+++ b/drivers/char/tty_io.c
@@ -369,25 +369,54 @@
}
/**
+ * __tty_buffer_flush - flush full tty buffers
+ * @tty: tty to flush
+ *
+ * flush all the buffers containing receive data. Caller must
+ * hold the buffer lock and must have ensured no parallel flush to
+ * ldisc is running.
+ *
+ * Locking: Caller must hold tty->buf.lock
+ */
+
+static void __tty_buffer_flush(struct tty_struct *tty)
+{
+ struct tty_buffer *thead;
+
+ while((thead = tty->buf.head) != NULL) {
+ tty->buf.head = thead->next;
+ tty_buffer_free(tty, thead);
+ }
+ tty->buf.tail = NULL;
+}
+
+/**
* tty_buffer_flush - flush full tty buffers
* @tty: tty to flush
*
- * flush all the buffers containing receive data
+ * flush all the buffers containing receive data. If the buffer is
+ * being processed by flush_to_ldisc then we defer the processing
+ * to that function
*
* Locking: none
*/
static void tty_buffer_flush(struct tty_struct *tty)
{
- struct tty_buffer *thead;
unsigned long flags;
-
spin_lock_irqsave(&tty->buf.lock, flags);
- while((thead = tty->buf.head) != NULL) {
- tty->buf.head = thead->next;
- tty_buffer_free(tty, thead);
- }
- tty->buf.tail = NULL;
+
+ /* If the data is being pushed to the tty layer then we can't
+ process it here. Instead set a flag and the flush_to_ldisc
+ path will process the flush request before it exits */
+ if (test_bit(TTY_FLUSHING, &tty->flags)) {
+ set_bit(TTY_FLUSHPENDING, &tty->flags);
+ spin_unlock_irqrestore(&tty->buf.lock, flags);
+ wait_event(tty->read_wait,
+ test_bit(TTY_FLUSHPENDING, &tty->flags) == 0);
+ return;
+ } else
+ __tty_buffer_flush(tty);
spin_unlock_irqrestore(&tty->buf.lock, flags);
}
@@ -2034,8 +2063,7 @@
}
if (!*tp_loc) {
- tp = (struct ktermios *) kmalloc(sizeof(struct ktermios),
- GFP_KERNEL);
+ tp = kmalloc(sizeof(struct ktermios), GFP_KERNEL);
if (!tp)
goto free_mem_out;
*tp = driver->init_termios;
@@ -2065,8 +2093,7 @@
}
if (!*o_tp_loc) {
- o_tp = (struct ktermios *)
- kmalloc(sizeof(struct ktermios), GFP_KERNEL);
+ o_tp = kmalloc(sizeof(struct ktermios), GFP_KERNEL);
if (!o_tp)
goto free_mem_out;
*o_tp = driver->other->init_termios;
@@ -3594,6 +3621,7 @@
return;
spin_lock_irqsave(&tty->buf.lock, flags);
+ set_bit(TTY_FLUSHING, &tty->flags); /* So we know a flush is running */
head = tty->buf.head;
if (head != NULL) {
tty->buf.head = NULL;
@@ -3607,6 +3635,11 @@
tty_buffer_free(tty, tbuf);
continue;
}
+ /* Ldisc or user is trying to flush the buffers
+ we are feeding to the ldisc, stop feeding the
+ line discipline as we want to empty the queue */
+ if (test_bit(TTY_FLUSHPENDING, &tty->flags))
+ break;
if (!tty->receive_room) {
schedule_delayed_work(&tty->buf.work, 1);
break;
@@ -3620,8 +3653,17 @@
disc->receive_buf(tty, char_buf, flag_buf, count);
spin_lock_irqsave(&tty->buf.lock, flags);
}
+ /* Restore the queue head */
tty->buf.head = head;
}
+ /* We may have a deferred request to flush the input buffer,
+ if so pull the chain under the lock and empty the queue */
+ if (test_bit(TTY_FLUSHPENDING, &tty->flags)) {
+ __tty_buffer_flush(tty);
+ clear_bit(TTY_FLUSHPENDING, &tty->flags);
+ wake_up(&tty->read_wait);
+ }
+ clear_bit(TTY_FLUSHING, &tty->flags);
spin_unlock_irqrestore(&tty->buf.lock, flags);
tty_ldisc_deref(disc);
diff --git a/drivers/char/watchdog/alim1535_wdt.c b/drivers/char/watchdog/alim1535_wdt.c
index e3f6a7d..c404fc6 100644
--- a/drivers/char/watchdog/alim1535_wdt.c
+++ b/drivers/char/watchdog/alim1535_wdt.c
@@ -312,6 +312,7 @@
*/
static struct pci_device_id ali_pci_tbl[] = {
+ { PCI_VENDOR_ID_AL, 0x1533, PCI_ANY_ID, PCI_ANY_ID,},
{ PCI_VENDOR_ID_AL, 0x1535, PCI_ANY_ID, PCI_ANY_ID,},
{ 0, },
};
@@ -329,9 +330,11 @@
struct pci_dev *pdev;
u32 wdog;
- /* Check for a 1535 series bridge */
+ /* Check for a 1533/1535 series bridge */
pdev = pci_get_device(PCI_VENDOR_ID_AL, 0x1535, NULL);
- if(pdev == NULL)
+ if (pdev == NULL)
+ pdev = pci_get_device(PCI_VENDOR_ID_AL, 0x1533, NULL);
+ if (pdev == NULL)
return -ENODEV;
pci_dev_put(pdev);
diff --git a/drivers/char/watchdog/eurotechwdt.c b/drivers/char/watchdog/eurotechwdt.c
index b070324..b14e9d1 100644
--- a/drivers/char/watchdog/eurotechwdt.c
+++ b/drivers/char/watchdog/eurotechwdt.c
@@ -1,5 +1,5 @@
/*
- * Eurotech CPU-1220/1410 on board WDT driver
+ * Eurotech CPU-1220/1410/1420 on board WDT driver
*
* (c) Copyright 2001 Ascensit <support@ascensit.com>
* (c) Copyright 2001 Rodolfo Giometti <giometti@ascensit.com>
@@ -25,6 +25,9 @@
/* Changelog:
*
+ * 2001 - Rodolfo Giometti
+ * Initial release
+ *
* 2002/04/25 - Rob Radez
* clean up #includes
* clean up locking
@@ -33,13 +36,15 @@
* add WDIOC_GETSTATUS and WDIOC_SETOPTIONS ioctls
* add expect_close support
*
- * 2001 - Rodolfo Giometti
- * Initial release
- *
* 2002.05.30 - Joel Becker <joel.becker@oracle.com>
* Added Matt Domsch's nowayout module option.
*/
+/*
+ * The eurotech CPU-1220/1410/1420's watchdog is a part
+ * of the on-board SUPER I/O device SMSC FDC 37B782.
+ */
+
#include <linux/interrupt.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
diff --git a/drivers/crypto/Kconfig b/drivers/crypto/Kconfig
index 84ebfcc..c0fc4ae 100644
--- a/drivers/crypto/Kconfig
+++ b/drivers/crypto/Kconfig
@@ -2,6 +2,11 @@
menuconfig CRYPTO_HW
bool "Hardware crypto devices"
default y
+ ---help---
+ Say Y here to get to see options for hardware crypto devices and
+ processors. This option alone does not add any kernel code.
+
+ If you say N, all options in this submenu will be skipped and disabled.
if CRYPTO_HW
diff --git a/drivers/dma/ioatdma.c b/drivers/dma/ioatdma.c
index 5fbe56b..2d1f178 100644
--- a/drivers/dma/ioatdma.c
+++ b/drivers/dma/ioatdma.c
@@ -347,8 +347,7 @@
new->async_tx.ack = 0; /* client is in control of this ack */
new->async_tx.cookie = -EBUSY;
- pci_unmap_len_set(new, src_len, orig_len);
- pci_unmap_len_set(new, dst_len, orig_len);
+ pci_unmap_len_set(new, len, orig_len);
spin_unlock_bh(&ioat_chan->desc_lock);
return new ? &new->async_tx : NULL;
@@ -423,11 +422,11 @@
*/
pci_unmap_page(chan->device->pdev,
pci_unmap_addr(desc, dst),
- pci_unmap_len(desc, dst_len),
+ pci_unmap_len(desc, len),
PCI_DMA_FROMDEVICE);
pci_unmap_page(chan->device->pdev,
pci_unmap_addr(desc, src),
- pci_unmap_len(desc, src_len),
+ pci_unmap_len(desc, len),
PCI_DMA_TODEVICE);
}
diff --git a/drivers/dma/ioatdma.h b/drivers/dma/ioatdma.h
index d372647..bf4dad7 100644
--- a/drivers/dma/ioatdma.h
+++ b/drivers/dma/ioatdma.h
@@ -111,10 +111,9 @@
struct ioat_dma_descriptor *hw;
struct list_head node;
int tx_cnt;
+ DECLARE_PCI_UNMAP_LEN(len)
DECLARE_PCI_UNMAP_ADDR(src)
- DECLARE_PCI_UNMAP_LEN(src_len)
DECLARE_PCI_UNMAP_ADDR(dst)
- DECLARE_PCI_UNMAP_LEN(dst_len)
struct dma_async_tx_descriptor async_tx;
};
diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig
index 3b63b0b..19667fc 100644
--- a/drivers/hid/Kconfig
+++ b/drivers/hid/Kconfig
@@ -5,6 +5,11 @@
bool "HID Devices"
depends on INPUT
default y
+ ---help---
+ Say Y here to get to see options for various computer-human interface
+ device drivers. This option alone does not add any kernel code.
+
+ If you say N, all options in this submenu will be skipped and disabled.
if HID_SUPPORT
diff --git a/drivers/hwmon/smsc47m1.c b/drivers/hwmon/smsc47m1.c
index 338ee4f..d318196 100644
--- a/drivers/hwmon/smsc47m1.c
+++ b/drivers/hwmon/smsc47m1.c
@@ -585,6 +585,8 @@
if ((err = device_create_file(dev, &dev_attr_alarms)))
goto error_remove_files;
+ if ((err = device_create_file(dev, &dev_attr_name)))
+ goto error_remove_files;
data->class_dev = hwmon_device_register(dev);
if (IS_ERR(data->class_dev)) {
diff --git a/drivers/hwmon/w83627ehf.c b/drivers/hwmon/w83627ehf.c
index c51ae2e..d9a9ec7 100644
--- a/drivers/hwmon/w83627ehf.c
+++ b/drivers/hwmon/w83627ehf.c
@@ -309,18 +309,16 @@
|| (reg & 0x00ff) == 0x55));
}
-/* We assume that the default bank is 0, thus the following two functions do
- nothing for registers which live in bank 0. For others, they respectively
- set the bank register to the correct value (before the register is
- accessed), and back to 0 (afterwards). */
+/* Registers 0x50-0x5f are banked */
static inline void w83627ehf_set_bank(struct w83627ehf_data *data, u16 reg)
{
- if (reg & 0xff00) {
+ if ((reg & 0x00f0) == 0x50) {
outb_p(W83627EHF_REG_BANK, data->addr + ADDR_REG_OFFSET);
outb_p(reg >> 8, data->addr + DATA_REG_OFFSET);
}
}
+/* Not strictly necessary, but play it safe for now */
static inline void w83627ehf_reset_bank(struct w83627ehf_data *data, u16 reg)
{
if (reg & 0xff00) {
@@ -421,6 +419,31 @@
}
}
+static void w83627ehf_update_fan_div(struct w83627ehf_data *data)
+{
+ int i;
+
+ i = w83627ehf_read_value(data, W83627EHF_REG_FANDIV1);
+ data->fan_div[0] = (i >> 4) & 0x03;
+ data->fan_div[1] = (i >> 6) & 0x03;
+ i = w83627ehf_read_value(data, W83627EHF_REG_FANDIV2);
+ data->fan_div[2] = (i >> 6) & 0x03;
+ i = w83627ehf_read_value(data, W83627EHF_REG_VBAT);
+ data->fan_div[0] |= (i >> 3) & 0x04;
+ data->fan_div[1] |= (i >> 4) & 0x04;
+ data->fan_div[2] |= (i >> 5) & 0x04;
+ if (data->has_fan & ((1 << 3) | (1 << 4))) {
+ i = w83627ehf_read_value(data, W83627EHF_REG_DIODE);
+ data->fan_div[3] = i & 0x03;
+ data->fan_div[4] = ((i >> 2) & 0x03)
+ | ((i >> 5) & 0x04);
+ }
+ if (data->has_fan & (1 << 3)) {
+ i = w83627ehf_read_value(data, W83627EHF_REG_SMI_OVT);
+ data->fan_div[3] |= (i >> 5) & 0x04;
+ }
+}
+
static struct w83627ehf_data *w83627ehf_update_device(struct device *dev)
{
struct w83627ehf_data *data = dev_get_drvdata(dev);
@@ -432,25 +455,7 @@
if (time_after(jiffies, data->last_updated + HZ + HZ/2)
|| !data->valid) {
/* Fan clock dividers */
- i = w83627ehf_read_value(data, W83627EHF_REG_FANDIV1);
- data->fan_div[0] = (i >> 4) & 0x03;
- data->fan_div[1] = (i >> 6) & 0x03;
- i = w83627ehf_read_value(data, W83627EHF_REG_FANDIV2);
- data->fan_div[2] = (i >> 6) & 0x03;
- i = w83627ehf_read_value(data, W83627EHF_REG_VBAT);
- data->fan_div[0] |= (i >> 3) & 0x04;
- data->fan_div[1] |= (i >> 4) & 0x04;
- data->fan_div[2] |= (i >> 5) & 0x04;
- if (data->has_fan & ((1 << 3) | (1 << 4))) {
- i = w83627ehf_read_value(data, W83627EHF_REG_DIODE);
- data->fan_div[3] = i & 0x03;
- data->fan_div[4] = ((i >> 2) & 0x03)
- | ((i >> 5) & 0x04);
- }
- if (data->has_fan & (1 << 3)) {
- i = w83627ehf_read_value(data, W83627EHF_REG_SMI_OVT);
- data->fan_div[3] |= (i >> 5) & 0x04;
- }
+ w83627ehf_update_fan_div(data);
/* Measured voltages and limits */
for (i = 0; i < data->in_num; i++) {
@@ -1312,6 +1317,9 @@
if (!(i & (1 << 1)) && (!fan5pin))
data->has_fan |= (1 << 4);
+ /* Read fan clock dividers immediately */
+ w83627ehf_update_fan_div(data);
+
/* Register sysfs hooks */
for (i = 0; i < ARRAY_SIZE(sda_sf3_arrays); i++)
if ((err = device_create_file(dev,
diff --git a/drivers/hwmon/w83781d.c b/drivers/hwmon/w83781d.c
index f85b48f..c95909c 100644
--- a/drivers/hwmon/w83781d.c
+++ b/drivers/hwmon/w83781d.c
@@ -740,9 +740,9 @@
static SENSOR_DEVICE_ATTR(temp1_type, S_IRUGO | S_IWUSR,
show_sensor, store_sensor, 0);
static SENSOR_DEVICE_ATTR(temp2_type, S_IRUGO | S_IWUSR,
- show_sensor, store_sensor, 0);
+ show_sensor, store_sensor, 1);
static SENSOR_DEVICE_ATTR(temp3_type, S_IRUGO | S_IWUSR,
- show_sensor, store_sensor, 0);
+ show_sensor, store_sensor, 2);
/* I2C devices get this name attribute automatically, but for ISA devices
we must create it by ourselves. */
diff --git a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c
index 8f5c686..289816d 100644
--- a/drivers/i2c/busses/i2c-i801.c
+++ b/drivers/i2c/busses/i2c-i801.c
@@ -272,11 +272,11 @@
/* Make sure the SMBus host is ready to start transmitting */
temp = inb_p(SMBHSTSTS);
if (i == 1) {
- /* Erronenous conditions before transaction:
+ /* Erroneous conditions before transaction:
* Byte_Done, Failed, Bus_Err, Dev_Err, Intr, Host_Busy */
errmask = 0x9f;
} else {
- /* Erronenous conditions during transaction:
+ /* Erroneous conditions during transaction:
* Failed, Bus_Err, Dev_Err, Intr */
errmask = 0x1e;
}
diff --git a/drivers/i2c/busses/i2c-iop3xx.c b/drivers/i2c/busses/i2c-iop3xx.c
index 440342b..ace644e 100644
--- a/drivers/i2c/busses/i2c-iop3xx.c
+++ b/drivers/i2c/busses/i2c-iop3xx.c
@@ -490,6 +490,7 @@
memcpy(new_adapter->name, pdev->name, strlen(pdev->name));
new_adapter->id = I2C_HW_IOP3XX;
new_adapter->owner = THIS_MODULE;
+ new_adapter->class = I2C_CLASS_HWMON;
new_adapter->dev.parent = &pdev->dev;
new_adapter->nr = pdev->id;
diff --git a/drivers/i2c/busses/i2c-mpc.c b/drivers/i2c/busses/i2c-mpc.c
index 851c3ed..d8de4ac 100644
--- a/drivers/i2c/busses/i2c-mpc.c
+++ b/drivers/i2c/busses/i2c-mpc.c
@@ -105,6 +105,7 @@
schedule();
if (time_after(jiffies, orig_jiffies + timeout)) {
pr_debug("I2C: timeout\n");
+ writeccr(i2c, 0);
result = -EIO;
break;
}
@@ -116,10 +117,12 @@
result = wait_event_interruptible_timeout(i2c->queue,
(i2c->interrupt & CSR_MIF), timeout * HZ);
- if (unlikely(result < 0))
+ if (unlikely(result < 0)) {
pr_debug("I2C: wait interrupted\n");
- else if (unlikely(!(i2c->interrupt & CSR_MIF))) {
+ writeccr(i2c, 0);
+ } else if (unlikely(!(i2c->interrupt & CSR_MIF))) {
pr_debug("I2C: wait timeout\n");
+ writeccr(i2c, 0);
result = -ETIMEDOUT;
}
@@ -172,7 +175,6 @@
static void mpc_i2c_stop(struct mpc_i2c *i2c)
{
writeccr(i2c, CCR_MEN);
- writeccr(i2c, 0);
}
static int mpc_write(struct mpc_i2c *i2c, int target,
@@ -261,6 +263,7 @@
while (readb(i2c->base + MPC_I2C_SR) & CSR_MBB) {
if (signal_pending(current)) {
pr_debug("I2C: Interrupted\n");
+ writeccr(i2c, 0);
return -EINTR;
}
if (time_after(jiffies, orig_jiffies + HZ)) {
@@ -362,7 +365,7 @@
fail_add:
if (i2c->irq != 0)
- free_irq(i2c->irq, NULL);
+ free_irq(i2c->irq, i2c);
fail_irq:
iounmap(i2c->base);
fail_map:
diff --git a/drivers/i2c/busses/i2c-mv64xxx.c b/drivers/i2c/busses/i2c-mv64xxx.c
index 251154a..bb7bf68 100644
--- a/drivers/i2c/busses/i2c-mv64xxx.c
+++ b/drivers/i2c/busses/i2c-mv64xxx.c
@@ -107,6 +107,21 @@
*
*****************************************************************************
*/
+
+/* Reset hardware and initialize FSM */
+static void
+mv64xxx_i2c_hw_init(struct mv64xxx_i2c_data *drv_data)
+{
+ writel(0, drv_data->reg_base + MV64XXX_I2C_REG_SOFT_RESET);
+ writel((((drv_data->freq_m & 0xf) << 3) | (drv_data->freq_n & 0x7)),
+ drv_data->reg_base + MV64XXX_I2C_REG_BAUD);
+ writel(0, drv_data->reg_base + MV64XXX_I2C_REG_SLAVE_ADDR);
+ writel(0, drv_data->reg_base + MV64XXX_I2C_REG_EXT_SLAVE_ADDR);
+ writel(MV64XXX_I2C_REG_CONTROL_TWSIEN | MV64XXX_I2C_REG_CONTROL_STOP,
+ drv_data->reg_base + MV64XXX_I2C_REG_CONTROL);
+ drv_data->state = MV64XXX_I2C_STATE_IDLE;
+}
+
static void
mv64xxx_i2c_fsm(struct mv64xxx_i2c_data *drv_data, u32 status)
{
@@ -203,7 +218,7 @@
drv_data->state, status, drv_data->msg->addr,
drv_data->msg->flags);
drv_data->action = MV64XXX_I2C_ACTION_SEND_STOP;
- drv_data->state = MV64XXX_I2C_STATE_IDLE;
+ mv64xxx_i2c_hw_init(drv_data);
drv_data->rc = -EIO;
}
}
@@ -367,6 +382,7 @@
"mv64xxx: I2C bus locked, block: %d, "
"time_left: %d\n", drv_data->block,
(int)time_left);
+ mv64xxx_i2c_hw_init(drv_data);
}
} else
spin_unlock_irqrestore(&drv_data->lock, flags);
@@ -443,19 +459,6 @@
*
*****************************************************************************
*/
-static void __devinit
-mv64xxx_i2c_hw_init(struct mv64xxx_i2c_data *drv_data)
-{
- writel(0, drv_data->reg_base + MV64XXX_I2C_REG_SOFT_RESET);
- writel((((drv_data->freq_m & 0xf) << 3) | (drv_data->freq_n & 0x7)),
- drv_data->reg_base + MV64XXX_I2C_REG_BAUD);
- writel(0, drv_data->reg_base + MV64XXX_I2C_REG_SLAVE_ADDR);
- writel(0, drv_data->reg_base + MV64XXX_I2C_REG_EXT_SLAVE_ADDR);
- writel(MV64XXX_I2C_REG_CONTROL_TWSIEN | MV64XXX_I2C_REG_CONTROL_STOP,
- drv_data->reg_base + MV64XXX_I2C_REG_CONTROL);
- drv_data->state = MV64XXX_I2C_STATE_IDLE;
-}
-
static int __devinit
mv64xxx_i2c_map_regs(struct platform_device *pd,
struct mv64xxx_i2c_data *drv_data)
diff --git a/drivers/i2c/busses/i2c-s3c2410.c b/drivers/i2c/busses/i2c-s3c2410.c
index e4540fc..c44ada5 100644
--- a/drivers/i2c/busses/i2c-s3c2410.c
+++ b/drivers/i2c/busses/i2c-s3c2410.c
@@ -39,8 +39,8 @@
#include <asm/io.h>
#include <asm/arch/regs-gpio.h>
-#include <asm/arch/regs-iic.h>
-#include <asm/arch/iic.h>
+#include <asm/plat-s3c/regs-iic.h>
+#include <asm/plat-s3c/iic.h>
/* i2c controller state */
diff --git a/drivers/i2c/chips/isp1301_omap.c b/drivers/i2c/chips/isp1301_omap.c
index 9fafadb..fe04e46 100644
--- a/drivers/i2c/chips/isp1301_omap.c
+++ b/drivers/i2c/chips/isp1301_omap.c
@@ -18,8 +18,6 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-#undef DEBUG
-#undef VERBOSE
#include <linux/kernel.h>
#include <linux/module.h>
@@ -44,7 +42,7 @@
#define DRIVER_VERSION "24 August 2004"
-#define DRIVER_NAME (isp1301_driver.name)
+#define DRIVER_NAME (isp1301_driver.driver.name)
MODULE_DESCRIPTION("ISP1301 USB OTG Transceiver Driver");
MODULE_LICENSE("GPL");
@@ -55,6 +53,7 @@
void (*i2c_release)(struct device *dev);
int irq;
+ int irq_type;
u32 last_otg_ctrl;
unsigned working:1;
@@ -63,7 +62,7 @@
/* use keventd context to change the state for us */
struct work_struct work;
-
+
unsigned long todo;
# define WORK_UPDATE_ISP 0 /* update ISP from OTG */
# define WORK_UPDATE_OTG 1 /* update OTG from ISP */
@@ -94,7 +93,7 @@
/* board-specific PM hooks */
-#include <asm/arch/gpio.h>
+#include <asm/gpio.h>
#include <asm/arch/mux.h>
#include <asm/mach-types.h>
@@ -291,7 +290,7 @@
{
// isp1301_clear_bits(isp, ISP1301_MODE_CONTROL_2, MC2_GLOBAL_PWR_DN);
isp1301_clear_bits(isp, ISP1301_MODE_CONTROL_1, MC1_SUSPEND_REG);
-
+
/* do this only when cpu is driving transceiver,
* so host won't see a low speed device...
*/
@@ -799,7 +798,7 @@
/* role is host */
} else {
if (!(otg_ctrl & OTG_ID)) {
- otg_ctrl &= OTG_CTRL_MASK & ~OTG_XCEIV_INPUTS;
+ otg_ctrl &= OTG_CTRL_MASK & ~OTG_XCEIV_INPUTS;
OTG_CTRL_REG = otg_ctrl | OTG_A_BUSREQ;
}
@@ -1100,9 +1099,9 @@
}
static void
-isp1301_work(void *data)
+isp1301_work(struct work_struct *work)
{
- struct isp1301 *isp = data;
+ struct isp1301 *isp = container_of(work, struct isp1301, work);
int stop;
/* implicit lock: we're the only task using this device */
@@ -1244,7 +1243,7 @@
* - DEVICE mode, for when there's a B/Mini-B (device) connector
*
* As a rule, you won't have an isp1301 chip unless it's there to
- * support the OTG mode. Other modes help testing USB controllers
+ * support the OTG mode. Other modes help testing USB controllers
* in isolation from (full) OTG support, or maybe so later board
* revisions can help to support those feature.
*/
@@ -1260,9 +1259,9 @@
* a few more interrupts than are strictly needed.
*/
isp1301_set_bits(isp, ISP1301_INTERRUPT_RISING,
- INTR_VBUS_VLD | INTR_SESS_VLD | INTR_ID_GND);
+ INTR_VBUS_VLD | INTR_SESS_VLD | INTR_ID_GND);
isp1301_set_bits(isp, ISP1301_INTERRUPT_FALLING,
- INTR_VBUS_VLD | INTR_SESS_VLD | INTR_ID_GND);
+ INTR_VBUS_VLD | INTR_SESS_VLD | INTR_ID_GND);
dev_info(&isp->client.dev, "ready for dual-role USB ...\n");
@@ -1306,9 +1305,9 @@
dev_info(&isp->client.dev, "A-Host sessions ok\n");
isp1301_set_bits(isp, ISP1301_INTERRUPT_RISING,
- INTR_ID_GND);
+ INTR_ID_GND);
isp1301_set_bits(isp, ISP1301_INTERRUPT_FALLING,
- INTR_ID_GND);
+ INTR_ID_GND);
/* If this has a Mini-AB connector, this mode is highly
* nonstandard ... but can be handy for testing, especially with
@@ -1368,9 +1367,9 @@
isp1301_set_bits(isp, ISP1301_MODE_CONTROL_1, MC1_DAT_SE0);
isp1301_set_bits(isp, ISP1301_INTERRUPT_RISING,
- INTR_SESS_VLD);
+ INTR_SESS_VLD);
isp1301_set_bits(isp, ISP1301_INTERRUPT_FALLING,
- INTR_VBUS_VLD);
+ INTR_VBUS_VLD);
dev_info(&isp->client.dev, "B-Peripheral sessions ok\n");
dump_regs(isp, __FUNCTION__);
@@ -1494,7 +1493,7 @@
if (!isp)
return 0;
- INIT_WORK(&isp->work, isp1301_work, isp);
+ INIT_WORK(&isp->work, isp1301_work);
init_timer(&isp->timer);
isp->timer.function = isp1301_timer;
isp->timer.data = (unsigned long) isp;
@@ -1572,13 +1571,14 @@
/* IRQ wired at M14 */
omap_cfg_reg(M14_1510_GPIO2);
isp->irq = OMAP_GPIO_IRQ(2);
- omap_request_gpio(2);
- omap_set_gpio_direction(2, 1);
- omap_set_gpio_edge_ctrl(2, OMAP_GPIO_FALLING_EDGE);
+ if (gpio_request(2, "isp1301") == 0)
+ gpio_direction_input(2);
+ isp->irq_type = IRQF_TRIGGER_FALLING;
}
+ isp->irq_type |= IRQF_SAMPLE_RANDOM;
status = request_irq(isp->irq, isp1301_irq,
- IRQF_SAMPLE_RANDOM, DRIVER_NAME, isp);
+ isp->irq_type, DRIVER_NAME, isp);
if (status < 0) {
dev_dbg(&i2c->dev, "can't get IRQ %d, err %d\n",
isp->irq, status);
diff --git a/drivers/i2c/chips/menelaus.c b/drivers/i2c/chips/menelaus.c
index 48a7e2f..d9c92c5 100644
--- a/drivers/i2c/chips/menelaus.c
+++ b/drivers/i2c/chips/menelaus.c
@@ -1,4 +1,3 @@
-#define DEBUG
/*
* Copyright (C) 2004 Texas Instruments, Inc.
*
@@ -933,7 +932,7 @@
return status;
status = menelaus_write_reg(MENELAUS_RTC_WKDAY, BIN2BCD(t->tm_wday));
if (status < 0) {
- dev_err(&the_menelaus->client->dev, "rtc write reg %02x",
+ dev_err(&the_menelaus->client->dev, "rtc write reg %02x "
"err %d\n", MENELAUS_RTC_WKDAY, status);
return status;
}
diff --git a/drivers/ide/Kconfig b/drivers/ide/Kconfig
index e049f65..7adb61b 100644
--- a/drivers/ide/Kconfig
+++ b/drivers/ide/Kconfig
@@ -304,9 +304,9 @@
config IDE_GENERIC
tristate "generic/default IDE chipset support"
- default y
+ default H8300
help
- If unsure, say Y.
+ If unsure, say N.
config BLK_DEV_CMD640
bool "CMD640 chipset bugfix/support"
@@ -345,6 +345,7 @@
config BLK_DEV_IDEPNP
bool "PNP EIDE support"
depends on PNP
+ select IDE_GENERIC
help
If you have a PnP (Plug and Play) compatible EIDE card and
would like the kernel to automatically detect and activate
@@ -834,6 +835,7 @@
config IDE_ARM
def_bool ARM && (ARCH_CLPS7500 || ARCH_RPC || ARCH_SHARK)
+ select IDE_GENERIC
config BLK_DEV_IDE_ICSIDE
tristate "ICS IDE interface support"
@@ -867,6 +869,7 @@
config BLK_DEV_GAYLE
bool "Amiga Gayle IDE interface support"
depends on AMIGA
+ select IDE_GENERIC
help
This is the IDE driver for the Amiga Gayle IDE interface. It supports
both the `A1200 style' and `A4000 style' of the Gayle IDE interface,
@@ -898,6 +901,7 @@
config BLK_DEV_BUDDHA
bool "Buddha/Catweasel/X-Surf IDE interface support (EXPERIMENTAL)"
depends on ZORRO && EXPERIMENTAL
+ select IDE_GENERIC
help
This is the IDE driver for the IDE interfaces on the Buddha,
Catweasel and X-Surf expansion boards. It supports up to two interfaces
@@ -910,6 +914,7 @@
config BLK_DEV_FALCON_IDE
bool "Falcon IDE interface support"
depends on ATARI
+ select IDE_GENERIC
help
This is the IDE driver for the builtin IDE interface on the Atari
Falcon. Say Y if you have a Falcon and want to use IDE devices (hard
@@ -919,6 +924,7 @@
config BLK_DEV_MAC_IDE
bool "Macintosh Quadra/Powerbook IDE interface support"
depends on MAC
+ select IDE_GENERIC
help
This is the IDE driver for the builtin IDE interface on some m68k
Macintosh models. It supports both the `Quadra style' (used in
@@ -932,6 +938,7 @@
config BLK_DEV_Q40IDE
bool "Q40/Q60 IDE interface support"
depends on Q40
+ select IDE_GENERIC
help
Enable the on-board IDE controller in the Q40/Q60. This should
normally be on; disable it only if you are running a custom hard
@@ -940,6 +947,7 @@
config BLK_DEV_MPC8xx_IDE
bool "MPC8xx IDE support"
depends on 8xx && IDE=y && BLK_DEV_IDE=y
+ select IDE_GENERIC
help
This option provides support for IDE on Motorola MPC8xx Systems.
Please see 'Type of MPC8xx IDE interface' for details.
diff --git a/drivers/ide/cris/ide-cris.c b/drivers/ide/cris/ide-cris.c
index fbfea46..04636f7 100644
--- a/drivers/ide/cris/ide-cris.c
+++ b/drivers/ide/cris/ide-cris.c
@@ -718,6 +718,8 @@
}
cris_ide_set_speed(TYPE_PIO, setup, strobe, hold);
+
+ (void)ide_config_drive_speed(drive, XFER_PIO_0 + pio);
}
static int speed_cris_ide(ide_drive_t *drive, u8 speed)
diff --git a/drivers/ide/ide-disk.c b/drivers/ide/ide-disk.c
index 5ce4216..eba1adb 100644
--- a/drivers/ide/ide-disk.c
+++ b/drivers/ide/ide-disk.c
@@ -481,6 +481,15 @@
&& id->lba_capacity_2;
}
+/*
+ * Some disks report total number of sectors instead of
+ * maximum sector address. We list them here.
+ */
+static const struct drive_list_entry hpa_list[] = {
+ { "ST340823A", NULL },
+ { NULL, NULL }
+};
+
static void idedisk_check_hpa(ide_drive_t *drive)
{
unsigned long long capacity, set_max;
@@ -492,6 +501,15 @@
else
set_max = idedisk_read_native_max_address(drive);
+ if (ide_in_drive_list(drive->id, hpa_list)) {
+ /*
+ * Since we are inclusive wrt to firmware revisions do this
+ * extra check and apply the workaround only when needed.
+ */
+ if (set_max == capacity + 1)
+ set_max--;
+ }
+
if (set_max <= capacity)
return;
diff --git a/drivers/ide/ide-dma.c b/drivers/ide/ide-dma.c
index 5fe1d72..ff644a5 100644
--- a/drivers/ide/ide-dma.c
+++ b/drivers/ide/ide-dma.c
@@ -135,25 +135,6 @@
};
/**
- * ide_in_drive_list - look for drive in black/white list
- * @id: drive identifier
- * @drive_table: list to inspect
- *
- * Look for a drive in the blacklist and the whitelist tables
- * Returns 1 if the drive is found in the table.
- */
-
-int ide_in_drive_list(struct hd_driveid *id, const struct drive_list_entry *drive_table)
-{
- for ( ; drive_table->id_model ; drive_table++)
- if ((!strcmp(drive_table->id_model, id->model)) &&
- (!drive_table->id_firmware ||
- strstr(id->fw_rev, drive_table->id_firmware)))
- return 1;
- return 0;
-}
-
-/**
* ide_dma_intr - IDE DMA interrupt handler
* @drive: the drive the interrupt is for
*
@@ -349,9 +330,17 @@
static int config_drive_for_dma (ide_drive_t *drive)
{
+ ide_hwif_t *hwif = drive->hwif;
struct hd_driveid *id = drive->id;
- if ((id->capability & 1) && drive->hwif->autodma) {
+ /* consult the list of known "bad" drives */
+ if (__ide_dma_bad_drive(drive))
+ return -1;
+
+ if (drive->media != ide_disk && hwif->atapi_dma == 0)
+ return -1;
+
+ if ((id->capability & 1) && drive->autodma) {
/*
* Enable DMA on any drive that has
* UltraDMA (mode 0/1/2/3/4/5/6) enabled
@@ -514,20 +503,6 @@
EXPORT_SYMBOL(__ide_dma_on);
/**
- * __ide_dma_check - check DMA setup
- * @drive: drive to check
- *
- * Don't use - due for extermination
- */
-
-int __ide_dma_check (ide_drive_t *drive)
-{
- return config_drive_for_dma(drive);
-}
-
-EXPORT_SYMBOL(__ide_dma_check);
-
-/**
* ide_dma_setup - begin a DMA phase
* @drive: target device
*
@@ -1021,7 +996,7 @@
if (!hwif->dma_host_on)
hwif->dma_host_on = &ide_dma_host_on;
if (!hwif->ide_dma_check)
- hwif->ide_dma_check = &__ide_dma_check;
+ hwif->ide_dma_check = &config_drive_for_dma;
if (!hwif->dma_setup)
hwif->dma_setup = &ide_dma_setup;
if (!hwif->dma_exec_cmd)
diff --git a/drivers/ide/ide-iops.c b/drivers/ide/ide-iops.c
index 92578b6..f4cd270 100644
--- a/drivers/ide/ide-iops.c
+++ b/drivers/ide/ide-iops.c
@@ -565,6 +565,36 @@
EXPORT_SYMBOL(ide_wait_stat);
+/**
+ * ide_in_drive_list - look for drive in black/white list
+ * @id: drive identifier
+ * @drive_table: list to inspect
+ *
+ * Look for a drive in the blacklist and the whitelist tables
+ * Returns 1 if the drive is found in the table.
+ */
+
+int ide_in_drive_list(struct hd_driveid *id, const struct drive_list_entry *drive_table)
+{
+ for ( ; drive_table->id_model; drive_table++)
+ if ((!strcmp(drive_table->id_model, id->model)) &&
+ (!drive_table->id_firmware ||
+ strstr(id->fw_rev, drive_table->id_firmware)))
+ return 1;
+ return 0;
+}
+
+EXPORT_SYMBOL_GPL(ide_in_drive_list);
+
+/*
+ * Early UDMA66 devices don't set bit14 to 1, only bit13 is valid.
+ * We list them here and depend on the device side cable detection for them.
+ */
+static const struct drive_list_entry ivb_list[] = {
+ { "QUANTUM FIREBALLlct10 05" , "A03.0900" },
+ { NULL , NULL }
+};
+
/*
* All hosts that use the 80c ribbon must use!
* The name is derived from upper byte of word 93 and the 80c ribbon.
@@ -573,11 +603,16 @@
{
ide_hwif_t *hwif = drive->hwif;
struct hd_driveid *id = drive->id;
+ int ivb = ide_in_drive_list(id, ivb_list);
if (hwif->cbl == ATA_CBL_PATA40_SHORT)
return 1;
- if (hwif->cbl != ATA_CBL_PATA80)
+ if (ivb)
+ printk(KERN_DEBUG "%s: skipping word 93 validity check\n",
+ drive->name);
+
+ if (hwif->cbl != ATA_CBL_PATA80 && !ivb)
goto no_80w;
/* Check for SATA but only if we are ATA5 or higher */
@@ -587,11 +622,11 @@
/*
* FIXME:
* - change master/slave IDENTIFY order
- * - force bit13 (80c cable present) check
+ * - force bit13 (80c cable present) check also for !ivb devices
* (unless the slave device is pre-ATA3)
*/
#ifndef CONFIG_IDEDMA_IVB
- if (id->hw_config & 0x4000)
+ if ((id->hw_config & 0x4000) || (ivb && (id->hw_config & 0x2000)))
#else
if (id->hw_config & 0x6000)
#endif
@@ -795,7 +830,7 @@
hwif->OUTB(drive->ctl | 2, IDE_CONTROL_REG);
hwif->OUTB(speed, IDE_NSECTOR_REG);
hwif->OUTB(SETFEATURES_XFER, IDE_FEATURE_REG);
- hwif->OUTB(WIN_SETFEATURES, IDE_COMMAND_REG);
+ hwif->OUTBSYNC(drive, WIN_SETFEATURES, IDE_COMMAND_REG);
if ((IDE_CONTROL_REG) && (drive->quirk_list == 2))
hwif->OUTB(drive->ctl, IDE_CONTROL_REG);
udelay(1);
@@ -822,7 +857,7 @@
*/
for (i = 0; i < 10; i++) {
udelay(1);
- if (OK_STAT((stat = hwif->INB(IDE_STATUS_REG)), DRIVE_READY, BUSY_STAT|DRQ_STAT|ERR_STAT)) {
+ if (OK_STAT((stat = hwif->INB(IDE_STATUS_REG)), drive->ready_stat, BUSY_STAT|DRQ_STAT|ERR_STAT)) {
error = 0;
break;
}
diff --git a/drivers/ide/pci/cs5530.c b/drivers/ide/pci/cs5530.c
index acaf71f..e5949b1 100644
--- a/drivers/ide/pci/cs5530.c
+++ b/drivers/ide/pci/cs5530.c
@@ -1,5 +1,5 @@
/*
- * linux/drivers/ide/pci/cs5530.c Version 0.73 Mar 10 2007
+ * linux/drivers/ide/pci/cs5530.c Version 0.74 Jul 28 2007
*
* Copyright (C) 2000 Andre Hedrick <andre@linux-ide.org>
* Copyright (C) 2000 Mark Lord <mlord@pobox.com>
@@ -207,6 +207,9 @@
struct pci_dev *master_0 = NULL, *cs5530_0 = NULL;
unsigned long flags;
+ if (pci_resource_start(dev, 4) == 0)
+ return -EFAULT;
+
dev = NULL;
while ((dev = pci_get_device(PCI_VENDOR_ID_CYRIX, PCI_ANY_ID, dev)) != NULL) {
switch (dev->device) {
@@ -325,6 +328,9 @@
/* needs autotuning later */
}
+ if (hwif->dma_base == 0)
+ return;
+
hwif->atapi_dma = 1;
hwif->ultra_mask = 0x07;
hwif->mwdma_mask = 0x07;
diff --git a/drivers/ide/pci/hpt34x.c b/drivers/ide/pci/hpt34x.c
index 19778c5f..cb8fe56 100644
--- a/drivers/ide/pci/hpt34x.c
+++ b/drivers/ide/pci/hpt34x.c
@@ -89,11 +89,7 @@
drive->init_speed = 0;
if (ide_tune_dma(drive))
-#ifndef CONFIG_HPT34X_AUTODMA
return -1;
-#else
- return 0;
-#endif
if (ide_use_fast_pio(drive))
hpt34x_tune_drive(drive, 255);
@@ -160,9 +156,11 @@
if (!hwif->dma_base)
return;
+#ifdef CONFIG_HPT34X_AUTODMA
hwif->ultra_mask = 0x07;
hwif->mwdma_mask = 0x07;
hwif->swdma_mask = 0x07;
+#endif
hwif->ide_dma_check = &hpt34x_config_drive_xfer_rate;
if (!noautodma)
diff --git a/drivers/ide/pci/ns87415.c b/drivers/ide/pci/ns87415.c
index 09941f3..465c935 100644
--- a/drivers/ide/pci/ns87415.c
+++ b/drivers/ide/pci/ns87415.c
@@ -187,14 +187,6 @@
return 1;
}
-static int ns87415_ide_dma_check (ide_drive_t *drive)
-{
- if (drive->media != ide_disk)
- return -1;
-
- return __ide_dma_check(drive);
-}
-
static void __devinit init_hwif_ns87415 (ide_hwif_t *hwif)
{
struct pci_dev *dev = hwif->pci_dev;
@@ -266,7 +258,6 @@
outb(0x60, hwif->dma_status);
hwif->dma_setup = &ns87415_ide_dma_setup;
- hwif->ide_dma_check = &ns87415_ide_dma_check;
hwif->ide_dma_end = &ns87415_ide_dma_end;
if (!noautodma)
diff --git a/drivers/ide/pci/pdc202xx_new.c b/drivers/ide/pci/pdc202xx_new.c
index 8a66a28..f6db2f3 100644
--- a/drivers/ide/pci/pdc202xx_new.c
+++ b/drivers/ide/pci/pdc202xx_new.c
@@ -378,6 +378,9 @@
int f, r;
u8 pll_ctl0, pll_ctl1;
+ if (dma_base == 0)
+ return -EFAULT;
+
#ifdef CONFIG_PPC_PMAC
apple_kiwi_init(dev);
#endif
@@ -494,15 +497,18 @@
hwif->speedproc = &pdcnew_tune_chipset;
hwif->resetproc = &pdcnew_reset;
+ hwif->err_stops_fifo = 1;
+
hwif->drives[0].autotune = hwif->drives[1].autotune = 1;
+ if (hwif->dma_base == 0)
+ return;
+
hwif->atapi_dma = 1;
hwif->ultra_mask = hwif->cds->udma_mask;
hwif->mwdma_mask = 0x07;
- hwif->err_stops_fifo = 1;
-
hwif->ide_dma_check = &pdcnew_config_drive_xfer_rate;
if (hwif->cbl != ATA_CBL_PATA40_SHORT)
diff --git a/drivers/ide/pci/pdc202xx_old.c b/drivers/ide/pci/pdc202xx_old.c
index fbcb0bb..e19a891 100644
--- a/drivers/ide/pci/pdc202xx_old.c
+++ b/drivers/ide/pci/pdc202xx_old.c
@@ -1,5 +1,5 @@
/*
- * linux/drivers/ide/pci/pdc202xx_old.c Version 0.50 Mar 3, 2007
+ * linux/drivers/ide/pci/pdc202xx_old.c Version 0.51 Jul 27, 2007
*
* Copyright (C) 1998-2002 Andre Hedrick <andre@linux-ide.org>
* Copyright (C) 2006-2007 MontaVista Software, Inc.
@@ -337,15 +337,18 @@
hwif->speedproc = &pdc202xx_tune_chipset;
+ hwif->err_stops_fifo = 1;
+
hwif->drives[0].autotune = hwif->drives[1].autotune = 1;
+ if (hwif->dma_base == 0)
+ return;
+
hwif->ultra_mask = hwif->cds->udma_mask;
hwif->mwdma_mask = 0x07;
hwif->swdma_mask = 0x07;
hwif->atapi_dma = 1;
- hwif->err_stops_fifo = 1;
-
hwif->ide_dma_check = &pdc202xx_config_drive_xfer_rate;
hwif->dma_lost_irq = &pdc202xx_dma_lost_irq;
hwif->dma_timeout = &pdc202xx_dma_timeout;
diff --git a/drivers/ide/pci/triflex.c b/drivers/ide/pci/triflex.c
index 024bbfa..098692a 100644
--- a/drivers/ide/pci/triflex.c
+++ b/drivers/ide/pci/triflex.c
@@ -115,6 +115,9 @@
hwif->tuneproc = &triflex_tune_drive;
hwif->speedproc = &triflex_tune_chipset;
+ if (hwif->dma_base == 0)
+ return;
+
hwif->atapi_dma = 1;
hwif->mwdma_mask = 0x07;
hwif->swdma_mask = 0x07;
diff --git a/drivers/ide/ppc/pmac.c b/drivers/ide/ppc/pmac.c
index 33630ad..4b13cd9 100644
--- a/drivers/ide/ppc/pmac.c
+++ b/drivers/ide/ppc/pmac.c
@@ -604,6 +604,9 @@
drive->id->dma_1word |= 0x0101; break;
default: break;
}
+ if (!drive->init_speed)
+ drive->init_speed = command;
+ drive->current_speed = command;
}
enable_irq(hwif->irq);
return result;
@@ -986,7 +989,6 @@
return ret;
pmac_ide_do_update_timings(drive);
- drive->current_speed = speed;
return 0;
}
@@ -1737,11 +1739,6 @@
/* Apply timings to controller */
*timings = timing_local[0];
*timings2 = timing_local[1];
-
- /* Set speed info in drive */
- drive->current_speed = mode;
- if (!drive->init_speed)
- drive->init_speed = mode;
return 1;
}
@@ -1793,11 +1790,6 @@
*timings = timing_local[0];
*timings2 = timing_local[1];
- /* Set speed info in drive */
- drive->current_speed = mode;
- if (!drive->init_speed)
- drive->init_speed = mode;
-
return 1;
}
diff --git a/drivers/infiniband/core/agent.c b/drivers/infiniband/core/agent.c
index db2633e..ae7c288 100644
--- a/drivers/infiniband/core/agent.c
+++ b/drivers/infiniband/core/agent.c
@@ -78,15 +78,14 @@
return entry;
}
-int agent_send_response(struct ib_mad *mad, struct ib_grh *grh,
- struct ib_wc *wc, struct ib_device *device,
- int port_num, int qpn)
+void agent_send_response(struct ib_mad *mad, struct ib_grh *grh,
+ struct ib_wc *wc, struct ib_device *device,
+ int port_num, int qpn)
{
struct ib_agent_port_private *port_priv;
struct ib_mad_agent *agent;
struct ib_mad_send_buf *send_buf;
struct ib_ah *ah;
- int ret;
struct ib_mad_send_wr_private *mad_send_wr;
if (device->node_type == RDMA_NODE_IB_SWITCH)
@@ -96,23 +95,21 @@
if (!port_priv) {
printk(KERN_ERR SPFX "Unable to find port agent\n");
- return -ENODEV;
+ return;
}
agent = port_priv->agent[qpn];
ah = ib_create_ah_from_wc(agent->qp->pd, wc, grh, port_num);
if (IS_ERR(ah)) {
- ret = PTR_ERR(ah);
- printk(KERN_ERR SPFX "ib_create_ah_from_wc error:%d\n", ret);
- return ret;
+ printk(KERN_ERR SPFX "ib_create_ah_from_wc error\n");
+ return;
}
send_buf = ib_create_send_mad(agent, wc->src_qp, wc->pkey_index, 0,
IB_MGMT_MAD_HDR, IB_MGMT_MAD_DATA,
GFP_KERNEL);
if (IS_ERR(send_buf)) {
- ret = PTR_ERR(send_buf);
- printk(KERN_ERR SPFX "ib_create_send_mad error:%d\n", ret);
+ printk(KERN_ERR SPFX "ib_create_send_mad error\n");
goto err1;
}
@@ -126,16 +123,15 @@
mad_send_wr->send_wr.wr.ud.port_num = port_num;
}
- if ((ret = ib_post_send_mad(send_buf, NULL))) {
- printk(KERN_ERR SPFX "ib_post_send_mad error:%d\n", ret);
+ if (ib_post_send_mad(send_buf, NULL)) {
+ printk(KERN_ERR SPFX "ib_post_send_mad error\n");
goto err2;
}
- return 0;
+ return;
err2:
ib_free_send_mad(send_buf);
err1:
ib_destroy_ah(ah);
- return ret;
}
static void agent_send_handler(struct ib_mad_agent *mad_agent,
diff --git a/drivers/infiniband/core/agent.h b/drivers/infiniband/core/agent.h
index 86d72fa..fb9ed14 100644
--- a/drivers/infiniband/core/agent.h
+++ b/drivers/infiniband/core/agent.h
@@ -46,8 +46,8 @@
extern int ib_agent_port_close(struct ib_device *device, int port_num);
-extern int agent_send_response(struct ib_mad *mad, struct ib_grh *grh,
- struct ib_wc *wc, struct ib_device *device,
- int port_num, int qpn);
+extern void agent_send_response(struct ib_mad *mad, struct ib_grh *grh,
+ struct ib_wc *wc, struct ib_device *device,
+ int port_num, int qpn);
#endif /* __AGENT_H_ */
diff --git a/drivers/infiniband/core/device.c b/drivers/infiniband/core/device.c
index 3ada17c..2506c43 100644
--- a/drivers/infiniband/core/device.c
+++ b/drivers/infiniband/core/device.c
@@ -702,7 +702,7 @@
if (ret)
return ret;
- if (pkey == tmp_pkey) {
+ if ((pkey & 0x7fff) == (tmp_pkey & 0x7fff)) {
*index = i;
return 0;
}
diff --git a/drivers/infiniband/core/mad.c b/drivers/infiniband/core/mad.c
index bc547f1..6f42877 100644
--- a/drivers/infiniband/core/mad.c
+++ b/drivers/infiniband/core/mad.c
@@ -1842,16 +1842,11 @@
{
struct ib_mad_qp_info *qp_info;
struct ib_mad_private_header *mad_priv_hdr;
- struct ib_mad_private *recv, *response;
+ struct ib_mad_private *recv, *response = NULL;
struct ib_mad_list_head *mad_list;
struct ib_mad_agent_private *mad_agent;
int port_num;
- response = kmem_cache_alloc(ib_mad_cache, GFP_KERNEL);
- if (!response)
- printk(KERN_ERR PFX "ib_mad_recv_done_handler no memory "
- "for response buffer\n");
-
mad_list = (struct ib_mad_list_head *)(unsigned long)wc->wr_id;
qp_info = mad_list->mad_queue->qp_info;
dequeue_mad(mad_list);
@@ -1879,6 +1874,13 @@
if (!validate_mad(&recv->mad.mad, qp_info->qp->qp_num))
goto out;
+ response = kmem_cache_alloc(ib_mad_cache, GFP_KERNEL);
+ if (!response) {
+ printk(KERN_ERR PFX "ib_mad_recv_done_handler no memory "
+ "for response buffer\n");
+ goto out;
+ }
+
if (port_priv->device->node_type == RDMA_NODE_IB_SWITCH)
port_num = wc->port_num;
else
@@ -1914,12 +1916,11 @@
response->header.recv_wc.recv_buf.mad = &response->mad.mad;
response->header.recv_wc.recv_buf.grh = &response->grh;
- if (!agent_send_response(&response->mad.mad,
- &response->grh, wc,
- port_priv->device,
- smi_get_fwd_port(&recv->mad.smp),
- qp_info->qp->qp_num))
- response = NULL;
+ agent_send_response(&response->mad.mad,
+ &response->grh, wc,
+ port_priv->device,
+ smi_get_fwd_port(&recv->mad.smp),
+ qp_info->qp->qp_num);
goto out;
}
diff --git a/drivers/infiniband/core/mad_rmpp.c b/drivers/infiniband/core/mad_rmpp.c
index 3663fd7..d43bc62 100644
--- a/drivers/infiniband/core/mad_rmpp.c
+++ b/drivers/infiniband/core/mad_rmpp.c
@@ -163,8 +163,10 @@
hdr_len, 0, GFP_KERNEL);
if (IS_ERR(msg))
ib_destroy_ah(ah);
- else
+ else {
msg->ah = ah;
+ msg->context[0] = ah;
+ }
return msg;
}
@@ -197,9 +199,7 @@
void ib_rmpp_send_handler(struct ib_mad_send_wc *mad_send_wc)
{
- struct ib_rmpp_mad *rmpp_mad = mad_send_wc->send_buf->mad;
-
- if (rmpp_mad->rmpp_hdr.rmpp_type != IB_MGMT_RMPP_TYPE_ACK)
+ if (mad_send_wc->send_buf->context[0] == mad_send_wc->send_buf->ah)
ib_destroy_ah(mad_send_wc->send_buf->ah);
ib_free_send_mad(mad_send_wc->send_buf);
}
diff --git a/drivers/infiniband/core/sa_query.c b/drivers/infiniband/core/sa_query.c
index 20ab6b3..d271bd7 100644
--- a/drivers/infiniband/core/sa_query.c
+++ b/drivers/infiniband/core/sa_query.c
@@ -385,9 +385,7 @@
new_ah->pkey_index = 0;
if (ib_find_pkey(port->agent->device, port->port_num,
- IB_DEFAULT_PKEY_FULL, &new_ah->pkey_index) &&
- ib_find_pkey(port->agent->device, port->port_num,
- IB_DEFAULT_PKEY_PARTIAL, &new_ah->pkey_index))
+ IB_DEFAULT_PKEY_FULL, &new_ah->pkey_index))
printk(KERN_ERR "Couldn't find index for default PKey\n");
memset(&ah_attr, 0, sizeof ah_attr);
diff --git a/drivers/infiniband/core/umem.c b/drivers/infiniband/core/umem.c
index 26d0470..664d2faa 100644
--- a/drivers/infiniband/core/umem.c
+++ b/drivers/infiniband/core/umem.c
@@ -40,6 +40,11 @@
#include "uverbs.h"
+#define IB_UMEM_MAX_PAGE_CHUNK \
+ ((PAGE_SIZE - offsetof(struct ib_umem_chunk, page_list)) / \
+ ((void *) &((struct ib_umem_chunk *) 0)->page_list[1] - \
+ (void *) &((struct ib_umem_chunk *) 0)->page_list[0]))
+
static void __ib_umem_release(struct ib_device *dev, struct ib_umem *umem, int dirty)
{
struct ib_umem_chunk *chunk, *tmp;
diff --git a/drivers/infiniband/hw/cxgb3/iwch_cm.c b/drivers/infiniband/hw/cxgb3/iwch_cm.c
index 9574088..1cdfcd4 100644
--- a/drivers/infiniband/hw/cxgb3/iwch_cm.c
+++ b/drivers/infiniband/hw/cxgb3/iwch_cm.c
@@ -139,7 +139,7 @@
req->wr.wr_hi = htonl(V_WR_OP(FW_WROPCODE_FORWARD));
OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_TID_RELEASE, hwtid));
skb->priority = CPL_PRIORITY_SETUP;
- tdev->send(tdev, skb);
+ cxgb3_ofld_send(tdev, skb);
return;
}
@@ -161,7 +161,7 @@
req->val = cpu_to_be64(1 << S_TCB_RX_QUIESCE);
skb->priority = CPL_PRIORITY_DATA;
- ep->com.tdev->send(ep->com.tdev, skb);
+ cxgb3_ofld_send(ep->com.tdev, skb);
return 0;
}
@@ -183,7 +183,7 @@
req->val = 0;
skb->priority = CPL_PRIORITY_DATA;
- ep->com.tdev->send(ep->com.tdev, skb);
+ cxgb3_ofld_send(ep->com.tdev, skb);
return 0;
}
@@ -784,7 +784,7 @@
OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_RX_DATA_ACK, ep->hwtid));
req->credit_dack = htonl(V_RX_CREDITS(credits) | V_RX_FORCE_ACK(1));
skb->priority = CPL_PRIORITY_ACK;
- ep->com.tdev->send(ep->com.tdev, skb);
+ cxgb3_ofld_send(ep->com.tdev, skb);
return credits;
}
@@ -1152,7 +1152,7 @@
req->opt1 = htonl(V_CONN_POLICY(CPL_CONN_POLICY_ASK));
skb->priority = 1;
- ep->com.tdev->send(ep->com.tdev, skb);
+ cxgb3_ofld_send(ep->com.tdev, skb);
return 0;
}
@@ -1186,7 +1186,7 @@
req->cpu_idx = 0;
OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_CLOSE_LISTSRV_REQ, ep->stid));
skb->priority = 1;
- ep->com.tdev->send(ep->com.tdev, skb);
+ cxgb3_ofld_send(ep->com.tdev, skb);
return 0;
}
@@ -1264,7 +1264,7 @@
rpl->opt0l_status = htonl(CPL_PASS_OPEN_REJECT);
rpl->opt2 = 0;
rpl->rsvd = rpl->opt2;
- tdev->send(tdev, skb);
+ cxgb3_ofld_send(tdev, skb);
}
}
@@ -1557,7 +1557,7 @@
rpl->wr.wr_lo = htonl(V_WR_TID(ep->hwtid));
OPCODE_TID(rpl) = htonl(MK_OPCODE_TID(CPL_ABORT_RPL, ep->hwtid));
rpl->cmd = CPL_ABORT_NO_RST;
- ep->com.tdev->send(ep->com.tdev, rpl_skb);
+ cxgb3_ofld_send(ep->com.tdev, rpl_skb);
if (state != ABORTING) {
state_set(&ep->com, DEAD);
release_ep_resources(ep);
diff --git a/drivers/infiniband/hw/mlx4/cq.c b/drivers/infiniband/hw/mlx4/cq.c
index 660b27a..8bf44da 100644
--- a/drivers/infiniband/hw/mlx4/cq.c
+++ b/drivers/infiniband/hw/mlx4/cq.c
@@ -389,7 +389,7 @@
wc->opcode = IB_WC_SEND;
break;
case MLX4_OPCODE_RDMA_READ:
- wc->opcode = IB_WC_SEND;
+ wc->opcode = IB_WC_RDMA_READ;
wc->byte_len = be32_to_cpu(cqe->byte_cnt);
break;
case MLX4_OPCODE_ATOMIC_CS:
diff --git a/drivers/infiniband/hw/mlx4/mad.c b/drivers/infiniband/hw/mlx4/mad.c
index 3330917..0ed02b7 100644
--- a/drivers/infiniband/hw/mlx4/mad.c
+++ b/drivers/infiniband/hw/mlx4/mad.c
@@ -109,7 +109,7 @@
in_modifier, op_modifier,
MLX4_CMD_MAD_IFC, MLX4_CMD_TIME_CLASS_C);
- if (!err);
+ if (!err)
memcpy(response_mad, outmailbox->buf, 256);
mlx4_free_cmd_mailbox(dev->dev, inmailbox);
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_verbs.c b/drivers/infiniband/ulp/ipoib/ipoib_verbs.c
index 982eb88..563aeac 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_verbs.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_verbs.c
@@ -211,6 +211,7 @@
out_free_mr:
ib_dereg_mr(priv->mr);
+ ipoib_cm_dev_cleanup(dev);
out_free_pd:
ib_dealloc_pd(priv->pd);
diff --git a/drivers/infiniband/ulp/srp/ib_srp.c b/drivers/infiniband/ulp/srp/ib_srp.c
index f01ca18..f6a0514 100644
--- a/drivers/infiniband/ulp/srp/ib_srp.c
+++ b/drivers/infiniband/ulp/srp/ib_srp.c
@@ -75,16 +75,12 @@
MODULE_PARM_DESC(topspin_workarounds,
"Enable workarounds for Topspin/Cisco SRP target bugs if != 0");
-static const u8 topspin_oui[3] = { 0x00, 0x05, 0xad };
-
static int mellanox_workarounds = 1;
module_param(mellanox_workarounds, int, 0444);
MODULE_PARM_DESC(mellanox_workarounds,
"Enable workarounds for Mellanox SRP target bugs if != 0");
-static const u8 mellanox_oui[3] = { 0x00, 0x02, 0xc9 };
-
static void srp_add_one(struct ib_device *device);
static void srp_remove_one(struct ib_device *device);
static void srp_completion(struct ib_cq *cq, void *target_ptr);
@@ -108,6 +104,24 @@
return host_to_target(host)->target_name;
}
+static int srp_target_is_topspin(struct srp_target_port *target)
+{
+ static const u8 topspin_oui[3] = { 0x00, 0x05, 0xad };
+ static const u8 cisco_oui[3] = { 0x00, 0x1b, 0x0d };
+
+ return topspin_workarounds &&
+ (!memcmp(&target->ioc_guid, topspin_oui, sizeof topspin_oui) ||
+ !memcmp(&target->ioc_guid, cisco_oui, sizeof cisco_oui));
+}
+
+static int srp_target_is_mellanox(struct srp_target_port *target)
+{
+ static const u8 mellanox_oui[3] = { 0x00, 0x02, 0xc9 };
+
+ return mellanox_workarounds &&
+ !memcmp(&target->ioc_guid, mellanox_oui, sizeof mellanox_oui);
+}
+
static struct srp_iu *srp_alloc_iu(struct srp_host *host, size_t size,
gfp_t gfp_mask,
enum dma_data_direction direction)
@@ -360,7 +374,7 @@
* zero out the first 8 bytes of our initiator port ID and set
* the second 8 bytes to the local node GUID.
*/
- if (topspin_workarounds && !memcmp(&target->ioc_guid, topspin_oui, 3)) {
+ if (srp_target_is_topspin(target)) {
printk(KERN_DEBUG PFX "Topspin/Cisco initiator port ID workaround "
"activated for target GUID %016llx\n",
(unsigned long long) be64_to_cpu(target->ioc_guid));
@@ -585,8 +599,8 @@
if (!dev->fmr_pool)
return -ENODEV;
- if ((ib_sg_dma_address(ibdev, &scat[0]) & ~dev->fmr_page_mask) &&
- mellanox_workarounds && !memcmp(&target->ioc_guid, mellanox_oui, 3))
+ if (srp_target_is_mellanox(target) &&
+ (ib_sg_dma_address(ibdev, &scat[0]) & ~dev->fmr_page_mask))
return -EINVAL;
len = page_cnt = 0;
@@ -1087,8 +1101,7 @@
break;
case IB_CM_REJ_PORT_REDIRECT:
- if (topspin_workarounds &&
- !memcmp(&target->ioc_guid, topspin_oui, 3)) {
+ if (srp_target_is_topspin(target)) {
/*
* Topspin/Cisco SRP gateways incorrectly send
* reject reason code 25 when they mean 24
diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig
index 9b26574..d602b8f 100644
--- a/drivers/input/misc/Kconfig
+++ b/drivers/input/misc/Kconfig
@@ -68,6 +68,7 @@
select INPUT_POLLDEV
select NEW_LEDS
select LEDS_CLASS
+ select CHECK_SIGNATURE
help
Say Y here for support of Winstron laptop button interface, used on
laptops of various brands, including Acer and Fujitsu-Siemens. If
diff --git a/drivers/isdn/hisax/hfc_usb.c b/drivers/isdn/hisax/hfc_usb.c
index b1a26e0..60843b3 100644
--- a/drivers/isdn/hisax/hfc_usb.c
+++ b/drivers/isdn/hisax/hfc_usb.c
@@ -1,12 +1,12 @@
/*
* hfc_usb.c
*
- * $Id: hfc_usb.c,v 2.3.2.13 2006/02/17 17:17:22 mbachem Exp $
+ * $Id: hfc_usb.c,v 2.3.2.20 2007/08/20 14:07:54 mbachem Exp $
*
* modular HiSax ISDN driver for Colognechip HFC-S USB chip
*
- * Authors : Peter Sprenger (sprenger@moving-bytes.de)
- * Martin Bachem (info@colognechip.com)
+ * Authors : Peter Sprenger (sprenger@moving-bytes.de)
+ * Martin Bachem (m.bachem@gmx.de, info@colognechip.com)
*
* based on the first hfc_usb driver of
* Werner Cornelius (werner@isdn-development.de)
@@ -37,24 +37,25 @@
#include <linux/kernel_stat.h>
#include <linux/usb.h>
#include <linux/kernel.h>
+#include <linux/smp_lock.h>
+#include <linux/sched.h>
+#include <linux/moduleparam.h>
#include "hisax.h"
#include "hisax_if.h"
#include "hfc_usb.h"
static const char *hfcusb_revision =
- "$Revision: 2.3.2.13 $ $Date: 2006/02/17 17:17:22 $ ";
+ "$Revision: 2.3.2.20 $ $Date: 2007/08/20 14:07:54 $ ";
/* Hisax debug support
-* use "modprobe debug=x" where x is bitfield of USB_DBG & ISDN_DBG
+* debug flags defined in hfc_usb.h as HFCUSB_DBG_[*]
*/
-#ifdef CONFIG_HISAX_DEBUG
-#include <linux/moduleparam.h>
#define __debug_variable hfc_debug
#include "hisax_debug.h"
static u_int debug;
module_param(debug, uint, 0);
static int hfc_debug;
-#endif
+
/* private vendor specific data */
typedef struct {
@@ -63,9 +64,7 @@
char *vend_name; // device name
} hfcsusb_vdata;
-/****************************************/
-/* data defining the devices to be used */
-/****************************************/
+/* VID/PID device list */
static struct usb_device_id hfcusb_idtab[] = {
{
USB_DEVICE(0x0959, 0x2bd0),
@@ -90,49 +89,47 @@
.driver_info = (unsigned long) &((hfcsusb_vdata)
{LED_SCHEME1, {4, 0, 2, 1},
"Stollmann USB TA"}),
- },
+ },
{
USB_DEVICE(0x0742, 0x2009),
.driver_info = (unsigned long) &((hfcsusb_vdata)
{LED_SCHEME1, {4, 0, 2, 1},
"Aceex USB ISDN TA"}),
- },
+ },
{
USB_DEVICE(0x0742, 0x200A),
.driver_info = (unsigned long) &((hfcsusb_vdata)
{LED_SCHEME1, {4, 0, 2, 1},
"OEM USB ISDN TA"}),
- },
+ },
{
USB_DEVICE(0x08e3, 0x0301),
.driver_info = (unsigned long) &((hfcsusb_vdata)
{LED_SCHEME1, {2, 0, 1, 4},
"Olitec USB RNIS"}),
- },
+ },
{
USB_DEVICE(0x07fa, 0x0846),
.driver_info = (unsigned long) &((hfcsusb_vdata)
{LED_SCHEME1, {0x80, -64, -32, -16},
"Bewan Modem RNIS USB"}),
- },
+ },
{
USB_DEVICE(0x07fa, 0x0847),
.driver_info = (unsigned long) &((hfcsusb_vdata)
{LED_SCHEME1, {0x80, -64, -32, -16},
"Djinn Numeris USB"}),
- },
+ },
{
USB_DEVICE(0x07b0, 0x0006),
.driver_info = (unsigned long) &((hfcsusb_vdata)
{LED_SCHEME1, {0x80, -64, -32, -16},
"Twister ISDN TA"}),
- },
+ },
{ }
};
-/***************************************************************/
/* structure defining input+output fifos (interrupt/bulk mode) */
-/***************************************************************/
struct usb_fifo; /* forward definition */
typedef struct iso_urb_struct {
struct urb *purb;
@@ -140,8 +137,8 @@
struct usb_fifo *owner_fifo; /* pointer to owner fifo */
} iso_urb_struct;
-
struct hfcusb_data; /* forward definition */
+
typedef struct usb_fifo {
int fifonum; /* fifo index attached to this structure */
int active; /* fifo is currently active */
@@ -160,15 +157,12 @@
struct hisax_if *hif; /* hisax interface */
int delete_flg; /* only delete skbuff once */
int last_urblen; /* remember length of last packet */
-
} usb_fifo;
-/*********************************************/
/* structure holding all data for one device */
-/*********************************************/
typedef struct hfcusb_data {
/* HiSax Interface for loadable Layer1 drivers */
- struct hisax_d_if d_if; /* see hisax_if.h */
+ struct hisax_d_if d_if; /* see hisax_if.h */
struct hisax_b_if b_if[2]; /* see hisax_if.h */
int protocol;
@@ -176,12 +170,13 @@
int if_used; /* used interface number */
int alt_used; /* used alternate config */
int ctrl_paksize; /* control pipe packet size */
- int ctrl_in_pipe, ctrl_out_pipe; /* handles for control pipe */
+ int ctrl_in_pipe, /* handles for control pipe */
+ ctrl_out_pipe;
int cfg_used; /* configuration index used */
int vend_idx; /* vendor found */
int b_mode[2]; /* B-channel mode */
int l1_activated; /* layer 1 activated */
- int disc_flag; /* 'true' if device was disonnected to avoid some USB actions */
+ int disc_flag; /* TRUE if device was disonnected to avoid some USB actions */
int packet_size, iso_packet_size;
/* control pipe background handling */
@@ -208,7 +203,6 @@
static void collect_rx_frame(usb_fifo * fifo, __u8 * data, int len,
int finish);
-
static inline const char *
symbolic(struct hfcusb_symbolic_list list[], const int num)
{
@@ -219,10 +213,6 @@
return "<unknown ERROR>";
}
-
-/******************************************************/
-/* start next background transfer for control channel */
-/******************************************************/
static void
ctrl_start_transfer(hfcusb_data * hfc)
{
@@ -240,10 +230,6 @@
}
} /* ctrl_start_transfer */
-/************************************/
-/* queue a control transfer request */
-/* return 0 on success. */
-/************************************/
static int
queue_control_request(hfcusb_data * hfc, __u8 reg, __u8 val, int action)
{
@@ -260,19 +246,8 @@
if (++hfc->ctrl_cnt == 1)
ctrl_start_transfer(hfc);
return (0);
-} /* queue_control_request */
-
-static int
-control_action_handler(hfcusb_data * hfc, int reg, int val, int action)
-{
- if (!action)
- return (1); /* no action defined */
- return (0);
}
-/***************************************************************/
-/* control completion routine handling background control cmds */
-/***************************************************************/
static void
ctrl_complete(struct urb *urb)
{
@@ -282,9 +257,6 @@
urb->dev = hfc->dev;
if (hfc->ctrl_cnt) {
buf = &hfc->ctrl_buff[hfc->ctrl_out_idx];
- control_action_handler(hfc, buf->hfc_reg, buf->reg_val,
- buf->action);
-
hfc->ctrl_cnt--; /* decrement actual count */
if (++hfc->ctrl_out_idx >= HFC_CTRL_BUFSIZE)
hfc->ctrl_out_idx = 0; /* pointer wrap */
@@ -293,9 +265,7 @@
}
} /* ctrl_complete */
-/***************************************************/
/* write led data to auxport & invert if necessary */
-/***************************************************/
static void
write_led(hfcusb_data * hfc, __u8 led_state)
{
@@ -305,9 +275,6 @@
}
}
-/**************************/
-/* handle LED bits */
-/**************************/
static void
set_led_bit(hfcusb_data * hfc, signed short led_bits, int unset)
{
@@ -324,9 +291,7 @@
}
}
-/**************************/
-/* handle LED requests */
-/**************************/
+/* handle LED requests */
static void
handle_led(hfcusb_data * hfc, int event)
{
@@ -339,85 +304,73 @@
switch (event) {
case LED_POWER_ON:
- set_led_bit(hfc, driver_info->led_bits[0],
- 0);
- set_led_bit(hfc, driver_info->led_bits[1],
- 1);
- set_led_bit(hfc, driver_info->led_bits[2],
- 1);
- set_led_bit(hfc, driver_info->led_bits[3],
- 1);
+ set_led_bit(hfc, driver_info->led_bits[0], 0);
+ set_led_bit(hfc, driver_info->led_bits[1], 1);
+ set_led_bit(hfc, driver_info->led_bits[2], 1);
+ set_led_bit(hfc, driver_info->led_bits[3], 1);
break;
- case LED_POWER_OFF: /* no Power off handling */
+ case LED_POWER_OFF:
+ set_led_bit(hfc, driver_info->led_bits[0], 1);
+ set_led_bit(hfc, driver_info->led_bits[1], 1);
+ set_led_bit(hfc, driver_info->led_bits[2], 1);
+ set_led_bit(hfc, driver_info->led_bits[3], 1);
break;
case LED_S0_ON:
- set_led_bit(hfc, driver_info->led_bits[1],
- 0);
+ set_led_bit(hfc, driver_info->led_bits[1], 0);
break;
case LED_S0_OFF:
- set_led_bit(hfc, driver_info->led_bits[1],
- 1);
+ set_led_bit(hfc, driver_info->led_bits[1], 1);
break;
case LED_B1_ON:
- set_led_bit(hfc, driver_info->led_bits[2],
- 0);
+ set_led_bit(hfc, driver_info->led_bits[2], 0);
break;
case LED_B1_OFF:
- set_led_bit(hfc, driver_info->led_bits[2],
- 1);
+ set_led_bit(hfc, driver_info->led_bits[2], 1);
break;
case LED_B2_ON:
- set_led_bit(hfc, driver_info->led_bits[3],
- 0);
+ set_led_bit(hfc, driver_info->led_bits[3], 0);
break;
case LED_B2_OFF:
- set_led_bit(hfc, driver_info->led_bits[3],
- 1);
+ set_led_bit(hfc, driver_info->led_bits[3], 1);
break;
}
write_led(hfc, hfc->led_state);
}
-/********************************/
-/* called when timer t3 expires */
-/********************************/
+/* ISDN l1 timer T3 expires */
static void
l1_timer_expire_t3(hfcusb_data * hfc)
{
hfc->d_if.ifc.l1l2(&hfc->d_if.ifc, PH_DEACTIVATE | INDICATION,
NULL);
-#ifdef CONFIG_HISAX_DEBUG
- DBG(ISDN_DBG,
+
+ DBG(HFCUSB_DBG_STATES,
"HFC-S USB: PH_DEACTIVATE | INDICATION sent (T3 expire)");
-#endif
- hfc->l1_activated = false;
+
+ hfc->l1_activated = 0;
handle_led(hfc, LED_S0_OFF);
/* deactivate : */
queue_control_request(hfc, HFCUSB_STATES, 0x10, 1);
queue_control_request(hfc, HFCUSB_STATES, 3, 1);
}
-/********************************/
-/* called when timer t4 expires */
-/********************************/
+/* ISDN l1 timer T4 expires */
static void
l1_timer_expire_t4(hfcusb_data * hfc)
{
hfc->d_if.ifc.l1l2(&hfc->d_if.ifc, PH_DEACTIVATE | INDICATION,
NULL);
-#ifdef CONFIG_HISAX_DEBUG
- DBG(ISDN_DBG,
+
+ DBG(HFCUSB_DBG_STATES,
"HFC-S USB: PH_DEACTIVATE | INDICATION sent (T4 expire)");
-#endif
- hfc->l1_activated = false;
+
+ hfc->l1_activated = 0;
handle_led(hfc, LED_S0_OFF);
}
-/*****************************/
-/* handle S0 state changes */
-/*****************************/
+/* S0 state changed */
static void
-state_handler(hfcusb_data * hfc, __u8 state)
+s0_state_handler(hfcusb_data * hfc, __u8 state)
{
__u8 old_state;
@@ -425,38 +378,29 @@
if (state == old_state || state < 1 || state > 8)
return;
-#ifdef CONFIG_HISAX_DEBUG
- DBG(ISDN_DBG, "HFC-S USB: new S0 state:%d old_state:%d", state,
- old_state);
-#endif
+ DBG(HFCUSB_DBG_STATES, "HFC-S USB: S0 statechange(%d -> %d)",
+ old_state, state);
+
if (state < 4 || state == 7 || state == 8) {
if (timer_pending(&hfc->t3_timer))
del_timer(&hfc->t3_timer);
-#ifdef CONFIG_HISAX_DEBUG
- DBG(ISDN_DBG, "HFC-S USB: T3 deactivated");
-#endif
+ DBG(HFCUSB_DBG_STATES, "HFC-S USB: T3 deactivated");
}
if (state >= 7) {
if (timer_pending(&hfc->t4_timer))
del_timer(&hfc->t4_timer);
-#ifdef CONFIG_HISAX_DEBUG
- DBG(ISDN_DBG, "HFC-S USB: T4 deactivated");
-#endif
+ DBG(HFCUSB_DBG_STATES, "HFC-S USB: T4 deactivated");
}
if (state == 7 && !hfc->l1_activated) {
hfc->d_if.ifc.l1l2(&hfc->d_if.ifc,
PH_ACTIVATE | INDICATION, NULL);
-#ifdef CONFIG_HISAX_DEBUG
- DBG(ISDN_DBG, "HFC-S USB: PH_ACTIVATE | INDICATION sent");
-#endif
- hfc->l1_activated = true;
+ DBG(HFCUSB_DBG_STATES, "HFC-S USB: PH_ACTIVATE | INDICATION sent");
+ hfc->l1_activated = 1;
handle_led(hfc, LED_S0_ON);
} else if (state <= 3 /* && activated */ ) {
if (old_state == 7 || old_state == 8) {
-#ifdef CONFIG_HISAX_DEBUG
- DBG(ISDN_DBG, "HFC-S USB: T4 activated");
-#endif
+ DBG(HFCUSB_DBG_STATES, "HFC-S USB: T4 activated");
if (!timer_pending(&hfc->t4_timer)) {
hfc->t4_timer.expires =
jiffies + (HFC_TIMER_T4 * HZ) / 1000;
@@ -466,18 +410,15 @@
hfc->d_if.ifc.l1l2(&hfc->d_if.ifc,
PH_DEACTIVATE | INDICATION,
NULL);
-#ifdef CONFIG_HISAX_DEBUG
- DBG(ISDN_DBG,
+ DBG(HFCUSB_DBG_STATES,
"HFC-S USB: PH_DEACTIVATE | INDICATION sent");
-#endif
- hfc->l1_activated = false;
+ hfc->l1_activated = 0;
handle_led(hfc, LED_S0_OFF);
}
}
hfc->l1_state = state;
}
-/* prepare iso urb */
static void
fill_isoc_urb(struct urb *urb, struct usb_device *dev, unsigned int pipe,
void *buf, int num_packets, int packet_size, int interval,
@@ -503,15 +444,16 @@
}
/* allocs urbs and start isoc transfer with two pending urbs to avoid
- gaps in the transfer chain */
+ * gaps in the transfer chain
+ */
static int
start_isoc_chain(usb_fifo * fifo, int num_packets_per_urb,
usb_complete_t complete, int packet_size)
{
int i, k, errcode;
- printk(KERN_INFO "HFC-S USB: starting ISO-chain for Fifo %i\n",
- fifo->fifonum);
+ DBG(HFCUSB_DBG_INIT, "HFC-S USB: starting ISO-URBs for fifo:%d\n",
+ fifo->fifonum);
/* allocate Memory for Iso out Urbs */
for (i = 0; i < 2; i++) {
@@ -556,10 +498,9 @@
errcode = usb_submit_urb(fifo->iso[i].purb, GFP_KERNEL);
fifo->active = (errcode >= 0) ? 1 : 0;
- if (errcode < 0) {
- printk(KERN_INFO "HFC-S USB: %s URB nr:%d\n",
- symbolic(urb_errlist, errcode), i);
- };
+ if (errcode < 0)
+ printk(KERN_INFO "HFC-S USB: usb_submit_urb URB nr:%d, error(%i): '%s'\n",
+ i, errcode, symbolic(urb_errlist, errcode));
}
return (fifo->active);
}
@@ -572,16 +513,15 @@
for (i = 0; i < 2; i++) {
if (fifo->iso[i].purb) {
-#ifdef CONFIG_HISAX_DEBUG
- DBG(USB_DBG,
+ DBG(HFCUSB_DBG_INIT,
"HFC-S USB: Stopping iso chain for fifo %i.%i",
fifo->fifonum, i);
-#endif
usb_kill_urb(fifo->iso[i].purb);
usb_free_urb(fifo->iso[i].purb);
fifo->iso[i].purb = NULL;
}
}
+
usb_kill_urb(fifo->urb);
usb_free_urb(fifo->urb);
fifo->urb = NULL;
@@ -594,9 +534,6 @@
ISOC_PACKETS_D, ISOC_PACKETS_D, ISOC_PACKETS_D, ISOC_PACKETS_D
};
-/*****************************************************/
-/* transmit completion routine for all ISO tx fifos */
-/*****************************************************/
static void
tx_iso_complete(struct urb *urb)
{
@@ -607,20 +544,38 @@
errcode;
int frame_complete, transp_mode, fifon, status;
__u8 threshbit;
- __u8 threshtable[8] = { 1, 2, 4, 8, 0x10, 0x20, 0x40, 0x80 };
fifon = fifo->fifonum;
status = urb->status;
tx_offset = 0;
+ /* ISO transfer only partially completed,
+ look at individual frame status for details */
+ if (status == -EXDEV) {
+ DBG(HFCUSB_DBG_VERBOSE_USB, "HFC-S USB: tx_iso_complete with -EXDEV"
+ ", urb->status %d, fifonum %d\n",
+ status, fifon);
+
+ for (k = 0; k < iso_packets[fifon]; ++k) {
+ errcode = urb->iso_frame_desc[k].status;
+ if (errcode)
+ DBG(HFCUSB_DBG_VERBOSE_USB, "HFC-S USB: tx_iso_complete "
+ "packet %i, status: %i\n",
+ k, errcode);
+ }
+
+ // clear status, so go on with ISO transfers
+ status = 0;
+ }
+
if (fifo->active && !status) {
transp_mode = 0;
if (fifon < 4 && hfc->b_mode[fifon / 2] == L1_MODE_TRANS)
- transp_mode = true;
+ transp_mode = 1;
/* is FifoFull-threshold set for our channel? */
- threshbit = threshtable[fifon] & hfc->threshold_mask;
+ threshbit = (hfc->threshold_mask & (1 << fifon));
num_isoc_packets = iso_packets[fifon];
/* predict dataflow to avoid fifo overflow */
@@ -635,8 +590,9 @@
tx_iso_complete, urb->context);
memset(context_iso_urb->buffer, 0,
sizeof(context_iso_urb->buffer));
- frame_complete = false;
- /* Generate next Iso Packets */
+ frame_complete = 0;
+
+ /* Generate next ISO Packets */
for (k = 0; k < num_isoc_packets; ++k) {
if (fifo->skbuff) {
len = fifo->skbuff->len;
@@ -661,7 +617,7 @@
/* add 2 byte flags and 16bit CRC at end of ISDN frame */
fifo->bit_line += 32;
}
- frame_complete = true;
+ frame_complete = 1;
}
memcpy(context_iso_urb->buffer +
@@ -688,7 +644,7 @@
}
if (frame_complete) {
- fifo->delete_flg = true;
+ fifo->delete_flg = 1;
fifo->hif->l1l2(fifo->hif,
PH_DATA | CONFIRM,
(void *) (unsigned long) fifo->skbuff->
@@ -696,30 +652,26 @@
if (fifo->skbuff && fifo->delete_flg) {
dev_kfree_skb_any(fifo->skbuff);
fifo->skbuff = NULL;
- fifo->delete_flg = false;
+ fifo->delete_flg = 0;
}
- frame_complete = false;
+ frame_complete = 0;
}
}
errcode = usb_submit_urb(urb, GFP_ATOMIC);
if (errcode < 0) {
printk(KERN_INFO
- "HFC-S USB: error submitting ISO URB: %d \n",
+ "HFC-S USB: error submitting ISO URB: %d\n",
errcode);
}
} else {
if (status && !hfc->disc_flag) {
printk(KERN_INFO
- "HFC-S USB: tx_iso_complete : urb->status %s (%i), fifonum=%d\n",
- symbolic(urb_errlist, status), status,
- fifon);
+ "HFC-S USB: tx_iso_complete: error(%i): '%s', fifonum=%d\n",
+ status, symbolic(urb_errlist, status), fifon);
}
}
-} /* tx_iso_complete */
+}
-/*****************************************************/
-/* receive completion routine for all ISO tx fifos */
-/*****************************************************/
static void
rx_iso_complete(struct urb *urb)
{
@@ -731,21 +683,25 @@
unsigned int iso_status;
__u8 *buf;
static __u8 eof[8];
-#ifdef CONFIG_HISAX_DEBUG
- __u8 i;
-#endif
fifon = fifo->fifonum;
status = urb->status;
if (urb->status == -EOVERFLOW) {
-#ifdef CONFIG_HISAX_DEBUG
- DBG(USB_DBG,
- "HFC-USB: ignoring USB DATAOVERRUN for fifo %i \n",
- fifon);
-#endif
+ DBG(HFCUSB_DBG_VERBOSE_USB,
+ "HFC-USB: ignoring USB DATAOVERRUN fifo(%i)", fifon);
status = 0;
}
+
+ /* ISO transfer only partially completed,
+ look at individual frame status for details */
+ if (status == -EXDEV) {
+ DBG(HFCUSB_DBG_VERBOSE_USB, "HFC-S USB: rx_iso_complete with -EXDEV "
+ "urb->status %d, fifonum %d\n",
+ status, fifon);
+ status = 0;
+ }
+
if (fifo->active && !status) {
num_isoc_packets = iso_packets[fifon];
maxlen = fifo->usb_packet_maxlen;
@@ -754,40 +710,38 @@
offset = urb->iso_frame_desc[k].offset;
buf = context_iso_urb->buffer + offset;
iso_status = urb->iso_frame_desc[k].status;
-#ifdef CONFIG_HISAX_DEBUG
- if (iso_status && !hfc->disc_flag)
- DBG(USB_DBG,
- "HFC-S USB: ISO packet failure - status:%x",
- iso_status);
- if ((fifon == 5) && (debug > 1)) {
- printk(KERN_INFO
+ if (iso_status && !hfc->disc_flag)
+ DBG(HFCUSB_DBG_VERBOSE_USB,
+ "HFC-S USB: rx_iso_complete "
+ "ISO packet %i, status: %i\n",
+ k, iso_status);
+
+ if (fifon == HFCUSB_D_RX) {
+ DBG(HFCUSB_DBG_VERBOSE_USB,
"HFC-S USB: ISO-D-RX lst_urblen:%2d "
- "act_urblen:%2d max-urblen:%2d "
- "EOF:0x%0x DATA: ",
+ "act_urblen:%2d max-urblen:%2d EOF:0x%0x",
fifo->last_urblen, len, maxlen,
eof[5]);
- for (i = 0; i < len; i++)
- printk("%.2x ", buf[i]);
- printk("\n");
+
+ DBG_PACKET(HFCUSB_DBG_VERBOSE_USB, buf, len);
}
-#endif
+
if (fifo->last_urblen != maxlen) {
/* the threshold mask is in the 2nd status byte */
hfc->threshold_mask = buf[1];
/* care for L1 state only for D-Channel
to avoid overlapped iso completions */
- if (fifon == 5) {
+ if (fifon == HFCUSB_D_RX) {
/* the S0 state is in the upper half
of the 1st status byte */
- state_handler(hfc, buf[0] >> 4);
+ s0_state_handler(hfc, buf[0] >> 4);
}
eof[fifon] = buf[0] & 1;
if (len > 2)
collect_rx_frame(fifo, buf + 2,
len - 2,
- (len <
- maxlen) ?
+ (len < maxlen) ?
eof[fifon] : 0);
} else {
collect_rx_frame(fifo, buf, len,
@@ -804,41 +758,37 @@
rx_iso_complete, urb->context);
errcode = usb_submit_urb(urb, GFP_ATOMIC);
if (errcode < 0) {
- printk(KERN_INFO
- "HFC-S USB: error submitting ISO URB: %d \n",
+ printk(KERN_ERR
+ "HFC-S USB: error submitting ISO URB: %d\n",
errcode);
}
} else {
if (status && !hfc->disc_flag) {
- printk(KERN_INFO
+ printk(KERN_ERR
"HFC-S USB: rx_iso_complete : "
"urb->status %d, fifonum %d\n",
status, fifon);
}
}
-} /* rx_iso_complete */
+}
-/*****************************************************/
-/* collect data from interrupt or isochron in */
-/*****************************************************/
+/* collect rx data from INT- and ISO-URBs */
static void
collect_rx_frame(usb_fifo * fifo, __u8 * data, int len, int finish)
{
hfcusb_data *hfc = fifo->hfc;
int transp_mode, fifon;
-#ifdef CONFIG_HISAX_DEBUG
- int i;
-#endif
+
fifon = fifo->fifonum;
transp_mode = 0;
if (fifon < 4 && hfc->b_mode[fifon / 2] == L1_MODE_TRANS)
- transp_mode = true;
+ transp_mode = 1;
if (!fifo->skbuff) {
fifo->skbuff = dev_alloc_skb(fifo->max_size + 3);
if (!fifo->skbuff) {
- printk(KERN_INFO
- "HFC-S USB: cannot allocate buffer (dev_alloc_skb) fifo:%d\n",
+ printk(KERN_ERR
+ "HFC-S USB: cannot allocate buffer for fifo(%d)\n",
fifon);
return;
}
@@ -847,17 +797,11 @@
if (fifo->skbuff->len + len < fifo->max_size) {
memcpy(skb_put(fifo->skbuff, len), data, len);
} else {
-#ifdef CONFIG_HISAX_DEBUG
- printk(KERN_INFO "HFC-S USB: ");
- for (i = 0; i < 15; i++)
- printk("%.2x ",
- fifo->skbuff->data[fifo->skbuff->
- len - 15 + i]);
- printk("\n");
-#endif
- printk(KERN_INFO
- "HCF-USB: got frame exceeded fifo->max_size:%d on fifo:%d\n",
+ DBG(HFCUSB_DBG_FIFO_ERR,
+ "HCF-USB: got frame exceeded fifo->max_size(%d) fifo(%d)",
fifo->max_size, fifon);
+ DBG_SKB(HFCUSB_DBG_VERBOSE_USB, fifo->skbuff);
+ skb_trim(fifo->skbuff, 0);
}
}
if (transp_mode && fifo->skbuff->len >= 128) {
@@ -870,6 +814,13 @@
if (finish) {
if ((!fifo->skbuff->data[fifo->skbuff->len - 1])
&& (fifo->skbuff->len > 3)) {
+
+ if (fifon == HFCUSB_D_RX) {
+ DBG(HFCUSB_DBG_DCHANNEL,
+ "HFC-S USB: D-RX len(%d)", fifo->skbuff->len);
+ DBG_SKB(HFCUSB_DBG_DCHANNEL, fifo->skbuff);
+ }
+
/* remove CRC & status */
skb_trim(fifo->skbuff, fifo->skbuff->len - 3);
if (fifon == HFCUSB_PCM_RX) {
@@ -882,39 +833,17 @@
fifo->skbuff);
fifo->skbuff = NULL; /* buffer was freed from upper layer */
} else {
- if (fifo->skbuff->len > 3) {
- printk(KERN_INFO
- "HFC-S USB: got frame %d bytes but CRC ERROR on fifo:%d!!!\n",
- fifo->skbuff->len, fifon);
-#ifdef CONFIG_HISAX_DEBUG
- if (debug > 1) {
- printk(KERN_INFO "HFC-S USB: ");
- for (i = 0; i < 15; i++)
- printk("%.2x ",
- fifo->skbuff->
- data[fifo->skbuff->
- len - 15 + i]);
- printk("\n");
- }
-#endif
- }
-#ifdef CONFIG_HISAX_DEBUG
- else {
- printk(KERN_INFO
- "HFC-S USB: frame to small (%d bytes)!!!\n",
- fifo->skbuff->len);
- }
-#endif
+ DBG(HFCUSB_DBG_FIFO_ERR,
+ "HFC-S USB: ERROR frame len(%d) fifo(%d)",
+ fifo->skbuff->len, fifon);
+ DBG_SKB(HFCUSB_DBG_VERBOSE_USB, fifo->skbuff);
skb_trim(fifo->skbuff, 0);
}
}
}
-/***********************************************/
-/* receive completion routine for all rx fifos */
-/***********************************************/
static void
-rx_complete(struct urb *urb)
+rx_int_complete(struct urb *urb)
{
int len;
int status;
@@ -922,18 +851,14 @@
usb_fifo *fifo = (usb_fifo *) urb->context;
hfcusb_data *hfc = fifo->hfc;
static __u8 eof[8];
-#ifdef CONFIG_HISAX_DEBUG
- __u8 i;
-#endif
urb->dev = hfc->dev; /* security init */
fifon = fifo->fifonum;
if ((!fifo->active) || (urb->status)) {
-#ifdef CONFIG_HISAX_DEBUG
- DBG(USB_DBG, "HFC-S USB: RX-Fifo %i is going down (%i)",
+ DBG(HFCUSB_DBG_INIT, "HFC-S USB: RX-Fifo %i is going down (%i)",
fifon, urb->status);
-#endif
+
fifo->urb->interval = 0; /* cancel automatic rescheduling */
if (fifo->skbuff) {
dev_kfree_skb_any(fifo->skbuff);
@@ -945,22 +870,20 @@
buf = fifo->buffer;
maxlen = fifo->usb_packet_maxlen;
-#ifdef CONFIG_HISAX_DEBUG
- if ((fifon == 5) && (debug > 1)) {
- printk(KERN_INFO
- "HFC-S USB: INT-D-RX lst_urblen:%2d act_urblen:%2d max-urblen:%2d EOF:0x%0x DATA: ",
- fifo->last_urblen, len, maxlen, eof[5]);
- for (i = 0; i < len; i++)
- printk("%.2x ", buf[i]);
- printk("\n");
+ if (fifon == HFCUSB_D_RX) {
+ DBG(HFCUSB_DBG_VERBOSE_USB,
+ "HFC-S USB: INT-D-RX lst_urblen:%2d "
+ "act_urblen:%2d max-urblen:%2d EOF:0x%0x",
+ fifo->last_urblen, len, maxlen,
+ eof[5]);
+ DBG_PACKET(HFCUSB_DBG_VERBOSE_USB, buf, len);
}
-#endif
if (fifo->last_urblen != fifo->usb_packet_maxlen) {
/* the threshold mask is in the 2nd status byte */
hfc->threshold_mask = buf[1];
/* the S0 state is in the upper half of the 1st status byte */
- state_handler(hfc, buf[0] >> 4);
+ s0_state_handler(hfc, buf[0] >> 4);
eof[fifon] = buf[0] & 1;
/* if we have more than the 2 status bytes -> collect data */
if (len > 2)
@@ -975,20 +898,19 @@
status = usb_submit_urb(urb, GFP_ATOMIC);
if (status) {
printk(KERN_INFO
- "HFC-S USB: error resubmitting URN at rx_complete...\n");
+ "HFC-S USB: %s error resubmitting URB fifo(%d)\n",
+ __FUNCTION__, fifon);
}
-} /* rx_complete */
+}
-/***************************************************/
-/* start the interrupt transfer for the given fifo */
-/***************************************************/
+/* start initial INT-URB for certain fifo */
static void
start_int_fifo(usb_fifo * fifo)
{
int errcode;
- printk(KERN_INFO "HFC-S USB: starting intr IN fifo:%d\n",
- fifo->fifonum);
+ DBG(HFCUSB_DBG_INIT, "HFC-S USB: starting RX INT-URB for fifo:%d\n",
+ fifo->fifonum);
if (!fifo->urb) {
fifo->urb = usb_alloc_urb(0, GFP_KERNEL);
@@ -997,33 +919,28 @@
}
usb_fill_int_urb(fifo->urb, fifo->hfc->dev, fifo->pipe,
fifo->buffer, fifo->usb_packet_maxlen,
- rx_complete, fifo, fifo->intervall);
+ rx_int_complete, fifo, fifo->intervall);
fifo->active = 1; /* must be marked active */
errcode = usb_submit_urb(fifo->urb, GFP_KERNEL);
if (errcode) {
- printk(KERN_INFO
+ printk(KERN_ERR
"HFC-S USB: submit URB error(start_int_info): status:%i\n",
errcode);
fifo->active = 0;
fifo->skbuff = NULL;
}
-} /* start_int_fifo */
+}
-/*****************************/
-/* set the B-channel mode */
-/*****************************/
static void
-set_hfcmode(hfcusb_data * hfc, int channel, int mode)
+setup_bchannel(hfcusb_data * hfc, int channel, int mode)
{
__u8 val, idx_table[2] = { 0, 2 };
if (hfc->disc_flag) {
return;
}
-#ifdef CONFIG_HISAX_DEBUG
- DBG(ISDN_DBG, "HFC-S USB: setting channel %d to mode %d", channel,
- mode);
-#endif
+ DBG(HFCUSB_DBG_STATES, "HFC-S USB: setting channel %d to mode %d",
+ channel, mode);
hfc->b_mode[channel] = mode;
/* setup CON_HDLC */
@@ -1080,20 +997,17 @@
switch (pr) {
case PH_ACTIVATE | REQUEST:
if (fifo->fifonum == HFCUSB_D_TX) {
-#ifdef CONFIG_HISAX_DEBUG
- DBG(ISDN_DBG,
+ DBG(HFCUSB_DBG_STATES,
"HFC_USB: hfc_usb_d_l2l1 D-chan: PH_ACTIVATE | REQUEST");
-#endif
+
if (hfc->l1_state != 3
&& hfc->l1_state != 7) {
hfc->d_if.ifc.l1l2(&hfc->d_if.ifc,
PH_DEACTIVATE |
INDICATION,
NULL);
-#ifdef CONFIG_HISAX_DEBUG
- DBG(ISDN_DBG,
+ DBG(HFCUSB_DBG_STATES,
"HFC-S USB: PH_DEACTIVATE | INDICATION sent (not state 3 or 7)");
-#endif
} else {
if (hfc->l1_state == 7) { /* l1 already active */
hfc->d_if.ifc.l1l2(&hfc->
@@ -1103,10 +1017,8 @@
|
INDICATION,
NULL);
-#ifdef CONFIG_HISAX_DEBUG
- DBG(ISDN_DBG,
+ DBG(HFCUSB_DBG_STATES,
"HFC-S USB: PH_ACTIVATE | INDICATION sent again ;)");
-#endif
} else {
/* force sending sending INFO1 */
queue_control_request(hfc,
@@ -1132,11 +1044,9 @@
}
}
} else {
-#ifdef CONFIG_HISAX_DEBUG
- DBG(ISDN_DBG,
- "HFC_USB: hfc_usb_d_l2l1 Bx-chan: PH_ACTIVATE | REQUEST");
-#endif
- set_hfcmode(hfc,
+ DBG(HFCUSB_DBG_STATES,
+ "HFC_USB: hfc_usb_d_l2l1 B-chan: PH_ACTIVATE | REQUEST");
+ setup_bchannel(hfc,
(fifo->fifonum ==
HFCUSB_B1_TX) ? 0 : 1,
(long) arg);
@@ -1147,18 +1057,12 @@
break;
case PH_DEACTIVATE | REQUEST:
if (fifo->fifonum == HFCUSB_D_TX) {
-#ifdef CONFIG_HISAX_DEBUG
- DBG(ISDN_DBG,
+ DBG(HFCUSB_DBG_STATES,
"HFC_USB: hfc_usb_d_l2l1 D-chan: PH_DEACTIVATE | REQUEST");
-#endif
- printk(KERN_INFO
- "HFC-S USB: ISDN TE device should not deativate...\n");
} else {
-#ifdef CONFIG_HISAX_DEBUG
- DBG(ISDN_DBG,
+ DBG(HFCUSB_DBG_STATES,
"HFC_USB: hfc_usb_d_l2l1 Bx-chan: PH_DEACTIVATE | REQUEST");
-#endif
- set_hfcmode(hfc,
+ setup_bchannel(hfc,
(fifo->fifonum ==
HFCUSB_B1_TX) ? 0 : 1,
(int) L1_MODE_NULL);
@@ -1171,25 +1075,20 @@
if (fifo->skbuff && fifo->delete_flg) {
dev_kfree_skb_any(fifo->skbuff);
fifo->skbuff = NULL;
- fifo->delete_flg = false;
+ fifo->delete_flg = 0;
}
fifo->skbuff = arg; /* we have a new buffer */
break;
default:
- printk(KERN_INFO
- "HFC_USB: hfc_usb_d_l2l1: unkown state : %#x\n",
- pr);
+ DBG(HFCUSB_DBG_STATES,
+ "HFC_USB: hfc_usb_d_l2l1: unkown state : %#x", pr);
break;
}
}
-/***************************************************************************/
-/* usb_init is called once when a new matching device is detected to setup */
-/* main parameters. It registers the driver at the main hisax module. */
-/* on success 0 is returned. */
-/***************************************************************************/
+/* initial init HFC-S USB chip registers, HiSax interface, USB URBs */
static int
-usb_init(hfcusb_data * hfc)
+hfc_usb_init(hfcusb_data * hfc)
{
usb_fifo *fifo;
int i, err;
@@ -1214,11 +1113,11 @@
/* aux = output, reset off */
write_usb(hfc, HFCUSB_CIRM, 0x10);
- /* set USB_SIZE to match the wMaxPacketSize for INT or BULK transfers */
+ /* set USB_SIZE to match wMaxPacketSize for INT or BULK transfers */
write_usb(hfc, HFCUSB_USB_SIZE,
(hfc->packet_size / 8) | ((hfc->packet_size / 8) << 4));
- /* set USB_SIZE_I to match the wMaxPacketSize for ISO transfers */
+ /* set USB_SIZE_I to match wMaxPacketSize for ISO transfers */
write_usb(hfc, HFCUSB_USB_SIZE_I, hfc->iso_packet_size);
/* enable PCM/GCI master mode */
@@ -1257,8 +1156,8 @@
hfc->b_mode[0] = L1_MODE_NULL;
hfc->b_mode[1] = L1_MODE_NULL;
- hfc->l1_activated = false;
- hfc->disc_flag = false;
+ hfc->l1_activated = 0;
+ hfc->disc_flag = 0;
hfc->led_state = 0;
hfc->led_new_data = 0;
hfc->old_led_state = 0;
@@ -1349,11 +1248,9 @@
handle_led(hfc, LED_POWER_ON);
return (0);
-} /* usb_init */
+}
-/*************************************************/
-/* function called to probe a new plugged device */
-/*************************************************/
+/* initial callback for each plugged USB device */
static int
hfc_usb_probe(struct usb_interface *intf, const struct usb_device_id *id)
{
@@ -1378,11 +1275,6 @@
}
}
-#ifdef CONFIG_HISAX_DEBUG
- DBG(USB_DBG,
- "HFC-USB: probing interface(%d) actalt(%d) minor(%d)\n", ifnum,
- iface->desc.bAlternateSetting, intf->minor);
-#endif
printk(KERN_INFO
"HFC-S USB: probing interface(%d) actalt(%d) minor(%d)\n",
ifnum, iface->desc.bAlternateSetting, intf->minor);
@@ -1403,15 +1295,11 @@
/* check for config EOL element */
while (validconf[cfg_used][0]) {
- cfg_found = true;
+ cfg_found = 1;
vcf = validconf[cfg_used];
/* first endpoint descriptor */
ep = iface->endpoint;
-#ifdef CONFIG_HISAX_DEBUG
- DBG(USB_DBG,
- "HFC-S USB: (if=%d alt=%d cfg_used=%d)\n",
- ifnum, probe_alt_setting, cfg_used);
-#endif
+
memcpy(cmptbl, vcf, 16 * sizeof(int));
/* check for all endpoints in this alternate setting */
@@ -1425,7 +1313,7 @@
idx++;
attr = ep->desc.bmAttributes;
if (cmptbl[idx] == EP_NUL) {
- cfg_found = false;
+ cfg_found = 0;
}
if (attr == USB_ENDPOINT_XFER_INT
&& cmptbl[idx] == EP_INT)
@@ -1438,16 +1326,9 @@
cmptbl[idx] = EP_NUL;
/* check if all INT endpoints match minimum interval */
- if (attr == USB_ENDPOINT_XFER_INT
- && ep->desc.bInterval <
- vcf[17]) {
-#ifdef CONFIG_HISAX_DEBUG
- if (cfg_found)
- DBG(USB_DBG,
- "HFC-S USB: Interrupt Endpoint interval < %d found - skipping config",
- vcf[17]);
-#endif
- cfg_found = false;
+ if ((attr == USB_ENDPOINT_XFER_INT)
+ && (ep->desc.bInterval < vcf[17])) {
+ cfg_found = 0;
}
ep++;
}
@@ -1455,7 +1336,7 @@
/* all entries must be EP_NOP or EP_NUL for a valid config */
if (cmptbl[i] != EP_NOP
&& cmptbl[i] != EP_NUL)
- cfg_found = false;
+ cfg_found = 0;
}
if (cfg_found) {
if (cfg_used < small_match) {
@@ -1464,23 +1345,16 @@
probe_alt_setting;
iface_used = iface;
}
-#ifdef CONFIG_HISAX_DEBUG
- DBG(USB_DBG,
- "HFC-USB: small_match=%x %x\n",
- small_match, alt_used);
-#endif
}
cfg_used++;
}
alt_idx++;
- } /* (alt_idx < intf->num_altsetting) */
+ } /* (alt_idx < intf->num_altsetting) */
/* found a valid USB Ta Endpint config */
if (small_match != 0xffff) {
iface = iface_used;
- if (!
- (context =
- kzalloc(sizeof(hfcusb_data), GFP_KERNEL)))
+ if (!(context = kzalloc(sizeof(hfcusb_data), GFP_KERNEL)))
return (-ENOMEM); /* got no mem */
ep = iface->endpoint;
@@ -1613,20 +1487,15 @@
driver_info;
printk(KERN_INFO "HFC-S USB: detected \"%s\"\n",
driver_info->vend_name);
-#ifdef CONFIG_HISAX_DEBUG
- DBG(USB_DBG,
- "HFC-S USB: Endpoint-Config: %s (if=%d alt=%d)\n",
+
+ DBG(HFCUSB_DBG_INIT,
+ "HFC-S USB: Endpoint-Config: %s (if=%d alt=%d), E-Channel(%d)",
conf_str[small_match], context->if_used,
- context->alt_used);
- printk(KERN_INFO
- "HFC-S USB: E-channel (\"ECHO:\") logging ");
- if (validconf[small_match][18])
- printk(" possible\n");
- else
- printk("NOT possible\n");
-#endif
+ context->alt_used,
+ validconf[small_match][18]);
+
/* init the chip and register the driver */
- if (usb_init(context)) {
+ if (hfc_usb_init(context)) {
usb_kill_urb(context->ctrl_urb);
usb_free_urb(context->ctrl_urb);
context->ctrl_urb = NULL;
@@ -1643,17 +1512,19 @@
return (-EIO);
}
-/****************************************************/
-/* function called when an active device is removed */
-/****************************************************/
+/* callback for unplugged USB device */
static void
hfc_usb_disconnect(struct usb_interface
*intf)
{
hfcusb_data *context = usb_get_intfdata(intf);
int i;
+
+ handle_led(context, LED_POWER_OFF);
+ schedule_timeout((10 * HZ) / 1000);
+
printk(KERN_INFO "HFC-S USB: device disconnect\n");
- context->disc_flag = true;
+ context->disc_flag = 1;
usb_set_intfdata(intf, NULL);
if (!context)
return;
@@ -1661,25 +1532,22 @@
del_timer(&context->t3_timer);
if (timer_pending(&context->t4_timer))
del_timer(&context->t4_timer);
+
/* tell all fifos to terminate */
for (i = 0; i < HFCUSB_NUM_FIFOS; i++) {
if (context->fifos[i].usb_transfer_mode == USB_ISOC) {
if (context->fifos[i].active > 0) {
stop_isoc_chain(&context->fifos[i]);
-#ifdef CONFIG_HISAX_DEBUG
- DBG(USB_DBG,
- "HFC-S USB: hfc_usb_disconnect: stopping ISOC chain Fifo no %i",
- i);
-#endif
+ DBG(HFCUSB_DBG_INIT,
+ "HFC-S USB: %s stopping ISOC chain Fifo(%i)",
+ __FUNCTION__, i);
}
} else {
if (context->fifos[i].active > 0) {
context->fifos[i].active = 0;
-#ifdef CONFIG_HISAX_DEBUG
- DBG(USB_DBG,
- "HFC-S USB: hfc_usb_disconnect: unlinking URB for Fifo no %i",
- i);
-#endif
+ DBG(HFCUSB_DBG_INIT,
+ "HFC-S USB: %s unlinking URB for Fifo(%i)",
+ __FUNCTION__, i);
}
usb_kill_urb(context->fifos[i].urb);
usb_free_urb(context->fifos[i].urb);
@@ -1692,34 +1560,29 @@
context->ctrl_urb = NULL;
hisax_unregister(&context->d_if);
kfree(context); /* free our structure again */
-} /* hfc_usb_disconnect */
+}
-/************************************/
-/* our driver information structure */
-/************************************/
static struct usb_driver hfc_drv = {
.name = "hfc_usb",
.id_table = hfcusb_idtab,
.probe = hfc_usb_probe,
.disconnect = hfc_usb_disconnect,
};
+
static void __exit
-hfc_usb_exit(void)
+hfc_usb_mod_exit(void)
{
-#ifdef CONFIG_HISAX_DEBUG
- DBG(USB_DBG, "HFC-S USB: calling \"hfc_usb_exit\" ...");
-#endif
- usb_deregister(&hfc_drv); /* release our driver */
+ usb_deregister(&hfc_drv); /* release our driver */
printk(KERN_INFO "HFC-S USB: module removed\n");
}
static int __init
-hfc_usb_init(void)
+hfc_usb_mod_init(void)
{
-#ifndef CONFIG_HISAX_DEBUG
- unsigned int debug = -1;
-#endif
char revstr[30], datestr[30], dummy[30];
+#ifndef CONFIG_HISAX_DEBUG
+ hfc_debug = debug;
+#endif
sscanf(hfcusb_revision,
"%s %s $ %s %s %s $ ", dummy, revstr,
dummy, datestr, dummy);
@@ -1734,8 +1597,8 @@
return (0);
}
-module_init(hfc_usb_init);
-module_exit(hfc_usb_exit);
+module_init(hfc_usb_mod_init);
+module_exit(hfc_usb_mod_exit);
MODULE_AUTHOR(DRIVER_AUTHOR);
MODULE_DESCRIPTION(DRIVER_DESC);
MODULE_LICENSE("GPL");
diff --git a/drivers/isdn/hisax/hfc_usb.h b/drivers/isdn/hisax/hfc_usb.h
index 471f235..e79f565 100644
--- a/drivers/isdn/hisax/hfc_usb.h
+++ b/drivers/isdn/hisax/hfc_usb.h
@@ -1,8 +1,8 @@
/*
-* hfc_usb.h
-*
-* $Id: hfc_usb.h,v 4.2 2005/04/07 15:27:17 martinb1 Exp $
-*/
+ * hfc_usb.h
+ *
+ * $Id: hfc_usb.h,v 1.1.2.5 2007/08/20 14:36:03 mbachem Exp $
+ */
#ifndef __HFC_USB_H__
#define __HFC_USB_H__
@@ -10,25 +10,20 @@
#define DRIVER_AUTHOR "Peter Sprenger (sprenger@moving-byters.de)"
#define DRIVER_DESC "HFC-S USB based HiSAX ISDN driver"
-#define VERBOSE_USB_DEBUG
+#define HFC_CTRL_TIMEOUT 20 /* 5ms timeout writing/reading regs */
+#define HFC_TIMER_T3 8000 /* timeout for l1 activation timer */
+#define HFC_TIMER_T4 500 /* time for state change interval */
-/***********/
-/* defines */
-/***********/
-#define HFC_CTRL_TIMEOUT 20 /* 5ms timeout writing/reading regs */
-#define HFC_TIMER_T3 8000 /* timeout for l1 activation timer */
-#define HFC_TIMER_T4 500 /* time for state change interval */
+#define HFCUSB_L1_STATECHANGE 0 /* L1 state changed */
+#define HFCUSB_L1_DRX 1 /* D-frame received */
+#define HFCUSB_L1_ERX 2 /* E-frame received */
+#define HFCUSB_L1_DTX 4 /* D-frames completed */
-#define HFCUSB_L1_STATECHANGE 0 /* L1 state changed */
-#define HFCUSB_L1_DRX 1 /* D-frame received */
-#define HFCUSB_L1_ERX 2 /* E-frame received */
-#define HFCUSB_L1_DTX 4 /* D-frames completed */
+#define MAX_BCH_SIZE 2048 /* allowed B-channel packet size */
-#define MAX_BCH_SIZE 2048 /* allowed B-channel packet size */
-
-#define HFCUSB_RX_THRESHOLD 64 /* threshold for fifo report bit rx */
-#define HFCUSB_TX_THRESHOLD 64 /* threshold for fifo report bit tx */
+#define HFCUSB_RX_THRESHOLD 64 /* threshold for fifo report bit rx */
+#define HFCUSB_TX_THRESHOLD 64 /* threshold for fifo report bit tx */
#define HFCUSB_CHIP_ID 0x16 /* Chip ID register index */
#define HFCUSB_CIRM 0x00 /* cirm register index */
@@ -52,9 +47,8 @@
#define HFCUSB_CHIPID 0x40 /* ID value of HFC-S USB */
-/******************/
+
/* fifo registers */
-/******************/
#define HFCUSB_NUM_FIFOS 8 /* maximum number of fifos */
#define HFCUSB_B1_TX 0 /* index for B1 transmit bulk/int */
#define HFCUSB_B1_RX 1 /* index for B1 receive bulk/int */
@@ -66,9 +60,9 @@
#define HFCUSB_PCM_RX 7
/*
-* used to switch snd_transfer_mode for different TA modes e.g. the Billion USB TA just
-* supports ISO out, while the Cologne Chip EVAL TA just supports BULK out
-*/
+ * used to switch snd_transfer_mode for different TA modes e.g. the Billion USB TA just
+ * supports ISO out, while the Cologne Chip EVAL TA just supports BULK out
+ */
#define USB_INT 0
#define USB_BULK 1
#define USB_ISOC 2
@@ -77,49 +71,36 @@
#define ISOC_PACKETS_B 8
#define ISO_BUFFER_SIZE 128
-// ISO send definitions
+/* Fifo flow Control for TX ISO */
#define SINK_MAX 68
#define SINK_MIN 48
#define SINK_DMIN 12
#define SINK_DMAX 18
#define BITLINE_INF (-64*8)
-
-/**********/
-/* macros */
-/**********/
+/* HFC-S USB register access by Control-URSs */
#define write_usb(a,b,c)usb_control_msg((a)->dev,(a)->ctrl_out_pipe,0,0x40,(c),(b),NULL,0,HFC_CTRL_TIMEOUT)
#define read_usb(a,b,c) usb_control_msg((a)->dev,(a)->ctrl_in_pipe,1,0xC0,0,(b),(c),1,HFC_CTRL_TIMEOUT)
-
-
-/*******************/
-/* Debugging Flags */
-/*******************/
-#define USB_DBG 1
-#define ISDN_DBG 2
-
-
-/* *********************/
-/* USB related defines */
-/***********************/
#define HFC_CTRL_BUFSIZE 32
-
-
-/*************************************************/
/* entry and size of output/input control buffer */
-/*************************************************/
typedef struct {
__u8 hfc_reg; /* register number */
__u8 reg_val; /* value to be written (or read) */
int action; /* data for action handler */
} ctrl_buft;
+/* Debugging Flags */
+#define HFCUSB_DBG_INIT 0x0001
+#define HFCUSB_DBG_STATES 0x0002
+#define HFCUSB_DBG_DCHANNEL 0x0080
+#define HFCUSB_DBG_FIFO_ERR 0x4000
+#define HFCUSB_DBG_VERBOSE_USB 0x8000
-/********************/
-/* URB error codes: */
-/********************/
-/* Used to represent a list of values and their respective symbolic names */
+/*
+ * URB error codes:
+ * Used to represent a list of values and their respective symbolic names
+ */
struct hfcusb_symbolic_list {
const int num;
const char *name;
@@ -134,20 +115,20 @@
{-ENXIO, "URB already queued"},
{-EFBIG, "Too much ISO frames requested"},
{-ENOSR, "Buffer error (overrun)"},
- {-EPIPE, "Specified endpoint is stalled"},
+ {-EPIPE, "Specified endpoint is stalled (device not responding)"},
{-EOVERFLOW, "Babble (bad cable?)"},
{-EPROTO, "Bit-stuff error (bad cable?)"},
- {-EILSEQ, "CRC or missing token"},
- {-ETIME, "Device did not respond"},
+ {-EILSEQ, "CRC/Timeout"},
+ {-ETIMEDOUT, "NAK (device does not respond)"},
{-ESHUTDOWN, "Device unplugged"},
{-1, NULL}
};
-/*****************************************************/
-/* device dependant information to support different */
-/* ISDN Ta's using the HFC-S USB chip */
-/*****************************************************/
+/*
+ * device dependant information to support different
+ * ISDN Ta's using the HFC-S USB chip
+ */
/* USB descriptor need to contain one of the following EndPoint combination: */
#define CNF_4INT3ISO 1 // 4 INT IN, 3 ISO OUT
@@ -155,16 +136,19 @@
#define CNF_4ISO3ISO 3 // 4 ISO IN, 3 ISO OUT
#define CNF_3ISO3ISO 4 // 3 ISO IN, 3 ISO OUT
-#define EP_NUL 1 // Endpoint at this position not allowed
-#define EP_NOP 2 // all type of endpoints allowed at this position
-#define EP_ISO 3 // Isochron endpoint mandatory at this position
-#define EP_BLK 4 // Bulk endpoint mandatory at this position
-#define EP_INT 5 // Interrupt endpoint mandatory at this position
+#define EP_NUL 1 // Endpoint at this position not allowed
+#define EP_NOP 2 // all type of endpoints allowed at this position
+#define EP_ISO 3 // Isochron endpoint mandatory at this position
+#define EP_BLK 4 // Bulk endpoint mandatory at this position
+#define EP_INT 5 // Interrupt endpoint mandatory at this position
-/* this array represents all endpoints possible in the HCF-USB the last
-* 3 entries are the configuration number, the minimum interval for
-* Interrupt endpoints & boolean if E-channel logging possible
-*/
+/*
+ * List of all supported endpoint configuration sets, used to find the
+ * best matching endpoint configuration within a devices' USB descriptor.
+ * We need at least 3 RX endpoints, and 3 TX endpoints, either
+ * INT-in and ISO-out, or ISO-in and ISO-out)
+ * with 4 RX endpoints even E-Channel logging is possible
+ */
static int validconf[][19] = {
// INT in, ISO out config
{EP_NUL, EP_INT, EP_NUL, EP_INT, EP_NUL, EP_INT, EP_NOP, EP_INT,
@@ -193,7 +177,6 @@
};
#endif
-
typedef struct {
int vendor; // vendor id
int prod_id; // product id
@@ -202,9 +185,9 @@
signed short led_bits[8]; // array of 8 possible LED bitmask settings
} vendor_data;
-#define LED_OFF 0 // no LED support
-#define LED_SCHEME1 1 // LED standard scheme
-#define LED_SCHEME2 2 // not used yet...
+#define LED_OFF 0 // no LED support
+#define LED_SCHEME1 1 // LED standard scheme
+#define LED_SCHEME2 2 // not used yet...
#define LED_POWER_ON 1
#define LED_POWER_OFF 2
@@ -217,11 +200,8 @@
#define LED_B2_OFF 9
#define LED_B2_DATA 10
-#define LED_NORMAL 0 // LEDs are normal
-#define LED_INVERTED 1 // LEDs are inverted
-
-/* time in ms to perform a Flashing LED when B-Channel has traffic */
-#define LED_TIME 250
+#define LED_NORMAL 0 // LEDs are normal
+#define LED_INVERTED 1 // LEDs are inverted
-#endif // __HFC_USB_H__
+#endif // __HFC_USB_H__
diff --git a/drivers/kvm/Kconfig b/drivers/kvm/Kconfig
index 6cecc39..7b64fd4 100644
--- a/drivers/kvm/Kconfig
+++ b/drivers/kvm/Kconfig
@@ -5,6 +5,11 @@
bool "Virtualization"
depends on X86
default y
+ ---help---
+ Say Y here to get to see options for virtualization guest drivers.
+ This option alone does not add any kernel code.
+
+ If you say N, all options in this submenu will be skipped and disabled.
if VIRTUALIZATION
diff --git a/drivers/kvm/kvm_main.c b/drivers/kvm/kvm_main.c
index 9685609..cd05579 100644
--- a/drivers/kvm/kvm_main.c
+++ b/drivers/kvm/kvm_main.c
@@ -2974,6 +2974,10 @@
switch (val) {
case CPU_DYING:
case CPU_DYING_FROZEN:
+ printk(KERN_INFO "kvm: disabling virtualization on CPU%d\n",
+ cpu);
+ hardware_disable(NULL);
+ break;
case CPU_UP_CANCELED:
case CPU_UP_CANCELED_FROZEN:
printk(KERN_INFO "kvm: disabling virtualization on CPU%d\n",
diff --git a/drivers/kvm/x86_emulate.c b/drivers/kvm/x86_emulate.c
index 1f979cb..4b8a0cc 100644
--- a/drivers/kvm/x86_emulate.c
+++ b/drivers/kvm/x86_emulate.c
@@ -1217,11 +1217,13 @@
}
break;
case 0x21: /* mov from dr to reg */
+ no_wb = 1;
if (modrm_mod != 3)
goto cannot_emulate;
rc = emulator_get_dr(ctxt, modrm_reg, &_regs[modrm_rm]);
break;
case 0x23: /* mov from reg to dr */
+ no_wb = 1;
if (modrm_mod != 3)
goto cannot_emulate;
rc = emulator_set_dr(ctxt, modrm_reg, _regs[modrm_rm]);
diff --git a/drivers/lguest/Kconfig b/drivers/lguest/Kconfig
index 888205c..41e2250 100644
--- a/drivers/lguest/Kconfig
+++ b/drivers/lguest/Kconfig
@@ -1,6 +1,6 @@
config LGUEST
tristate "Linux hypervisor example code"
- depends on X86 && PARAVIRT && EXPERIMENTAL && !X86_PAE
+ depends on X86 && PARAVIRT && EXPERIMENTAL && !X86_PAE && FUTEX
select LGUEST_GUEST
select HVC_DRIVER
---help---
@@ -21,8 +21,10 @@
config LGUEST_NET
tristate
+ default y
depends on LGUEST_GUEST && NET
config LGUEST_BLOCK
tristate
+ default y
depends on LGUEST_GUEST && BLOCK
diff --git a/drivers/lguest/core.c b/drivers/lguest/core.c
index 0a46e88..4a315f0 100644
--- a/drivers/lguest/core.c
+++ b/drivers/lguest/core.c
@@ -453,6 +453,11 @@
* lguest_pages". */
copy_in_guest_info(lg, pages);
+ /* Set the trap number to 256 (impossible value). If we fault while
+ * switching to the Guest (bad segment registers or bug), this will
+ * cause us to abort the Guest. */
+ lg->regs->trapnum = 256;
+
/* Now: we push the "eflags" register on the stack, then do an "lcall".
* This is how we change from using the kernel code segment to using
* the dedicated lguest code segment, as well as jumping into the
diff --git a/drivers/lguest/interrupts_and_traps.c b/drivers/lguest/interrupts_and_traps.c
index 49787e9..49aa555 100644
--- a/drivers/lguest/interrupts_and_traps.c
+++ b/drivers/lguest/interrupts_and_traps.c
@@ -195,13 +195,16 @@
/* deliver_trap() returns true if it could deliver the trap. */
int deliver_trap(struct lguest *lg, unsigned int num)
{
- u32 lo = lg->idt[num].a, hi = lg->idt[num].b;
+ /* Trap numbers are always 8 bit, but we set an impossible trap number
+ * for traps inside the Switcher, so check that here. */
+ if (num >= ARRAY_SIZE(lg->idt))
+ return 0;
/* Early on the Guest hasn't set the IDT entries (or maybe it put a
* bogus one in): if we fail here, the Guest will be killed. */
- if (!idt_present(lo, hi))
+ if (!idt_present(lg->idt[num].a, lg->idt[num].b))
return 0;
- set_guest_interrupt(lg, lo, hi, has_err(num));
+ set_guest_interrupt(lg, lg->idt[num].a, lg->idt[num].b, has_err(num));
return 1;
}
diff --git a/drivers/lguest/lguest.c b/drivers/lguest/lguest.c
index 1bc1546..6e135ac 100644
--- a/drivers/lguest/lguest.c
+++ b/drivers/lguest/lguest.c
@@ -323,9 +323,12 @@
* __thread variables). So we have a hypercall specifically for this case. */
static void lguest_load_tls(struct thread_struct *t, unsigned int cpu)
{
+ /* There's one problem which normal hardware doesn't have: the Host
+ * can't handle us removing entries we're currently using. So we clear
+ * the GS register here: if it's needed it'll be reloaded anyway. */
+ loadsegment(gs, 0);
lazy_hcall(LHCALL_LOAD_TLS, __pa(&t->tls_array), cpu, 0);
}
-/*:*/
/*G:038 That's enough excitement for now, back to ploughing through each of
* the paravirt_ops (we're about 1/3 of the way through).
@@ -687,7 +690,8 @@
.rating = 400,
.read = lguest_clock_read,
.mask = CLOCKSOURCE_MASK(64),
- .mult = 1,
+ .mult = 1 << 22,
+ .shift = 22,
};
/* The "scheduler clock" is just our real clock, adjusted to start at zero */
@@ -770,7 +774,6 @@
* way, the "rating" is initialized so high that it's always chosen
* over any other clocksource. */
if (lguest_data.tsc_khz) {
- lguest_clock.shift = 22;
lguest_clock.mult = clocksource_khz2mult(lguest_data.tsc_khz,
lguest_clock.shift);
lguest_clock.flags = CLOCK_SOURCE_IS_CONTINUOUS;
@@ -933,23 +936,24 @@
/* Now our patch routine is fairly simple (based on the native one in
* paravirt.c). If we have a replacement, we copy it in and return how much of
* the available space we used. */
-static unsigned lguest_patch(u8 type, u16 clobber, void *insns, unsigned len)
+static unsigned lguest_patch(u8 type, u16 clobber, void *ibuf,
+ unsigned long addr, unsigned len)
{
unsigned int insn_len;
/* Don't do anything special if we don't have a replacement */
if (type >= ARRAY_SIZE(lguest_insns) || !lguest_insns[type].start)
- return paravirt_patch_default(type, clobber, insns, len);
+ return paravirt_patch_default(type, clobber, ibuf, addr, len);
insn_len = lguest_insns[type].end - lguest_insns[type].start;
/* Similarly if we can't fit replacement (shouldn't happen, but let's
* be thorough). */
if (len < insn_len)
- return paravirt_patch_default(type, clobber, insns, len);
+ return paravirt_patch_default(type, clobber, ibuf, addr, len);
/* Copy in our instructions. */
- memcpy(insns, lguest_insns[type].start, insn_len);
+ memcpy(ibuf, lguest_insns[type].start, insn_len);
return insn_len;
}
diff --git a/drivers/lguest/lguest_bus.c b/drivers/lguest/lguest_bus.c
index 55a7940..9e7752c 100644
--- a/drivers/lguest/lguest_bus.c
+++ b/drivers/lguest/lguest_bus.c
@@ -5,6 +5,7 @@
#include <linux/bootmem.h>
#include <linux/lguest_bus.h>
#include <asm/io.h>
+#include <asm/paravirt.h>
static ssize_t type_show(struct device *_dev,
struct device_attribute *attr, char *buf)
diff --git a/drivers/lguest/segments.c b/drivers/lguest/segments.c
index f675a41..9b81119 100644
--- a/drivers/lguest/segments.c
+++ b/drivers/lguest/segments.c
@@ -43,22 +43,6 @@
* begin.
*/
-/* Is the descriptor the Guest wants us to put in OK?
- *
- * The flag which Intel says must be zero: must be zero. The descriptor must
- * be present, (this is actually checked earlier but is here for thorougness),
- * and the descriptor type must be 1 (a memory segment). */
-static int desc_ok(const struct desc_struct *gdt)
-{
- return ((gdt->b & 0x00209000) == 0x00009000);
-}
-
-/* Is the segment present? (Otherwise it can't be used by the Guest). */
-static int segment_present(const struct desc_struct *gdt)
-{
- return gdt->b & 0x8000;
-}
-
/* There are several entries we don't let the Guest set. The TSS entry is the
* "Task State Segment" which controls all kinds of delicate things. The
* LGUEST_CS and LGUEST_DS entries are reserved for the Switcher, and the
@@ -71,37 +55,11 @@
|| num == GDT_ENTRY_DOUBLEFAULT_TSS);
}
-/* If the Guest asks us to remove an entry from the GDT, we have to be careful.
- * If one of the segment registers is pointing at that entry the Switcher will
- * crash when it tries to reload the segment registers for the Guest.
- *
- * It doesn't make much sense for the Guest to try to remove its own code, data
- * or stack segments while they're in use: assume that's a Guest bug. If it's
- * one of the lesser segment registers using the removed entry, we simply set
- * that register to 0 (unusable). */
-static void check_segment_use(struct lguest *lg, unsigned int desc)
-{
- /* GDT entries are 8 bytes long, so we divide to get the index and
- * ignore the bottom bits. */
- if (lg->regs->gs / 8 == desc)
- lg->regs->gs = 0;
- if (lg->regs->fs / 8 == desc)
- lg->regs->fs = 0;
- if (lg->regs->es / 8 == desc)
- lg->regs->es = 0;
- if (lg->regs->ds / 8 == desc
- || lg->regs->cs / 8 == desc
- || lg->regs->ss / 8 == desc)
- kill_guest(lg, "Removed live GDT entry %u", desc);
-}
-/*:*/
-/*M:009 We wouldn't need to check for removal of in-use segments if we handled
- * faults in the Switcher. However, it's probably not a worthwhile
- * optimization. :*/
-
-/*H:610 Once the GDT has been changed, we look through the changed entries and
- * see if they're OK. If not, we'll call kill_guest() and the Guest will never
- * get to use the invalid entries. */
+/*H:610 Once the GDT has been changed, we fix the new entries up a little. We
+ * don't care if they're invalid: the worst that can happen is a General
+ * Protection Fault in the Switcher when it restores a Guest segment register
+ * which tries to use that entry. Then we kill the Guest for causing such a
+ * mess: the message will be "unhandled trap 256". */
static void fixup_gdt_table(struct lguest *lg, unsigned start, unsigned end)
{
unsigned int i;
@@ -112,16 +70,6 @@
if (ignored_gdt(i))
continue;
- /* We could fault in switch_to_guest if they are using
- * a removed segment. */
- if (!segment_present(&lg->gdt[i])) {
- check_segment_use(lg, i);
- continue;
- }
-
- if (!desc_ok(&lg->gdt[i]))
- kill_guest(lg, "Bad GDT descriptor %i", i);
-
/* Segment descriptors contain a privilege level: the Guest is
* sometimes careless and leaves this as 0, even though it's
* running at privilege level 1. If so, we fix it here. */
diff --git a/drivers/lguest/switcher.S b/drivers/lguest/switcher.S
index d418179..7c9c230 100644
--- a/drivers/lguest/switcher.S
+++ b/drivers/lguest/switcher.S
@@ -47,6 +47,7 @@
// Down here in the depths of assembler code.
#include <linux/linkage.h>
#include <asm/asm-offsets.h>
+#include <asm/page.h>
#include "lg.h"
// We mark the start of the code to copy
@@ -182,13 +183,15 @@
movl $(LGUEST_DS), %eax; \
movl %eax, %ds; \
/* So where are we? Which CPU, which struct? \
- * The stack is our clue: our TSS sets \
- * It at the end of "struct lguest_pages" \
- * And we then pushed and pushed and pushed Guest regs: \
- * Now stack points atop the "struct lguest_regs". \
- * Subtract that offset, and we find our struct. */ \
+ * The stack is our clue: our TSS starts \
+ * It at the end of "struct lguest_pages". \
+ * Or we may have stumbled while restoring \
+ * Our Guest segment regs while in switch_to_guest, \
+ * The fault pushed atop that part-unwound stack. \
+ * If we round the stack down to the page start \
+ * We're at the start of "struct lguest_pages". */ \
movl %esp, %eax; \
- subl $LGUEST_PAGES_regs, %eax; \
+ andl $(~(1 << PAGE_SHIFT - 1)), %eax; \
/* Save our trap number: the switch will obscure it \
* (The Guest regs are not mapped here in the Host) \
* %ebx holds it safe for deliver_to_host */ \
diff --git a/drivers/macintosh/Kconfig b/drivers/macintosh/Kconfig
index dbe9626..56cd899 100644
--- a/drivers/macintosh/Kconfig
+++ b/drivers/macintosh/Kconfig
@@ -3,6 +3,11 @@
bool "Macintosh device drivers"
depends on PPC || MAC || X86
default y if (PPC_PMAC || MAC)
+ ---help---
+ Say Y here to get to see options for devices used with Macintosh
+ computers. This option alone does not add any kernel code.
+
+ If you say N, all options in this submenu will be skipped and disabled.
if MACINTOSH_DRIVERS
diff --git a/drivers/macintosh/mac_hid.c b/drivers/macintosh/mac_hid.c
index 76c1e8e..33dee3a 100644
--- a/drivers/macintosh/mac_hid.c
+++ b/drivers/macintosh/mac_hid.c
@@ -13,6 +13,7 @@
#include <linux/sysctl.h>
#include <linux/input.h>
#include <linux/module.h>
+#include <linux/kbd_kern.h>
static struct input_dev *emumousebtn;
diff --git a/drivers/macintosh/via-pmu68k.c b/drivers/macintosh/via-pmu68k.c
index dfdf11c..e2f84da 100644
--- a/drivers/macintosh/via-pmu68k.c
+++ b/drivers/macintosh/via-pmu68k.c
@@ -818,243 +818,3 @@
{
return (pmu_kind != PMU_UNKNOWN);
}
-
-#if 0 /* needs some work for 68K */
-
-/*
- * This struct is used to store config register values for
- * PCI devices which may get powered off when we sleep.
- */
-static struct pci_save {
- u16 command;
- u16 cache_lat;
- u16 intr;
-} *pbook_pci_saves;
-static int n_pbook_pci_saves;
-
-static inline void
-pbook_pci_save(void)
-{
- int npci;
- struct pci_dev *pd = NULL;
- struct pci_save *ps;
-
- npci = 0;
- while ((pd = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pd)) != NULL)
- ++npci;
- n_pbook_pci_saves = npci;
- if (npci == 0)
- return;
- ps = kmalloc(npci * sizeof(*ps), GFP_KERNEL);
- pbook_pci_saves = ps;
- if (ps == NULL)
- return;
-
- pd = NULL;
- while ((pd = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pd)) != NULL) {
- pci_read_config_word(pd, PCI_COMMAND, &ps->command);
- pci_read_config_word(pd, PCI_CACHE_LINE_SIZE, &ps->cache_lat);
- pci_read_config_word(pd, PCI_INTERRUPT_LINE, &ps->intr);
- ++ps;
- --npci;
- }
-}
-
-static inline void
-pbook_pci_restore(void)
-{
- u16 cmd;
- struct pci_save *ps = pbook_pci_saves;
- struct pci_dev *pd = NULL;
- int j;
-
- while ((pd = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pd)) != NULL) {
- if (ps->command == 0)
- continue;
- pci_read_config_word(pd, PCI_COMMAND, &cmd);
- if ((ps->command & ~cmd) == 0)
- continue;
- switch (pd->hdr_type) {
- case PCI_HEADER_TYPE_NORMAL:
- for (j = 0; j < 6; ++j)
- pci_write_config_dword(pd,
- PCI_BASE_ADDRESS_0 + j*4,
- pd->resource[j].start);
- pci_write_config_dword(pd, PCI_ROM_ADDRESS,
- pd->resource[PCI_ROM_RESOURCE].start);
- pci_write_config_word(pd, PCI_CACHE_LINE_SIZE,
- ps->cache_lat);
- pci_write_config_word(pd, PCI_INTERRUPT_LINE,
- ps->intr);
- pci_write_config_word(pd, PCI_COMMAND, ps->command);
- break;
- /* other header types not restored at present */
- }
- }
-}
-
-/*
- * Put the powerbook to sleep.
- */
-#define IRQ_ENABLE ((unsigned int *)0xf3000024)
-#define MEM_CTRL ((unsigned int *)0xf8000070)
-
-int powerbook_sleep(void)
-{
- int ret, i, x;
- static int save_backlight;
- static unsigned int save_irqen;
- unsigned long msr;
- unsigned int hid0;
- unsigned long p, wait;
- struct adb_request sleep_req;
-
- /* Notify device drivers */
- ret = blocking_notifier_call_chain(&sleep_notifier_list,
- PBOOK_SLEEP, NULL);
- if (ret & NOTIFY_STOP_MASK)
- return -EBUSY;
-
- /* Sync the disks. */
- /* XXX It would be nice to have some way to ensure that
- * nobody is dirtying any new buffers while we wait. */
- sys_sync();
-
- /* Turn off the display backlight */
- save_backlight = backlight_enabled;
- if (save_backlight)
- pmu_enable_backlight(0);
-
- /* Give the disks a little time to actually finish writing */
- for (wait = jiffies + (HZ/4); time_before(jiffies, wait); )
- mb();
-
- /* Disable all interrupts except pmu */
- save_irqen = in_le32(IRQ_ENABLE);
- for (i = 0; i < 32; ++i)
- if (i != vias->intrs[0].line && (save_irqen & (1 << i)))
- disable_irq(i);
- asm volatile("mtdec %0" : : "r" (0x7fffffff));
-
- /* Save the state of PCI config space for some slots */
- pbook_pci_save();
-
- /* Set the memory controller to keep the memory refreshed
- while we're asleep */
- for (i = 0x403f; i >= 0x4000; --i) {
- out_be32(MEM_CTRL, i);
- do {
- x = (in_be32(MEM_CTRL) >> 16) & 0x3ff;
- } while (x == 0);
- if (x >= 0x100)
- break;
- }
-
- /* Ask the PMU to put us to sleep */
- pmu_request(&sleep_req, NULL, 5, PMU_SLEEP, 'M', 'A', 'T', 'T');
- while (!sleep_req.complete)
- mb();
- /* displacement-flush the L2 cache - necessary? */
- for (p = KERNELBASE; p < KERNELBASE + 0x100000; p += 0x1000)
- i = *(volatile int *)p;
- asleep = 1;
-
- /* Put the CPU into sleep mode */
- asm volatile("mfspr %0,1008" : "=r" (hid0) :);
- hid0 = (hid0 & ~(HID0_NAP | HID0_DOZE)) | HID0_SLEEP;
- asm volatile("mtspr 1008,%0" : : "r" (hid0));
- local_save_flags(msr);
- msr |= MSR_POW | MSR_EE;
- local_irq_restore(msr);
- udelay(10);
-
- /* OK, we're awake again, start restoring things */
- out_be32(MEM_CTRL, 0x3f);
- pbook_pci_restore();
-
- /* wait for the PMU interrupt sequence to complete */
- while (asleep)
- mb();
-
- /* reenable interrupts */
- for (i = 0; i < 32; ++i)
- if (i != vias->intrs[0].line && (save_irqen & (1 << i)))
- enable_irq(i);
-
- /* Notify drivers */
- blocking_notifier_call_chain(&sleep_notifier_list, PBOOK_WAKE, NULL);
-
- /* reenable ADB autopoll */
- pmu_adb_autopoll(adb_dev_map);
-
- /* Turn on the screen backlight, if it was on before */
- if (save_backlight)
- pmu_enable_backlight(1);
-
- /* Wait for the hard disk to spin up */
-
- return 0;
-}
-
-/*
- * Support for /dev/pmu device
- */
-static int pmu_open(struct inode *inode, struct file *file)
-{
- return 0;
-}
-
-static ssize_t pmu_read(struct file *file, char *buf,
- size_t count, loff_t *ppos)
-{
- return 0;
-}
-
-static ssize_t pmu_write(struct file *file, const char *buf,
- size_t count, loff_t *ppos)
-{
- return 0;
-}
-
-static int pmu_ioctl(struct inode * inode, struct file *filp,
- u_int cmd, u_long arg)
-{
- int error;
- __u32 value;
-
- switch (cmd) {
- case PMU_IOC_SLEEP:
- return -ENOSYS;
- case PMU_IOC_GET_BACKLIGHT:
- return put_user(backlight_level, (__u32 *)arg);
- case PMU_IOC_SET_BACKLIGHT:
- error = get_user(value, (__u32 *)arg);
- if (!error)
- pmu_set_brightness(value);
- return error;
- case PMU_IOC_GET_MODEL:
- return put_user(pmu_kind, (__u32 *)arg);
- }
- return -EINVAL;
-}
-
-static const struct file_operations pmu_device_fops = {
- .read = pmu_read,
- .write = pmu_write,
- .ioctl = pmu_ioctl,
- .open = pmu_open,
-};
-
-static struct miscdevice pmu_device = {
- PMU_MINOR, "pmu", &pmu_device_fops
-};
-
-void pmu_device_init(void)
-{
- if (!via)
- return;
- if (misc_register(&pmu_device) < 0)
- printk(KERN_ERR "via-pmu68k: cannot register misc device.\n");
-}
-#endif /* CONFIG_PMAC_PBOOK */
-
diff --git a/drivers/md/Kconfig b/drivers/md/Kconfig
index 531d4d1..34a8c60 100644
--- a/drivers/md/Kconfig
+++ b/drivers/md/Kconfig
@@ -263,7 +263,7 @@
config DM_MULTIPATH_RDAC
tristate "LSI/Engenio RDAC multipath support (EXPERIMENTAL)"
- depends on DM_MULTIPATH && BLK_DEV_DM && EXPERIMENTAL
+ depends on DM_MULTIPATH && BLK_DEV_DM && SCSI && EXPERIMENTAL
---help---
Multipath support for LSI/Engenio RDAC.
diff --git a/drivers/md/dm.c b/drivers/md/dm.c
index 141ff9f..2120155 100644
--- a/drivers/md/dm.c
+++ b/drivers/md/dm.c
@@ -580,8 +580,8 @@
/* the bio has been remapped so dispatch it */
blk_add_trace_remap(bdev_get_queue(clone->bi_bdev), clone,
- tio->io->bio->bi_bdev->bd_dev, sector,
- clone->bi_sector);
+ tio->io->bio->bi_bdev->bd_dev,
+ clone->bi_sector, sector);
generic_make_request(clone);
} else if (r < 0 || r == DM_MAPIO_REQUEUE) {
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c
index 650991b..f33a729 100644
--- a/drivers/md/raid1.c
+++ b/drivers/md/raid1.c
@@ -1972,7 +1972,8 @@
!test_bit(In_sync, &disk->rdev->flags)) {
disk->head_position = 0;
mddev->degraded++;
- conf->fullsync = 1;
+ if (disk->rdev)
+ conf->fullsync = 1;
}
}
if (mddev->degraded == conf->raid_disks) {
@@ -2153,11 +2154,25 @@
oldpool = conf->r1bio_pool;
conf->r1bio_pool = newpool;
- for (d=d2=0; d < conf->raid_disks; d++)
- if (conf->mirrors[d].rdev) {
- conf->mirrors[d].rdev->raid_disk = d2;
- newmirrors[d2++].rdev = conf->mirrors[d].rdev;
+ for (d = d2 = 0; d < conf->raid_disks; d++) {
+ mdk_rdev_t *rdev = conf->mirrors[d].rdev;
+ if (rdev && rdev->raid_disk != d2) {
+ char nm[20];
+ sprintf(nm, "rd%d", rdev->raid_disk);
+ sysfs_remove_link(&mddev->kobj, nm);
+ rdev->raid_disk = d2;
+ sprintf(nm, "rd%d", rdev->raid_disk);
+ sysfs_remove_link(&mddev->kobj, nm);
+ if (sysfs_create_link(&mddev->kobj,
+ &rdev->kobj, nm))
+ printk(KERN_WARNING
+ "md/raid1: cannot register "
+ "%s for %s\n",
+ nm, mdname(mddev));
}
+ if (rdev)
+ newmirrors[d2++].rdev = rdev;
+ }
kfree(conf->mirrors);
conf->mirrors = newmirrors;
kfree(conf->poolinfo);
diff --git a/drivers/media/dvb/b2c2/flexcop-i2c.c b/drivers/media/dvb/b2c2/flexcop-i2c.c
index 02a0ea6..6bf858a 100644
--- a/drivers/media/dvb/b2c2/flexcop-i2c.c
+++ b/drivers/media/dvb/b2c2/flexcop-i2c.c
@@ -135,6 +135,13 @@
struct flexcop_device *fc = i2c_get_adapdata(i2c_adap);
int i, ret = 0;
+ /* Some drivers use 1 byte or 0 byte reads as probes, which this
+ * driver doesn't support. These probes will always fail, so this
+ * hack makes them always succeed. If one knew how, it would of
+ * course be better to actually do the read. */
+ if (num == 1 && msgs[0].flags == I2C_M_RD && msgs[0].len <= 1)
+ return 1;
+
if (mutex_lock_interruptible(&fc->i2c_mutex))
return -ERESTARTSYS;
diff --git a/drivers/media/dvb/dvb-core/dvb_net.c b/drivers/media/dvb/dvb-core/dvb_net.c
index acf0263..bdd7970 100644
--- a/drivers/media/dvb/dvb-core/dvb_net.c
+++ b/drivers/media/dvb/dvb-core/dvb_net.c
@@ -800,7 +800,8 @@
}
-static void dvb_net_sec(struct net_device *dev, u8 *pkt, int pkt_len)
+static void dvb_net_sec(struct net_device *dev, const u8 *pkt, int
+pkt_len)
{
u8 *eth;
struct sk_buff *skb;
@@ -902,7 +903,7 @@
* we rely on the DVB API definition where exactly one complete
* section is delivered in buffer1
*/
- dvb_net_sec (dev, (u8*) buffer1, buffer1_len);
+ dvb_net_sec (dev, buffer1, buffer1_len);
return 0;
}
diff --git a/drivers/media/dvb/frontends/dvb-pll.c b/drivers/media/dvb/frontends/dvb-pll.c
index ca99e43..11f7d59 100644
--- a/drivers/media/dvb/frontends/dvb-pll.c
+++ b/drivers/media/dvb/frontends/dvb-pll.c
@@ -784,7 +784,7 @@
strncpy(fe->ops.tuner_ops.info.name, desc->name,
sizeof(fe->ops.tuner_ops.info.name));
fe->ops.tuner_ops.info.frequency_min = desc->min;
- fe->ops.tuner_ops.info.frequency_min = desc->max;
+ fe->ops.tuner_ops.info.frequency_max = desc->max;
if (!desc->initdata)
fe->ops.tuner_ops.init = NULL;
if (!desc->sleepdata)
diff --git a/drivers/media/video/cafe_ccic.c b/drivers/media/video/cafe_ccic.c
index c08f650..ef53618 100644
--- a/drivers/media/video/cafe_ccic.c
+++ b/drivers/media/video/cafe_ccic.c
@@ -356,6 +356,7 @@
{
unsigned int rval;
unsigned long flags;
+ DEFINE_WAIT(the_wait);
spin_lock_irqsave(&cam->dev_lock, flags);
rval = TWSIC0_EN | ((addr << TWSIC0_SID_SHIFT) & TWSIC0_SID);
@@ -369,10 +370,29 @@
rval = value | ((command << TWSIC1_ADDR_SHIFT) & TWSIC1_ADDR);
cafe_reg_write(cam, REG_TWSIC1, rval);
spin_unlock_irqrestore(&cam->dev_lock, flags);
- msleep(2); /* Required or things flake */
+ /*
+ * Time to wait for the write to complete. THIS IS A RACY
+ * WAY TO DO IT, but the sad fact is that reading the TWSIC1
+ * register too quickly after starting the operation sends
+ * the device into a place that may be kinder and better, but
+ * which is absolutely useless for controlling the sensor. In
+ * practice we have plenty of time to get into our sleep state
+ * before the interrupt hits, and the worst case is that we
+ * time out and then see that things completed, so this seems
+ * the best way for now.
+ */
+ do {
+ prepare_to_wait(&cam->smbus_wait, &the_wait,
+ TASK_UNINTERRUPTIBLE);
+ schedule_timeout(1); /* even 1 jiffy is too long */
+ finish_wait(&cam->smbus_wait, &the_wait);
+ } while (!cafe_smbus_write_done(cam));
+
+#ifdef IF_THE_CAFE_HARDWARE_WORKED_RIGHT
wait_event_timeout(cam->smbus_wait, cafe_smbus_write_done(cam),
CAFE_SMBUS_TIMEOUT);
+#endif
spin_lock_irqsave(&cam->dev_lock, flags);
rval = cafe_reg_read(cam, REG_TWSIC1);
spin_unlock_irqrestore(&cam->dev_lock, flags);
@@ -710,7 +730,7 @@
* Here we must wait a bit for the controller to come around.
*/
spin_unlock_irqrestore(&cam->dev_lock, flags);
- mdelay(5); /* FIXME revisit this */
+ msleep(5);
spin_lock_irqsave(&cam->dev_lock, flags);
cafe_reg_write(cam, REG_GL_CSR, GCSR_CCIC_EN|GCSR_SRC|GCSR_MRC);
@@ -2233,12 +2253,21 @@
if (ret)
return ret;
ret = pci_enable_device(pdev);
+
if (ret) {
cam_warn(cam, "Unable to re-enable device on resume!\n");
return ret;
}
cafe_ctlr_init(cam);
- cafe_ctlr_power_up(cam);
+ cafe_ctlr_power_down(cam);
+
+ mutex_lock(&cam->s_mutex);
+ if (cam->users > 0) {
+ cafe_ctlr_power_up(cam);
+ __cafe_cam_reset(cam);
+ }
+ mutex_unlock(&cam->s_mutex);
+
set_bit(CF_CONFIG_NEEDED, &cam->flags);
if (cam->state == S_SPECREAD)
cam->state = S_IDLE; /* Don't bother restarting */
diff --git a/drivers/media/video/em28xx/em28xx-video.c b/drivers/media/video/em28xx/em28xx-video.c
index 2c7b158..40307f3 100644
--- a/drivers/media/video/em28xx/em28xx-video.c
+++ b/drivers/media/video/em28xx/em28xx-video.c
@@ -1772,6 +1772,7 @@
if (dev->alt_max_pkt_size == NULL) {
em28xx_errdev("out of memory!\n");
em28xx_devused&=~(1<<nr);
+ kfree(dev);
return -ENOMEM;
}
diff --git a/drivers/media/video/ivtv/ivtv-ioctl.c b/drivers/media/video/ivtv/ivtv-ioctl.c
index 047624b..5977a79 100644
--- a/drivers/media/video/ivtv/ivtv-ioctl.c
+++ b/drivers/media/video/ivtv/ivtv-ioctl.c
@@ -1190,6 +1190,7 @@
itv->osd_global_alpha_state = (fb->flags & V4L2_FBUF_FLAG_GLOBAL_ALPHA) != 0;
itv->osd_local_alpha_state = (fb->flags & V4L2_FBUF_FLAG_LOCAL_ALPHA) != 0;
itv->osd_color_key_state = (fb->flags & V4L2_FBUF_FLAG_CHROMAKEY) != 0;
+ ivtv_set_osd_alpha(itv);
break;
}
@@ -1234,7 +1235,7 @@
IVTV_INFO("Tuner: %s\n",
test_bit(IVTV_F_I_RADIO_USER, &itv->i_flags) ? "Radio" : "TV");
cx2341x_log_status(&itv->params, itv->name);
- IVTV_INFO("Status flags: 0x%08lx\n", itv->i_flags);
+ IVTV_INFO("Version: %s Status flags: 0x%08lx\n", IVTV_VERSION, itv->i_flags);
for (i = 0; i < IVTV_MAX_STREAMS; i++) {
struct ivtv_stream *s = &itv->streams[i];
diff --git a/drivers/media/video/ov7670.c b/drivers/media/video/ov7670.c
index f8f21dd..c4c5bd6 100644
--- a/drivers/media/video/ov7670.c
+++ b/drivers/media/video/ov7670.c
@@ -416,7 +416,10 @@
static int ov7670_write(struct i2c_client *c, unsigned char reg,
unsigned char value)
{
- return i2c_smbus_write_byte_data(c, reg, value);
+ int ret = i2c_smbus_write_byte_data(c, reg, value);
+ if (reg == REG_COM7 && (value & COM7_RESET))
+ msleep(2); /* Wait for reset to run */
+ return ret;
}
diff --git a/drivers/media/video/pwc/pwc-if.c b/drivers/media/video/pwc/pwc-if.c
index 9c0e8d1..3d81966 100644
--- a/drivers/media/video/pwc/pwc-if.c
+++ b/drivers/media/video/pwc/pwc-if.c
@@ -1196,12 +1196,19 @@
return 0;
}
+
+static void pwc_cleanup(struct pwc_device *pdev)
+{
+ pwc_remove_sysfs_files(pdev->vdev);
+ video_unregister_device(pdev->vdev);
+}
+
/* Note that all cleanup is done in the reverse order as in _open */
static int pwc_video_close(struct inode *inode, struct file *file)
{
struct video_device *vdev = file->private_data;
struct pwc_device *pdev;
- int i;
+ int i, hint;
PWC_DEBUG_OPEN(">> video_close called(vdev = 0x%p).\n", vdev);
@@ -1224,8 +1231,9 @@
pwc_isoc_cleanup(pdev);
pwc_free_buffers(pdev);
+ lock_kernel();
/* Turn off LEDS and power down camera, but only when not unplugged */
- if (pdev->error_status != EPIPE) {
+ if (!pdev->unplugged) {
/* Turn LEDs off */
if (pwc_set_leds(pdev, 0, 0) < 0)
PWC_DEBUG_MODULE("Failed to set LED on/off time.\n");
@@ -1234,9 +1242,19 @@
if (i < 0)
PWC_ERROR("Failed to power down camera (%d)\n", i);
}
+ pdev->vopen--;
+ PWC_DEBUG_OPEN("<< video_close() vopen=%d\n", i);
+ } else {
+ pwc_cleanup(pdev);
+ /* Free memory (don't set pdev to 0 just yet) */
+ kfree(pdev);
+ /* search device_hint[] table if we occupy a slot, by any chance */
+ for (hint = 0; hint < MAX_DEV_HINTS; hint++)
+ if (device_hint[hint].pdev == pdev)
+ device_hint[hint].pdev = NULL;
}
- pdev->vopen--;
- PWC_DEBUG_OPEN("<< video_close() vopen=%d\n", pdev->vopen);
+ unlock_kernel();
+
return 0;
}
@@ -1791,21 +1809,21 @@
/* Alert waiting processes */
wake_up_interruptible(&pdev->frameq);
/* Wait until device is closed */
- while (pdev->vopen)
- schedule();
- /* Device is now closed, so we can safely unregister it */
- PWC_DEBUG_PROBE("Unregistering video device in disconnect().\n");
- pwc_remove_sysfs_files(pdev->vdev);
- video_unregister_device(pdev->vdev);
-
- /* Free memory (don't set pdev to 0 just yet) */
- kfree(pdev);
+ if(pdev->vopen) {
+ pdev->unplugged = 1;
+ } else {
+ /* Device is closed, so we can safely unregister it */
+ PWC_DEBUG_PROBE("Unregistering video device in disconnect().\n");
+ pwc_cleanup(pdev);
+ /* Free memory (don't set pdev to 0 just yet) */
+ kfree(pdev);
disconnect_out:
- /* search device_hint[] table if we occupy a slot, by any chance */
- for (hint = 0; hint < MAX_DEV_HINTS; hint++)
- if (device_hint[hint].pdev == pdev)
- device_hint[hint].pdev = NULL;
+ /* search device_hint[] table if we occupy a slot, by any chance */
+ for (hint = 0; hint < MAX_DEV_HINTS; hint++)
+ if (device_hint[hint].pdev == pdev)
+ device_hint[hint].pdev = NULL;
+ }
unlock_kernel();
}
diff --git a/drivers/media/video/pwc/pwc.h b/drivers/media/video/pwc/pwc.h
index 910a04f..8e8e5b2 100644
--- a/drivers/media/video/pwc/pwc.h
+++ b/drivers/media/video/pwc/pwc.h
@@ -193,6 +193,7 @@
char vsnapshot; /* snapshot mode */
char vsync; /* used by isoc handler */
char vmirror; /* for ToUCaM series */
+ char unplugged;
int cmd_len;
unsigned char cmd_buf[13];
diff --git a/drivers/message/fusion/mptbase.c b/drivers/message/fusion/mptbase.c
index e866dac..414c109 100644
--- a/drivers/message/fusion/mptbase.c
+++ b/drivers/message/fusion/mptbase.c
@@ -88,7 +88,9 @@
MODULE_PARM_DESC(mpt_channel_mapping, " Mapping id's to channels (default=0)");
static int mpt_debug_level;
-module_param(mpt_debug_level, int, 0);
+static int mpt_set_debug_level(const char *val, struct kernel_param *kp);
+module_param_call(mpt_debug_level, mpt_set_debug_level, param_get_int,
+ &mpt_debug_level, 0600);
MODULE_PARM_DESC(mpt_debug_level, " debug level - refer to mptdebug.h - (default=0)");
#ifdef MFCNT
@@ -220,6 +222,19 @@
pci_write_config_word(pdev, PCI_COMMAND, command_reg);
}
+static int mpt_set_debug_level(const char *val, struct kernel_param *kp)
+{
+ int ret = param_set_int(val, kp);
+ MPT_ADAPTER *ioc;
+
+ if (ret)
+ return ret;
+
+ list_for_each_entry(ioc, &ioc_list, list)
+ ioc->debug_level = mpt_debug_level;
+ return 0;
+}
+
/*
* Process turbo (context) reply...
*/
diff --git a/drivers/message/fusion/mptsas.c b/drivers/message/fusion/mptsas.c
index 29add83..b9c69bf 100644
--- a/drivers/message/fusion/mptsas.c
+++ b/drivers/message/fusion/mptsas.c
@@ -1312,11 +1312,137 @@
return rc;
}
+static int mptsas_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy,
+ struct request *req)
+{
+ MPT_ADAPTER *ioc = ((MPT_SCSI_HOST *) shost->hostdata)->ioc;
+ MPT_FRAME_HDR *mf;
+ SmpPassthroughRequest_t *smpreq;
+ struct request *rsp = req->next_rq;
+ int ret;
+ int flagsLength;
+ unsigned long timeleft;
+ char *psge;
+ dma_addr_t dma_addr_in = 0;
+ dma_addr_t dma_addr_out = 0;
+ u64 sas_address = 0;
+
+ if (!rsp) {
+ printk(KERN_ERR "%s: the smp response space is missing\n",
+ __FUNCTION__);
+ return -EINVAL;
+ }
+
+ /* do we need to support multiple segments? */
+ if (req->bio->bi_vcnt > 1 || rsp->bio->bi_vcnt > 1) {
+ printk(KERN_ERR "%s: multiple segments req %u %u, rsp %u %u\n",
+ __FUNCTION__, req->bio->bi_vcnt, req->data_len,
+ rsp->bio->bi_vcnt, rsp->data_len);
+ return -EINVAL;
+ }
+
+ ret = mutex_lock_interruptible(&ioc->sas_mgmt.mutex);
+ if (ret)
+ goto out;
+
+ mf = mpt_get_msg_frame(mptsasMgmtCtx, ioc);
+ if (!mf) {
+ ret = -ENOMEM;
+ goto out_unlock;
+ }
+
+ smpreq = (SmpPassthroughRequest_t *)mf;
+ memset(smpreq, 0, sizeof(*smpreq));
+
+ smpreq->RequestDataLength = cpu_to_le16(req->data_len - 4);
+ smpreq->Function = MPI_FUNCTION_SMP_PASSTHROUGH;
+
+ if (rphy)
+ sas_address = rphy->identify.sas_address;
+ else {
+ struct mptsas_portinfo *port_info;
+
+ mutex_lock(&ioc->sas_topology_mutex);
+ port_info = mptsas_find_portinfo_by_handle(ioc, ioc->handle);
+ if (port_info && port_info->phy_info)
+ sas_address =
+ port_info->phy_info[0].phy->identify.sas_address;
+ mutex_unlock(&ioc->sas_topology_mutex);
+ }
+
+ *((u64 *)&smpreq->SASAddress) = cpu_to_le64(sas_address);
+
+ psge = (char *)
+ (((int *) mf) + (offsetof(SmpPassthroughRequest_t, SGL) / 4));
+
+ /* request */
+ flagsLength = (MPI_SGE_FLAGS_SIMPLE_ELEMENT |
+ MPI_SGE_FLAGS_END_OF_BUFFER |
+ MPI_SGE_FLAGS_DIRECTION |
+ mpt_addr_size()) << MPI_SGE_FLAGS_SHIFT;
+ flagsLength |= (req->data_len - 4);
+
+ dma_addr_out = pci_map_single(ioc->pcidev, bio_data(req->bio),
+ req->data_len, PCI_DMA_BIDIRECTIONAL);
+ if (!dma_addr_out)
+ goto put_mf;
+ mpt_add_sge(psge, flagsLength, dma_addr_out);
+ psge += (sizeof(u32) + sizeof(dma_addr_t));
+
+ /* response */
+ flagsLength = MPT_SGE_FLAGS_SSIMPLE_READ;
+ flagsLength |= rsp->data_len + 4;
+ dma_addr_in = pci_map_single(ioc->pcidev, bio_data(rsp->bio),
+ rsp->data_len, PCI_DMA_BIDIRECTIONAL);
+ if (!dma_addr_in)
+ goto unmap;
+ mpt_add_sge(psge, flagsLength, dma_addr_in);
+
+ mpt_put_msg_frame(mptsasMgmtCtx, ioc, mf);
+
+ timeleft = wait_for_completion_timeout(&ioc->sas_mgmt.done, 10 * HZ);
+ if (!timeleft) {
+ printk(KERN_ERR "%s: smp timeout!\n", __FUNCTION__);
+ /* On timeout reset the board */
+ mpt_HardResetHandler(ioc, CAN_SLEEP);
+ ret = -ETIMEDOUT;
+ goto unmap;
+ }
+ mf = NULL;
+
+ if (ioc->sas_mgmt.status & MPT_IOCTL_STATUS_RF_VALID) {
+ SmpPassthroughReply_t *smprep;
+
+ smprep = (SmpPassthroughReply_t *)ioc->sas_mgmt.reply;
+ memcpy(req->sense, smprep, sizeof(*smprep));
+ req->sense_len = sizeof(*smprep);
+ } else {
+ printk(KERN_ERR "%s: smp passthru reply failed to be returned\n",
+ __FUNCTION__);
+ ret = -ENXIO;
+ }
+unmap:
+ if (dma_addr_out)
+ pci_unmap_single(ioc->pcidev, dma_addr_out, req->data_len,
+ PCI_DMA_BIDIRECTIONAL);
+ if (dma_addr_in)
+ pci_unmap_single(ioc->pcidev, dma_addr_in, rsp->data_len,
+ PCI_DMA_BIDIRECTIONAL);
+put_mf:
+ if (mf)
+ mpt_free_msg_frame(ioc, mf);
+out_unlock:
+ mutex_unlock(&ioc->sas_mgmt.mutex);
+out:
+ return ret;
+}
+
static struct sas_function_template mptsas_transport_functions = {
.get_linkerrors = mptsas_get_linkerrors,
.get_enclosure_identifier = mptsas_get_enclosure_identifier,
.get_bay_identifier = mptsas_get_bay_identifier,
.phy_reset = mptsas_phy_reset,
+ .smp_handler = mptsas_smp_handler,
};
static struct scsi_transport_template *mptsas_transport_template;
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index aaaa61e..a266558 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -5,6 +5,11 @@
menuconfig MISC_DEVICES
bool "Misc devices"
default y
+ ---help---
+ Say Y here to get to see options for device drivers from various
+ different categories. This option alone does not add any kernel code.
+
+ If you say N, all options in this submenu will be skipped and disabled.
if MISC_DEVICES
@@ -200,14 +205,22 @@
config THINKPAD_ACPI_INPUT_ENABLED
bool "Enable input layer support by default"
depends on THINKPAD_ACPI
- default y
+ default n
---help---
- Enables hot key handling over the input layer by default. If unset,
- the driver does not enable any hot key handling by default, and also
- starts up with a mostly empty keymap.
+ This option enables thinkpad-acpi hot key handling over the input
+ layer at driver load time. When it is unset, the driver does not
+ enable hot key handling by default, and also starts up with a mostly
+ empty keymap.
- If you are not sure, say Y here. Say N to retain the deprecated
- behavior of ibm-acpi, and thinkpad-acpi for kernels up to 2.6.21.
+ This option should be enabled if you have a new enough HAL or other
+ userspace support that properly handles the thinkpad-acpi event
+ device. It auto-tunes the hot key support to those reported by the
+ firmware and enables it automatically.
+
+ If unsure, say N here to retain the old behaviour of ibm-acpi, and
+ thinkpad-acpi up to kernel 2.6.21: userspace will have to enable and
+ set up the thinkpad-acpi hot key handling using the sysfs interace
+ after loading the driver.
endif # MISC_DEVICES
diff --git a/drivers/misc/asus-laptop.c b/drivers/misc/asus-laptop.c
index d0fc4fd..7dce318 100644
--- a/drivers/misc/asus-laptop.c
+++ b/drivers/misc/asus-laptop.c
@@ -732,7 +732,7 @@
lcd_blank(FB_BLANK_POWERDOWN);
}
- acpi_bus_generate_event(hotk->device, event,
+ acpi_bus_generate_proc_event(hotk->device, event,
hotk->event_count[event % 128]++);
return;
@@ -1072,7 +1072,8 @@
}
#define ASUS_LED_UNREGISTER(object) \
- led_classdev_unregister(&object##_led)
+ if (object##_led.dev) \
+ led_classdev_unregister(&object##_led)
static void asus_led_exit(void)
{
diff --git a/drivers/misc/sony-laptop.c b/drivers/misc/sony-laptop.c
index 14ee06c..d38ddce 100644
--- a/drivers/misc/sony-laptop.c
+++ b/drivers/misc/sony-laptop.c
@@ -845,7 +845,7 @@
};
/* SNC-only model map */
-struct dmi_system_id sony_nc_ids[] = {
+static struct dmi_system_id sony_nc_ids[] = {
{
.ident = "Sony Vaio FE Series",
.callback = sony_nc_C_enable,
@@ -856,6 +856,15 @@
},
},
{
+ .ident = "Sony Vaio FZ Series",
+ .callback = sony_nc_C_enable,
+ .driver_data = sony_C_events,
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "VGN-FZ"),
+ },
+ },
+ {
.ident = "Sony Vaio C Series",
.callback = sony_nc_C_enable,
.driver_data = sony_C_events,
@@ -904,7 +913,7 @@
dprintk("sony_acpi_notify, event: 0x%.2x\n", ev);
sony_laptop_report_input_event(ev);
- acpi_bus_generate_event(sony_nc_acpi_device, 1, ev);
+ acpi_bus_generate_proc_event(sony_nc_acpi_device, 1, ev);
}
static acpi_status sony_walk_callback(acpi_handle handle, u32 level,
@@ -942,6 +951,11 @@
}
}
+ /* set the last requested brightness level */
+ if (sony_backlight_device &&
+ !sony_backlight_update_status(sony_backlight_device))
+ printk(KERN_WARNING DRV_PFX "unable to restore brightness level");
+
/* re-initialize models with specific requirements */
dmi_check_system(sony_nc_ids);
@@ -2287,7 +2301,7 @@
found:
sony_laptop_report_input_event(device_event);
- acpi_bus_generate_event(spic_dev.acpi_dev, 1, device_event);
+ acpi_bus_generate_proc_event(spic_dev.acpi_dev, 1, device_event);
sonypi_compat_report_event(device_event);
return IRQ_HANDLED;
@@ -2303,8 +2317,6 @@
struct sony_pic_ioport *io, *tmp_io;
struct sony_pic_irq *irq, *tmp_irq;
- sonypi_compat_exit();
-
if (sony_pic_disable(device)) {
printk(KERN_ERR DRV_PFX "Couldn't disable device.\n");
return -ENXIO;
@@ -2314,6 +2326,8 @@
release_region(spic_dev.cur_ioport->io.minimum,
spic_dev.cur_ioport->io.address_length);
+ sonypi_compat_exit();
+
sony_laptop_remove_input();
/* pf attrs */
@@ -2379,6 +2393,9 @@
goto err_free_resources;
}
+ if (sonypi_compat_init())
+ goto err_remove_input;
+
/* request io port */
list_for_each_entry(io, &spic_dev.ioports, list) {
if (request_region(io->io.minimum, io->io.address_length,
@@ -2393,7 +2410,7 @@
if (!spic_dev.cur_ioport) {
printk(KERN_ERR DRV_PFX "Failed to request_region.\n");
result = -ENODEV;
- goto err_remove_input;
+ goto err_remove_compat;
}
/* request IRQ */
@@ -2433,9 +2450,6 @@
if (result)
goto err_remove_pf;
- if (sonypi_compat_init())
- goto err_remove_pf;
-
return 0;
err_remove_pf:
@@ -2451,6 +2465,9 @@
release_region(spic_dev.cur_ioport->io.minimum,
spic_dev.cur_ioport->io.address_length);
+err_remove_compat:
+ sonypi_compat_exit();
+
err_remove_input:
sony_laptop_remove_input();
diff --git a/drivers/misc/thinkpad_acpi.c b/drivers/misc/thinkpad_acpi.c
index fa80f35..bb8956d 100644
--- a/drivers/misc/thinkpad_acpi.c
+++ b/drivers/misc/thinkpad_acpi.c
@@ -1190,10 +1190,10 @@
}
if (sendacpi)
- acpi_bus_generate_event(ibm->acpi->device, event, hkey);
+ acpi_bus_generate_proc_event(ibm->acpi->device, event, hkey);
} else {
printk(IBM_ERR "unknown hotkey notification event %d\n", event);
- acpi_bus_generate_event(ibm->acpi->device, event, 0);
+ acpi_bus_generate_proc_event(ibm->acpi->device, event, 0);
}
}
@@ -2162,22 +2162,27 @@
int docked = dock_docked();
int pci = ibm->acpi->hid && ibm->acpi->device &&
acpi_match_device_ids(ibm->acpi->device, ibm_pci_device_ids);
+ int data;
if (event == 1 && !pci) /* 570 */
- acpi_bus_generate_event(ibm->acpi->device, event, 1); /* button */
+ data = 1; /* button */
else if (event == 1 && pci) /* 570 */
- acpi_bus_generate_event(ibm->acpi->device, event, 3); /* dock */
+ data = 3; /* dock */
else if (event == 3 && docked)
- acpi_bus_generate_event(ibm->acpi->device, event, 1); /* button */
+ data = 1; /* button */
else if (event == 3 && !docked)
- acpi_bus_generate_event(ibm->acpi->device, event, 2); /* undock */
+ data = 2; /* undock */
else if (event == 0 && docked)
- acpi_bus_generate_event(ibm->acpi->device, event, 3); /* dock */
+ data = 3; /* dock */
else {
printk(IBM_ERR "unknown dock event %d, status %d\n",
event, _sta(dock_handle));
- acpi_bus_generate_event(ibm->acpi->device, event, 0); /* unknown */
+ data = 0; /* unknown */
}
+ acpi_bus_generate_proc_event(ibm->acpi->device, event, data);
+ acpi_bus_generate_netlink_event(ibm->acpi->device->pnp.device_class,
+ ibm->acpi->device->dev.bus_id,
+ event, data);
}
static int dock_read(char *p)
@@ -2275,7 +2280,10 @@
static void bay_notify(struct ibm_struct *ibm, u32 event)
{
- acpi_bus_generate_event(ibm->acpi->device, event, 0);
+ acpi_bus_generate_proc_event(ibm->acpi->device, event, 0);
+ acpi_bus_generate_netlink_event(ibm->acpi->device->pnp.device_class,
+ ibm->acpi->device->dev.bus_id,
+ event, 0);
}
#define bay_occupied(b) (_sta(b##_handle) & 1)
@@ -4668,12 +4676,15 @@
thinkpad_acpi_module_exit();
return ret;
}
+ tp_features.platform_drv_registered = 1;
+
ret = tpacpi_create_driver_attributes(&tpacpi_pdriver.driver);
if (ret) {
printk(IBM_ERR "unable to create sysfs driver attributes\n");
thinkpad_acpi_module_exit();
return ret;
}
+ tp_features.platform_drv_attrs_registered = 1;
/* Device initialization */
@@ -4756,8 +4767,11 @@
if (tpacpi_pdev)
platform_device_unregister(tpacpi_pdev);
- tpacpi_remove_driver_attributes(&tpacpi_pdriver.driver);
- platform_driver_unregister(&tpacpi_pdriver);
+ if (tp_features.platform_drv_attrs_registered)
+ tpacpi_remove_driver_attributes(&tpacpi_pdriver.driver);
+
+ if (tp_features.platform_drv_registered)
+ platform_driver_unregister(&tpacpi_pdriver);
if (proc_dir)
remove_proc_entry(IBM_PROC_DIR, acpi_root_dir);
diff --git a/drivers/misc/thinkpad_acpi.h b/drivers/misc/thinkpad_acpi.h
index 88af089..eee8809 100644
--- a/drivers/misc/thinkpad_acpi.h
+++ b/drivers/misc/thinkpad_acpi.h
@@ -246,6 +246,8 @@
u16 wan:1;
u16 fan_ctrl_status_undef:1;
u16 input_device_registered:1;
+ u16 platform_drv_registered:1;
+ u16 platform_drv_attrs_registered:1;
} tp_features;
struct thinkpad_id_data {
diff --git a/drivers/mmc/card/queue.c b/drivers/mmc/card/queue.c
index c9a289c..b0abc7d 100644
--- a/drivers/mmc/card/queue.c
+++ b/drivers/mmc/card/queue.c
@@ -117,7 +117,6 @@
struct mmc_host *host = card->host;
u64 limit = BLK_BOUNCE_HIGH;
int ret;
- unsigned int bouncesz;
if (mmc_dev(host)->dma_mask && *mmc_dev(host)->dma_mask)
limit = *mmc_dev(host)->dma_mask;
@@ -134,6 +133,8 @@
#ifdef CONFIG_MMC_BLOCK_BOUNCE
if (host->max_hw_segs == 1) {
+ unsigned int bouncesz;
+
bouncesz = MMC_QUEUE_BOUNCESZ;
if (bouncesz > host->max_req_size)
@@ -156,14 +157,14 @@
GFP_KERNEL);
if (!mq->sg) {
ret = -ENOMEM;
- goto free_bounce_buf;
+ goto cleanup_queue;
}
mq->bounce_sg = kmalloc(sizeof(struct scatterlist) *
bouncesz / 512, GFP_KERNEL);
if (!mq->bounce_sg) {
ret = -ENOMEM;
- goto free_sg;
+ goto cleanup_queue;
}
}
}
@@ -197,14 +198,13 @@
if (mq->bounce_sg)
kfree(mq->bounce_sg);
mq->bounce_sg = NULL;
- free_sg:
- kfree(mq->sg);
+ cleanup_queue:
+ if (mq->sg)
+ kfree(mq->sg);
mq->sg = NULL;
- free_bounce_buf:
if (mq->bounce_buf)
kfree(mq->bounce_buf);
mq->bounce_buf = NULL;
- cleanup_queue:
blk_cleanup_queue(mq->queue);
return ret;
}
diff --git a/drivers/mmc/core/bus.c b/drivers/mmc/core/bus.c
index fe0e785..817a794 100644
--- a/drivers/mmc/core/bus.c
+++ b/drivers/mmc/core/bus.c
@@ -186,12 +186,10 @@
{
struct mmc_card *card;
- card = kmalloc(sizeof(struct mmc_card), GFP_KERNEL);
+ card = kzalloc(sizeof(struct mmc_card), GFP_KERNEL);
if (!card)
return ERR_PTR(-ENOMEM);
- memset(card, 0, sizeof(struct mmc_card));
-
card->host = host;
device_initialize(&card->dev);
diff --git a/drivers/mmc/core/host.c b/drivers/mmc/core/host.c
index 6a7e298..2c7ce8f 100644
--- a/drivers/mmc/core/host.c
+++ b/drivers/mmc/core/host.c
@@ -58,12 +58,10 @@
{
struct mmc_host *host;
- host = kmalloc(sizeof(struct mmc_host) + extra, GFP_KERNEL);
+ host = kzalloc(sizeof(struct mmc_host) + extra, GFP_KERNEL);
if (!host)
return NULL;
- memset(host, 0, sizeof(struct mmc_host) + extra);
-
host->parent = dev;
host->class_dev.parent = dev;
host->class_dev.class = &mmc_host_class;
diff --git a/drivers/mmc/host/at91_mci.c b/drivers/mmc/host/at91_mci.c
index 62564cc..bfebd2f 100644
--- a/drivers/mmc/host/at91_mci.c
+++ b/drivers/mmc/host/at91_mci.c
@@ -83,7 +83,7 @@
#define AT91_MCI_ERRORS (AT91_MCI_RINDE | AT91_MCI_RDIRE | AT91_MCI_RCRCE \
| AT91_MCI_RENDE | AT91_MCI_RTOE | AT91_MCI_DCRCE \
- | AT91_MCI_DTOE | AT91_MCI_OVRE | AT91_MCI_UNRE)
+ | AT91_MCI_DTOE | AT91_MCI_OVRE | AT91_MCI_UNRE)
#define at91_mci_read(host, reg) __raw_readl((host)->baseaddr + (reg))
#define at91_mci_write(host, reg, val) __raw_writel((val), (host)->baseaddr + (reg))
@@ -676,15 +676,15 @@
int_status = at91_mci_read(host, AT91_MCI_SR);
int_mask = at91_mci_read(host, AT91_MCI_IMR);
-
+
pr_debug("MCI irq: status = %08X, %08X, %08X\n", int_status, int_mask,
int_status & int_mask);
-
+
int_status = int_status & int_mask;
if (int_status & AT91_MCI_ERRORS) {
completed = 1;
-
+
if (int_status & AT91_MCI_UNRE)
pr_debug("MMC: Underrun error\n");
if (int_status & AT91_MCI_OVRE)
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index f2bc87a..20a7d89 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -385,6 +385,9 @@
BUG_ON(data->blksz > host->mmc->max_blk_size);
BUG_ON(data->blocks > 65535);
+ host->data = data;
+ host->data_early = 0;
+
/* timeout in us */
target_timeout = data->timeout_ns / 1000 +
data->timeout_clks / host->clock;
@@ -443,11 +446,11 @@
{
u16 mode;
- WARN_ON(host->data);
-
if (data == NULL)
return;
+ WARN_ON(!host->data);
+
mode = SDHCI_TRNS_BLK_CNT_EN;
if (data->blocks > 1)
mode |= SDHCI_TRNS_MULTI;
@@ -477,8 +480,8 @@
/*
* Controller doesn't count down when in single block mode.
*/
- if ((data->blocks == 1) && (data->error == MMC_ERR_NONE))
- blocks = 0;
+ if (data->blocks == 1)
+ blocks = (data->error == MMC_ERR_NONE) ? 0 : 1;
else
blocks = readw(host->ioaddr + SDHCI_BLOCK_COUNT);
data->bytes_xfered = data->blksz * (data->blocks - blocks);
@@ -600,9 +603,10 @@
host->cmd->error = MMC_ERR_NONE;
- if (host->cmd->data)
- host->data = host->cmd->data;
- else
+ if (host->data && host->data_early)
+ sdhci_finish_data(host);
+
+ if (!host->cmd->data)
tasklet_schedule(&host->finish_tasklet);
host->cmd = NULL;
@@ -929,9 +933,9 @@
BUG_ON(intmask == 0);
if (!host->cmd) {
- printk(KERN_ERR "%s: Got command interrupt even though no "
- "command operation was in progress.\n",
- mmc_hostname(host->mmc));
+ printk(KERN_ERR "%s: Got command interrupt 0x%08x even "
+ "though no command operation was in progress.\n",
+ mmc_hostname(host->mmc), (unsigned)intmask);
sdhci_dumpregs(host);
return;
}
@@ -961,9 +965,9 @@
if (intmask & SDHCI_INT_DATA_END)
return;
- printk(KERN_ERR "%s: Got data interrupt even though no "
- "data operation was in progress.\n",
- mmc_hostname(host->mmc));
+ printk(KERN_ERR "%s: Got data interrupt 0x%08x even "
+ "though no data operation was in progress.\n",
+ mmc_hostname(host->mmc), (unsigned)intmask);
sdhci_dumpregs(host);
return;
@@ -991,8 +995,18 @@
writel(readl(host->ioaddr + SDHCI_DMA_ADDRESS),
host->ioaddr + SDHCI_DMA_ADDRESS);
- if (intmask & SDHCI_INT_DATA_END)
- sdhci_finish_data(host);
+ if (intmask & SDHCI_INT_DATA_END) {
+ if (host->cmd) {
+ /*
+ * Data managed to finish before the
+ * command completed. Make sure we do
+ * things in the proper order.
+ */
+ host->data_early = 1;
+ } else {
+ sdhci_finish_data(host);
+ }
+ }
}
}
@@ -1347,12 +1361,11 @@
*/
mmc->max_blk_size = (caps & SDHCI_MAX_BLOCK_MASK) >> SDHCI_MAX_BLOCK_SHIFT;
if (mmc->max_blk_size >= 3) {
- printk(KERN_ERR "%s: Invalid maximum block size.\n",
+ printk(KERN_WARNING "%s: Invalid maximum block size, assuming 512\n",
host->slot_descr);
- ret = -ENODEV;
- goto unmap;
- }
- mmc->max_blk_size = 512 << mmc->max_blk_size;
+ mmc->max_blk_size = 512;
+ } else
+ mmc->max_blk_size = 512 << mmc->max_blk_size;
/*
* Maximum block count.
diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h
index d157776..e28987d 100644
--- a/drivers/mmc/host/sdhci.h
+++ b/drivers/mmc/host/sdhci.h
@@ -182,6 +182,7 @@
struct mmc_request *mrq; /* Current request */
struct mmc_command *cmd; /* Current command */
struct mmc_data *data; /* Current data request */
+ int data_early:1; /* Data finished before cmd */
struct scatterlist *cur_sg; /* We're working on this */
int num_sg; /* Entries left */
diff --git a/drivers/mmc/host/wbsd.c b/drivers/mmc/host/wbsd.c
index e0c9808..9bf2a87 100644
--- a/drivers/mmc/host/wbsd.c
+++ b/drivers/mmc/host/wbsd.c
@@ -1266,7 +1266,7 @@
return 0;
}
-static void __devexit wbsd_free_mmc(struct device *dev)
+static void wbsd_free_mmc(struct device *dev)
{
struct mmc_host *mmc;
struct wbsd_host *host;
@@ -1358,7 +1358,7 @@
return 0;
}
-static void __devexit wbsd_release_regions(struct wbsd_host *host)
+static void wbsd_release_regions(struct wbsd_host *host)
{
if (host->base)
release_region(host->base, 8);
@@ -1434,7 +1434,7 @@
"Falling back on FIFO.\n", dma);
}
-static void __devexit wbsd_release_dma(struct wbsd_host *host)
+static void wbsd_release_dma(struct wbsd_host *host)
{
if (host->dma_addr) {
dma_unmap_single(mmc_dev(host->mmc), host->dma_addr,
@@ -1484,7 +1484,7 @@
return 0;
}
-static void __devexit wbsd_release_irq(struct wbsd_host *host)
+static void wbsd_release_irq(struct wbsd_host *host)
{
if (!host->irq)
return;
@@ -1535,7 +1535,7 @@
* Release all resources for the host.
*/
-static void __devexit wbsd_release_resources(struct wbsd_host *host)
+static void wbsd_release_resources(struct wbsd_host *host)
{
wbsd_release_dma(host);
wbsd_release_irq(host);
diff --git a/drivers/mtd/mtdchar.c b/drivers/mtd/mtdchar.c
index 8c86b80..d091b24 100644
--- a/drivers/mtd/mtdchar.c
+++ b/drivers/mtd/mtdchar.c
@@ -7,6 +7,7 @@
#include <linux/device.h>
#include <linux/fs.h>
+#include <linux/mm.h>
#include <linux/err.h>
#include <linux/init.h>
#include <linux/kernel.h>
diff --git a/drivers/net/3c59x.c b/drivers/net/3c59x.c
index 001c66d..a8c0f43 100644
--- a/drivers/net/3c59x.c
+++ b/drivers/net/3c59x.c
@@ -1555,6 +1555,7 @@
mii_reg1 = mdio_read(dev, vp->phys[0], MII_BMSR);
mii_reg5 = mdio_read(dev, vp->phys[0], MII_LPA);
vp->partner_flow_ctrl = ((mii_reg5 & 0x0400) != 0);
+ vp->mii.full_duplex = vp->full_duplex;
vortex_check_media(dev, 1);
}
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index 81ef81c..5b9e17b 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -1968,6 +1968,16 @@
bool "Ethernet (1000 Mbit)"
depends on !UML
default y
+ ---help---
+ Ethernet (also called IEEE 802.3 or ISO 8802-2) is the most common
+ type of Local Area Network (LAN) in universities and companies.
+
+ Say Y here to get to see options for Gigabit Ethernet drivers.
+ This option alone does not add any kernel code.
+ Note that drivers supporting both 100 and 1000 MBit may be listed
+ under "Ethernet (10 or 100MBit)" instead.
+
+ If you say N, all options in this submenu will be skipped and disabled.
if NETDEV_1000
@@ -2339,6 +2349,11 @@
bool "Ethernet (10000 Mbit)"
depends on !UML
default y
+ ---help---
+ Say Y here to get to see options for 10 Gigabit Ethernet drivers.
+ This option alone does not add any kernel code.
+
+ If you say N, all options in this submenu will be skipped and disabled.
if NETDEV_10000
diff --git a/drivers/net/atl1/atl1_main.c b/drivers/net/atl1/atl1_main.c
index 56f6389..3c1984e 100644
--- a/drivers/net/atl1/atl1_main.c
+++ b/drivers/net/atl1/atl1_main.c
@@ -1704,10 +1704,8 @@
}
}
- local_irq_save(flags);
- if (!spin_trylock(&adapter->lock)) {
+ if (!spin_trylock_irqsave(&adapter->lock, flags)) {
/* Can't get lock - tell upper layer to requeue */
- local_irq_restore(flags);
dev_printk(KERN_DEBUG, &adapter->pdev->dev, "tx locked\n");
return NETDEV_TX_LOCKED;
}
diff --git a/drivers/net/ax88796.c b/drivers/net/ax88796.c
index 83da177..90e0734 100644
--- a/drivers/net/ax88796.c
+++ b/drivers/net/ax88796.c
@@ -821,8 +821,9 @@
dev->base_addr = (unsigned long)ei_status.mem;
if (ei_status.mem == NULL) {
- dev_err(&pdev->dev, "Cannot ioremap area (%08zx,%08zx)\n",
- res->start, res->end);
+ dev_err(&pdev->dev, "Cannot ioremap area (%08llx,%08llx)\n",
+ (unsigned long long)res->start,
+ (unsigned long long)res->end);
ret = -ENXIO;
goto exit_req;
diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c
index d53dfc5..24e7f9a 100644
--- a/drivers/net/bnx2.c
+++ b/drivers/net/bnx2.c
@@ -54,8 +54,8 @@
#define DRV_MODULE_NAME "bnx2"
#define PFX DRV_MODULE_NAME ": "
-#define DRV_MODULE_VERSION "1.6.3"
-#define DRV_MODULE_RELDATE "July 16, 2007"
+#define DRV_MODULE_VERSION "1.6.4"
+#define DRV_MODULE_RELDATE "August 3, 2007"
#define RUN_AT(x) (jiffies + (x))
@@ -6937,6 +6937,11 @@
struct bnx2 *bp = netdev_priv(dev);
u32 reset_code;
+ /* PCI register 4 needs to be saved whether netif_running() or not.
+ * MSI address and data need to be saved if using MSI and
+ * netif_running().
+ */
+ pci_save_state(pdev);
if (!netif_running(dev))
return 0;
@@ -6952,7 +6957,6 @@
reset_code = BNX2_DRV_MSG_CODE_SUSPEND_NO_WOL;
bnx2_reset_chip(bp, reset_code);
bnx2_free_skbs(bp);
- pci_save_state(pdev);
bnx2_set_power_state(bp, pci_choose_state(pdev, state));
return 0;
}
@@ -6963,10 +6967,10 @@
struct net_device *dev = pci_get_drvdata(pdev);
struct bnx2 *bp = netdev_priv(dev);
+ pci_restore_state(pdev);
if (!netif_running(dev))
return 0;
- pci_restore_state(pdev);
bnx2_set_power_state(bp, PCI_D0);
netif_device_attach(dev);
bnx2_init_nic(bp);
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index 070b78d..1afda32 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -1202,43 +1202,35 @@
return 0;
}
-#define BOND_INTERSECT_FEATURES \
- (NETIF_F_SG | NETIF_F_ALL_CSUM | NETIF_F_TSO | NETIF_F_UFO)
+#define BOND_VLAN_FEATURES \
+ (NETIF_F_VLAN_CHALLENGED | NETIF_F_HW_VLAN_RX | NETIF_F_HW_VLAN_TX | \
+ NETIF_F_HW_VLAN_FILTER)
/*
* Compute the common dev->feature set available to all slaves. Some
- * feature bits are managed elsewhere, so preserve feature bits set on
- * master device that are not part of the examined set.
+ * feature bits are managed elsewhere, so preserve those feature bits
+ * on the master device.
*/
static int bond_compute_features(struct bonding *bond)
{
- unsigned long features = BOND_INTERSECT_FEATURES;
struct slave *slave;
struct net_device *bond_dev = bond->dev;
+ unsigned long features = bond_dev->features;
unsigned short max_hard_header_len = ETH_HLEN;
int i;
+ features &= ~(NETIF_F_ALL_CSUM | BOND_VLAN_FEATURES);
+ features |= NETIF_F_SG | NETIF_F_FRAGLIST | NETIF_F_HIGHDMA |
+ NETIF_F_GSO_MASK | NETIF_F_NO_CSUM;
+
bond_for_each_slave(bond, slave, i) {
- features &= (slave->dev->features & BOND_INTERSECT_FEATURES);
+ features = netdev_compute_features(features,
+ slave->dev->features);
if (slave->dev->hard_header_len > max_hard_header_len)
max_hard_header_len = slave->dev->hard_header_len;
}
- if ((features & NETIF_F_SG) &&
- !(features & NETIF_F_ALL_CSUM))
- features &= ~NETIF_F_SG;
-
- /*
- * features will include NETIF_F_TSO (NETIF_F_UFO) iff all
- * slave devices support NETIF_F_TSO (NETIF_F_UFO), which
- * implies that all slaves also support scatter-gather
- * (NETIF_F_SG), which implies that features also includes
- * NETIF_F_SG. So no need to check whether we have an
- * illegal combination of NETIF_F_{TSO,UFO} and
- * !NETIF_F_SG
- */
-
- features |= (bond_dev->features & ~BOND_INTERSECT_FEATURES);
+ features |= (bond_dev->features & BOND_VLAN_FEATURES);
bond_dev->features = features;
bond_dev->hard_header_len = max_hard_header_len;
diff --git a/drivers/net/dm9000.c b/drivers/net/dm9000.c
index c3de81b..738aa59 100644
--- a/drivers/net/dm9000.c
+++ b/drivers/net/dm9000.c
@@ -700,6 +700,7 @@
static int
dm9000_start_xmit(struct sk_buff *skb, struct net_device *dev)
{
+ unsigned long flags;
board_info_t *db = (board_info_t *) dev->priv;
PRINTK3("dm9000_start_xmit\n");
@@ -707,10 +708,7 @@
if (db->tx_pkt_cnt > 1)
return 1;
- netif_stop_queue(dev);
-
- /* Disable all interrupts */
- iow(db, DM9000_IMR, IMR_PAR);
+ spin_lock_irqsave(&db->lock, flags);
/* Move data to DM9000 TX RAM */
writeb(DM9000_MWCMD, db->io_addr);
@@ -718,12 +716,9 @@
(db->outblk)(db->io_data, skb->data, skb->len);
db->stats.tx_bytes += skb->len;
+ db->tx_pkt_cnt++;
/* TX control: First packet immediately send, second packet queue */
- if (db->tx_pkt_cnt == 0) {
-
- /* First Packet */
- db->tx_pkt_cnt++;
-
+ if (db->tx_pkt_cnt == 1) {
/* Set TX length to DM9000 */
iow(db, DM9000_TXPLL, skb->len & 0xff);
iow(db, DM9000_TXPLH, (skb->len >> 8) & 0xff);
@@ -732,23 +727,17 @@
iow(db, DM9000_TCR, TCR_TXREQ); /* Cleared after TX complete */
dev->trans_start = jiffies; /* save the time stamp */
-
} else {
/* Second packet */
- db->tx_pkt_cnt++;
db->queue_pkt_len = skb->len;
+ netif_stop_queue(dev);
}
+ spin_unlock_irqrestore(&db->lock, flags);
+
/* free this SKB */
dev_kfree_skb(skb);
- /* Re-enable resource check */
- if (db->tx_pkt_cnt == 1)
- netif_wake_queue(dev);
-
- /* Re-enable interrupt */
- iow(db, DM9000_IMR, IMR_PAR | IMR_PTM | IMR_PRM);
-
return 0;
}
diff --git a/drivers/net/e1000/e1000_ethtool.c b/drivers/net/e1000/e1000_ethtool.c
index c90c92e..4c3785c 100644
--- a/drivers/net/e1000/e1000_ethtool.c
+++ b/drivers/net/e1000/e1000_ethtool.c
@@ -1706,6 +1706,7 @@
case E1000_DEV_ID_82545EM_COPPER:
case E1000_DEV_ID_82546GB_QUAD_COPPER:
case E1000_DEV_ID_82546GB_PCIE:
+ case E1000_DEV_ID_82571EB_SERDES_QUAD:
/* these don't support WoL at all */
wol->supported = 0;
break;
@@ -1723,6 +1724,7 @@
retval = 0;
break;
case E1000_DEV_ID_82571EB_QUAD_COPPER:
+ case E1000_DEV_ID_82571EB_QUAD_FIBER:
case E1000_DEV_ID_82571EB_QUAD_COPPER_LOWPROFILE:
case E1000_DEV_ID_82546GB_QUAD_COPPER_KSP3:
/* quad port adapters only support WoL on port A */
diff --git a/drivers/net/e1000/e1000_hw.c b/drivers/net/e1000/e1000_hw.c
index 9be4469..ba120f7 100644
--- a/drivers/net/e1000/e1000_hw.c
+++ b/drivers/net/e1000/e1000_hw.c
@@ -384,7 +384,10 @@
case E1000_DEV_ID_82571EB_COPPER:
case E1000_DEV_ID_82571EB_FIBER:
case E1000_DEV_ID_82571EB_SERDES:
+ case E1000_DEV_ID_82571EB_SERDES_DUAL:
+ case E1000_DEV_ID_82571EB_SERDES_QUAD:
case E1000_DEV_ID_82571EB_QUAD_COPPER:
+ case E1000_DEV_ID_82571EB_QUAD_FIBER:
case E1000_DEV_ID_82571EB_QUAD_COPPER_LOWPROFILE:
hw->mac_type = e1000_82571;
break;
@@ -485,6 +488,8 @@
case E1000_DEV_ID_82545GM_SERDES:
case E1000_DEV_ID_82546GB_SERDES:
case E1000_DEV_ID_82571EB_SERDES:
+ case E1000_DEV_ID_82571EB_SERDES_DUAL:
+ case E1000_DEV_ID_82571EB_SERDES_QUAD:
case E1000_DEV_ID_82572EI_SERDES:
case E1000_DEV_ID_80003ES2LAN_SERDES_DPT:
hw->media_type = e1000_media_type_internal_serdes;
diff --git a/drivers/net/e1000/e1000_hw.h b/drivers/net/e1000/e1000_hw.h
index bd000b8..fe87146 100644
--- a/drivers/net/e1000/e1000_hw.h
+++ b/drivers/net/e1000/e1000_hw.h
@@ -475,7 +475,10 @@
#define E1000_DEV_ID_82571EB_FIBER 0x105F
#define E1000_DEV_ID_82571EB_SERDES 0x1060
#define E1000_DEV_ID_82571EB_QUAD_COPPER 0x10A4
+#define E1000_DEV_ID_82571EB_QUAD_FIBER 0x10A5
#define E1000_DEV_ID_82571EB_QUAD_COPPER_LOWPROFILE 0x10BC
+#define E1000_DEV_ID_82571EB_SERDES_DUAL 0x10D9
+#define E1000_DEV_ID_82571EB_SERDES_QUAD 0x10DA
#define E1000_DEV_ID_82572EI_COPPER 0x107D
#define E1000_DEV_ID_82572EI_FIBER 0x107E
#define E1000_DEV_ID_82572EI_SERDES 0x107F
diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c
index f48b659..4a22595 100644
--- a/drivers/net/e1000/e1000_main.c
+++ b/drivers/net/e1000/e1000_main.c
@@ -100,6 +100,7 @@
INTEL_E1000_ETHERNET_DEVICE(0x1099),
INTEL_E1000_ETHERNET_DEVICE(0x109A),
INTEL_E1000_ETHERNET_DEVICE(0x10A4),
+ INTEL_E1000_ETHERNET_DEVICE(0x10A5),
INTEL_E1000_ETHERNET_DEVICE(0x10B5),
INTEL_E1000_ETHERNET_DEVICE(0x10B9),
INTEL_E1000_ETHERNET_DEVICE(0x10BA),
@@ -107,6 +108,8 @@
INTEL_E1000_ETHERNET_DEVICE(0x10BC),
INTEL_E1000_ETHERNET_DEVICE(0x10C4),
INTEL_E1000_ETHERNET_DEVICE(0x10C5),
+ INTEL_E1000_ETHERNET_DEVICE(0x10D9),
+ INTEL_E1000_ETHERNET_DEVICE(0x10DA),
/* required last entry */
{0,}
};
@@ -1096,6 +1099,7 @@
break;
case E1000_DEV_ID_82546GB_QUAD_COPPER_KSP3:
case E1000_DEV_ID_82571EB_QUAD_COPPER:
+ case E1000_DEV_ID_82571EB_QUAD_FIBER:
case E1000_DEV_ID_82571EB_QUAD_COPPER_LOWPROFILE:
/* if quad port adapter, disable WoL on all but port A */
if (global_quad_port_a != 0)
diff --git a/drivers/net/ehea/ehea.h b/drivers/net/ehea/ehea.h
index 8ee2c2c..d67f97b 100644
--- a/drivers/net/ehea/ehea.h
+++ b/drivers/net/ehea/ehea.h
@@ -39,7 +39,7 @@
#include <asm/io.h>
#define DRV_NAME "ehea"
-#define DRV_VERSION "EHEA_0072"
+#define DRV_VERSION "EHEA_0073"
/* eHEA capability flags */
#define DLPAR_PORT_ADD_REM 1
diff --git a/drivers/net/ehea/ehea_main.c b/drivers/net/ehea/ehea_main.c
index 58702f5..db57474 100644
--- a/drivers/net/ehea/ehea_main.c
+++ b/drivers/net/ehea/ehea_main.c
@@ -76,7 +76,7 @@
MODULE_PARM_DESC(sq_entries, " Number of entries for the Send Queue "
"[2^x - 1], x = [6..14]. Default = "
__MODULE_STRING(EHEA_DEF_ENTRIES_SQ) ")");
-MODULE_PARM_DESC(use_mcs, " 0:NAPI, 1:Multiple receive queues, Default = 1 ");
+MODULE_PARM_DESC(use_mcs, " 0:NAPI, 1:Multiple receive queues, Default = 0 ");
static int port_name_cnt = 0;
static LIST_HEAD(adapter_list);
@@ -1326,7 +1326,6 @@
u8 *imm_data = &swqe->u.immdata_desc.immediate_data[0];
int skb_data_size = skb->len - skb->data_len;
int headersize;
- u64 tmp_addr;
/* Packet is TCP with TSO enabled */
swqe->tx_control |= EHEA_SWQE_TSO;
@@ -1347,9 +1346,8 @@
/* set sg1entry data */
sg1entry->l_key = lkey;
sg1entry->len = skb_data_size - headersize;
-
- tmp_addr = (u64)(skb->data + headersize);
- sg1entry->vaddr = ehea_map_vaddr(tmp_addr);
+ sg1entry->vaddr =
+ ehea_map_vaddr(skb->data + headersize);
swqe->descriptors++;
}
} else
@@ -1362,7 +1360,6 @@
int skb_data_size = skb->len - skb->data_len;
u8 *imm_data = &swqe->u.immdata_desc.immediate_data[0];
struct ehea_vsgentry *sg1entry = &swqe->u.immdata_desc.sg_entry;
- u64 tmp_addr;
/* Packet is any nonTSO type
*
@@ -1379,8 +1376,8 @@
/* copy sg1entry data */
sg1entry->l_key = lkey;
sg1entry->len = skb_data_size - SWQE2_MAX_IMM;
- tmp_addr = (u64)(skb->data + SWQE2_MAX_IMM);
- sg1entry->vaddr = ehea_map_vaddr(tmp_addr);
+ sg1entry->vaddr =
+ ehea_map_vaddr(skb->data + SWQE2_MAX_IMM);
swqe->descriptors++;
}
} else {
@@ -1395,7 +1392,6 @@
struct ehea_vsgentry *sg_list, *sg1entry, *sgentry;
skb_frag_t *frag;
int nfrags, sg1entry_contains_frag_data, i;
- u64 tmp_addr;
nfrags = skb_shinfo(skb)->nr_frags;
sg1entry = &swqe->u.immdata_desc.sg_entry;
@@ -1417,9 +1413,9 @@
/* copy sg1entry data */
sg1entry->l_key = lkey;
sg1entry->len = frag->size;
- tmp_addr = (u64)(page_address(frag->page)
- + frag->page_offset);
- sg1entry->vaddr = ehea_map_vaddr(tmp_addr);
+ sg1entry->vaddr =
+ ehea_map_vaddr(page_address(frag->page)
+ + frag->page_offset);
swqe->descriptors++;
sg1entry_contains_frag_data = 1;
}
@@ -1431,10 +1427,9 @@
sgentry->l_key = lkey;
sgentry->len = frag->size;
-
- tmp_addr = (u64)(page_address(frag->page)
- + frag->page_offset);
- sgentry->vaddr = ehea_map_vaddr(tmp_addr);
+ sgentry->vaddr =
+ ehea_map_vaddr(page_address(frag->page)
+ + frag->page_offset);
swqe->descriptors++;
}
}
@@ -2165,24 +2160,18 @@
return ret;
}
-static void ehea_remove_adapter_mr (struct ehea_adapter *adapter)
+static void ehea_remove_adapter_mr(struct ehea_adapter *adapter)
{
- int i;
-
- for (i=0; i < EHEA_MAX_PORTS; i++)
- if (adapter->port[i])
- return;
+ if (adapter->active_ports)
+ return;
ehea_rem_mr(&adapter->mr);
}
-static int ehea_add_adapter_mr (struct ehea_adapter *adapter)
+static int ehea_add_adapter_mr(struct ehea_adapter *adapter)
{
- int i;
-
- for (i=0; i < EHEA_MAX_PORTS; i++)
- if (adapter->port[i])
- return 0;
+ if (adapter->active_ports)
+ return 0;
return ehea_reg_kernel_mr(adapter, &adapter->mr);
}
@@ -2501,7 +2490,7 @@
struct device_attribute *attr, char *buf)
{
struct ehea_port *port = container_of(dev, struct ehea_port, ofdev.dev);
- return sprintf(buf, "0x%X", port->logical_port_id);
+ return sprintf(buf, "%d", port->logical_port_id);
}
static DEVICE_ATTR(log_port_id, S_IRUSR | S_IRGRP | S_IROTH, ehea_show_port_id,
@@ -2792,7 +2781,7 @@
u32 logical_port_id;
- sscanf(buf, "%X", &logical_port_id);
+ sscanf(buf, "%d", &logical_port_id);
port = ehea_get_port(adapter, logical_port_id);
@@ -2845,7 +2834,7 @@
int i;
u32 logical_port_id;
- sscanf(buf, "%X", &logical_port_id);
+ sscanf(buf, "%d", &logical_port_id);
port = ehea_get_port(adapter, logical_port_id);
@@ -3099,6 +3088,7 @@
static void __exit ehea_module_exit(void)
{
+ destroy_workqueue(ehea_driver_wq);
driver_remove_file(&ehea_driver.driver, &driver_attr_capabilities);
ibmebus_unregister_driver(&ehea_driver);
ehea_destroy_busmap();
diff --git a/drivers/net/ehea/ehea_qmr.c b/drivers/net/ehea/ehea_qmr.c
index a36fa6c..c82e245 100644
--- a/drivers/net/ehea/ehea_qmr.c
+++ b/drivers/net/ehea/ehea_qmr.c
@@ -235,6 +235,8 @@
if (!cq)
return 0;
+ hcp_epas_dtor(&cq->epas);
+
if ((hret = ehea_destroy_cq_res(cq, NORMAL_FREE)) == H_R_STATE) {
ehea_error_data(cq->adapter, cq->fw_handle);
hret = ehea_destroy_cq_res(cq, FORCE_FREE);
@@ -361,6 +363,8 @@
if (!eq)
return 0;
+ hcp_epas_dtor(&eq->epas);
+
if ((hret = ehea_destroy_eq_res(eq, NORMAL_FREE)) == H_R_STATE) {
ehea_error_data(eq->adapter, eq->fw_handle);
hret = ehea_destroy_eq_res(eq, FORCE_FREE);
@@ -541,6 +545,8 @@
if (!qp)
return 0;
+ hcp_epas_dtor(&qp->epas);
+
if ((hret = ehea_destroy_qp_res(qp, NORMAL_FREE)) == H_R_STATE) {
ehea_error_data(qp->adapter, qp->fw_handle);
hret = ehea_destroy_qp_res(qp, FORCE_FREE);
diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c
index 69f5f36..1938d6d 100644
--- a/drivers/net/forcedeth.c
+++ b/drivers/net/forcedeth.c
@@ -552,7 +552,7 @@
#define PHY_OUI_MARVELL 0x5043
#define PHY_OUI_CICADA 0x03f1
#define PHY_OUI_VITESSE 0x01c1
-#define PHY_OUI_REALTEK 0x01c1
+#define PHY_OUI_REALTEK 0x0732
#define PHYID1_OUI_MASK 0x03ff
#define PHYID1_OUI_SHFT 6
#define PHYID2_OUI_MASK 0xfc00
@@ -3068,8 +3068,8 @@
np->nic_poll_irq = np->irqmask;
mod_timer(&np->nic_poll, jiffies + POLL_WAIT);
}
- printk(KERN_DEBUG "%s: too many iterations (%d) in nv_nic_irq.\n", dev->name, i);
spin_unlock(&np->lock);
+ printk(KERN_DEBUG "%s: too many iterations (%d) in nv_nic_irq.\n", dev->name, i);
break;
}
@@ -3186,8 +3186,8 @@
np->nic_poll_irq = np->irqmask;
mod_timer(&np->nic_poll, jiffies + POLL_WAIT);
}
- printk(KERN_DEBUG "%s: too many iterations (%d) in nv_nic_irq.\n", dev->name, i);
spin_unlock(&np->lock);
+ printk(KERN_DEBUG "%s: too many iterations (%d) in nv_nic_irq.\n", dev->name, i);
break;
}
@@ -3233,8 +3233,8 @@
np->nic_poll_irq |= NVREG_IRQ_TX_ALL;
mod_timer(&np->nic_poll, jiffies + POLL_WAIT);
}
- printk(KERN_DEBUG "%s: too many iterations (%d) in nv_nic_irq_tx.\n", dev->name, i);
spin_unlock_irqrestore(&np->lock, flags);
+ printk(KERN_DEBUG "%s: too many iterations (%d) in nv_nic_irq_tx.\n", dev->name, i);
break;
}
@@ -3348,8 +3348,8 @@
np->nic_poll_irq |= NVREG_IRQ_RX_ALL;
mod_timer(&np->nic_poll, jiffies + POLL_WAIT);
}
- printk(KERN_DEBUG "%s: too many iterations (%d) in nv_nic_irq_rx.\n", dev->name, i);
spin_unlock_irqrestore(&np->lock, flags);
+ printk(KERN_DEBUG "%s: too many iterations (%d) in nv_nic_irq_rx.\n", dev->name, i);
break;
}
}
@@ -3421,8 +3421,8 @@
np->nic_poll_irq |= NVREG_IRQ_OTHER;
mod_timer(&np->nic_poll, jiffies + POLL_WAIT);
}
- printk(KERN_DEBUG "%s: too many iterations (%d) in nv_nic_irq_other.\n", dev->name, i);
spin_unlock_irqrestore(&np->lock, flags);
+ printk(KERN_DEBUG "%s: too many iterations (%d) in nv_nic_irq_other.\n", dev->name, i);
break;
}
diff --git a/drivers/net/ibmveth.c b/drivers/net/ibmveth.c
index d96eb72..acba90f 100644
--- a/drivers/net/ibmveth.c
+++ b/drivers/net/ibmveth.c
@@ -963,7 +963,7 @@
{
int rc, i;
struct net_device *netdev;
- struct ibmveth_adapter *adapter = NULL;
+ struct ibmveth_adapter *adapter;
unsigned char *mac_addr_p;
unsigned int *mcastFilterSize_p;
@@ -997,7 +997,6 @@
SET_MODULE_OWNER(netdev);
adapter = netdev->priv;
- memset(adapter, 0, sizeof(adapter));
dev->dev.driver_data = netdev;
adapter->vdev = dev;
@@ -1280,24 +1279,28 @@
int i;
/* Make sure there is a buffer pool with buffers that
can hold a packet of the size of the MTU */
- for(i = 0; i<IbmVethNumBufferPools; i++) {
+ for (i = 0; i < IbmVethNumBufferPools; i++) {
if (pool == &adapter->rx_buff_pool[i])
continue;
if (!adapter->rx_buff_pool[i].active)
continue;
- if (mtu < adapter->rx_buff_pool[i].buff_size) {
- pool->active = 0;
- h_free_logical_lan_buffer(adapter->
- vdev->
- unit_address,
- pool->
- buff_size);
- }
+ if (mtu <= adapter->rx_buff_pool[i].buff_size)
+ break;
}
- if (pool->active) {
+
+ if (i == IbmVethNumBufferPools) {
ibmveth_error_printk("no active pool >= MTU\n");
return -EPERM;
}
+
+ pool->active = 0;
+ if (netif_running(netdev)) {
+ adapter->pool_config = 1;
+ ibmveth_close(netdev);
+ adapter->pool_config = 0;
+ if ((rc = ibmveth_open(netdev)))
+ return rc;
+ }
}
} else if (attr == &veth_num_attr) {
if (value <= 0 || value > IBMVETH_MAX_POOL_COUNT)
diff --git a/drivers/net/ibmveth.h b/drivers/net/ibmveth.h
index bb69cca..72cc15a 100644
--- a/drivers/net/ibmveth.h
+++ b/drivers/net/ibmveth.h
@@ -73,9 +73,6 @@
#define h_change_logical_lan_mac(ua, mac) \
plpar_hcall_norets(H_CHANGE_LOGICAL_LAN_MAC, ua, mac)
-#define h_free_logical_lan_buffer(ua, bufsize) \
- plpar_hcall_norets(H_FREE_LOGICAL_LAN_BUFFER, ua, bufsize)
-
#define IbmVethNumBufferPools 5
#define IBMVETH_BUFF_OH 22 /* Overhead: 14 ethernet header + 8 opaque handle */
#define IBMVETH_MAX_MTU 68
diff --git a/drivers/net/irda/irda-usb.c b/drivers/net/irda/irda-usb.c
index 0ac240c..3b0fd83 100644
--- a/drivers/net/irda/irda-usb.c
+++ b/drivers/net/irda/irda-usb.c
@@ -1561,10 +1561,9 @@
struct irda_class_desc *desc;
int ret;
- desc = kmalloc(sizeof (*desc), GFP_KERNEL);
- if (desc == NULL)
+ desc = kzalloc(sizeof(*desc), GFP_KERNEL);
+ if (!desc)
return NULL;
- memset(desc, 0, sizeof(*desc));
/* USB-IrDA class spec 1.0:
* 6.1.3: Standard "Get Descriptor" Device Request is not
@@ -1617,7 +1616,7 @@
{
struct net_device *net;
struct usb_device *dev = interface_to_usbdev(intf);
- struct irda_usb_cb *self = NULL;
+ struct irda_usb_cb *self;
struct usb_host_interface *interface;
struct irda_class_desc *irda_desc;
int ret = -ENOMEM;
@@ -1655,7 +1654,7 @@
self->header_length = USB_IRDA_HEADER;
}
- self->rx_urb = kzalloc(self->max_rx_urb * sizeof(struct urb *),
+ self->rx_urb = kcalloc(self->max_rx_urb, sizeof(struct urb *),
GFP_KERNEL);
for (i = 0; i < self->max_rx_urb; i++) {
@@ -1715,7 +1714,7 @@
/* Find IrDA class descriptor */
irda_desc = irda_usb_find_class_desc(intf);
ret = -ENODEV;
- if (irda_desc == NULL)
+ if (!irda_desc)
goto err_out_3;
if (self->needspatch) {
@@ -1738,15 +1737,13 @@
/* Don't change this buffer size and allocation without doing
* some heavy and complete testing. Don't ask why :-(
* Jean II */
- self->speed_buff = kmalloc(IRDA_USB_SPEED_MTU, GFP_KERNEL);
- if (self->speed_buff == NULL)
+ self->speed_buff = kzalloc(IRDA_USB_SPEED_MTU, GFP_KERNEL);
+ if (!self->speed_buff)
goto err_out_3;
- memset(self->speed_buff, 0, IRDA_USB_SPEED_MTU);
-
self->tx_buff = kzalloc(IRDA_SKB_MAX_MTU + self->header_length,
GFP_KERNEL);
- if (self->tx_buff == NULL)
+ if (!self->tx_buff)
goto err_out_4;
ret = irda_usb_open(self);
@@ -1767,12 +1764,11 @@
/* replace IrDA class descriptor with what patched device is now reporting */
irda_desc = irda_usb_find_class_desc (self->usbintf);
- if (irda_desc == NULL) {
+ if (!irda_desc) {
ret = -ENODEV;
goto err_out_6;
}
- if (self->irda_desc)
- kfree (self->irda_desc);
+ kfree(self->irda_desc);
self->irda_desc = irda_desc;
irda_usb_init_qos(self);
}
diff --git a/drivers/net/meth.c b/drivers/net/meth.c
index 92b403b..32bed6b 100644
--- a/drivers/net/meth.c
+++ b/drivers/net/meth.c
@@ -405,7 +405,7 @@
priv->stats.rx_length_errors++;
skb = priv->rx_skbs[priv->rx_write];
} else {
- skb = alloc_skb(METH_RX_BUFF_SIZE, GFP_ATOMIC | GFP_DMA);
+ skb = alloc_skb(METH_RX_BUFF_SIZE, GFP_ATOMIC);
if (!skb) {
/* Ouch! No memory! Drop packet on the floor */
DPRINTK("No mem: dropping packet\n");
diff --git a/drivers/net/mlx4/reset.c b/drivers/net/mlx4/reset.c
index e4dfd4b..e199715 100644
--- a/drivers/net/mlx4/reset.c
+++ b/drivers/net/mlx4/reset.c
@@ -119,6 +119,9 @@
writel(MLX4_RESET_VALUE, reset + MLX4_RESET_OFFSET);
iounmap(reset);
+ /* Docs say to wait one second before accessing device */
+ msleep(1000);
+
end = jiffies + MLX4_RESET_TIMEOUT_JIFFIES;
do {
if (!pci_read_config_word(dev->pdev, PCI_VENDOR_ID, &vendor) &&
diff --git a/drivers/net/myri10ge/myri10ge.c b/drivers/net/myri10ge/myri10ge.c
index deca653..1c42266 100644
--- a/drivers/net/myri10ge/myri10ge.c
+++ b/drivers/net/myri10ge/myri10ge.c
@@ -72,7 +72,7 @@
#include "myri10ge_mcp.h"
#include "myri10ge_mcp_gen_header.h"
-#define MYRI10GE_VERSION_STR "1.3.1-1.248"
+#define MYRI10GE_VERSION_STR "1.3.2-1.269"
MODULE_DESCRIPTION("Myricom 10G driver (10GbE)");
MODULE_AUTHOR("Maintainer: help@myri.com");
@@ -191,6 +191,7 @@
struct timer_list watchdog_timer;
int watchdog_tx_done;
int watchdog_tx_req;
+ int watchdog_pause;
int watchdog_resets;
int tx_linearized;
int pause;
@@ -2513,26 +2514,20 @@
{
struct pci_dev *pdev = mgp->pdev;
struct device *dev = &pdev->dev;
- int cap, status;
- u16 val;
+ int status;
mgp->tx.boundary = 4096;
/*
* Verify the max read request size was set to 4KB
* before trying the test with 4KB.
*/
- cap = pci_find_capability(pdev, PCI_CAP_ID_EXP);
- if (cap < 64) {
- dev_err(dev, "Bad PCI_CAP_ID_EXP location %d\n", cap);
- goto abort;
- }
- status = pci_read_config_word(pdev, cap + PCI_EXP_DEVCTL, &val);
- if (status != 0) {
+ status = pcie_get_readrq(pdev);
+ if (status < 0) {
dev_err(dev, "Couldn't read max read req size: %d\n", status);
goto abort;
}
- if ((val & (5 << 12)) != (5 << 12)) {
- dev_warn(dev, "Max Read Request size != 4096 (0x%x)\n", val);
+ if (status != 4096) {
+ dev_warn(dev, "Max Read Request size != 4096 (%d)\n", status);
mgp->tx.boundary = 2048;
}
/*
@@ -2800,6 +2795,7 @@
static void myri10ge_watchdog_timer(unsigned long arg)
{
struct myri10ge_priv *mgp;
+ u32 rx_pause_cnt;
mgp = (struct myri10ge_priv *)arg;
@@ -2816,19 +2812,28 @@
myri10ge_fill_thresh)
mgp->rx_big.watchdog_needed = 0;
}
+ rx_pause_cnt = ntohl(mgp->fw_stats->dropped_pause);
if (mgp->tx.req != mgp->tx.done &&
mgp->tx.done == mgp->watchdog_tx_done &&
- mgp->watchdog_tx_req != mgp->watchdog_tx_done)
+ mgp->watchdog_tx_req != mgp->watchdog_tx_done) {
/* nic seems like it might be stuck.. */
- schedule_work(&mgp->watchdog_work);
- else
- /* rearm timer */
- mod_timer(&mgp->watchdog_timer,
- jiffies + myri10ge_watchdog_timeout * HZ);
-
+ if (rx_pause_cnt != mgp->watchdog_pause) {
+ if (net_ratelimit())
+ printk(KERN_WARNING "myri10ge %s:"
+ "TX paused, check link partner\n",
+ mgp->dev->name);
+ } else {
+ schedule_work(&mgp->watchdog_work);
+ return;
+ }
+ }
+ /* rearm timer */
+ mod_timer(&mgp->watchdog_timer,
+ jiffies + myri10ge_watchdog_timeout * HZ);
mgp->watchdog_tx_done = mgp->tx.done;
mgp->watchdog_tx_req = mgp->tx.req;
+ mgp->watchdog_pause = rx_pause_cnt;
}
static int myri10ge_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
@@ -2839,9 +2844,7 @@
size_t bytes;
int i;
int status = -ENXIO;
- int cap;
int dac_enabled;
- u16 val;
netdev = alloc_etherdev(sizeof(*mgp));
if (netdev == NULL) {
@@ -2873,19 +2876,7 @@
= pci_find_capability(pdev, PCI_CAP_ID_VNDR);
/* Set our max read request to 4KB */
- cap = pci_find_capability(pdev, PCI_CAP_ID_EXP);
- if (cap < 64) {
- dev_err(&pdev->dev, "Bad PCI_CAP_ID_EXP location %d\n", cap);
- goto abort_with_netdev;
- }
- status = pci_read_config_word(pdev, cap + PCI_EXP_DEVCTL, &val);
- if (status != 0) {
- dev_err(&pdev->dev, "Error %d reading PCI_EXP_DEVCTL\n",
- status);
- goto abort_with_netdev;
- }
- val = (val & ~PCI_EXP_DEVCTL_READRQ) | (5 << 12);
- status = pci_write_config_word(pdev, cap + PCI_EXP_DEVCTL, val);
+ status = pcie_set_readrq(pdev, 4096);
if (status != 0) {
dev_err(&pdev->dev, "Error %d writing PCI_EXP_DEVCTL\n",
status);
diff --git a/drivers/net/natsemi.c b/drivers/net/natsemi.c
index 6bb48ba..b47a12d 100644
--- a/drivers/net/natsemi.c
+++ b/drivers/net/natsemi.c
@@ -2438,13 +2438,16 @@
dev->name);
}
np->stats.rx_fifo_errors++;
+ np->stats.rx_errors++;
}
/* Hmmmmm, it's not clear how to recover from PCI faults. */
if (intr_status & IntrPCIErr) {
printk(KERN_NOTICE "%s: PCI error %#08x\n", dev->name,
intr_status & IntrPCIErr);
np->stats.tx_fifo_errors++;
+ np->stats.tx_errors++;
np->stats.rx_fifo_errors++;
+ np->stats.rx_errors++;
}
spin_unlock(&np->lock);
}
diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c
index f71dab3..e323efd 100644
--- a/drivers/net/phy/phy.c
+++ b/drivers/net/phy/phy.c
@@ -261,7 +261,7 @@
/* Sanitize settings based on PHY capabilities */
if ((features & SUPPORTED_Autoneg) == 0)
- phydev->autoneg = 0;
+ phydev->autoneg = AUTONEG_DISABLE;
idx = phy_find_valid(phy_find_setting(phydev->speed, phydev->duplex),
features);
@@ -374,7 +374,7 @@
if (mii_data->phy_id == phydev->addr) {
switch(mii_data->reg_num) {
case MII_BMCR:
- if (val & (BMCR_RESET|BMCR_ANENABLE))
+ if ((val & (BMCR_RESET|BMCR_ANENABLE)) == 0)
phydev->autoneg = AUTONEG_DISABLE;
else
phydev->autoneg = AUTONEG_ENABLE;
diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c
index a8b74cd..e275df8 100644
--- a/drivers/net/phy/phy_device.c
+++ b/drivers/net/phy/phy_device.c
@@ -364,7 +364,7 @@
*/
int genphy_setup_forced(struct phy_device *phydev)
{
- int ctl = BMCR_RESET;
+ int ctl = 0;
phydev->pause = phydev->asym_pause = 0;
diff --git a/drivers/net/ppp_generic.c b/drivers/net/ppp_generic.c
index ef3325b..9293c82 100644
--- a/drivers/net/ppp_generic.c
+++ b/drivers/net/ppp_generic.c
@@ -1726,7 +1726,7 @@
}
/* the decompressor still expects the A/C bytes in the hdr */
len = ppp->rcomp->decompress(ppp->rc_state, skb->data - 2,
- skb->len + 2, ns->data, ppp->mru + PPP_HDRLEN);
+ skb->len + 2, ns->data, obuff_size);
if (len < 0) {
/* Pass the compressed frame to pppd as an
error indication. */
diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c
index c9333b9..b85ab4a 100644
--- a/drivers/net/r8169.c
+++ b/drivers/net/r8169.c
@@ -725,6 +725,12 @@
auto_nego |= ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM;
+ if (tp->mac_version == RTL_GIGA_MAC_VER_12) {
+ /* Vendor specific (0x1f) and reserved (0x0e) MII registers. */
+ mdio_write(ioaddr, 0x1f, 0x0000);
+ mdio_write(ioaddr, 0x0e, 0x0000);
+ }
+
tp->phy_auto_nego_reg = auto_nego;
tp->phy_1000_ctrl_reg = giga_ctrl;
@@ -2760,14 +2766,16 @@
rtl8169_check_link_status(dev, tp, ioaddr);
#ifdef CONFIG_R8169_NAPI
- RTL_W16(IntrMask, tp->intr_event & ~tp->napi_event);
- tp->intr_mask = ~tp->napi_event;
+ if (status & tp->napi_event) {
+ RTL_W16(IntrMask, tp->intr_event & ~tp->napi_event);
+ tp->intr_mask = ~tp->napi_event;
- if (likely(netif_rx_schedule_prep(dev)))
- __netif_rx_schedule(dev);
- else if (netif_msg_intr(tp)) {
- printk(KERN_INFO "%s: interrupt %04x taken in poll\n",
- dev->name, status);
+ if (likely(netif_rx_schedule_prep(dev)))
+ __netif_rx_schedule(dev);
+ else if (netif_msg_intr(tp)) {
+ printk(KERN_INFO "%s: interrupt %04x in poll\n",
+ dev->name, status);
+ }
}
break;
#else
diff --git a/drivers/net/sgiseeq.c b/drivers/net/sgiseeq.c
index 384b468..0fb74cb 100644
--- a/drivers/net/sgiseeq.c
+++ b/drivers/net/sgiseeq.c
@@ -726,7 +726,7 @@
return err;
}
-static void __exit sgiseeq_remove(struct platform_device *pdev)
+static int __exit sgiseeq_remove(struct platform_device *pdev)
{
struct net_device *dev = platform_get_drvdata(pdev);
struct sgiseeq_private *sp = netdev_priv(dev);
@@ -735,6 +735,8 @@
free_page((unsigned long) sp->srings);
free_netdev(dev);
platform_set_drvdata(pdev, NULL);
+
+ return 0;
}
static struct platform_driver sgiseeq_driver = {
diff --git a/drivers/net/sis190.c b/drivers/net/sis190.c
index ec2ad9f..d470b19 100644
--- a/drivers/net/sis190.c
+++ b/drivers/net/sis190.c
@@ -1593,6 +1593,9 @@
pci_name(pdev));
isa_bridge = pci_get_device(PCI_VENDOR_ID_SI, 0x0965, NULL);
+ if (!isa_bridge)
+ isa_bridge = pci_get_device(PCI_VENDOR_ID_SI, 0x0966, NULL);
+
if (!isa_bridge) {
net_probe(tp, KERN_INFO "%s: Can not find ISA bridge.\n",
pci_name(pdev));
diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c
index e7a2ead..e6d937e 100644
--- a/drivers/net/sky2.c
+++ b/drivers/net/sky2.c
@@ -51,7 +51,7 @@
#include "sky2.h"
#define DRV_NAME "sky2"
-#define DRV_VERSION "1.16"
+#define DRV_VERSION "1.17"
#define PFX DRV_NAME " "
/*
@@ -99,10 +99,6 @@
module_param(disable_msi, int, 0);
MODULE_PARM_DESC(disable_msi, "Disable Message Signaled Interrupt (MSI)");
-static int idle_timeout = 100;
-module_param(idle_timeout, int, 0);
-MODULE_PARM_DESC(idle_timeout, "Watchdog timer for lost interrupts (ms)");
-
static const struct pci_device_id sky2_id_table[] = {
{ PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, 0x9000) }, /* SK-9Sxx */
{ PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, 0x9E00) }, /* SK-9Exx */
@@ -219,9 +215,12 @@
else
sky2_write8(hw, B2_Y2_CLK_GATE, 0);
- if (hw->chip_id == CHIP_ID_YUKON_EC_U || hw->chip_id == CHIP_ID_YUKON_EX) {
+ if (hw->chip_id == CHIP_ID_YUKON_EC_U ||
+ hw->chip_id == CHIP_ID_YUKON_EX) {
u32 reg;
+ sky2_pci_write32(hw, PCI_DEV_REG3, 0);
+
reg = sky2_pci_read32(hw, PCI_DEV_REG4);
/* set all bits to 0 except bits 15..12 and 8 */
reg &= P_ASPM_CONTROL_MSK;
@@ -238,6 +237,8 @@
reg = sky2_read32(hw, B2_GP_IO);
reg |= GLB_GPIO_STAT_RACE_DIS;
sky2_write32(hw, B2_GP_IO, reg);
+
+ sky2_read32(hw, B2_GP_IO);
}
}
@@ -696,8 +697,8 @@
int i;
const u8 *addr = hw->dev[port]->dev_addr;
- sky2_write32(hw, SK_REG(port, GPHY_CTRL), GPC_RST_SET);
- sky2_write32(hw, SK_REG(port, GPHY_CTRL), GPC_RST_CLR);
+ sky2_write8(hw, SK_REG(port, GPHY_CTRL), GPC_RST_SET);
+ sky2_write8(hw, SK_REG(port, GPHY_CTRL), GPC_RST_CLR);
sky2_write8(hw, SK_REG(port, GMAC_CTRL), GMC_RST_CLR);
@@ -1619,6 +1620,9 @@
if (netif_msg_ifdown(sky2))
printk(KERN_INFO PFX "%s: disabling interface\n", dev->name);
+ if (netif_carrier_ok(dev) && --hw->active == 0)
+ del_timer(&hw->watchdog_timer);
+
/* Stop more packets from being queued */
netif_stop_queue(dev);
@@ -1739,6 +1743,10 @@
netif_carrier_on(sky2->netdev);
+ if (hw->active++ == 0)
+ mod_timer(&hw->watchdog_timer, jiffies + 1);
+
+
/* Turn on link LED */
sky2_write8(hw, SK_REG(port, LNK_LED_REG),
LINKLED_ON | LINKLED_BLINK_OFF | LINKLED_LINKSYNC_OFF);
@@ -1790,6 +1798,11 @@
netif_carrier_off(sky2->netdev);
+ /* Stop watchdog if both ports are not active */
+ if (--hw->active == 0)
+ del_timer(&hw->watchdog_timer);
+
+
/* Turn on link LED */
sky2_write8(hw, SK_REG(port, LNK_LED_REG), LINKLED_OFF);
@@ -2421,25 +2434,20 @@
sky2_write32(hw, Q_ADDR(q, Q_CSR), BMU_CLR_IRQ_CHK);
}
-/* If idle then force a fake soft NAPI poll once a second
- * to work around cases where sharing an edge triggered interrupt.
- */
-static inline void sky2_idle_start(struct sky2_hw *hw)
-{
- if (idle_timeout > 0)
- mod_timer(&hw->idle_timer,
- jiffies + msecs_to_jiffies(idle_timeout));
-}
-
-static void sky2_idle(unsigned long arg)
+/* Check for lost IRQ once a second */
+static void sky2_watchdog(unsigned long arg)
{
struct sky2_hw *hw = (struct sky2_hw *) arg;
- struct net_device *dev = hw->dev[0];
- if (__netif_rx_schedule_prep(dev))
- __netif_rx_schedule(dev);
+ if (sky2_read32(hw, B0_ISRC)) {
+ struct net_device *dev = hw->dev[0];
- mod_timer(&hw->idle_timer, jiffies + msecs_to_jiffies(idle_timeout));
+ if (__netif_rx_schedule_prep(dev))
+ __netif_rx_schedule(dev);
+ }
+
+ if (hw->active > 0)
+ mod_timer(&hw->watchdog_timer, round_jiffies(jiffies + HZ));
}
/* Hardware/software error handling */
@@ -2727,8 +2735,6 @@
struct net_device *dev;
int i, err;
- del_timer_sync(&hw->idle_timer);
-
rtnl_lock();
sky2_write32(hw, B0_IMSK, 0);
sky2_read32(hw, B0_IMSK);
@@ -2757,8 +2763,6 @@
}
}
- sky2_idle_start(hw);
-
rtnl_unlock();
}
@@ -4025,11 +4029,9 @@
sky2_show_addr(dev1);
}
- setup_timer(&hw->idle_timer, sky2_idle, (unsigned long) hw);
+ setup_timer(&hw->watchdog_timer, sky2_watchdog, (unsigned long) hw);
INIT_WORK(&hw->restart_work, sky2_restart);
- sky2_idle_start(hw);
-
pci_set_drvdata(pdev, hw);
return 0;
@@ -4064,7 +4066,7 @@
if (!hw)
return;
- del_timer_sync(&hw->idle_timer);
+ del_timer_sync(&hw->watchdog_timer);
flush_scheduled_work();
@@ -4108,7 +4110,6 @@
if (!hw)
return 0;
- del_timer_sync(&hw->idle_timer);
netif_poll_disable(hw->dev[0]);
for (i = 0; i < hw->ports; i++) {
@@ -4174,7 +4175,7 @@
}
netif_poll_enable(hw->dev[0]);
- sky2_idle_start(hw);
+
return 0;
out:
dev_err(&pdev->dev, "resume failed (%d)\n", err);
@@ -4191,7 +4192,6 @@
if (!hw)
return;
- del_timer_sync(&hw->idle_timer);
netif_poll_disable(hw->dev[0]);
for (i = 0; i < hw->ports; i++) {
diff --git a/drivers/net/sky2.h b/drivers/net/sky2.h
index dce4d27..72e12b7c 100644
--- a/drivers/net/sky2.h
+++ b/drivers/net/sky2.h
@@ -2045,12 +2045,13 @@
u8 chip_rev;
u8 pmd_type;
u8 ports;
+ u8 active;
struct sky2_status_le *st_le;
u32 st_idx;
dma_addr_t st_dma;
- struct timer_list idle_timer;
+ struct timer_list watchdog_timer;
struct work_struct restart_work;
int msi;
wait_queue_head_t msi_wait;
diff --git a/drivers/net/smc91x.h b/drivers/net/smc91x.h
index f842944..6ff3a16 100644
--- a/drivers/net/smc91x.h
+++ b/drivers/net/smc91x.h
@@ -299,7 +299,7 @@
#define SMC_CAN_USE_8BIT 1
#define SMC_CAN_USE_16BIT 1
-#define SMC_CAN_USE_32BIT 1
+#define SMC_CAN_USE_32BIT 0
#define SMC_inb(a, r) inb((a) + (r))
#define SMC_inw(a, r) inw((a) + (r))
@@ -310,8 +310,6 @@
#endif /* BOARDS */
-#define set_irq_type(irq, type) do {} while (0)
-
#elif defined(CONFIG_M32R)
#define SMC_CAN_USE_8BIT 0
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
index dc41c05..5874042 100644
--- a/drivers/net/tg3.c
+++ b/drivers/net/tg3.c
@@ -64,8 +64,8 @@
#define DRV_MODULE_NAME "tg3"
#define PFX DRV_MODULE_NAME ": "
-#define DRV_MODULE_VERSION "3.79"
-#define DRV_MODULE_RELDATE "July 18, 2007"
+#define DRV_MODULE_VERSION "3.80"
+#define DRV_MODULE_RELDATE "August 2, 2007"
#define TG3_DEF_MAC_MODE 0
#define TG3_DEF_RX_MODE 0
@@ -12111,6 +12111,12 @@
struct tg3 *tp = netdev_priv(dev);
int err;
+ /* PCI register 4 needs to be saved whether netif_running() or not.
+ * MSI address and data need to be saved if using MSI and
+ * netif_running().
+ */
+ pci_save_state(pdev);
+
if (!netif_running(dev))
return 0;
@@ -12130,9 +12136,6 @@
tp->tg3_flags &= ~TG3_FLAG_INIT_COMPLETE;
tg3_full_unlock(tp);
- /* Save MSI address and data for resume. */
- pci_save_state(pdev);
-
err = tg3_set_power_state(tp, pci_choose_state(pdev, state));
if (err) {
tg3_full_lock(tp, 0);
@@ -12160,11 +12163,11 @@
struct tg3 *tp = netdev_priv(dev);
int err;
+ pci_restore_state(tp->pdev);
+
if (!netif_running(dev))
return 0;
- pci_restore_state(tp->pdev);
-
err = tg3_set_power_state(tp, PCI_D0);
if (err)
return err;
diff --git a/drivers/net/ucc_geth_ethtool.c b/drivers/net/ucc_geth_ethtool.c
index a8994c7..64bef7c 100644
--- a/drivers/net/ucc_geth_ethtool.c
+++ b/drivers/net/ucc_geth_ethtool.c
@@ -379,7 +379,6 @@
.get_stats_count = uec_get_stats_count,
.get_strings = uec_get_strings,
.get_ethtool_stats = uec_get_ethtool_stats,
- .get_perm_addr = ethtool_op_get_perm_addr,
};
void uec_set_ethtool_ops(struct net_device *netdev)
diff --git a/drivers/net/ucc_geth_mii.c b/drivers/net/ucc_geth_mii.c
index 5f8c2d3..6c257b8 100644
--- a/drivers/net/ucc_geth_mii.c
+++ b/drivers/net/ucc_geth_mii.c
@@ -272,7 +272,8 @@
return of_register_platform_driver(&uec_mdio_driver);
}
-void __exit uec_mdio_exit(void)
+/* called from __init ucc_geth_init, therefore can not be __exit */
+void uec_mdio_exit(void)
{
of_unregister_platform_driver(&uec_mdio_driver);
}
diff --git a/drivers/net/via-rhine.c b/drivers/net/via-rhine.c
index c3fe230..b56dff2 100644
--- a/drivers/net/via-rhine.c
+++ b/drivers/net/via-rhine.c
@@ -42,7 +42,13 @@
/* Set the copy breakpoint for the copy-only-tiny-frames scheme.
Setting to > 1518 effectively disables this feature. */
+#if defined(__alpha__) || defined(__arm__) || defined(__hppa__) \
+ || defined(CONFIG_SPARC) || defined(__ia64__) \
+ || defined(__sh__) || defined(__mips__)
+static int rx_copybreak = 1518;
+#else
static int rx_copybreak;
+#endif
/* Work-around for broken BIOSes: they are unable to get the chip back out of
power state D3 so PXE booting fails. bootparam(7): via-rhine.avoid_D3=1 */
diff --git a/drivers/net/wan/hdlc_fr.c b/drivers/net/wan/hdlc_fr.c
index 15b6e07..071a64c 100644
--- a/drivers/net/wan/hdlc_fr.c
+++ b/drivers/net/wan/hdlc_fr.c
@@ -212,14 +212,13 @@
pvc_p = &(*pvc_p)->next;
}
- pvc = kmalloc(sizeof(pvc_device), GFP_ATOMIC);
+ pvc = kzalloc(sizeof(pvc_device), GFP_ATOMIC);
#ifdef DEBUG_PVC
printk(KERN_DEBUG "add_pvc: allocated pvc %p, frad %p\n", pvc, dev);
#endif
if (!pvc)
return NULL;
- memset(pvc, 0, sizeof(pvc_device));
pvc->dlci = dlci;
pvc->frad = dev;
pvc->next = *pvc_p; /* Put it in the chain */
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_phy.c b/drivers/net/wireless/bcm43xx/bcm43xx_phy.c
index d779199..b37f1e3 100644
--- a/drivers/net/wireless/bcm43xx/bcm43xx_phy.c
+++ b/drivers/net/wireless/bcm43xx/bcm43xx_phy.c
@@ -1638,7 +1638,7 @@
return;
}
- if (phy->analog == 1) {
+ if (phy->analog > 1) {
value = bcm43xx_phy_read(bcm, 0x0060) & ~0x003C;
value |= (baseband_attenuation << 2) & 0x003C;
} else {
diff --git a/drivers/net/wireless/rtl8187_dev.c b/drivers/net/wireless/rtl8187_dev.c
index cea8589..e61c6d5 100644
--- a/drivers/net/wireless/rtl8187_dev.c
+++ b/drivers/net/wireless/rtl8187_dev.c
@@ -466,7 +466,7 @@
return -EOPNOTSUPP;
}
- priv->hwaddr = conf->mac_addr;
+ priv->hwaddr = conf->mac_addr ? conf->mac_addr : dev->wiphy->perm_addr;
return 0;
}
diff --git a/drivers/net/wireless/zd1211rw/zd_mac.c b/drivers/net/wireless/zd1211rw/zd_mac.c
index f6c487a..26869d1 100644
--- a/drivers/net/wireless/zd1211rw/zd_mac.c
+++ b/drivers/net/wireless/zd1211rw/zd_mac.c
@@ -822,7 +822,7 @@
cs->control |= ZD_CS_MULTICAST;
/* PS-POLL */
- if (stype == IEEE80211_STYPE_PSPOLL)
+ if (ftype == IEEE80211_FTYPE_CTL && stype == IEEE80211_STYPE_PSPOLL)
cs->control |= ZD_CS_PS_POLL_FRAME;
/* Unicast data frames over the threshold should have RTS */
diff --git a/drivers/net/xen-netfront.c b/drivers/net/xen-netfront.c
index 489f69c..4445810 100644
--- a/drivers/net/xen-netfront.c
+++ b/drivers/net/xen-netfront.c
@@ -566,6 +566,10 @@
if (notify)
notify_remote_via_irq(np->netdev->irq);
+ np->stats.tx_bytes += skb->len;
+ np->stats.tx_packets++;
+
+ /* Note: It is not safe to access skb after xennet_tx_buf_gc()! */
xennet_tx_buf_gc(dev);
if (!netfront_tx_slot_available(np))
@@ -573,9 +577,6 @@
spin_unlock_irq(&np->tx_lock);
- np->stats.tx_bytes += skb->len;
- np->stats.tx_packets++;
-
return 0;
drop:
diff --git a/drivers/pci/hotplug/acpiphp_ibm.c b/drivers/pci/hotplug/acpiphp_ibm.c
index 70db38c..56829f8 100644
--- a/drivers/pci/hotplug/acpiphp_ibm.c
+++ b/drivers/pci/hotplug/acpiphp_ibm.c
@@ -267,7 +267,10 @@
if (subevent == 0x80) {
dbg("%s: generationg bus event\n", __FUNCTION__);
- acpi_bus_generate_event(note->device, note->event, detail);
+ acpi_bus_generate_proc_event(note->device, note->event, detail);
+ acpi_bus_generate_netlink_event(note->device->pnp.device_class,
+ note->device->dev.bus_id,
+ note->event, detail);
} else
note->event = event;
}
@@ -399,7 +402,7 @@
status = acpi_get_object_info(handle, &info_buffer);
if (ACPI_FAILURE(status)) {
- err("%s: Failed to get device information", __FUNCTION__);
+ err("%s: Failed to get device information\n", __FUNCTION__);
return 0;
}
info.hardware_id.value[sizeof(info.hardware_id.value) - 1] = '\0';
diff --git a/drivers/pci/hotplug/cpqphp_ctrl.c b/drivers/pci/hotplug/cpqphp_ctrl.c
index 79ff6b4..37d72f1 100644
--- a/drivers/pci/hotplug/cpqphp_ctrl.c
+++ b/drivers/pci/hotplug/cpqphp_ctrl.c
@@ -1746,10 +1746,8 @@
static int event_thread(void* data)
{
struct controller *ctrl;
- lock_kernel();
+
daemonize("phpd_event");
-
- unlock_kernel();
while (1) {
dbg("!!!!event_thread sleeping\n");
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
index c6e132d..4c36e80 100644
--- a/drivers/pci/pci.h
+++ b/drivers/pci/pci.h
@@ -5,12 +5,7 @@
extern int pci_create_sysfs_dev_files(struct pci_dev *pdev);
extern void pci_remove_sysfs_dev_files(struct pci_dev *pdev);
extern void pci_cleanup_rom(struct pci_dev *dev);
-extern int pci_bus_alloc_resource(struct pci_bus *bus, struct resource *res,
- resource_size_t size, resource_size_t align,
- resource_size_t min, unsigned int type_mask,
- void (*alignf)(void *, struct resource *,
- resource_size_t, resource_size_t),
- void *alignf_data);
+
/* Firmware callbacks */
extern pci_power_t (*platform_pci_choose_state)(struct pci_dev *dev, pm_message_t state);
extern int (*platform_pci_set_power_state)(struct pci_dev *dev, pci_power_t state);
@@ -35,7 +30,6 @@
/* Functions for PCI Hotplug drivers to use */
extern unsigned int pci_do_scan_bus(struct pci_bus *bus);
-extern int pci_bus_find_capability (struct pci_bus *bus, unsigned int devfn, int cap);
extern void pci_remove_legacy_files(struct pci_bus *bus);
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index 34b8dae..27e00b2 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -653,20 +653,20 @@
sprintf(child->name, (is_cardbus ? "PCI CardBus #%02x" : "PCI Bus #%02x"), child->number);
+ /* Has only triggered on CardBus, fixup is in yenta_socket */
while (bus->parent) {
if ((child->subordinate > bus->subordinate) ||
(child->number > bus->subordinate) ||
(child->number < bus->number) ||
(child->subordinate < bus->number)) {
- printk(KERN_WARNING "PCI: Bus #%02x (-#%02x) is "
- "hidden behind%s bridge #%02x (-#%02x)%s\n",
- child->number, child->subordinate,
- bus->self->transparent ? " transparent" : " ",
- bus->number, bus->subordinate,
- pcibios_assign_all_busses() ? " " :
- " (try 'pci=assign-busses')");
- printk(KERN_WARNING "Please report the result to "
- "<bk@suse.de> to fix this permanently\n");
+ pr_debug("PCI: Bus #%02x (-#%02x) is %s"
+ "hidden behind%s bridge #%02x (-#%02x)\n",
+ child->number, child->subordinate,
+ (bus->number > child->subordinate &&
+ bus->subordinate < child->number) ?
+ "wholly " : " partially",
+ bus->self->transparent ? " transparent" : " ",
+ bus->number, bus->subordinate);
}
bus = bus->parent;
}
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
index c559085..2d40f43 100644
--- a/drivers/pci/quirks.c
+++ b/drivers/pci/quirks.c
@@ -947,7 +947,7 @@
unsigned char val;
pci_read_config_byte(dev, 0x50, &val);
- if (val == 0x88 || val == 0xc8) {
+ if (val == 0xc8) {
/* Assume it's probably a MSI-K8T-Neo2Fir */
printk(KERN_INFO "PCI: MSI-K8T-Neo2Fir, attempting to turn soundcard ON\n");
pci_write_config_byte(dev, 0x50, val & (~0x40));
@@ -1485,7 +1485,7 @@
iounmap(csr);
}
-DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, PCI_ANY_ID, quirk_e100_interrupt);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_ANY_ID, quirk_e100_interrupt);
static void __devinit fixup_rev1_53c810(struct pci_dev* dev)
{
@@ -1650,6 +1650,9 @@
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_HT1000_PCIX, quirk_disable_all_msi);
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RS400_200, quirk_disable_all_msi);
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RS480, quirk_disable_all_msi);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RD580, quirk_disable_all_msi);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RX790, quirk_disable_all_msi);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RS690, quirk_disable_all_msi);
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_VT3351, quirk_disable_all_msi);
/* Disable MSI on chipsets that are known to not support it */
diff --git a/drivers/pnp/card.c b/drivers/pnp/card.c
index b6a4f02..6c0440c 100644
--- a/drivers/pnp/card.c
+++ b/drivers/pnp/card.c
@@ -25,13 +25,13 @@
int found;
struct pnp_dev *dev;
- if (i == PNP_MAX_DEVICES
- || !*drv_id->devs[i].id)
+ if (i == PNP_MAX_DEVICES ||
+ !*drv_id->devs[i].id)
return drv_id;
found = 0;
card_for_each_dev(card, dev) {
- if (compare_pnp_id
- (dev->id, drv_id->devs[i].id)) {
+ if (compare_pnp_id(dev->id,
+ drv_id->devs[i].id)) {
found = 1;
break;
}
@@ -183,7 +183,7 @@
return 0;
- err_name:
+err_name:
device_remove_file(&card->dev, &dev_attr_name);
return rc;
}
@@ -321,10 +321,10 @@
pos = pos->next;
}
- done:
+done:
return NULL;
- found:
+found:
dev->card_link = clink;
dev->dev.driver = &drv->link.driver;
if (pnp_bus_type.probe(&dev->dev))
@@ -334,7 +334,7 @@
return dev;
- err_out:
+err_out:
dev->dev.driver = NULL;
dev->card_link = NULL;
return NULL;
diff --git a/drivers/pnp/core.c b/drivers/pnp/core.c
index 61066fd..d5964fe 100644
--- a/drivers/pnp/core.c
+++ b/drivers/pnp/core.c
@@ -52,9 +52,6 @@
int nodenum;
struct list_head *pos;
- if (!protocol)
- return -EINVAL;
-
INIT_LIST_HEAD(&protocol->devices);
INIT_LIST_HEAD(&protocol->cards);
nodenum = 0;
@@ -94,8 +91,6 @@
struct pnp_id *id;
struct pnp_id *next;
- if (!dev)
- return;
id = dev->id;
while (id) {
next = id->next;
@@ -143,7 +138,7 @@
*/
int pnp_add_device(struct pnp_dev *dev)
{
- if (!dev || !dev->protocol || dev->card)
+ if (dev->card)
return -EINVAL;
dev->dev.parent = &dev->protocol->dev;
sprintf(dev->dev.bus_id, "%02x:%02x", dev->protocol->number,
diff --git a/drivers/pnp/driver.c b/drivers/pnp/driver.c
index 30b8f6f..2fa64a6 100644
--- a/drivers/pnp/driver.c
+++ b/drivers/pnp/driver.c
@@ -118,7 +118,7 @@
goto fail;
return error;
- fail:
+fail:
pnp_device_detach(pnp_dev);
return error;
}
@@ -232,10 +232,6 @@
{
struct pnp_id *ptr;
- if (!id)
- return -EINVAL;
- if (!dev)
- return -EINVAL;
id->next = NULL;
ptr = dev->id;
while (ptr && ptr->next)
diff --git a/drivers/pnp/interface.c b/drivers/pnp/interface.c
index fe6684e..a0cfb75 100644
--- a/drivers/pnp/interface.c
+++ b/drivers/pnp/interface.c
@@ -459,7 +459,8 @@
up(&pnp_res_mutex);
goto done;
}
- done:
+
+done:
if (retval < 0)
return retval;
return count;
@@ -499,10 +500,10 @@
return 0;
- err_res:
+err_res:
device_remove_file(&dev->dev, &dev_attr_resources);
- err_opt:
+err_opt:
device_remove_file(&dev->dev, &dev_attr_options);
- err:
+err:
return rc;
}
diff --git a/drivers/pnp/isapnp/core.c b/drivers/pnp/isapnp/core.c
index b4e2aa9..b035d60 100644
--- a/drivers/pnp/isapnp/core.c
+++ b/drivers/pnp/isapnp/core.c
@@ -47,9 +47,6 @@
#if 0
#define ISAPNP_REGION_OK
#endif
-#if 0
-#define ISAPNP_DEBUG
-#endif
int isapnp_disable; /* Disable ISA PnP */
static int isapnp_rdp; /* Read Data Port */
@@ -93,7 +90,6 @@
static unsigned char isapnp_checksum_value;
static DEFINE_MUTEX(isapnp_cfg_mutex);
-static int isapnp_detected;
static int isapnp_csn_count;
/* some prototypes */
@@ -335,7 +331,7 @@
} else if (iteration > 1) {
break;
}
- __next:
+__next:
if (csn == 255)
break;
checksum = 0x6a;
@@ -733,7 +729,7 @@
"isapnp: unexpected or unknown tag type 0x%x for logical device %i (device %i), ignored\n",
type, dev->number, card->number);
}
- __skip:
+__skip:
if (size > 0)
isapnp_skip_bytes(size);
}
@@ -788,7 +784,7 @@
"isapnp: unexpected or unknown tag type 0x%x for device %i, ignored\n",
type, card->number);
}
- __skip:
+__skip:
if (size > 0)
isapnp_skip_bytes(size);
}
@@ -940,9 +936,6 @@
EXPORT_SYMBOL(isapnp_present);
EXPORT_SYMBOL(isapnp_cfg_begin);
EXPORT_SYMBOL(isapnp_cfg_end);
-#if 0
-EXPORT_SYMBOL(isapnp_read_byte);
-#endif
EXPORT_SYMBOL(isapnp_write_byte);
static int isapnp_read_resources(struct pnp_dev *dev,
@@ -993,6 +986,7 @@
struct pnp_resource_table *res)
{
int ret;
+
pnp_init_resource_table(res);
isapnp_cfg_begin(dev->card->number, dev->number);
ret = isapnp_read_resources(dev, res);
@@ -1046,7 +1040,7 @@
static int isapnp_disable_resources(struct pnp_dev *dev)
{
- if (!dev || !dev->active)
+ if (!dev->active)
return -EINVAL;
isapnp_cfg_begin(dev->card->number, dev->number);
isapnp_deactivate(dev->number);
@@ -1069,7 +1063,6 @@
struct pnp_dev *dev;
if (isapnp_disable) {
- isapnp_detected = 0;
printk(KERN_INFO "isapnp: ISA Plug & Play support disabled\n");
return 0;
}
@@ -1117,7 +1110,6 @@
}
isapnp_set_rdp();
}
- isapnp_detected = 1;
if (isapnp_rdp < 0x203 || isapnp_rdp > 0x3ff) {
cards = isapnp_isolate();
if (cards < 0 || (isapnp_rdp < 0x203 || isapnp_rdp > 0x3ff)) {
@@ -1125,7 +1117,6 @@
release_region(_PIDXR, 1);
#endif
release_region(_PNPWRP, 1);
- isapnp_detected = 0;
printk(KERN_INFO
"isapnp: No Plug & Play device found\n");
return 0;
@@ -1148,13 +1139,12 @@
}
}
}
- if (cards) {
+ if (cards)
printk(KERN_INFO
"isapnp: %i Plug & Play card%s detected total\n", cards,
cards > 1 ? "s" : "");
- } else {
+ else
printk(KERN_INFO "isapnp: No Plug & Play card found\n");
- }
isapnp_proc_init();
return 0;
diff --git a/drivers/pnp/isapnp/proc.c b/drivers/pnp/isapnp/proc.c
index 3fbc0f9..560ccb6 100644
--- a/drivers/pnp/isapnp/proc.c
+++ b/drivers/pnp/isapnp/proc.c
@@ -112,33 +112,6 @@
return 0;
}
-#ifdef MODULE
-static int __exit isapnp_proc_detach_device(struct pnp_dev *dev)
-{
- struct pnp_card *bus = dev->card;
- struct proc_dir_entry *de;
- char name[16];
-
- if (!(de = bus->procdir))
- return -EINVAL;
- sprintf(name, "%02x", dev->number);
- remove_proc_entry(name, de);
- return 0;
-}
-
-static int __exit isapnp_proc_detach_bus(struct pnp_card *bus)
-{
- struct proc_dir_entry *de;
- char name[16];
-
- if (!(de = bus->procdir))
- return -EINVAL;
- sprintf(name, "%02x", bus->number);
- remove_proc_entry(name, isapnp_proc_bus_dir);
- return 0;
-}
-#endif /* MODULE */
-
int __init isapnp_proc_init(void)
{
struct pnp_dev *dev;
@@ -149,21 +122,3 @@
}
return 0;
}
-
-#ifdef MODULE
-int __exit isapnp_proc_done(void)
-{
- struct pnp_dev *dev;
- struct pnp_bus *card;
-
- isapnp_for_each_dev(dev) {
- isapnp_proc_detach_device(dev);
- }
- isapnp_for_each_card(card) {
- isapnp_proc_detach_bus(card);
- }
- if (isapnp_proc_bus_dir)
- remove_proc_entry("isapnp", proc_bus);
- return 0;
-}
-#endif /* MODULE */
diff --git a/drivers/pnp/manager.c b/drivers/pnp/manager.c
index 3bda513..0826287e 100644
--- a/drivers/pnp/manager.c
+++ b/drivers/pnp/manager.c
@@ -21,9 +21,6 @@
resource_size_t *start, *end;
unsigned long *flags;
- if (!dev || !rule)
- return -EINVAL;
-
if (idx >= PNP_MAX_PORT) {
pnp_err
("More than 4 ports is incompatible with pnp specifications.");
@@ -66,9 +63,6 @@
resource_size_t *start, *end;
unsigned long *flags;
- if (!dev || !rule)
- return -EINVAL;
-
if (idx >= PNP_MAX_MEM) {
pnp_err
("More than 8 mems is incompatible with pnp specifications.");
@@ -127,9 +121,6 @@
5, 10, 11, 12, 9, 14, 15, 7, 3, 4, 13, 0, 1, 6, 8, 2
};
- if (!dev || !rule)
- return -EINVAL;
-
if (idx >= PNP_MAX_IRQ) {
pnp_err
("More than 2 irqs is incompatible with pnp specifications.");
@@ -181,9 +172,6 @@
1, 3, 5, 6, 7, 0, 2, 4
};
- if (!dev || !rule)
- return -EINVAL;
-
if (idx >= PNP_MAX_DMA) {
pnp_err
("More than 2 dmas is incompatible with pnp specifications.");
@@ -390,7 +378,7 @@
up(&pnp_res_mutex);
return 1;
- fail:
+fail:
pnp_clean_resource_table(&dev->res);
up(&pnp_res_mutex);
return 0;
@@ -410,8 +398,6 @@
int i;
struct pnp_resource_table *bak;
- if (!dev || !res)
- return -EINVAL;
if (!pnp_can_configure(dev))
return -ENODEV;
bak = pnp_alloc(sizeof(struct pnp_resource_table));
@@ -444,7 +430,7 @@
kfree(bak);
return 0;
- fail:
+fail:
dev->res = *bak;
up(&pnp_res_mutex);
kfree(bak);
@@ -460,9 +446,6 @@
struct pnp_option *dep;
int i = 1;
- if (!dev)
- return -EINVAL;
-
if (!pnp_can_configure(dev)) {
pnp_dbg("Device %s does not support resource configuration.",
dev->dev.bus_id);
@@ -541,8 +524,6 @@
{
int error;
- if (!dev)
- return -EINVAL;
if (dev->active)
return 0; /* the device is already active */
@@ -568,8 +549,6 @@
{
int error;
- if (!dev)
- return -EINVAL;
if (!dev->active)
return 0; /* the device is already disabled */
@@ -596,8 +575,6 @@
void pnp_resource_change(struct resource *resource, resource_size_t start,
resource_size_t size)
{
- if (resource == NULL)
- return;
resource->flags &= ~(IORESOURCE_AUTO | IORESOURCE_UNSET);
resource->start = start;
resource->end = start + size - 1;
diff --git a/drivers/pnp/pnpacpi/core.c b/drivers/pnp/pnpacpi/core.c
index 616fc72..a5a3722 100644
--- a/drivers/pnp/pnpacpi/core.c
+++ b/drivers/pnp/pnpacpi/core.c
@@ -248,9 +248,9 @@
num++;
return AE_OK;
- err1:
+err1:
kfree(dev_id);
- err:
+err:
kfree(dev);
return -EINVAL;
}
diff --git a/drivers/pnp/pnpacpi/rsparser.c b/drivers/pnp/pnpacpi/rsparser.c
index ce5027f..0e3b8d0 100644
--- a/drivers/pnp/pnpacpi/rsparser.c
+++ b/drivers/pnp/pnpacpi/rsparser.c
@@ -34,19 +34,17 @@
*/
static int irq_flags(int triggering, int polarity)
{
- int flag;
if (triggering == ACPI_LEVEL_SENSITIVE) {
if (polarity == ACPI_ACTIVE_LOW)
- flag = IORESOURCE_IRQ_LOWLEVEL;
+ return IORESOURCE_IRQ_LOWLEVEL;
else
- flag = IORESOURCE_IRQ_HIGHLEVEL;
+ return IORESOURCE_IRQ_HIGHLEVEL;
} else {
if (polarity == ACPI_ACTIVE_LOW)
- flag = IORESOURCE_IRQ_LOWEDGE;
+ return IORESOURCE_IRQ_LOWEDGE;
else
- flag = IORESOURCE_IRQ_HIGHEDGE;
+ return IORESOURCE_IRQ_HIGHEDGE;
}
- return flag;
}
static void decode_irq_flags(int flag, int *triggering, int *polarity)
@@ -242,8 +240,7 @@
static acpi_status pnpacpi_allocated_resource(struct acpi_resource *res,
void *data)
{
- struct pnp_resource_table *res_table =
- (struct pnp_resource_table *)data;
+ struct pnp_resource_table *res_table = data;
int i;
switch (res->type) {
@@ -566,8 +563,7 @@
void *data)
{
int priority = 0;
- struct acpipnp_parse_option_s *parse_data =
- (struct acpipnp_parse_option_s *)data;
+ struct acpipnp_parse_option_s *parse_data = data;
struct pnp_dev *dev = parse_data->dev;
struct pnp_option *option = parse_data->option;
@@ -705,7 +701,7 @@
static acpi_status pnpacpi_count_resources(struct acpi_resource *res,
void *data)
{
- int *res_cnt = (int *)data;
+ int *res_cnt = data;
if (pnpacpi_supported_resource(res))
(*res_cnt)++;
@@ -714,7 +710,7 @@
static acpi_status pnpacpi_type_resources(struct acpi_resource *res, void *data)
{
- struct acpi_resource **resource = (struct acpi_resource **)data;
+ struct acpi_resource **resource = data;
if (pnpacpi_supported_resource(res)) {
(*resource)->type = res->type;
@@ -886,8 +882,7 @@
int i = 0;
/* pnpacpi_build_resource_template allocates extra mem */
int res_cnt = (buffer->length - 1) / sizeof(struct acpi_resource) - 1;
- struct acpi_resource *resource =
- (struct acpi_resource *)buffer->pointer;
+ struct acpi_resource *resource = buffer->pointer;
int port = 0, irq = 0, dma = 0, mem = 0;
pnp_dbg("res cnt %d", res_cnt);
diff --git a/drivers/pnp/pnpbios/core.c b/drivers/pnp/pnpbios/core.c
index 3692a09..0691f47 100644
--- a/drivers/pnp/pnpbios/core.c
+++ b/drivers/pnp/pnpbios/core.c
@@ -419,7 +419,6 @@
static int pnpbios_disabled;
int pnpbios_dont_use_current_config;
-#ifndef MODULE
static int __init pnpbios_setup(char *str)
{
int invert;
@@ -443,7 +442,6 @@
}
__setup("pnpbios=", pnpbios_setup);
-#endif
/* PnP BIOS signature: "$PnP" */
#define PNP_SIGNATURE (('$' << 0) + ('P' << 8) + ('n' << 16) + ('P' << 24))
@@ -591,6 +589,7 @@
static int __init pnpbios_thread_init(void)
{
struct task_struct *task;
+
#if defined(CONFIG_PPC_MERGE)
if (check_legacy_ioport(PNPBIOS_BASE))
return 0;
@@ -606,48 +605,7 @@
return 0;
}
-#ifndef MODULE
-
-/* init/main.c calls pnpbios_init early */
-
/* Start the kernel thread later: */
module_init(pnpbios_thread_init);
-#else
-
-/*
- * N.B.: Building pnpbios as a module hasn't been fully implemented
- */
-
-MODULE_LICENSE("GPL");
-
-static int __init pnpbios_init_all(void)
-{
- int r;
-
- r = pnpbios_init();
- if (r)
- return r;
- r = pnpbios_thread_init();
- if (r)
- return r;
- return 0;
-}
-
-static void __exit pnpbios_exit(void)
-{
-#ifdef CONFIG_HOTPLUG
- unloading = 1;
- wait_for_completion(&unload_sem);
-#endif
- pnpbios_proc_exit();
- /* We ought to free resources here */
- return;
-}
-
-module_init(pnpbios_init_all);
-module_exit(pnpbios_exit);
-
-#endif
-
EXPORT_SYMBOL(pnpbios_protocol);
diff --git a/drivers/pnp/pnpbios/proc.c b/drivers/pnp/pnpbios/proc.c
index 9c8c077..9d9841f 100644
--- a/drivers/pnp/pnpbios/proc.c
+++ b/drivers/pnp/pnpbios/proc.c
@@ -212,7 +212,7 @@
goto out;
}
ret = count;
- out:
+out:
kfree(node);
return ret;
}
diff --git a/drivers/pnp/pnpbios/rsparser.c b/drivers/pnp/pnpbios/rsparser.c
index 04ecd7b..3fabf11 100644
--- a/drivers/pnp/pnpbios/rsparser.c
+++ b/drivers/pnp/pnpbios/rsparser.c
@@ -238,7 +238,7 @@
break;
default: /* an unkown tag */
- len_err:
+len_err:
printk(KERN_ERR
"PnPBIOS: Unknown tag '0x%x', length '%d'.\n",
tag, len);
@@ -298,6 +298,7 @@
struct pnp_option *option)
{
struct pnp_mem *mem;
+
mem = kzalloc(sizeof(struct pnp_mem), GFP_KERNEL);
if (!mem)
return;
@@ -468,7 +469,7 @@
return p + 2;
default: /* an unkown tag */
- len_err:
+len_err:
printk(KERN_ERR
"PnPBIOS: Unknown tag '0x%x', length '%d'.\n",
tag, len);
@@ -562,7 +563,7 @@
break;
default: /* an unkown tag */
- len_err:
+len_err:
printk(KERN_ERR
"PnPBIOS: Unknown tag '0x%x', length '%d'.\n",
tag, len);
@@ -756,7 +757,7 @@
break;
default: /* an unkown tag */
- len_err:
+len_err:
printk(KERN_ERR
"PnPBIOS: Unknown tag '0x%x', length '%d'.\n",
tag, len);
diff --git a/drivers/pnp/resource.c b/drivers/pnp/resource.c
index ea6ec14..ef12869 100644
--- a/drivers/pnp/resource.c
+++ b/drivers/pnp/resource.c
@@ -47,9 +47,6 @@
{
struct pnp_option *option;
- if (!dev)
- return NULL;
-
option = pnp_build_option(PNP_RES_PRIORITY_PREFERRED);
/* this should never happen but if it does we'll try to continue */
@@ -64,9 +61,6 @@
{
struct pnp_option *option;
- if (!dev)
- return NULL;
-
option = pnp_build_option(priority);
if (dev->dependent) {
@@ -83,11 +77,6 @@
{
struct pnp_irq *ptr;
- if (!option)
- return -EINVAL;
- if (!data)
- return -EINVAL;
-
ptr = option->irq;
while (ptr && ptr->next)
ptr = ptr->next;
@@ -112,11 +101,6 @@
{
struct pnp_dma *ptr;
- if (!option)
- return -EINVAL;
- if (!data)
- return -EINVAL;
-
ptr = option->dma;
while (ptr && ptr->next)
ptr = ptr->next;
@@ -132,11 +116,6 @@
{
struct pnp_port *ptr;
- if (!option)
- return -EINVAL;
- if (!data)
- return -EINVAL;
-
ptr = option->port;
while (ptr && ptr->next)
ptr = ptr->next;
@@ -152,11 +131,6 @@
{
struct pnp_mem *ptr;
- if (!option)
- return -EINVAL;
- if (!data)
- return -EINVAL;
-
ptr = option->mem;
while (ptr && ptr->next)
ptr = ptr->next;
diff --git a/drivers/rtc/rtc-m41t80.c b/drivers/rtc/rtc-m41t80.c
index 80c4a84..1cb33ca 100644
--- a/drivers/rtc/rtc-m41t80.c
+++ b/drivers/rtc/rtc-m41t80.c
@@ -892,7 +892,7 @@
static struct i2c_driver m41t80_driver = {
.driver = {
- .name = "m41t80",
+ .name = "rtc-m41t80",
},
.probe = m41t80_probe,
.remove = m41t80_remove,
diff --git a/drivers/rtc/rtc-max6902.c b/drivers/rtc/rtc-max6902.c
index d941707..3e183cf 100644
--- a/drivers/rtc/rtc-max6902.c
+++ b/drivers/rtc/rtc-max6902.c
@@ -13,7 +13,7 @@
*
* 24-May-2006: Raphael Assenat <raph@8d.com>
* - Major rework
- * Converted to rtc_device and uses the SPI layer.
+ * Converted to rtc_device and uses the SPI layer.
*
* ??-???-2005: Someone at Compulab
* - Initial driver creation.
@@ -259,11 +259,11 @@
static struct spi_driver max6902_driver = {
.driver = {
- .name = "max6902",
+ .name = "rtc-max6902",
.bus = &spi_bus_type,
.owner = THIS_MODULE,
},
- .probe = max6902_probe,
+ .probe = max6902_probe,
.remove = __devexit_p(max6902_remove),
};
diff --git a/drivers/s390/block/dasd_diag.c b/drivers/s390/block/dasd_diag.c
index eccac1c..d32c60d 100644
--- a/drivers/s390/block/dasd_diag.c
+++ b/drivers/s390/block/dasd_diag.c
@@ -24,6 +24,7 @@
#include <asm/s390_ext.h>
#include <asm/todclk.h>
#include <asm/vtoc.h>
+#include <asm/diag.h>
#include "dasd_int.h"
#include "dasd_diag.h"
diff --git a/drivers/s390/char/monwriter.c b/drivers/s390/char/monwriter.c
index 268598e..20442fb 100644
--- a/drivers/s390/char/monwriter.c
+++ b/drivers/s390/char/monwriter.c
@@ -17,6 +17,7 @@
#include <linux/miscdevice.h>
#include <linux/ctype.h>
#include <linux/poll.h>
+#include <linux/mutex.h>
#include <asm/uaccess.h>
#include <asm/ebcdic.h>
#include <asm/io.h>
@@ -41,6 +42,7 @@
size_t hdr_to_read;
size_t data_to_read;
struct mon_buf *current_buf;
+ struct mutex thread_mutex;
};
/*
@@ -179,6 +181,7 @@
return -ENOMEM;
INIT_LIST_HEAD(&monpriv->list);
monpriv->hdr_to_read = sizeof(monpriv->hdr);
+ mutex_init(&monpriv->thread_mutex);
filp->private_data = monpriv;
return nonseekable_open(inode, filp);
}
@@ -209,6 +212,7 @@
void *to;
int rc;
+ mutex_lock(&monpriv->thread_mutex);
for (written = 0; written < count; ) {
if (monpriv->hdr_to_read) {
len = min(count - written, monpriv->hdr_to_read);
@@ -247,11 +251,13 @@
}
monpriv->hdr_to_read = sizeof(monpriv->hdr);
}
+ mutex_unlock(&monpriv->thread_mutex);
return written;
out_error:
monpriv->data_to_read = 0;
monpriv->hdr_to_read = sizeof(struct monwrite_hdr);
+ mutex_unlock(&monpriv->thread_mutex);
return rc;
}
diff --git a/drivers/s390/char/raw3270.c b/drivers/s390/char/raw3270.c
index 4f2f81b..2edd5fb 100644
--- a/drivers/s390/char/raw3270.c
+++ b/drivers/s390/char/raw3270.c
@@ -21,6 +21,7 @@
#include <asm/ccwdev.h>
#include <asm/cio.h>
#include <asm/ebcdic.h>
+#include <asm/diag.h>
#include "raw3270.h"
diff --git a/drivers/s390/char/vmur.c b/drivers/s390/char/vmur.c
index 161867c..d70a6e6 100644
--- a/drivers/s390/char/vmur.c
+++ b/drivers/s390/char/vmur.c
@@ -14,6 +14,7 @@
#include <asm/cio.h>
#include <asm/ccwdev.h>
#include <asm/debug.h>
+#include <asm/diag.h>
#include "vmur.h"
@@ -68,8 +69,26 @@
.set_offline = ur_set_offline,
};
+static DEFINE_MUTEX(vmur_mutex);
+
/*
* Allocation, freeing, getting and putting of urdev structures
+ *
+ * Each ur device (urd) contains a reference to its corresponding ccw device
+ * (cdev) using the urd->cdev pointer. Each ccw device has a reference to the
+ * ur device using the cdev->dev.driver_data pointer.
+ *
+ * urd references:
+ * - ur_probe gets a urd reference, ur_remove drops the reference
+ * (cdev->dev.driver_data)
+ * - ur_open gets a urd reference, ur_relase drops the reference
+ * (urf->urd)
+ *
+ * cdev references:
+ * - urdev_alloc get a cdev reference (urd->cdev)
+ * - urdev_free drops the cdev reference (urd->cdev)
+ *
+ * Setting and clearing of cdev->dev.driver_data is protected by the ccwdev lock
*/
static struct urdev *urdev_alloc(struct ccw_device *cdev)
{
@@ -78,51 +97,72 @@
urd = kzalloc(sizeof(struct urdev), GFP_KERNEL);
if (!urd)
return NULL;
- urd->cdev = cdev;
urd->reclen = cdev->id.driver_info;
ccw_device_get_id(cdev, &urd->dev_id);
mutex_init(&urd->io_mutex);
mutex_init(&urd->open_mutex);
+ atomic_set(&urd->ref_count, 1);
+ urd->cdev = cdev;
+ get_device(&cdev->dev);
return urd;
}
static void urdev_free(struct urdev *urd)
{
+ TRACE("urdev_free: %p\n", urd);
+ if (urd->cdev)
+ put_device(&urd->cdev->dev);
kfree(urd);
}
-/*
- * This is how the character device driver gets a reference to a
- * ur device. When this call returns successfully, a reference has
- * been taken (by get_device) on the underlying kobject. The recipient
- * of this urdev pointer must eventually drop it with urdev_put(urd)
- * which does the corresponding put_device().
- */
+static void urdev_get(struct urdev *urd)
+{
+ atomic_inc(&urd->ref_count);
+}
+
+static struct urdev *urdev_get_from_cdev(struct ccw_device *cdev)
+{
+ struct urdev *urd;
+ unsigned long flags;
+
+ spin_lock_irqsave(get_ccwdev_lock(cdev), flags);
+ urd = cdev->dev.driver_data;
+ if (urd)
+ urdev_get(urd);
+ spin_unlock_irqrestore(get_ccwdev_lock(cdev), flags);
+ return urd;
+}
+
static struct urdev *urdev_get_from_devno(u16 devno)
{
char bus_id[16];
struct ccw_device *cdev;
+ struct urdev *urd;
sprintf(bus_id, "0.0.%04x", devno);
cdev = get_ccwdev_by_busid(&ur_driver, bus_id);
if (!cdev)
return NULL;
-
- return cdev->dev.driver_data;
+ urd = urdev_get_from_cdev(cdev);
+ put_device(&cdev->dev);
+ return urd;
}
static void urdev_put(struct urdev *urd)
{
- put_device(&urd->cdev->dev);
+ if (atomic_dec_and_test(&urd->ref_count))
+ urdev_free(urd);
}
/*
* Low-level functions to do I/O to a ur device.
* alloc_chan_prog
+ * free_chan_prog
* do_ur_io
* ur_int_handler
*
* alloc_chan_prog allocates and builds the channel program
+ * free_chan_prog frees memory of the channel program
*
* do_ur_io issues the channel program to the device and blocks waiting
* on a completion event it publishes at urd->io_done. The function
@@ -137,6 +177,16 @@
* address pointer that alloc_chan_prog returned.
*/
+static void free_chan_prog(struct ccw1 *cpa)
+{
+ struct ccw1 *ptr = cpa;
+
+ while (ptr->cda) {
+ kfree((void *)(addr_t) ptr->cda);
+ ptr++;
+ }
+ kfree(cpa);
+}
/*
* alloc_chan_prog
@@ -144,44 +194,45 @@
* with a final NOP CCW command-chained on (which ensures that CE and DE
* are presented together in a single interrupt instead of as separate
* interrupts unless an incorrect length indication kicks in first). The
- * data length in each CCW is reclen. The caller must ensure that count
- * is an integral multiple of reclen.
- * The channel program pointer returned by this function must be freed
- * with kfree. The caller is responsible for checking that
- * count/reclen is not ridiculously large.
+ * data length in each CCW is reclen.
*/
-static struct ccw1 *alloc_chan_prog(char *buf, size_t count, size_t reclen)
+static struct ccw1 *alloc_chan_prog(const char __user *ubuf, int rec_count,
+ int reclen)
{
- size_t num_ccws;
struct ccw1 *cpa;
+ void *kbuf;
int i;
- TRACE("alloc_chan_prog(%p, %zu, %zu)\n", buf, count, reclen);
+ TRACE("alloc_chan_prog(%p, %i, %i)\n", ubuf, rec_count, reclen);
/*
* We chain a NOP onto the writes to force CE+DE together.
* That means we allocate room for CCWs to cover count/reclen
* records plus a NOP.
*/
- num_ccws = count / reclen + 1;
- cpa = kmalloc(num_ccws * sizeof(struct ccw1), GFP_KERNEL | GFP_DMA);
+ cpa = kzalloc((rec_count + 1) * sizeof(struct ccw1),
+ GFP_KERNEL | GFP_DMA);
if (!cpa)
- return NULL;
+ return ERR_PTR(-ENOMEM);
- for (i = 0; count; i++) {
+ for (i = 0; i < rec_count; i++) {
cpa[i].cmd_code = WRITE_CCW_CMD;
cpa[i].flags = CCW_FLAG_CC | CCW_FLAG_SLI;
cpa[i].count = reclen;
- cpa[i].cda = __pa(buf);
- buf += reclen;
- count -= reclen;
+ kbuf = kmalloc(reclen, GFP_KERNEL | GFP_DMA);
+ if (!kbuf) {
+ free_chan_prog(cpa);
+ return ERR_PTR(-ENOMEM);
+ }
+ cpa[i].cda = (u32)(addr_t) kbuf;
+ if (copy_from_user(kbuf, ubuf, reclen)) {
+ free_chan_prog(cpa);
+ return ERR_PTR(-EFAULT);
+ }
+ ubuf += reclen;
}
/* The following NOP CCW forces CE+DE to be presented together */
cpa[i].cmd_code = CCW_CMD_NOOP;
- cpa[i].flags = 0;
- cpa[i].count = 0;
- cpa[i].cda = 0;
-
return cpa;
}
@@ -189,7 +240,7 @@
{
int rc;
struct ccw_device *cdev = urd->cdev;
- DECLARE_COMPLETION(event);
+ DECLARE_COMPLETION_ONSTACK(event);
TRACE("do_ur_io: cpa=%p\n", cpa);
@@ -232,6 +283,7 @@
return;
}
urd = cdev->dev.driver_data;
+ BUG_ON(!urd);
/* On special conditions irb is an error pointer */
if (IS_ERR(irb))
urd->io_request_rc = PTR_ERR(irb);
@@ -249,9 +301,15 @@
static ssize_t ur_attr_reclen_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
- struct urdev *urd = dev->driver_data;
+ struct urdev *urd;
+ int rc;
- return sprintf(buf, "%zu\n", urd->reclen);
+ urd = urdev_get_from_cdev(to_ccwdev(dev));
+ if (!urd)
+ return -ENODEV;
+ rc = sprintf(buf, "%zu\n", urd->reclen);
+ urdev_put(urd);
+ return rc;
}
static DEVICE_ATTR(reclen, 0444, ur_attr_reclen_show, NULL);
@@ -325,24 +383,11 @@
size_t count, size_t reclen, loff_t *ppos)
{
struct ccw1 *cpa;
- char *buf;
int rc;
- /* Data buffer must be under 2GB line for fmt1 CCWs: hence GFP_DMA */
- buf = kmalloc(count, GFP_KERNEL | GFP_DMA);
- if (!buf)
- return -ENOMEM;
-
- if (copy_from_user(buf, udata, count)) {
- rc = -EFAULT;
- goto fail_kfree_buf;
- }
-
- cpa = alloc_chan_prog(buf, count, reclen);
- if (!cpa) {
- rc = -ENOMEM;
- goto fail_kfree_buf;
- }
+ cpa = alloc_chan_prog(udata, count / reclen, reclen);
+ if (IS_ERR(cpa))
+ return PTR_ERR(cpa);
rc = do_ur_io(urd, cpa);
if (rc)
@@ -354,10 +399,9 @@
}
*ppos += count;
rc = count;
+
fail_kfree_cpa:
- kfree(cpa);
-fail_kfree_buf:
- kfree(buf);
+ free_chan_prog(cpa);
return rc;
}
@@ -380,31 +424,6 @@
return do_write(urf->urd, udata, count, urf->dev_reclen, ppos);
}
-static int do_diag_14(unsigned long rx, unsigned long ry1,
- unsigned long subcode)
-{
- register unsigned long _ry1 asm("2") = ry1;
- register unsigned long _ry2 asm("3") = subcode;
- int rc = 0;
-
- asm volatile(
-#ifdef CONFIG_64BIT
- " sam31\n"
- " diag %2,2,0x14\n"
- " sam64\n"
-#else
- " diag %2,2,0x14\n"
-#endif
- " ipm %0\n"
- " srl %0,28\n"
- : "=d" (rc), "+d" (_ry2)
- : "d" (rx), "d" (_ry1)
- : "cc");
-
- TRACE("diag 14: subcode=0x%lx, cc=%i\n", subcode, rc);
- return rc;
-}
-
/*
* diagnose code 0x14 subcode 0x0028 - position spool file to designated
* record
@@ -416,7 +435,7 @@
{
int cc;
- cc = do_diag_14(record, devno, 0x28);
+ cc = diag14(record, devno, 0x28);
switch (cc) {
case 0:
return 0;
@@ -441,7 +460,7 @@
{
int cc;
- cc = do_diag_14((unsigned long) buf, devno, 0x00);
+ cc = diag14((unsigned long) buf, devno, 0x00);
switch (cc) {
case 0:
return 0;
@@ -473,7 +492,7 @@
return rc;
len = min((size_t) PAGE_SIZE, count);
- buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
+ buf = (char *) __get_free_page(GFP_KERNEL | GFP_DMA);
if (!buf)
return -ENOMEM;
@@ -500,7 +519,7 @@
*offs += copied;
rc = copied;
fail:
- kfree(buf);
+ free_page((unsigned long) buf);
return rc;
}
@@ -534,7 +553,7 @@
{
int cc;
- cc = do_diag_14((unsigned long) buf, spid, 0xfff);
+ cc = diag14((unsigned long) buf, spid, 0xfff);
switch (cc) {
case 0:
return 0;
@@ -543,56 +562,97 @@
}
}
-static int verify_device(struct urdev *urd)
+static int verify_uri_device(struct urdev *urd)
{
- struct file_control_block fcb;
+ struct file_control_block *fcb;
char *buf;
int rc;
+ fcb = kmalloc(sizeof(*fcb), GFP_KERNEL | GFP_DMA);
+ if (!fcb)
+ return -ENOMEM;
+
+ /* check for empty reader device (beginning of chain) */
+ rc = diag_read_next_file_info(fcb, 0);
+ if (rc)
+ goto fail_free_fcb;
+
+ /* if file is in hold status, we do not read it */
+ if (fcb->file_stat & (FLG_SYSTEM_HOLD | FLG_USER_HOLD)) {
+ rc = -EPERM;
+ goto fail_free_fcb;
+ }
+
+ /* open file on virtual reader */
+ buf = (char *) __get_free_page(GFP_KERNEL | GFP_DMA);
+ if (!buf) {
+ rc = -ENOMEM;
+ goto fail_free_fcb;
+ }
+ rc = diag_read_file(urd->dev_id.devno, buf);
+ if ((rc != 0) && (rc != -ENODATA)) /* EOF does not hurt */
+ goto fail_free_buf;
+
+ /* check if the file on top of the queue is open now */
+ rc = diag_read_next_file_info(fcb, 0);
+ if (rc)
+ goto fail_free_buf;
+ if (!(fcb->file_stat & FLG_IN_USE)) {
+ rc = -EMFILE;
+ goto fail_free_buf;
+ }
+ rc = 0;
+
+fail_free_buf:
+ free_page((unsigned long) buf);
+fail_free_fcb:
+ kfree(fcb);
+ return rc;
+}
+
+static int verify_device(struct urdev *urd)
+{
switch (urd->class) {
case DEV_CLASS_UR_O:
return 0; /* no check needed here */
case DEV_CLASS_UR_I:
- /* check for empty reader device (beginning of chain) */
- rc = diag_read_next_file_info(&fcb, 0);
- if (rc)
- return rc;
-
- /* open file on virtual reader */
- buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
- if (!buf)
- return -ENOMEM;
- rc = diag_read_file(urd->dev_id.devno, buf);
- kfree(buf);
-
- if ((rc != 0) && (rc != -ENODATA)) /* EOF does not hurt */
- return rc;
- return 0;
+ return verify_uri_device(urd);
default:
return -ENOTSUPP;
}
}
-static int get_file_reclen(struct urdev *urd)
+static int get_uri_file_reclen(struct urdev *urd)
{
- struct file_control_block fcb;
+ struct file_control_block *fcb;
int rc;
+ fcb = kmalloc(sizeof(*fcb), GFP_KERNEL | GFP_DMA);
+ if (!fcb)
+ return -ENOMEM;
+ rc = diag_read_next_file_info(fcb, 0);
+ if (rc)
+ goto fail_free;
+ if (fcb->file_stat & FLG_CP_DUMP)
+ rc = 0;
+ else
+ rc = fcb->rec_len;
+
+fail_free:
+ kfree(fcb);
+ return rc;
+}
+
+static int get_file_reclen(struct urdev *urd)
+{
switch (urd->class) {
case DEV_CLASS_UR_O:
return 0;
case DEV_CLASS_UR_I:
- rc = diag_read_next_file_info(&fcb, 0);
- if (rc)
- return rc;
- break;
+ return get_uri_file_reclen(urd);
default:
return -ENOTSUPP;
}
- if (fcb.file_stat & FLG_CP_DUMP)
- return 0;
-
- return fcb.rec_len;
}
static int ur_open(struct inode *inode, struct file *file)
@@ -710,64 +770,63 @@
/*
* ccw_device infrastructure:
- * ur_probe gets its own ref to the device (i.e. get_device),
- * creates the struct urdev, the device attributes, sets up
- * the interrupt handler and validates the virtual unit record device.
- * ur_remove removes the device attributes, frees the struct urdev
- * and drops (put_device) the ref to the device we got in ur_probe.
+ * ur_probe creates the struct urdev (with refcount = 1), the device
+ * attributes, sets up the interrupt handler and validates the virtual
+ * unit record device.
+ * ur_remove removes the device attributes and drops the reference to
+ * struct urdev.
+ *
+ * ur_probe, ur_remove, ur_set_online and ur_set_offline are serialized
+ * by the vmur_mutex lock.
+ *
+ * urd->char_device is used as indication that the online function has
+ * been completed successfully.
*/
static int ur_probe(struct ccw_device *cdev)
{
struct urdev *urd;
int rc;
- TRACE("ur_probe: cdev=%p state=%d\n", cdev, *(int *) cdev->private);
+ TRACE("ur_probe: cdev=%p\n", cdev);
- if (!get_device(&cdev->dev))
- return -ENODEV;
-
+ mutex_lock(&vmur_mutex);
urd = urdev_alloc(cdev);
if (!urd) {
rc = -ENOMEM;
- goto fail;
+ goto fail_unlock;
}
+
rc = ur_create_attributes(&cdev->dev);
if (rc) {
rc = -ENOMEM;
- goto fail;
+ goto fail_urdev_put;
}
- cdev->dev.driver_data = urd;
cdev->handler = ur_int_handler;
/* validate virtual unit record device */
urd->class = get_urd_class(urd);
if (urd->class < 0) {
rc = urd->class;
- goto fail;
+ goto fail_remove_attr;
}
if ((urd->class != DEV_CLASS_UR_I) && (urd->class != DEV_CLASS_UR_O)) {
rc = -ENOTSUPP;
- goto fail;
+ goto fail_remove_attr;
}
+ spin_lock_irq(get_ccwdev_lock(cdev));
+ cdev->dev.driver_data = urd;
+ spin_unlock_irq(get_ccwdev_lock(cdev));
+ mutex_unlock(&vmur_mutex);
return 0;
-fail:
- urdev_free(urd);
- put_device(&cdev->dev);
- return rc;
-}
-
-static void ur_remove(struct ccw_device *cdev)
-{
- struct urdev *urd = cdev->dev.driver_data;
-
- TRACE("ur_remove\n");
- if (cdev->online)
- ur_set_offline(cdev);
+fail_remove_attr:
ur_remove_attributes(&cdev->dev);
- urdev_free(urd);
- put_device(&cdev->dev);
+fail_urdev_put:
+ urdev_put(urd);
+fail_unlock:
+ mutex_unlock(&vmur_mutex);
+ return rc;
}
static int ur_set_online(struct ccw_device *cdev)
@@ -776,20 +835,29 @@
int minor, major, rc;
char node_id[16];
- TRACE("ur_set_online: cdev=%p state=%d\n", cdev,
- *(int *) cdev->private);
+ TRACE("ur_set_online: cdev=%p\n", cdev);
- if (!try_module_get(ur_driver.owner))
- return -EINVAL;
+ mutex_lock(&vmur_mutex);
+ urd = urdev_get_from_cdev(cdev);
+ if (!urd) {
+ /* ur_remove already deleted our urd */
+ rc = -ENODEV;
+ goto fail_unlock;
+ }
- urd = (struct urdev *) cdev->dev.driver_data;
+ if (urd->char_device) {
+ /* Another ur_set_online was faster */
+ rc = -EBUSY;
+ goto fail_urdev_put;
+ }
+
minor = urd->dev_id.devno;
major = MAJOR(ur_first_dev_maj_min);
urd->char_device = cdev_alloc();
if (!urd->char_device) {
rc = -ENOMEM;
- goto fail_module_put;
+ goto fail_urdev_put;
}
cdev_init(urd->char_device, &ur_fops);
@@ -818,29 +886,79 @@
TRACE("ur_set_online: device_create rc=%d\n", rc);
goto fail_free_cdev;
}
-
+ urdev_put(urd);
+ mutex_unlock(&vmur_mutex);
return 0;
fail_free_cdev:
cdev_del(urd->char_device);
-fail_module_put:
- module_put(ur_driver.owner);
+ urd->char_device = NULL;
+fail_urdev_put:
+ urdev_put(urd);
+fail_unlock:
+ mutex_unlock(&vmur_mutex);
+ return rc;
+}
+static int ur_set_offline_force(struct ccw_device *cdev, int force)
+{
+ struct urdev *urd;
+ int rc;
+
+ TRACE("ur_set_offline: cdev=%p\n", cdev);
+ urd = urdev_get_from_cdev(cdev);
+ if (!urd)
+ /* ur_remove already deleted our urd */
+ return -ENODEV;
+ if (!urd->char_device) {
+ /* Another ur_set_offline was faster */
+ rc = -EBUSY;
+ goto fail_urdev_put;
+ }
+ if (!force && (atomic_read(&urd->ref_count) > 2)) {
+ /* There is still a user of urd (e.g. ur_open) */
+ TRACE("ur_set_offline: BUSY\n");
+ rc = -EBUSY;
+ goto fail_urdev_put;
+ }
+ device_destroy(vmur_class, urd->char_device->dev);
+ cdev_del(urd->char_device);
+ urd->char_device = NULL;
+ rc = 0;
+
+fail_urdev_put:
+ urdev_put(urd);
return rc;
}
static int ur_set_offline(struct ccw_device *cdev)
{
- struct urdev *urd;
+ int rc;
- TRACE("ur_set_offline: cdev=%p cdev->private=%p state=%d\n",
- cdev, cdev->private, *(int *) cdev->private);
- urd = (struct urdev *) cdev->dev.driver_data;
- device_destroy(vmur_class, urd->char_device->dev);
- cdev_del(urd->char_device);
- module_put(ur_driver.owner);
+ mutex_lock(&vmur_mutex);
+ rc = ur_set_offline_force(cdev, 0);
+ mutex_unlock(&vmur_mutex);
+ return rc;
+}
- return 0;
+static void ur_remove(struct ccw_device *cdev)
+{
+ unsigned long flags;
+
+ TRACE("ur_remove\n");
+
+ mutex_lock(&vmur_mutex);
+
+ if (cdev->online)
+ ur_set_offline_force(cdev, 1);
+ ur_remove_attributes(&cdev->dev);
+
+ spin_lock_irqsave(get_ccwdev_lock(cdev), flags);
+ urdev_put(cdev->dev.driver_data);
+ cdev->dev.driver_data = NULL;
+ spin_unlock_irqrestore(get_ccwdev_lock(cdev), flags);
+
+ mutex_unlock(&vmur_mutex);
}
/*
diff --git a/drivers/s390/char/vmur.h b/drivers/s390/char/vmur.h
index 16d0a4e..fa95964 100644
--- a/drivers/s390/char/vmur.h
+++ b/drivers/s390/char/vmur.h
@@ -50,7 +50,10 @@
char rest[200];
} __attribute__ ((packed));
-#define FLG_CP_DUMP 0x10
+#define FLG_SYSTEM_HOLD 0x04
+#define FLG_CP_DUMP 0x10
+#define FLG_USER_HOLD 0x20
+#define FLG_IN_USE 0x80
/*
* A struct urdev is created for each ur device that is made available
@@ -67,6 +70,7 @@
size_t reclen; /* Record length for *write* CCWs */
int class; /* VM device class */
int io_request_rc; /* return code from I/O request */
+ atomic_t ref_count; /* reference counter */
};
/*
diff --git a/drivers/s390/cio/cmf.c b/drivers/s390/cio/cmf.c
index 02fd00b..34a7969 100644
--- a/drivers/s390/cio/cmf.c
+++ b/drivers/s390/cio/cmf.c
@@ -594,6 +594,9 @@
free_pages((unsigned long)mem, get_order(size));
} else if (!mem) {
/* no luck */
+ printk(KERN_WARNING "cio: failed to allocate area "
+ "for measuring %d subchannels\n",
+ cmb_area.num_channels);
ret = -ENOMEM;
goto out;
} else {
@@ -1279,13 +1282,6 @@
case CMF_BASIC:
format_string = "basic";
cmbops = &cmbops_basic;
- if (cmb_area.num_channels > 4096 || cmb_area.num_channels < 1) {
- printk(KERN_ERR "cio: Basic channel measurement "
- "facility can only use 1 to 4096 devices\n"
- KERN_ERR "when the cmf driver is built"
- " as a loadable module\n");
- return 1;
- }
break;
case CMF_EXTENDED:
format_string = "extended";
diff --git a/drivers/s390/cio/css.c b/drivers/s390/cio/css.c
index 1c27a5a..5635e65 100644
--- a/drivers/s390/cio/css.c
+++ b/drivers/s390/cio/css.c
@@ -79,6 +79,7 @@
sch->schib.pmcw.intparm = (__u32)(unsigned long)sch;
ret = cio_modify(sch);
if (ret) {
+ kfree(sch->lock);
kfree(sch);
return ERR_PTR(ret);
}
diff --git a/drivers/s390/cio/device.c b/drivers/s390/cio/device.c
index 297659f..e44d92e 100644
--- a/drivers/s390/cio/device.c
+++ b/drivers/s390/cio/device.c
@@ -117,7 +117,10 @@
snprint_alias(modalias_buf, sizeof(modalias_buf), id, "");
ret = add_uevent_var(envp, num_envp, &i, buffer, buffer_size, &len,
"MODALIAS=%s", modalias_buf);
- return ret;
+ if (ret)
+ return ret;
+ envp[i] = NULL;
+ return 0;
}
struct bus_type ccw_bus_type;
diff --git a/drivers/s390/cio/device_id.c b/drivers/s390/cio/device_id.c
index 60b9347..f232832 100644
--- a/drivers/s390/cio/device_id.c
+++ b/drivers/s390/cio/device_id.c
@@ -17,6 +17,7 @@
#include <asm/delay.h>
#include <asm/cio.h>
#include <asm/lowcore.h>
+#include <asm/diag.h>
#include "cio.h"
#include "cio_debug.h"
@@ -25,51 +26,6 @@
#include "ioasm.h"
/*
- * diag210 is used under VM to get information about a virtual device
- */
-int
-diag210(struct diag210 * addr)
-{
- /*
- * diag 210 needs its data below the 2GB border, so we
- * use a static data area to be sure
- */
- static struct diag210 diag210_tmp;
- static DEFINE_SPINLOCK(diag210_lock);
- unsigned long flags;
- int ccode;
-
- spin_lock_irqsave(&diag210_lock, flags);
- diag210_tmp = *addr;
-
-#ifdef CONFIG_64BIT
- asm volatile(
- " lhi %0,-1\n"
- " sam31\n"
- " diag %1,0,0x210\n"
- "0: ipm %0\n"
- " srl %0,28\n"
- "1: sam64\n"
- EX_TABLE(0b,1b)
- : "=&d" (ccode) : "a" (&diag210_tmp) : "cc", "memory");
-#else
- asm volatile(
- " lhi %0,-1\n"
- " diag %1,0,0x210\n"
- "0: ipm %0\n"
- " srl %0,28\n"
- "1:\n"
- EX_TABLE(0b,1b)
- : "=&d" (ccode) : "a" (&diag210_tmp) : "cc", "memory");
-#endif
-
- *addr = diag210_tmp;
- spin_unlock_irqrestore(&diag210_lock, flags);
-
- return ccode;
-}
-
-/*
* Input :
* devno - device number
* ps - pointer to sense ID data area
@@ -349,5 +305,3 @@
break;
}
}
-
-EXPORT_SYMBOL(diag210);
diff --git a/drivers/s390/cio/qdio.c b/drivers/s390/cio/qdio.c
index ed026a1..d8d4798 100644
--- a/drivers/s390/cio/qdio.c
+++ b/drivers/s390/cio/qdio.c
@@ -81,6 +81,7 @@
static atomic_t spare_indicator_usecount;
#define QDIO_MEMPOOL_SCSSC_ELEMENTS 2
static mempool_t *qdio_mempool_scssc;
+static struct kmem_cache *qdio_q_cache;
static debug_info_t *qdio_dbf_setup;
static debug_info_t *qdio_dbf_sbal;
@@ -194,6 +195,8 @@
again:
ccq = do_eqbs(irq->sch_token, state, q_no, start, cnt);
rc = qdio_check_ccq(q, ccq);
+ if ((ccq == 96) && (tmp_cnt != *cnt))
+ rc = 0;
if (rc == 1) {
QDIO_DBF_TEXT5(1,trace,"eqAGAIN");
goto again;
@@ -739,7 +742,8 @@
first_not_to_check=f+qdio_min(atomic_read(&q->number_of_buffers_used),
(QDIO_MAX_BUFFERS_PER_Q-1));
- if ((!q->is_iqdio_q)&&(!q->hydra_gives_outbound_pcis))
+ if (((!q->is_iqdio_q) && (!q->hydra_gives_outbound_pcis)) ||
+ (q->queue_type == QDIO_IQDIO_QFMT_ASYNCH))
SYNC_MEMORY;
check_next:
@@ -1617,23 +1621,21 @@
qdio_release_irq_memory(struct qdio_irq *irq_ptr)
{
int i;
+ struct qdio_q *q;
- for (i=0;i<QDIO_MAX_QUEUES_PER_IRQ;i++) {
- if (!irq_ptr->input_qs[i])
- goto next;
-
- kfree(irq_ptr->input_qs[i]->slib);
- kfree(irq_ptr->input_qs[i]);
-
-next:
- if (!irq_ptr->output_qs[i])
- continue;
-
- kfree(irq_ptr->output_qs[i]->slib);
- kfree(irq_ptr->output_qs[i]);
-
+ for (i = 0; i < QDIO_MAX_QUEUES_PER_IRQ; i++) {
+ q = irq_ptr->input_qs[i];
+ if (q) {
+ free_page((unsigned long) q->slib);
+ kmem_cache_free(qdio_q_cache, q);
+ }
+ q = irq_ptr->output_qs[i];
+ if (q) {
+ free_page((unsigned long) q->slib);
+ kmem_cache_free(qdio_q_cache, q);
+ }
}
- kfree(irq_ptr->qdr);
+ free_page((unsigned long) irq_ptr->qdr);
free_page((unsigned long) irq_ptr);
}
@@ -1680,44 +1682,35 @@
{
int i;
struct qdio_q *q;
- int result=-ENOMEM;
- for (i=0;i<no_input_qs;i++) {
- q = kzalloc(sizeof(struct qdio_q), GFP_KERNEL);
+ for (i = 0; i < no_input_qs; i++) {
+ q = kmem_cache_alloc(qdio_q_cache, GFP_KERNEL);
+ if (!q)
+ return -ENOMEM;
+ memset(q, 0, sizeof(*q));
- if (!q) {
- QDIO_PRINT_ERR("kmalloc of q failed!\n");
- goto out;
- }
-
- q->slib = kmalloc(PAGE_SIZE, GFP_KERNEL);
+ q->slib = (struct slib *) __get_free_page(GFP_KERNEL);
if (!q->slib) {
- QDIO_PRINT_ERR("kmalloc of slib failed!\n");
- goto out;
+ kmem_cache_free(qdio_q_cache, q);
+ return -ENOMEM;
}
-
irq_ptr->input_qs[i]=q;
}
- for (i=0;i<no_output_qs;i++) {
- q = kzalloc(sizeof(struct qdio_q), GFP_KERNEL);
+ for (i = 0; i < no_output_qs; i++) {
+ q = kmem_cache_alloc(qdio_q_cache, GFP_KERNEL);
+ if (!q)
+ return -ENOMEM;
+ memset(q, 0, sizeof(*q));
- if (!q) {
- goto out;
- }
-
- q->slib=kmalloc(PAGE_SIZE,GFP_KERNEL);
+ q->slib = (struct slib *) __get_free_page(GFP_KERNEL);
if (!q->slib) {
- QDIO_PRINT_ERR("kmalloc of slib failed!\n");
- goto out;
+ kmem_cache_free(qdio_q_cache, q);
+ return -ENOMEM;
}
-
irq_ptr->output_qs[i]=q;
}
-
- result=0;
-out:
- return result;
+ return 0;
}
static void
@@ -2985,17 +2978,17 @@
QDIO_DBF_HEX0(0,setup,&irq_ptr,sizeof(void*));
if (!irq_ptr) {
- QDIO_PRINT_ERR("kmalloc of irq_ptr failed!\n");
+ QDIO_PRINT_ERR("allocation of irq_ptr failed!\n");
return -ENOMEM;
}
init_MUTEX(&irq_ptr->setting_up_sema);
/* QDR must be in DMA area since CCW data address is only 32 bit */
- irq_ptr->qdr=kmalloc(sizeof(struct qdr), GFP_KERNEL | GFP_DMA);
+ irq_ptr->qdr = (struct qdr *) __get_free_page(GFP_KERNEL | GFP_DMA);
if (!(irq_ptr->qdr)) {
free_page((unsigned long) irq_ptr);
- QDIO_PRINT_ERR("kmalloc of irq_ptr->qdr failed!\n");
+ QDIO_PRINT_ERR("allocation of irq_ptr->qdr failed!\n");
return -ENOMEM;
}
QDIO_DBF_TEXT0(0,setup,"qdr:");
@@ -3004,6 +2997,7 @@
if (qdio_alloc_qs(irq_ptr,
init_data->no_input_qs,
init_data->no_output_qs)) {
+ QDIO_PRINT_ERR("queue allocation failed!\n");
qdio_release_irq_memory(irq_ptr);
return -ENOMEM;
}
@@ -3895,9 +3889,19 @@
if (res)
return res;
+ qdio_q_cache = kmem_cache_create("qdio_q", sizeof(struct qdio_q),
+ 256, 0, NULL);
+ if (!qdio_q_cache) {
+ qdio_release_qdio_memory();
+ return -ENOMEM;
+ }
+
res = qdio_register_dbf_views();
- if (res)
+ if (res) {
+ kmem_cache_destroy(qdio_q_cache);
+ qdio_release_qdio_memory();
return res;
+ }
QDIO_DBF_TEXT0(0,setup,"initQDIO");
res = bus_create_file(&ccw_bus_type, &bus_attr_qdio_performance_stats);
@@ -3929,6 +3933,7 @@
qdio_release_qdio_memory();
qdio_unregister_dbf_views();
mempool_destroy(qdio_mempool_scssc);
+ kmem_cache_destroy(qdio_q_cache);
bus_remove_file(&ccw_bus_type, &bus_attr_qdio_performance_stats);
printk("qdio: %s: module removed\n",version);
}
diff --git a/drivers/s390/scsi/zfcp_fsf.c b/drivers/s390/scsi/zfcp_fsf.c
index b240800..9929997 100644
--- a/drivers/s390/scsi/zfcp_fsf.c
+++ b/drivers/s390/scsi/zfcp_fsf.c
@@ -4154,8 +4154,9 @@
fcp_rsp_iu->fcp_resid,
(int) zfcp_get_fcp_dl(fcp_cmnd_iu));
- scpnt->resid = fcp_rsp_iu->fcp_resid;
- if (scpnt->request_bufflen - scpnt->resid < scpnt->underflow)
+ scsi_set_resid(scpnt, fcp_rsp_iu->fcp_resid);
+ if (scsi_bufflen(scpnt) - scsi_get_resid(scpnt) <
+ scpnt->underflow)
set_host_byte(&scpnt->result, DID_ERROR);
}
diff --git a/drivers/s390/scsi/zfcp_qdio.c b/drivers/s390/scsi/zfcp_qdio.c
index c408bad..81daa82 100644
--- a/drivers/s390/scsi/zfcp_qdio.c
+++ b/drivers/s390/scsi/zfcp_qdio.c
@@ -36,8 +36,6 @@
(struct zfcp_fsf_req *, unsigned long, void *, int);
static int zfcp_qdio_sbals_from_segment
(struct zfcp_fsf_req *, unsigned long, void *, unsigned long);
-static int zfcp_qdio_sbals_from_buffer
- (struct zfcp_fsf_req *, unsigned long, void *, unsigned long, int);
static qdio_handler_t zfcp_qdio_request_handler;
static qdio_handler_t zfcp_qdio_response_handler;
@@ -632,28 +630,6 @@
/**
- * zfcp_qdio_sbals_from_buffer - fill SBALs from buffer
- * @fsf_req: request to be processed
- * @sbtype: SBALE flags
- * @buffer: data buffer
- * @length: length of buffer
- * @max_sbals: upper bound for number of SBALs to be used
- */
-static int
-zfcp_qdio_sbals_from_buffer(struct zfcp_fsf_req *fsf_req, unsigned long sbtype,
- void *buffer, unsigned long length, int max_sbals)
-{
- struct scatterlist sg_segment;
-
- zfcp_address_to_sg(buffer, &sg_segment);
- sg_segment.length = length;
-
- return zfcp_qdio_sbals_from_sg(fsf_req, sbtype, &sg_segment, 1,
- max_sbals);
-}
-
-
-/**
* zfcp_qdio_sbals_from_scsicmnd - fill SBALs from scsi command
* @fsf_req: request to be processed
* @sbtype: SBALE flags
@@ -664,18 +640,13 @@
zfcp_qdio_sbals_from_scsicmnd(struct zfcp_fsf_req *fsf_req,
unsigned long sbtype, struct scsi_cmnd *scsi_cmnd)
{
- if (scsi_cmnd->use_sg) {
+ if (scsi_sg_count(scsi_cmnd))
return zfcp_qdio_sbals_from_sg(fsf_req, sbtype,
- (struct scatterlist *)
- scsi_cmnd->request_buffer,
- scsi_cmnd->use_sg,
- ZFCP_MAX_SBALS_PER_REQ);
- } else {
- return zfcp_qdio_sbals_from_buffer(fsf_req, sbtype,
- scsi_cmnd->request_buffer,
- scsi_cmnd->request_bufflen,
- ZFCP_MAX_SBALS_PER_REQ);
- }
+ scsi_sglist(scsi_cmnd),
+ scsi_sg_count(scsi_cmnd),
+ ZFCP_MAX_SBALS_PER_REQ);
+ else
+ return 0;
}
/**
diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig
index d2b3898..6f2c71e 100644
--- a/drivers/scsi/Kconfig
+++ b/drivers/scsi/Kconfig
@@ -367,6 +367,7 @@
config SCSI_7000FASST
tristate "7000FASST SCSI support"
depends on ISA && SCSI && ISA_DMA_API
+ select CHECK_SIGNATURE
help
This driver supports the Western Digital 7000 SCSI host adapter
family. Some information is in the source:
@@ -388,6 +389,7 @@
tristate "Adaptec AHA152X/2825 support"
depends on ISA && SCSI && !64BIT
select SCSI_SPI_ATTRS
+ select CHECK_SIGNATURE
---help---
This is a driver for the AHA-1510, AHA-1520, AHA-1522, and AHA-2825
SCSI host adapters. It also works for the AVA-1505, but the IRQ etc.
@@ -583,6 +585,7 @@
tristate "DTC3180/3280 SCSI support"
depends on ISA && SCSI
select SCSI_SPI_ATTRS
+ select CHECK_SIGNATURE
help
This is support for DTC 3180/3280 SCSI Host Adapters. Please read
the SCSI-HOWTO, available from
@@ -657,6 +660,7 @@
config SCSI_FUTURE_DOMAIN
tristate "Future Domain 16xx SCSI/AHA-2920A support"
depends on (ISA || PCI) && SCSI
+ select CHECK_SIGNATURE
---help---
This is support for Future Domain's 16-bit SCSI host adapters
(TMC-1660/1680, TMC-1650/1670, TMC-3260, TMC-1610M/MER/MEX) and
@@ -1324,6 +1328,7 @@
config SCSI_SEAGATE
tristate "Seagate ST-02 and Future Domain TMC-8xx SCSI support"
depends on X86 && ISA && SCSI
+ select CHECK_SIGNATURE
---help---
These are 8-bit SCSI controllers; the ST-01 is also supported by
this driver. It is explained in section 3.9 of the SCSI-HOWTO,
@@ -1397,6 +1402,7 @@
tristate "Trantor T128/T128F/T228 SCSI support"
depends on ISA && SCSI
select SCSI_SPI_ATTRS
+ select CHECK_SIGNATURE
---help---
This is support for a SCSI host adapter. It is explained in section
3.11 of the SCSI-HOWTO, available from
@@ -1561,7 +1567,7 @@
built-in SCSI controller, say Y. Otherwise, say N.
To compile this driver as a module, choose M here: the
- module will be called wd33c93.
+ module will be called a3000.
config A2091_SCSI
tristate "A2091/A590 WD33C93A support"
@@ -1571,7 +1577,7 @@
say N.
To compile this driver as a module, choose M here: the
- module will be called wd33c93.
+ module will be called a2091.
config GVP11_SCSI
tristate "GVP Series II WD33C93A support"
diff --git a/drivers/scsi/aacraid/linit.c b/drivers/scsi/aacraid/linit.c
index 813556c..a7f42a1 100644
--- a/drivers/scsi/aacraid/linit.c
+++ b/drivers/scsi/aacraid/linit.c
@@ -1110,7 +1110,9 @@
__aac_shutdown(aac);
out_unmap:
aac_fib_map_free(aac);
- pci_free_consistent(aac->pdev, aac->comm_size, aac->comm_addr, aac->comm_phys);
+ if (aac->comm_addr)
+ pci_free_consistent(aac->pdev, aac->comm_size, aac->comm_addr,
+ aac->comm_phys);
kfree(aac->queues);
aac_adapter_ioremap(aac, 0);
kfree(aac->fibs);
diff --git a/drivers/scsi/aha152x.c b/drivers/scsi/aha152x.c
index 85f2394..d30a307 100644
--- a/drivers/scsi/aha152x.c
+++ b/drivers/scsi/aha152x.c
@@ -289,18 +289,18 @@
if(spin_is_locked(&QLOCK)) { \
DPRINTK(debug_intr, DEBUG_LEAD "(%s:%d) already locked at %s:%d\n", CMDINFO(CURRENT_SC), __FUNCTION__, __LINE__, QLOCKER, QLOCKERL); \
} \
- DPRINTK(debug_locks, DEBUG_LEAD "(%s:%d) locking\n", CMDINFO(CURRENT_SC), __FUNCTION__, __LINE__); \
+ DPRINTK(debug_locking, DEBUG_LEAD "(%s:%d) locking\n", CMDINFO(CURRENT_SC), __FUNCTION__, __LINE__); \
spin_lock_irqsave(&QLOCK,flags); \
- DPRINTK(debug_locks, DEBUG_LEAD "(%s:%d) locked\n", CMDINFO(CURRENT_SC), __FUNCTION__, __LINE__); \
+ DPRINTK(debug_locking, DEBUG_LEAD "(%s:%d) locked\n", CMDINFO(CURRENT_SC), __FUNCTION__, __LINE__); \
QLOCKER=__FUNCTION__; \
QLOCKERL=__LINE__; \
} while(0)
#define DO_UNLOCK(flags) \
do { \
- DPRINTK(debug_locks, DEBUG_LEAD "(%s:%d) unlocking (locked at %s:%d)\n", CMDINFO(CURRENT_SC), __FUNCTION__, __LINE__, QLOCKER, QLOCKERL); \
+ DPRINTK(debug_locking, DEBUG_LEAD "(%s:%d) unlocking (locked at %s:%d)\n", CMDINFO(CURRENT_SC), __FUNCTION__, __LINE__, QLOCKER, QLOCKERL); \
spin_unlock_irqrestore(&QLOCK,flags); \
- DPRINTK(debug_locks, DEBUG_LEAD "(%s:%d) unlocked\n", CMDINFO(CURRENT_SC), __FUNCTION__, __LINE__); \
+ DPRINTK(debug_locking, DEBUG_LEAD "(%s:%d) unlocked\n", CMDINFO(CURRENT_SC), __FUNCTION__, __LINE__); \
QLOCKER="(not locked)"; \
QLOCKERL=0; \
} while(0)
@@ -322,6 +322,12 @@
(cmd) ? ((cmd)->device->id & 0x0f) : -1, \
(cmd) ? ((cmd)->device->lun & 0x07) : -1
+static inline void
+CMD_INC_RESID(struct scsi_cmnd *cmd, int inc)
+{
+ scsi_set_resid(cmd, scsi_get_resid(cmd) + inc);
+}
+
#define DELAY_DEFAULT 1000
#if defined(PCMCIA)
@@ -552,14 +558,11 @@
struct aha152x_scdata {
Scsi_Cmnd *next; /* next sc in queue */
struct completion *done;/* semaphore to block on */
- unsigned char cmd_len;
- unsigned char cmnd[MAX_COMMAND_SIZE];
- unsigned short use_sg;
- unsigned request_bufflen;
- void *request_buffer;
+ unsigned char aha_orig_cmd_len;
+ unsigned char aha_orig_cmnd[MAX_COMMAND_SIZE];
+ int aha_orig_resid;
};
-
/* access macros for hostdata */
#define HOSTDATA(shpnt) ((struct aha152x_hostdata *) &shpnt->hostdata)
@@ -978,15 +981,15 @@
#if defined(AHA152X_DEBUG)
if (HOSTDATA(shpnt)->debug & debug_queue) {
printk(INFO_LEAD "queue: %p; cmd_len=%d pieces=%d size=%u cmnd=",
- CMDINFO(SCpnt), SCpnt, SCpnt->cmd_len, SCpnt->use_sg, SCpnt->request_bufflen);
+ CMDINFO(SCpnt), SCpnt, SCpnt->cmd_len,
+ scsi_sg_count(SCpnt), scsi_bufflen(SCpnt));
__scsi_print_command(SCpnt->cmnd);
}
#endif
SCpnt->scsi_done = done;
- SCpnt->resid = SCpnt->request_bufflen;
SCpnt->SCp.phase = not_issued | phase;
- SCpnt->SCp.Status = CHECK_CONDITION;
+ SCpnt->SCp.Status = 0x1; /* Ilegal status by SCSI standard */
SCpnt->SCp.Message = 0;
SCpnt->SCp.have_data_in = 0;
SCpnt->SCp.sent_command = 0;
@@ -997,20 +1000,11 @@
return FAILED;
}
} else {
- struct aha152x_scdata *sc;
-
SCpnt->host_scribble = kmalloc(sizeof(struct aha152x_scdata), GFP_ATOMIC);
if(SCpnt->host_scribble==0) {
printk(ERR_LEAD "allocation failed\n", CMDINFO(SCpnt));
return FAILED;
}
-
- sc = SCDATA(SCpnt);
- memcpy(sc->cmnd, SCpnt->cmnd, sizeof(sc->cmnd));
- sc->request_buffer = SCpnt->request_buffer;
- sc->request_bufflen = SCpnt->request_bufflen;
- sc->use_sg = SCpnt->use_sg;
- sc->cmd_len = SCpnt->cmd_len;
}
SCNEXT(SCpnt) = NULL;
@@ -1022,16 +1016,25 @@
SCp.buffer : next buffer
SCp.buffers_residual : left buffers in list
SCp.phase : current state of the command */
- if (SCpnt->use_sg) {
- SCpnt->SCp.buffer = (struct scatterlist *) SCpnt->request_buffer;
- SCpnt->SCp.ptr = SG_ADDRESS(SCpnt->SCp.buffer);
- SCpnt->SCp.this_residual = SCpnt->SCp.buffer->length;
- SCpnt->SCp.buffers_residual = SCpnt->use_sg - 1;
- } else {
- SCpnt->SCp.ptr = (char *) SCpnt->request_buffer;
- SCpnt->SCp.this_residual = SCpnt->request_bufflen;
+
+ if ((phase & (check_condition|resetting)) || !scsi_sglist(SCpnt)) {
+ if (phase & check_condition) {
+ SCpnt->SCp.ptr = SCpnt->sense_buffer;
+ SCpnt->SCp.this_residual = sizeof(SCpnt->sense_buffer);
+ scsi_set_resid(SCpnt, sizeof(SCpnt->sense_buffer));
+ } else {
+ SCpnt->SCp.ptr = NULL;
+ SCpnt->SCp.this_residual = 0;
+ scsi_set_resid(SCpnt, 0);
+ }
SCpnt->SCp.buffer = NULL;
SCpnt->SCp.buffers_residual = 0;
+ } else {
+ scsi_set_resid(SCpnt, scsi_bufflen(SCpnt));
+ SCpnt->SCp.buffer = scsi_sglist(SCpnt);
+ SCpnt->SCp.ptr = SG_ADDRESS(SCpnt->SCp.buffer);
+ SCpnt->SCp.this_residual = SCpnt->SCp.buffer->length;
+ SCpnt->SCp.buffers_residual = scsi_sg_count(SCpnt) - 1;
}
DO_LOCK(flags);
@@ -1150,9 +1153,6 @@
DECLARE_COMPLETION(done);
int ret, issued, disconnected;
unsigned char old_cmd_len = SCpnt->cmd_len;
- unsigned short old_use_sg = SCpnt->use_sg;
- void *old_buffer = SCpnt->request_buffer;
- unsigned old_bufflen = SCpnt->request_bufflen;
unsigned long flags;
unsigned long timeleft;
@@ -1174,9 +1174,6 @@
DO_UNLOCK(flags);
SCpnt->cmd_len = 0;
- SCpnt->use_sg = 0;
- SCpnt->request_buffer = NULL;
- SCpnt->request_bufflen = 0;
aha152x_internal_queue(SCpnt, &done, resetting, reset_done);
@@ -1189,9 +1186,6 @@
}
SCpnt->cmd_len = old_cmd_len;
- SCpnt->use_sg = old_use_sg;
- SCpnt->request_buffer = old_buffer;
- SCpnt->request_bufflen = old_bufflen;
DO_LOCK(flags);
@@ -1531,8 +1525,8 @@
/* target sent DISCONNECT */
DPRINTK(debug_selection, DEBUG_LEAD "target disconnected at %d/%d\n",
CMDINFO(CURRENT_SC),
- CURRENT_SC->resid,
- CURRENT_SC->request_bufflen);
+ scsi_get_resid(CURRENT_SC),
+ scsi_bufflen(CURRENT_SC));
#if defined(AHA152X_STAT)
HOSTDATA(shpnt)->disconnections++;
#endif
@@ -1568,18 +1562,16 @@
#endif
/* restore old command */
- memcpy(cmd->cmnd, sc->cmnd, sizeof(sc->cmnd));
- cmd->request_buffer = sc->request_buffer;
- cmd->request_bufflen = sc->request_bufflen;
- cmd->use_sg = sc->use_sg;
- cmd->cmd_len = sc->cmd_len;
+ memcpy(cmd->cmnd, sc->aha_orig_cmnd, sizeof(cmd->cmnd));
+ cmd->cmd_len = sc->aha_orig_cmd_len;
+ scsi_set_resid(cmd, sc->aha_orig_resid);
- cmd->SCp.Status = 0x02;
+ cmd->SCp.Status = SAM_STAT_CHECK_CONDITION;
HOSTDATA(shpnt)->commands--;
if (!HOSTDATA(shpnt)->commands)
SETPORT(PORTA, 0); /* turn led off */
- } else if(DONE_SC->SCp.Status==0x02) {
+ } else if(DONE_SC->SCp.Status==SAM_STAT_CHECK_CONDITION) {
#if defined(AHA152X_STAT)
HOSTDATA(shpnt)->busfree_with_check_condition++;
#endif
@@ -1587,13 +1579,23 @@
DPRINTK(debug_eh, ERR_LEAD "CHECK CONDITION found\n", CMDINFO(DONE_SC));
#endif
- if(!(DONE_SC->SCp.Status & not_issued)) {
+ if(!(DONE_SC->SCp.phase & not_issued)) {
+ struct aha152x_scdata *sc;
Scsi_Cmnd *ptr = DONE_SC;
DONE_SC=NULL;
#if 0
DPRINTK(debug_eh, ERR_LEAD "requesting sense\n", CMDINFO(ptr));
#endif
+ /* save old command */
+ sc = SCDATA(ptr);
+ /* It was allocated in aha152x_internal_queue? */
+ BUG_ON(!sc);
+ memcpy(sc->aha_orig_cmnd, ptr->cmnd,
+ sizeof(ptr->cmnd));
+ sc->aha_orig_cmd_len = ptr->cmd_len;
+ sc->aha_orig_resid = scsi_get_resid(ptr);
+
ptr->cmnd[0] = REQUEST_SENSE;
ptr->cmnd[1] = 0;
ptr->cmnd[2] = 0;
@@ -1601,10 +1603,7 @@
ptr->cmnd[4] = sizeof(ptr->sense_buffer);
ptr->cmnd[5] = 0;
ptr->cmd_len = 6;
- ptr->use_sg = 0;
- ptr->request_buffer = ptr->sense_buffer;
- ptr->request_bufflen = sizeof(ptr->sense_buffer);
-
+
DO_UNLOCK(flags);
aha152x_internal_queue(ptr, NULL, check_condition, ptr->scsi_done);
DO_LOCK(flags);
@@ -2180,7 +2179,8 @@
DATA_LEN=0;
DPRINTK(debug_datai,
DEBUG_LEAD "datai_init: request_bufflen=%d resid=%d\n",
- CMDINFO(CURRENT_SC), CURRENT_SC->request_bufflen, CURRENT_SC->resid);
+ CMDINFO(CURRENT_SC), scsi_bufflen(CURRENT_SC),
+ scsi_get_resid(CURRENT_SC));
}
static void datai_run(struct Scsi_Host *shpnt)
@@ -2293,11 +2293,12 @@
static void datai_end(struct Scsi_Host *shpnt)
{
- CURRENT_SC->resid -= GETSTCNT();
+ CMD_INC_RESID(CURRENT_SC, -GETSTCNT());
DPRINTK(debug_datai,
DEBUG_LEAD "datai_end: request_bufflen=%d resid=%d stcnt=%d\n",
- CMDINFO(CURRENT_SC), CURRENT_SC->request_bufflen, CURRENT_SC->resid, GETSTCNT());
+ CMDINFO(CURRENT_SC), scsi_bufflen(CURRENT_SC),
+ scsi_get_resid(CURRENT_SC), GETSTCNT());
SETPORT(SXFRCTL0, CH1|CLRSTCNT);
SETPORT(DMACNTRL0, 0);
@@ -2318,11 +2319,12 @@
SETPORT(SIMODE0, 0);
SETPORT(SIMODE1, ENSCSIPERR | ENSCSIRST | ENPHASEMIS | ENBUSFREE );
- DATA_LEN = CURRENT_SC->resid;
+ DATA_LEN = scsi_get_resid(CURRENT_SC);
DPRINTK(debug_datao,
DEBUG_LEAD "datao_init: request_bufflen=%d; resid=%d\n",
- CMDINFO(CURRENT_SC), CURRENT_SC->request_bufflen, CURRENT_SC->resid);
+ CMDINFO(CURRENT_SC), scsi_bufflen(CURRENT_SC),
+ scsi_get_resid(CURRENT_SC));
}
static void datao_run(struct Scsi_Host *shpnt)
@@ -2346,7 +2348,7 @@
SETPORT(DMACNTRL0,WRITE_READ|ENDMA|_8BIT);
SETPORT(DATAPORT, *CURRENT_SC->SCp.ptr++);
CURRENT_SC->SCp.this_residual--;
- CURRENT_SC->resid--;
+ CMD_INC_RESID(CURRENT_SC, -1);
SETPORT(DMACNTRL0,WRITE_READ|ENDMA);
}
@@ -2355,7 +2357,7 @@
outsw(DATAPORT, CURRENT_SC->SCp.ptr, data_count);
CURRENT_SC->SCp.ptr += 2 * data_count;
CURRENT_SC->SCp.this_residual -= 2 * data_count;
- CURRENT_SC->resid -= 2 * data_count;
+ CMD_INC_RESID(CURRENT_SC, -2 * data_count);
}
if(CURRENT_SC->SCp.this_residual==0 && CURRENT_SC->SCp.buffers_residual>0) {
@@ -2381,35 +2383,34 @@
static void datao_end(struct Scsi_Host *shpnt)
{
if(TESTLO(DMASTAT, DFIFOEMP)) {
- int data_count = (DATA_LEN - CURRENT_SC->resid) - GETSTCNT();
+ int data_count = (DATA_LEN - scsi_get_resid(CURRENT_SC)) -
+ GETSTCNT();
DPRINTK(debug_datao, DEBUG_LEAD "datao: %d bytes to resend (%d written, %d transferred)\n",
CMDINFO(CURRENT_SC),
data_count,
- DATA_LEN-CURRENT_SC->resid,
+ DATA_LEN - scsi_get_resid(CURRENT_SC),
GETSTCNT());
- CURRENT_SC->resid += data_count;
+ CMD_INC_RESID(CURRENT_SC, data_count);
- if(CURRENT_SC->use_sg) {
- data_count -= CURRENT_SC->SCp.ptr - SG_ADDRESS(CURRENT_SC->SCp.buffer);
- while(data_count>0) {
- CURRENT_SC->SCp.buffer--;
- CURRENT_SC->SCp.buffers_residual++;
- data_count -= CURRENT_SC->SCp.buffer->length;
- }
- CURRENT_SC->SCp.ptr = SG_ADDRESS(CURRENT_SC->SCp.buffer) - data_count;
- CURRENT_SC->SCp.this_residual = CURRENT_SC->SCp.buffer->length + data_count;
- } else {
- CURRENT_SC->SCp.ptr -= data_count;
- CURRENT_SC->SCp.this_residual += data_count;
+ data_count -= CURRENT_SC->SCp.ptr -
+ SG_ADDRESS(CURRENT_SC->SCp.buffer);
+ while(data_count>0) {
+ CURRENT_SC->SCp.buffer--;
+ CURRENT_SC->SCp.buffers_residual++;
+ data_count -= CURRENT_SC->SCp.buffer->length;
}
+ CURRENT_SC->SCp.ptr = SG_ADDRESS(CURRENT_SC->SCp.buffer) -
+ data_count;
+ CURRENT_SC->SCp.this_residual = CURRENT_SC->SCp.buffer->length +
+ data_count;
}
DPRINTK(debug_datao, DEBUG_LEAD "datao_end: request_bufflen=%d; resid=%d; stcnt=%d\n",
CMDINFO(CURRENT_SC),
- CURRENT_SC->request_bufflen,
- CURRENT_SC->resid,
+ scsi_bufflen(CURRENT_SC),
+ scsi_get_resid(CURRENT_SC),
GETSTCNT());
SETPORT(SXFRCTL0, CH1|CLRCH1|CLRSTCNT);
@@ -2936,7 +2937,7 @@
__scsi_print_command(ptr->cmnd);
printk(KERN_DEBUG "); request_bufflen=%d; resid=%d; phase |",
- ptr->request_bufflen, ptr->resid);
+ scsi_bufflen(ptr), scsi_get_resid(ptr));
if (ptr->SCp.phase & not_issued)
printk("not issued|");
@@ -3006,7 +3007,8 @@
SPRINTF("0x%02x ", ptr->cmnd[i]);
SPRINTF("); resid=%d; residual=%d; buffers=%d; phase |",
- ptr->resid, ptr->SCp.this_residual, ptr->SCp.buffers_residual);
+ scsi_get_resid(ptr), ptr->SCp.this_residual,
+ ptr->SCp.buffers_residual);
if (ptr->SCp.phase & not_issued)
SPRINTF("not issued|");
@@ -3395,7 +3397,7 @@
PDEBUG(debug_datai, "data in");
PDEBUG(debug_datao, "data out");
PDEBUG(debug_eh, "eh");
- PDEBUG(debug_locks, "locks");
+ PDEBUG(debug_locking, "locks");
PDEBUG(debug_phases, "phases");
SPRINTF("\n");
@@ -3474,6 +3476,12 @@
return thislength < length ? thislength : length;
}
+static int aha152x_adjust_queue(struct scsi_device *device)
+{
+ blk_queue_bounce_limit(device->request_queue, BLK_BOUNCE_HIGH);
+ return 0;
+}
+
static struct scsi_host_template aha152x_driver_template = {
.module = THIS_MODULE,
.name = AHA152X_REVID,
@@ -3490,6 +3498,7 @@
.sg_tablesize = SG_ALL,
.cmd_per_lun = 1,
.use_clustering = DISABLE_CLUSTERING,
+ .slave_alloc = aha152x_adjust_queue,
};
#if !defined(PCMCIA)
diff --git a/drivers/scsi/aha152x.h b/drivers/scsi/aha152x.h
index d2add24..ac4bfa438b 100644
--- a/drivers/scsi/aha152x.h
+++ b/drivers/scsi/aha152x.h
@@ -298,7 +298,7 @@
enum {
debug_procinfo = 0x0001,
debug_queue = 0x0002,
- debug_locks = 0x0004,
+ debug_locking = 0x0004,
debug_intr = 0x0008,
debug_selection = 0x0010,
debug_msgo = 0x0020,
diff --git a/drivers/scsi/aic7xxx/aic7xxx_core.c b/drivers/scsi/aic7xxx/aic7xxx_core.c
index 75733b0..f350b5e 100644
--- a/drivers/scsi/aic7xxx/aic7xxx_core.c
+++ b/drivers/scsi/aic7xxx/aic7xxx_core.c
@@ -1701,7 +1701,16 @@
if ((*ppr_options & MSG_EXT_PPR_DT_REQ) == 0
&& maxsync < AHC_SYNCRATE_ULTRA2)
maxsync = AHC_SYNCRATE_ULTRA2;
-
+
+ /* Now set the maxsync based on the card capabilities
+ * DT is already done above */
+ if ((ahc->features & (AHC_DT | AHC_ULTRA2)) == 0
+ && maxsync < AHC_SYNCRATE_ULTRA)
+ maxsync = AHC_SYNCRATE_ULTRA;
+ if ((ahc->features & (AHC_DT | AHC_ULTRA2 | AHC_ULTRA)) == 0
+ && maxsync < AHC_SYNCRATE_FAST)
+ maxsync = AHC_SYNCRATE_FAST;
+
for (syncrate = &ahc_syncrates[maxsync];
syncrate->rate != NULL;
syncrate++) {
@@ -1765,6 +1774,17 @@
else
scsirate &= SXFR;
+ /* now set maxsync based on card capabilities */
+ if ((ahc->features & AHC_DT) == 0 && maxsync < AHC_SYNCRATE_ULTRA2)
+ maxsync = AHC_SYNCRATE_ULTRA2;
+ if ((ahc->features & (AHC_DT | AHC_ULTRA2)) == 0
+ && maxsync < AHC_SYNCRATE_ULTRA)
+ maxsync = AHC_SYNCRATE_ULTRA;
+ if ((ahc->features & (AHC_DT | AHC_ULTRA2 | AHC_ULTRA)) == 0
+ && maxsync < AHC_SYNCRATE_FAST)
+ maxsync = AHC_SYNCRATE_FAST;
+
+
syncrate = &ahc_syncrates[maxsync];
while (syncrate->rate != NULL) {
diff --git a/drivers/scsi/dpt_i2o.c b/drivers/scsi/dpt_i2o.c
index 2e2362d..502732a 100644
--- a/drivers/scsi/dpt_i2o.c
+++ b/drivers/scsi/dpt_i2o.c
@@ -173,20 +173,20 @@
};
MODULE_DEVICE_TABLE(pci,dptids);
-static int adpt_detect(struct scsi_host_template* sht)
+static void adpt_exit(void);
+
+static int adpt_detect(void)
{
struct pci_dev *pDev = NULL;
adpt_hba* pHba;
- adpt_init();
-
PINFO("Detecting Adaptec I2O RAID controllers...\n");
/* search for all Adatpec I2O RAID cards */
while ((pDev = pci_get_device( PCI_DPT_VENDOR_ID, PCI_ANY_ID, pDev))) {
if(pDev->device == PCI_DPT_DEVICE_ID ||
pDev->device == PCI_DPT_RAPTOR_DEVICE_ID){
- if(adpt_install_hba(sht, pDev) ){
+ if(adpt_install_hba(pDev) ){
PERROR("Could not Init an I2O RAID device\n");
PERROR("Will not try to detect others.\n");
return hba_count-1;
@@ -248,34 +248,33 @@
}
for (pHba = hba_chain; pHba; pHba = pHba->next) {
- if( adpt_scsi_register(pHba,sht) < 0){
+ if (adpt_scsi_register(pHba) < 0) {
adpt_i2o_delete_hba(pHba);
continue;
}
pHba->initialized = TRUE;
pHba->state &= ~DPTI_STATE_RESET;
+ scsi_scan_host(pHba->host);
}
// Register our control device node
// nodes will need to be created in /dev to access this
// the nodes can not be created from within the driver
if (hba_count && register_chrdev(DPTI_I2O_MAJOR, DPT_DRIVER, &adpt_fops)) {
- adpt_i2o_sys_shutdown();
+ adpt_exit();
return 0;
}
return hba_count;
}
-/*
- * scsi_unregister will be called AFTER we return.
- */
-static int adpt_release(struct Scsi_Host *host)
+static int adpt_release(adpt_hba *pHba)
{
- adpt_hba* pHba = (adpt_hba*) host->hostdata[0];
+ struct Scsi_Host *shost = pHba->host;
+ scsi_remove_host(shost);
// adpt_i2o_quiesce_hba(pHba);
adpt_i2o_delete_hba(pHba);
- scsi_unregister(host);
+ scsi_host_put(shost);
return 0;
}
@@ -882,7 +881,7 @@
#endif
-static int adpt_install_hba(struct scsi_host_template* sht, struct pci_dev* pDev)
+static int adpt_install_hba(struct pci_dev* pDev)
{
adpt_hba* pHba = NULL;
@@ -1031,8 +1030,6 @@
mutex_lock(&adpt_configuration_lock);
- // scsi_unregister calls our adpt_release which
- // does a quiese
if(pHba->host){
free_irq(pHba->host->irq, pHba);
}
@@ -1084,17 +1081,6 @@
}
-static int adpt_init(void)
-{
- printk("Loading Adaptec I2O RAID: Version " DPT_I2O_VERSION "\n");
-#ifdef REBOOT_NOTIFIER
- register_reboot_notifier(&adpt_reboot_notifier);
-#endif
-
- return 0;
-}
-
-
static struct adpt_device* adpt_find_device(adpt_hba* pHba, u32 chan, u32 id, u32 lun)
{
struct adpt_device* d;
@@ -2180,37 +2166,6 @@
}
-static s32 adpt_scsi_register(adpt_hba* pHba,struct scsi_host_template * sht)
-{
- struct Scsi_Host *host = NULL;
-
- host = scsi_register(sht, sizeof(adpt_hba*));
- if (host == NULL) {
- printk ("%s: scsi_register returned NULL\n",pHba->name);
- return -1;
- }
- host->hostdata[0] = (unsigned long)pHba;
- pHba->host = host;
-
- host->irq = pHba->pDev->irq;
- /* no IO ports, so don't have to set host->io_port and
- * host->n_io_port
- */
- host->io_port = 0;
- host->n_io_port = 0;
- /* see comments in scsi_host.h */
- host->max_id = 16;
- host->max_lun = 256;
- host->max_channel = pHba->top_scsi_channel + 1;
- host->cmd_per_lun = 1;
- host->unique_id = (uint) pHba;
- host->sg_tablesize = pHba->sg_tablesize;
- host->can_queue = pHba->post_fifo_size;
-
- return 0;
-}
-
-
static s32 adpt_i2o_to_scsi(void __iomem *reply, struct scsi_cmnd* cmd)
{
adpt_hba* pHba;
@@ -3329,12 +3284,10 @@
#endif
-static struct scsi_host_template driver_template = {
+static struct scsi_host_template adpt_template = {
.name = "dpt_i2o",
.proc_name = "dpt_i2o",
.proc_info = adpt_proc_info,
- .detect = adpt_detect,
- .release = adpt_release,
.info = adpt_info,
.queuecommand = adpt_queue,
.eh_abort_handler = adpt_abort,
@@ -3348,5 +3301,62 @@
.cmd_per_lun = 1,
.use_clustering = ENABLE_CLUSTERING,
};
-#include "scsi_module.c"
+
+static s32 adpt_scsi_register(adpt_hba* pHba)
+{
+ struct Scsi_Host *host;
+
+ host = scsi_host_alloc(&adpt_template, sizeof(adpt_hba*));
+ if (host == NULL) {
+ printk ("%s: scsi_host_alloc returned NULL\n",pHba->name);
+ return -1;
+ }
+ host->hostdata[0] = (unsigned long)pHba;
+ pHba->host = host;
+
+ host->irq = pHba->pDev->irq;
+ /* no IO ports, so don't have to set host->io_port and
+ * host->n_io_port
+ */
+ host->io_port = 0;
+ host->n_io_port = 0;
+ /* see comments in scsi_host.h */
+ host->max_id = 16;
+ host->max_lun = 256;
+ host->max_channel = pHba->top_scsi_channel + 1;
+ host->cmd_per_lun = 1;
+ host->unique_id = (uint) pHba;
+ host->sg_tablesize = pHba->sg_tablesize;
+ host->can_queue = pHba->post_fifo_size;
+
+ if (scsi_add_host(host, &pHba->pDev->dev)) {
+ scsi_host_put(host);
+ return -1;
+ }
+
+ return 0;
+}
+
+static int __init adpt_init(void)
+{
+ int count;
+
+ printk("Loading Adaptec I2O RAID: Version " DPT_I2O_VERSION "\n");
+#ifdef REBOOT_NOTIFIER
+ register_reboot_notifier(&adpt_reboot_notifier);
+#endif
+
+ count = adpt_detect();
+
+ return count > 0 ? 0 : -ENODEV;
+}
+
+static void __exit adpt_exit(void)
+{
+ while (hba_chain)
+ adpt_release(hba_chain);
+}
+
+module_init(adpt_init);
+module_exit(adpt_exit);
MODULE_LICENSE("GPL");
diff --git a/drivers/scsi/dpti.h b/drivers/scsi/dpti.h
index fd79068..0892f6c 100644
--- a/drivers/scsi/dpti.h
+++ b/drivers/scsi/dpti.h
@@ -28,11 +28,9 @@
* SCSI interface function Prototypes
*/
-static int adpt_detect(struct scsi_host_template * sht);
static int adpt_queue(struct scsi_cmnd * cmd, void (*cmdcomplete) (struct scsi_cmnd *));
static int adpt_abort(struct scsi_cmnd * cmd);
static int adpt_reset(struct scsi_cmnd* cmd);
-static int adpt_release(struct Scsi_Host *host);
static int adpt_slave_configure(struct scsi_device *);
static const char *adpt_info(struct Scsi_Host *pSHost);
@@ -49,8 +47,6 @@
#define DPT_DRIVER_NAME "Adaptec I2O RAID"
-#ifndef HOSTS_C
-
#include "dpt/sys_info.h"
#include <linux/wait.h>
#include "dpt/dpti_i2o.h"
@@ -289,7 +285,7 @@
static s32 adpt_i2o_hrt_get(adpt_hba* pHba);
static s32 adpt_scsi_to_i2o(adpt_hba* pHba, struct scsi_cmnd* cmd, struct adpt_device* dptdevice);
static s32 adpt_i2o_to_scsi(void __iomem *reply, struct scsi_cmnd* cmd);
-static s32 adpt_scsi_register(adpt_hba* pHba,struct scsi_host_template * sht);
+static s32 adpt_scsi_register(adpt_hba* pHba);
static s32 adpt_hba_reset(adpt_hba* pHba);
static s32 adpt_i2o_reset_hba(adpt_hba* pHba);
static s32 adpt_rescan(adpt_hba* pHba);
@@ -299,7 +295,7 @@
static void adpt_inquiry(adpt_hba* pHba);
static void adpt_fail_posted_scbs(adpt_hba* pHba);
static struct adpt_device* adpt_find_device(adpt_hba* pHba, u32 chan, u32 id, u32 lun);
-static int adpt_install_hba(struct scsi_host_template* sht, struct pci_dev* pDev) ;
+static int adpt_install_hba(struct pci_dev* pDev) ;
static int adpt_i2o_online_hba(adpt_hba* pHba);
static void adpt_i2o_post_wait_complete(u32, int);
static int adpt_i2o_systab_send(adpt_hba* pHba);
@@ -343,5 +339,4 @@
#define FW_DEBUG_BLED_OFFSET 8
#define FW_DEBUG_FLAGS_NO_HEADERS_B 0x01
-#endif /* !HOSTS_C */
#endif /* _DPT_H */
diff --git a/drivers/scsi/esp_scsi.h b/drivers/scsi/esp_scsi.h
index 856e38b..d5576d5 100644
--- a/drivers/scsi/esp_scsi.h
+++ b/drivers/scsi/esp_scsi.h
@@ -220,7 +220,7 @@
#define ESP_BUSID_RESELID 0x10
#define ESP_BUSID_CTR32BIT 0x40
-#define ESP_BUS_TIMEOUT 275 /* In milli-seconds */
+#define ESP_BUS_TIMEOUT 250 /* In milli-seconds */
#define ESP_TIMEO_CONST 8192
#define ESP_NEG_DEFP(mhz, cfact) \
((ESP_BUS_TIMEOUT * ((mhz) / 1000)) / (8192 * (cfact)))
diff --git a/drivers/scsi/gdth.c b/drivers/scsi/gdth.c
index d0b95ce..55e4d2d 100644
--- a/drivers/scsi/gdth.c
+++ b/drivers/scsi/gdth.c
@@ -902,11 +902,6 @@
return;
/* GDT PCI controller found, resources are already in pdev */
pcistr[*cnt].pdev = pdev;
- pcistr[*cnt].vendor_id = vendor;
- pcistr[*cnt].device_id = device;
- pcistr[*cnt].subdevice_id = pdev->subsystem_device;
- pcistr[*cnt].bus = pdev->bus->number;
- pcistr[*cnt].device_fn = pdev->devfn;
pcistr[*cnt].irq = pdev->irq;
base0 = pci_resource_flags(pdev, 0);
base1 = pci_resource_flags(pdev, 1);
@@ -926,7 +921,8 @@
pcistr[*cnt].io = pci_resource_start(pdev, 1);
}
TRACE2(("Controller found at %d/%d, irq %d, dpmem 0x%lx\n",
- pcistr[*cnt].bus, PCI_SLOT(pcistr[*cnt].device_fn),
+ pcistr[*cnt].pdev->bus->number,
+ PCI_SLOT(pcistr[*cnt].pdev->devfn),
pcistr[*cnt].irq, pcistr[*cnt].dpmem));
(*cnt)++;
}
@@ -946,20 +942,20 @@
changed = FALSE;
for (i = 0; i < cnt-1; ++i) {
if (!reverse_scan) {
- if ((pcistr[i].bus > pcistr[i+1].bus) ||
- (pcistr[i].bus == pcistr[i+1].bus &&
- PCI_SLOT(pcistr[i].device_fn) >
- PCI_SLOT(pcistr[i+1].device_fn))) {
+ if ((pcistr[i].pdev->bus->number > pcistr[i+1].pdev->bus->number) ||
+ (pcistr[i].pdev->bus->number == pcistr[i+1].pdev->bus->number &&
+ PCI_SLOT(pcistr[i].pdev->devfn) >
+ PCI_SLOT(pcistr[i+1].pdev->devfn))) {
temp = pcistr[i];
pcistr[i] = pcistr[i+1];
pcistr[i+1] = temp;
changed = TRUE;
}
} else {
- if ((pcistr[i].bus < pcistr[i+1].bus) ||
- (pcistr[i].bus == pcistr[i+1].bus &&
- PCI_SLOT(pcistr[i].device_fn) <
- PCI_SLOT(pcistr[i+1].device_fn))) {
+ if ((pcistr[i].pdev->bus->number < pcistr[i+1].pdev->bus->number) ||
+ (pcistr[i].pdev->bus->number == pcistr[i+1].pdev->bus->number &&
+ PCI_SLOT(pcistr[i].pdev->devfn) <
+ PCI_SLOT(pcistr[i+1].pdev->devfn))) {
temp = pcistr[i];
pcistr[i] = pcistr[i+1];
pcistr[i+1] = temp;
@@ -1176,17 +1172,16 @@
TRACE(("gdth_init_pci()\n"));
- if (pcistr->vendor_id == PCI_VENDOR_ID_INTEL)
+ if (pcistr->pdev->vendor == PCI_VENDOR_ID_INTEL)
ha->oem_id = OEM_ID_INTEL;
else
ha->oem_id = OEM_ID_ICP;
- ha->brd_phys = (pcistr->bus << 8) | (pcistr->device_fn & 0xf8);
- ha->stype = (ulong32)pcistr->device_id;
- ha->subdevice_id = pcistr->subdevice_id;
+ ha->brd_phys = (pcistr->pdev->bus->number << 8) | (pcistr->pdev->devfn & 0xf8);
+ ha->stype = (ulong32)pcistr->pdev->device;
ha->irq = pcistr->irq;
ha->pdev = pcistr->pdev;
- if (ha->stype <= PCI_DEVICE_ID_VORTEX_GDT6000B) { /* GDT6000/B */
+ if (ha->pdev->device <= PCI_DEVICE_ID_VORTEX_GDT6000B) { /* GDT6000/B */
TRACE2(("init_pci() dpmem %lx irq %d\n",pcistr->dpmem,ha->irq));
ha->brd = ioremap(pcistr->dpmem, sizeof(gdt6_dpram_str));
if (ha->brd == NULL) {
@@ -1293,7 +1288,7 @@
ha->dma64_support = 0;
- } else if (ha->stype <= PCI_DEVICE_ID_VORTEX_GDT6555) { /* GDT6110, ... */
+ } else if (ha->pdev->device <= PCI_DEVICE_ID_VORTEX_GDT6555) { /* GDT6110, ... */
ha->plx = (gdt6c_plx_regs *)pcistr->io;
TRACE2(("init_pci_new() dpmem %lx irq %d\n",
pcistr->dpmem,ha->irq));
@@ -4601,7 +4596,8 @@
}
/* controller found and initialized */
printk("Configuring GDT-PCI HA at %d/%d IRQ %u\n",
- pcistr[ctr].bus,PCI_SLOT(pcistr[ctr].device_fn),ha->irq);
+ pcistr[ctr].pdev->bus->number,
+ PCI_SLOT(pcistr[ctr].pdev->devfn), ha->irq);
if (request_irq(ha->irq, gdth_interrupt,
IRQF_DISABLED|IRQF_SHARED, "gdth", ha))
@@ -4637,7 +4633,7 @@
#endif
ha->scratch_busy = FALSE;
ha->req_first = NULL;
- ha->tid_cnt = pcistr[ctr].device_id >= 0x200 ? MAXID : MAX_HDRIVES;
+ ha->tid_cnt = pcistr[ctr].pdev->device >= 0x200 ? MAXID : MAX_HDRIVES;
if (max_ids > 0 && max_ids < ha->tid_cnt)
ha->tid_cnt = max_ids;
for (i=0; i<GDTH_MAXCMDS; ++i)
@@ -4810,7 +4806,7 @@
} else if (ha->type == GDT_ISA) {
return("GDT2000/2020");
} else if (ha->type == GDT_PCI) {
- switch (ha->stype) {
+ switch (ha->pdev->device) {
case PCI_DEVICE_ID_VORTEX_GDT60x0:
return("GDT6000/6020/6050");
case PCI_DEVICE_ID_VORTEX_GDT6000B:
@@ -5448,12 +5444,12 @@
ctrt.type =
(ha->oem_id == OEM_ID_INTEL ? 0xfd : 0xfe);
if (ha->stype >= 0x300)
- ctrt.ext_type = 0x6000 | ha->subdevice_id;
+ ctrt.ext_type = 0x6000 | ha->pdev->subsystem_device;
else
ctrt.ext_type = 0x6000 | ha->stype;
}
- ctrt.device_id = ha->stype;
- ctrt.sub_device_id = ha->subdevice_id;
+ ctrt.device_id = ha->pdev->device;
+ ctrt.sub_device_id = ha->pdev->subsystem_device;
}
ctrt.info = ha->brd_phys;
ctrt.oem_id = ha->oem_id;
diff --git a/drivers/scsi/gdth.h b/drivers/scsi/gdth.h
index 8c29eaf..3742330 100644
--- a/drivers/scsi/gdth.h
+++ b/drivers/scsi/gdth.h
@@ -845,11 +845,6 @@
/* PCI resources */
typedef struct {
struct pci_dev *pdev;
- ushort vendor_id; /* vendor (ICP, Intel, ..) */
- ushort device_id; /* device ID (0,..,9) */
- ushort subdevice_id; /* sub device ID */
- unchar bus; /* PCI bus */
- unchar device_fn; /* PCI device/function no. */
ulong dpmem; /* DPRAM address */
ulong io; /* IO address */
ulong io_mm; /* IO address mem. mapped */
@@ -862,7 +857,6 @@
ushort oem_id; /* OEM */
ushort type; /* controller class */
ulong32 stype; /* subtype (PCI: device ID) */
- ushort subdevice_id; /* sub device ID (PCI) */
ushort fw_vers; /* firmware version */
ushort cache_feat; /* feat. cache serv. (s/g,..)*/
ushort raw_feat; /* feat. raw service (s/g,..)*/
diff --git a/drivers/scsi/hosts.c b/drivers/scsi/hosts.c
index bd8e7f3..96bc312 100644
--- a/drivers/scsi/hosts.c
+++ b/drivers/scsi/hosts.c
@@ -220,7 +220,7 @@
get_device(&shost->shost_gendev);
if (shost->transportt->host_size &&
- (shost->shost_data = kmalloc(shost->transportt->host_size,
+ (shost->shost_data = kzalloc(shost->transportt->host_size,
GFP_KERNEL)) == NULL)
goto out_del_classdev;
diff --git a/drivers/scsi/ibmvscsi/ibmvscsi.c b/drivers/scsi/ibmvscsi/ibmvscsi.c
index 5870866..5ecc63d 100644
--- a/drivers/scsi/ibmvscsi/ibmvscsi.c
+++ b/drivers/scsi/ibmvscsi/ibmvscsi.c
@@ -393,12 +393,6 @@
return 1;
else if (sg_mapped < 0)
return 0;
- else if (sg_mapped > SG_ALL) {
- printk(KERN_ERR
- "ibmvscsi: More than %d mapped sg entries, got %d\n",
- SG_ALL, sg_mapped);
- return 0;
- }
set_srp_direction(cmd, srp_cmd, sg_mapped);
@@ -708,8 +702,7 @@
struct srp_cmd *srp_cmd;
struct srp_event_struct *evt_struct;
struct srp_indirect_buf *indirect;
- struct ibmvscsi_host_data *hostdata =
- (struct ibmvscsi_host_data *)&cmnd->device->host->hostdata;
+ struct ibmvscsi_host_data *hostdata = shost_priv(cmnd->device->host);
u16 lun = lun_from_dev(cmnd->device);
u8 out_fmt, in_fmt;
@@ -960,8 +953,7 @@
*/
static int ibmvscsi_eh_abort_handler(struct scsi_cmnd *cmd)
{
- struct ibmvscsi_host_data *hostdata =
- (struct ibmvscsi_host_data *)cmd->device->host->hostdata;
+ struct ibmvscsi_host_data *hostdata = shost_priv(cmd->device->host);
struct srp_tsk_mgmt *tsk_mgmt;
struct srp_event_struct *evt;
struct srp_event_struct *tmp_evt, *found_evt;
@@ -1084,9 +1076,7 @@
*/
static int ibmvscsi_eh_device_reset_handler(struct scsi_cmnd *cmd)
{
- struct ibmvscsi_host_data *hostdata =
- (struct ibmvscsi_host_data *)cmd->device->host->hostdata;
-
+ struct ibmvscsi_host_data *hostdata = shost_priv(cmd->device->host);
struct srp_tsk_mgmt *tsk_mgmt;
struct srp_event_struct *evt;
struct srp_event_struct *tmp_evt, *pos;
@@ -1183,8 +1173,7 @@
static int ibmvscsi_eh_host_reset_handler(struct scsi_cmnd *cmd)
{
unsigned long wait_switch = 0;
- struct ibmvscsi_host_data *hostdata =
- (struct ibmvscsi_host_data *)cmd->device->host->hostdata;
+ struct ibmvscsi_host_data *hostdata = shost_priv(cmd->device->host);
dev_err(hostdata->dev, "Resetting connection due to error recovery\n");
@@ -1412,8 +1401,7 @@
static ssize_t show_host_srp_version(struct class_device *class_dev, char *buf)
{
struct Scsi_Host *shost = class_to_shost(class_dev);
- struct ibmvscsi_host_data *hostdata =
- (struct ibmvscsi_host_data *)shost->hostdata;
+ struct ibmvscsi_host_data *hostdata = shost_priv(shost);
int len;
len = snprintf(buf, PAGE_SIZE, "%s\n",
@@ -1433,8 +1421,7 @@
char *buf)
{
struct Scsi_Host *shost = class_to_shost(class_dev);
- struct ibmvscsi_host_data *hostdata =
- (struct ibmvscsi_host_data *)shost->hostdata;
+ struct ibmvscsi_host_data *hostdata = shost_priv(shost);
int len;
len = snprintf(buf, PAGE_SIZE, "%s\n",
@@ -1454,8 +1441,7 @@
char *buf)
{
struct Scsi_Host *shost = class_to_shost(class_dev);
- struct ibmvscsi_host_data *hostdata =
- (struct ibmvscsi_host_data *)shost->hostdata;
+ struct ibmvscsi_host_data *hostdata = shost_priv(shost);
int len;
len = snprintf(buf, PAGE_SIZE, "%d\n",
@@ -1474,8 +1460,7 @@
static ssize_t show_host_mad_version(struct class_device *class_dev, char *buf)
{
struct Scsi_Host *shost = class_to_shost(class_dev);
- struct ibmvscsi_host_data *hostdata =
- (struct ibmvscsi_host_data *)shost->hostdata;
+ struct ibmvscsi_host_data *hostdata = shost_priv(shost);
int len;
len = snprintf(buf, PAGE_SIZE, "%d\n",
@@ -1494,8 +1479,7 @@
static ssize_t show_host_os_type(struct class_device *class_dev, char *buf)
{
struct Scsi_Host *shost = class_to_shost(class_dev);
- struct ibmvscsi_host_data *hostdata =
- (struct ibmvscsi_host_data *)shost->hostdata;
+ struct ibmvscsi_host_data *hostdata = shost_priv(shost);
int len;
len = snprintf(buf, PAGE_SIZE, "%d\n", hostdata->madapter_info.os_type);
@@ -1513,8 +1497,7 @@
static ssize_t show_host_config(struct class_device *class_dev, char *buf)
{
struct Scsi_Host *shost = class_to_shost(class_dev);
- struct ibmvscsi_host_data *hostdata =
- (struct ibmvscsi_host_data *)shost->hostdata;
+ struct ibmvscsi_host_data *hostdata = shost_priv(shost);
/* returns null-terminated host config data */
if (ibmvscsi_do_host_config(hostdata, buf, PAGE_SIZE) == 0)
@@ -1582,7 +1565,7 @@
goto scsi_host_alloc_failed;
}
- hostdata = (struct ibmvscsi_host_data *)host->hostdata;
+ hostdata = shost_priv(host);
memset(hostdata, 0x00, sizeof(*hostdata));
INIT_LIST_HEAD(&hostdata->sent);
hostdata->host = host;
diff --git a/drivers/scsi/libsas/Kconfig b/drivers/scsi/libsas/Kconfig
index 3a3c1ac..c01a40d 100644
--- a/drivers/scsi/libsas/Kconfig
+++ b/drivers/scsi/libsas/Kconfig
@@ -32,7 +32,8 @@
config SCSI_SAS_ATA
bool "ATA support for libsas (requires libata)"
- depends on SCSI_SAS_LIBSAS && ATA
+ depends on SCSI_SAS_LIBSAS
+ depends on ATA = y || ATA = SCSI_SAS_LIBSAS
help
Builds in ATA support into libsas. Will necessitate
the loading of libata along with libsas.
diff --git a/drivers/scsi/lpfc/lpfc.h b/drivers/scsi/lpfc/lpfc.h
index f8f64d6..ba3ecab 100644
--- a/drivers/scsi/lpfc/lpfc.h
+++ b/drivers/scsi/lpfc/lpfc.h
@@ -45,7 +45,7 @@
#define LPFC_DISC_IOCB_BUFF_COUNT 20
#define LPFC_HB_MBOX_INTERVAL 5 /* Heart beat interval in seconds. */
-#define LPFC_HB_MBOX_TIMEOUT 30 /* Heart beat timeout in seconds. */
+#define LPFC_HB_MBOX_TIMEOUT 30 /* Heart beat timeout in seconds. */
/* Define macros for 64 bit support */
#define putPaddrLow(addr) ((uint32_t) (0xffffffff & (u64)(addr)))
@@ -78,6 +78,7 @@
struct hbq_dmabuf {
struct lpfc_dmabuf dbuf;
+ uint32_t size;
uint32_t tag;
};
@@ -329,13 +330,30 @@
#define FC_LOADING 0x1 /* HBA in process of loading drvr */
#define FC_UNLOADING 0x2 /* HBA in process of unloading drvr */
char *vname; /* Application assigned name */
+
+ /* Vport Config Parameters */
+ uint32_t cfg_scan_down;
+ uint32_t cfg_lun_queue_depth;
+ uint32_t cfg_nodev_tmo;
+ uint32_t cfg_devloss_tmo;
+ uint32_t cfg_restrict_login;
+ uint32_t cfg_peer_port_login;
+ uint32_t cfg_fcp_class;
+ uint32_t cfg_use_adisc;
+ uint32_t cfg_fdmi_on;
+ uint32_t cfg_discovery_threads;
+ uint32_t cfg_log_verbose;
+ uint32_t cfg_max_luns;
+
+ uint32_t dev_loss_tmo_changed;
+
struct fc_vport *fc_vport;
#ifdef CONFIG_LPFC_DEBUG_FS
struct dentry *debug_disc_trc;
struct dentry *debug_nodelist;
struct dentry *vport_debugfs_root;
- struct lpfc_disc_trc *disc_trc;
+ struct lpfc_debugfs_trc *disc_trc;
atomic_t disc_trc_cnt;
#endif
};
@@ -345,17 +363,25 @@
uint32_t next_hbqPutIdx; /* Index to next HBQ slot to use */
uint32_t hbqPutIdx; /* HBQ slot to use */
uint32_t local_hbqGetIdx; /* Local copy of Get index from Port */
+ void *hbq_virt; /* Virtual ptr to this hbq */
+ struct list_head hbq_buffer_list; /* buffers assigned to this HBQ */
+ /* Callback for HBQ buffer allocation */
+ struct hbq_dmabuf *(*hbq_alloc_buffer) (struct lpfc_hba *);
+ /* Callback for HBQ buffer free */
+ void (*hbq_free_buffer) (struct lpfc_hba *,
+ struct hbq_dmabuf *);
};
-#define LPFC_MAX_HBQS 16
-/* this matches the possition in the lpfc_hbq_defs array */
+#define LPFC_MAX_HBQS 4
+/* this matches the position in the lpfc_hbq_defs array */
#define LPFC_ELS_HBQ 0
+#define LPFC_EXTRA_HBQ 1
struct lpfc_hba {
struct lpfc_sli sli;
uint32_t sli_rev; /* SLI2 or SLI3 */
uint32_t sli3_options; /* Mask of enabled SLI3 options */
-#define LPFC_SLI3_ENABLED 0x01
+#define LPFC_SLI3_ENABLED 0x01
#define LPFC_SLI3_HBQ_ENABLED 0x02
#define LPFC_SLI3_NPIV_ENABLED 0x04
#define LPFC_SLI3_VPORT_TEARDOWN 0x08
@@ -364,7 +390,7 @@
enum hba_state link_state;
uint32_t link_flag; /* link state flags */
-#define LS_LOOPBACK_MODE 0x1 /* NPort is in Loopback mode */
+#define LS_LOOPBACK_MODE 0x1 /* NPort is in Loopback mode */
/* This flag is set while issuing */
/* INIT_LINK mailbox command */
#define LS_NPIV_FAB_SUPPORTED 0x2 /* Fabric supports NPIV */
@@ -413,28 +439,16 @@
uint8_t wwpn[8];
uint32_t RandomData[7];
- uint32_t cfg_log_verbose;
- uint32_t cfg_lun_queue_depth;
- uint32_t cfg_nodev_tmo;
- uint32_t cfg_devloss_tmo;
- uint32_t cfg_hba_queue_depth;
- uint32_t cfg_peer_port_login;
- uint32_t cfg_vport_restrict_login;
- uint32_t cfg_npiv_enable;
- uint32_t cfg_fcp_class;
- uint32_t cfg_use_adisc;
+ /* HBA Config Parameters */
uint32_t cfg_ack0;
+ uint32_t cfg_enable_npiv;
uint32_t cfg_topology;
- uint32_t cfg_scan_down;
uint32_t cfg_link_speed;
uint32_t cfg_cr_delay;
uint32_t cfg_cr_count;
uint32_t cfg_multi_ring_support;
uint32_t cfg_multi_ring_rctl;
uint32_t cfg_multi_ring_type;
- uint32_t cfg_fdmi_on;
- uint32_t cfg_discovery_threads;
- uint32_t cfg_max_luns;
uint32_t cfg_poll;
uint32_t cfg_poll_tmo;
uint32_t cfg_use_msi;
@@ -442,8 +456,8 @@
uint32_t cfg_sg_dma_buf_size;
uint64_t cfg_soft_wwnn;
uint64_t cfg_soft_wwpn;
+ uint32_t cfg_hba_queue_depth;
- uint32_t dev_loss_tmo_changed;
lpfc_vpd_t vpd; /* vital product data */
@@ -457,7 +471,6 @@
wait_queue_head_t *work_wait;
struct task_struct *worker_thread;
- struct list_head hbq_buffer_list;
uint32_t hbq_count; /* Count of configured HBQs */
struct hbq_s hbqs[LPFC_MAX_HBQS]; /* local copy of hbq indicies */
@@ -526,12 +539,14 @@
mempool_t *nlp_mem_pool;
struct fc_host_statistics link_stats;
+ uint8_t using_msi;
struct list_head port_list;
- struct lpfc_vport *pport; /* physical lpfc_vport pointer */
- uint16_t max_vpi; /* Maximum virtual nports */
-#define LPFC_MAX_VPI 100 /* Max number of VPorts supported */
- unsigned long *vpi_bmask; /* vpi allocation table */
+ struct lpfc_vport *pport; /* physical lpfc_vport pointer */
+ uint16_t max_vpi; /* Maximum virtual nports */
+#define LPFC_MAX_VPI 100 /* Max number of VPI supported */
+#define LPFC_MAX_VPORTS (LPFC_MAX_VPI+1)/* Max number of VPorts supported */
+ unsigned long *vpi_bmask; /* vpi allocation table */
/* Data structure used by fabric iocb scheduler */
struct list_head fabric_iocb_list;
@@ -547,6 +562,11 @@
#ifdef CONFIG_LPFC_DEBUG_FS
struct dentry *hba_debugfs_root;
atomic_t debugfs_vport_count;
+ struct dentry *debug_hbqinfo;
+ struct dentry *debug_dumpslim;
+ struct dentry *debug_slow_ring_trc;
+ struct lpfc_debugfs_trc *slow_ring_trc;
+ atomic_t slow_ring_trc_cnt;
#endif
/* Fields used for heart beat. */
diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c
index 860a52c..80a1121 100644
--- a/drivers/scsi/lpfc/lpfc_attr.c
+++ b/drivers/scsi/lpfc/lpfc_attr.c
@@ -68,12 +68,6 @@
}
static ssize_t
-management_version_show(struct class_device *cdev, char *buf)
-{
- return snprintf(buf, PAGE_SIZE, DFC_API_VERSION "\n");
-}
-
-static ssize_t
lpfc_info_show(struct class_device *cdev, char *buf)
{
struct Scsi_Host *host = class_to_shost(cdev);
@@ -319,9 +313,8 @@
if (cnt++ > 3000) {
lpfc_printf_log(phba,
KERN_WARNING, LOG_INIT,
- "%d:0466 Outstanding IO when "
- "bringing Adapter offline\n",
- phba->brd_no);
+ "0466 Outstanding IO when "
+ "bringing Adapter offline\n");
break;
}
}
@@ -437,7 +430,7 @@
return -EIO;
}
-int
+static int
lpfc_get_hba_info(struct lpfc_hba *phba,
uint32_t *mxri, uint32_t *axri,
uint32_t *mrpi, uint32_t *arpi,
@@ -694,9 +687,8 @@
return 0;\
}\
lpfc_printf_log(phba, KERN_ERR, LOG_INIT, \
- "%d:0449 lpfc_"#attr" attribute cannot be set to %d, "\
- "allowed range is ["#minval", "#maxval"]\n", \
- phba->brd_no, val); \
+ "0449 lpfc_"#attr" attribute cannot be set to %d, "\
+ "allowed range is ["#minval", "#maxval"]\n", val); \
phba->cfg_##attr = default;\
return -EINVAL;\
}
@@ -710,9 +702,8 @@
return 0;\
}\
lpfc_printf_log(phba, KERN_ERR, LOG_INIT, \
- "%d:0450 lpfc_"#attr" attribute cannot be set to %d, "\
- "allowed range is ["#minval", "#maxval"]\n", \
- phba->brd_no, val); \
+ "0450 lpfc_"#attr" attribute cannot be set to %d, "\
+ "allowed range is ["#minval", "#maxval"]\n", val); \
return -EINVAL;\
}
@@ -734,6 +725,75 @@
return -EINVAL;\
}
+#define lpfc_vport_param_show(attr) \
+static ssize_t \
+lpfc_##attr##_show(struct class_device *cdev, char *buf) \
+{ \
+ struct Scsi_Host *shost = class_to_shost(cdev);\
+ struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;\
+ int val = 0;\
+ val = vport->cfg_##attr;\
+ return snprintf(buf, PAGE_SIZE, "%d\n", vport->cfg_##attr);\
+}
+
+#define lpfc_vport_param_hex_show(attr) \
+static ssize_t \
+lpfc_##attr##_show(struct class_device *cdev, char *buf) \
+{ \
+ struct Scsi_Host *shost = class_to_shost(cdev);\
+ struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;\
+ int val = 0;\
+ val = vport->cfg_##attr;\
+ return snprintf(buf, PAGE_SIZE, "%#x\n", vport->cfg_##attr);\
+}
+
+#define lpfc_vport_param_init(attr, default, minval, maxval) \
+static int \
+lpfc_##attr##_init(struct lpfc_vport *vport, int val) \
+{ \
+ if (val >= minval && val <= maxval) {\
+ vport->cfg_##attr = val;\
+ return 0;\
+ }\
+ lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT, \
+ "0449 lpfc_"#attr" attribute cannot be set to %d, "\
+ "allowed range is ["#minval", "#maxval"]\n", val); \
+ vport->cfg_##attr = default;\
+ return -EINVAL;\
+}
+
+#define lpfc_vport_param_set(attr, default, minval, maxval) \
+static int \
+lpfc_##attr##_set(struct lpfc_vport *vport, int val) \
+{ \
+ if (val >= minval && val <= maxval) {\
+ vport->cfg_##attr = val;\
+ return 0;\
+ }\
+ lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT, \
+ "0450 lpfc_"#attr" attribute cannot be set to %d, "\
+ "allowed range is ["#minval", "#maxval"]\n", val); \
+ return -EINVAL;\
+}
+
+#define lpfc_vport_param_store(attr) \
+static ssize_t \
+lpfc_##attr##_store(struct class_device *cdev, const char *buf, size_t count) \
+{ \
+ struct Scsi_Host *shost = class_to_shost(cdev);\
+ struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;\
+ int val=0;\
+ if (!isdigit(buf[0]))\
+ return -EINVAL;\
+ if (sscanf(buf, "%i", &val) != 1)\
+ return -EINVAL;\
+ if (lpfc_##attr##_set(vport, val) == 0) \
+ return strlen(buf);\
+ else \
+ return -EINVAL;\
+}
+
+
#define LPFC_ATTR(name, defval, minval, maxval, desc) \
static int lpfc_##name = defval;\
module_param(lpfc_##name, int, 0);\
@@ -778,6 +838,50 @@
static CLASS_DEVICE_ATTR(lpfc_##name, S_IRUGO | S_IWUSR,\
lpfc_##name##_show, lpfc_##name##_store)
+#define LPFC_VPORT_ATTR(name, defval, minval, maxval, desc) \
+static int lpfc_##name = defval;\
+module_param(lpfc_##name, int, 0);\
+MODULE_PARM_DESC(lpfc_##name, desc);\
+lpfc_vport_param_init(name, defval, minval, maxval)
+
+#define LPFC_VPORT_ATTR_R(name, defval, minval, maxval, desc) \
+static int lpfc_##name = defval;\
+module_param(lpfc_##name, int, 0);\
+MODULE_PARM_DESC(lpfc_##name, desc);\
+lpfc_vport_param_show(name)\
+lpfc_vport_param_init(name, defval, minval, maxval)\
+static CLASS_DEVICE_ATTR(lpfc_##name, S_IRUGO , lpfc_##name##_show, NULL)
+
+#define LPFC_VPORT_ATTR_RW(name, defval, minval, maxval, desc) \
+static int lpfc_##name = defval;\
+module_param(lpfc_##name, int, 0);\
+MODULE_PARM_DESC(lpfc_##name, desc);\
+lpfc_vport_param_show(name)\
+lpfc_vport_param_init(name, defval, minval, maxval)\
+lpfc_vport_param_set(name, defval, minval, maxval)\
+lpfc_vport_param_store(name)\
+static CLASS_DEVICE_ATTR(lpfc_##name, S_IRUGO | S_IWUSR,\
+ lpfc_##name##_show, lpfc_##name##_store)
+
+#define LPFC_VPORT_ATTR_HEX_R(name, defval, minval, maxval, desc) \
+static int lpfc_##name = defval;\
+module_param(lpfc_##name, int, 0);\
+MODULE_PARM_DESC(lpfc_##name, desc);\
+lpfc_vport_param_hex_show(name)\
+lpfc_vport_param_init(name, defval, minval, maxval)\
+static CLASS_DEVICE_ATTR(lpfc_##name, S_IRUGO , lpfc_##name##_show, NULL)
+
+#define LPFC_VPORT_ATTR_HEX_RW(name, defval, minval, maxval, desc) \
+static int lpfc_##name = defval;\
+module_param(lpfc_##name, int, 0);\
+MODULE_PARM_DESC(lpfc_##name, desc);\
+lpfc_vport_param_hex_show(name)\
+lpfc_vport_param_init(name, defval, minval, maxval)\
+lpfc_vport_param_set(name, defval, minval, maxval)\
+lpfc_vport_param_store(name)\
+static CLASS_DEVICE_ATTR(lpfc_##name, S_IRUGO | S_IWUSR,\
+ lpfc_##name##_show, lpfc_##name##_store)
+
static CLASS_DEVICE_ATTR(info, S_IRUGO, lpfc_info_show, NULL);
static CLASS_DEVICE_ATTR(serialnum, S_IRUGO, lpfc_serialnum_show, NULL);
static CLASS_DEVICE_ATTR(modeldesc, S_IRUGO, lpfc_modeldesc_show, NULL);
@@ -794,8 +898,6 @@
static CLASS_DEVICE_ATTR(nport_evt_cnt, S_IRUGO, lpfc_nport_evt_cnt_show, NULL);
static CLASS_DEVICE_ATTR(lpfc_drvr_version, S_IRUGO, lpfc_drvr_version_show,
NULL);
-static CLASS_DEVICE_ATTR(management_version, S_IRUGO, management_version_show,
- NULL);
static CLASS_DEVICE_ATTR(board_mode, S_IRUGO | S_IWUSR,
lpfc_board_mode_show, lpfc_board_mode_store);
static CLASS_DEVICE_ATTR(issue_reset, S_IWUSR, NULL, lpfc_issue_reset);
@@ -908,17 +1010,15 @@
stat1 = lpfc_do_offline(phba, LPFC_EVT_OFFLINE);
if (stat1)
lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
- "%d:0463 lpfc_soft_wwpn attribute set failed to reinit "
- "adapter - %d\n", phba->brd_no, stat1);
-
+ "0463 lpfc_soft_wwpn attribute set failed to "
+ "reinit adapter - %d\n", stat1);
init_completion(&online_compl);
lpfc_workq_post_event(phba, &stat2, &online_compl, LPFC_EVT_ONLINE);
wait_for_completion(&online_compl);
if (stat2)
lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
- "%d:0464 lpfc_soft_wwpn attribute set failed to reinit "
- "adapter - %d\n", phba->brd_no, stat2);
-
+ "0464 lpfc_soft_wwpn attribute set failed to "
+ "reinit adapter - %d\n", stat2);
return (stat1 || stat2) ? -EIO : count;
}
static CLASS_DEVICE_ATTR(lpfc_soft_wwpn, S_IRUGO | S_IWUSR,\
@@ -927,8 +1027,8 @@
static ssize_t
lpfc_soft_wwnn_show(struct class_device *cdev, char *buf)
{
- struct Scsi_Host *host = class_to_shost(cdev);
- struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata;
+ struct Scsi_Host *shost = class_to_shost(cdev);
+ struct lpfc_hba *phba = ((struct lpfc_vport *)shost->hostdata)->phba;
return snprintf(buf, PAGE_SIZE, "0x%llx\n",
(unsigned long long)phba->cfg_soft_wwnn);
}
@@ -937,8 +1037,8 @@
static ssize_t
lpfc_soft_wwnn_store(struct class_device *cdev, const char *buf, size_t count)
{
- struct Scsi_Host *host = class_to_shost(cdev);
- struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata;
+ struct Scsi_Host *shost = class_to_shost(cdev);
+ struct lpfc_hba *phba = ((struct lpfc_vport *)shost->hostdata)->phba;
unsigned int i, j, cnt=count;
u8 wwnn[8];
@@ -1002,7 +1102,7 @@
" 2 - select SLI-2 even on SLI-3 capable HBAs,"
" 3 - select SLI-3");
-LPFC_ATTR_R(npiv_enable, 0, 0, 1, "Enable NPIV functionality");
+LPFC_ATTR_R(enable_npiv, 0, 0, 1, "Enable NPIV functionality");
/*
# lpfc_nodev_tmo: If set, it will hold all I/O errors on devices that disappear
@@ -1019,90 +1119,75 @@
{
struct Scsi_Host *shost = class_to_shost(cdev);
struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
- struct lpfc_hba *phba = vport->phba;
int val = 0;
- val = phba->cfg_devloss_tmo;
- return snprintf(buf, PAGE_SIZE, "%d\n",
- phba->cfg_devloss_tmo);
+ val = vport->cfg_devloss_tmo;
+ return snprintf(buf, PAGE_SIZE, "%d\n", vport->cfg_devloss_tmo);
}
static int
-lpfc_nodev_tmo_init(struct lpfc_hba *phba, int val)
+lpfc_nodev_tmo_init(struct lpfc_vport *vport, int val)
{
- static int warned;
- if (phba->cfg_devloss_tmo != LPFC_DEF_DEVLOSS_TMO) {
- phba->cfg_nodev_tmo = phba->cfg_devloss_tmo;
- if (!warned && val != LPFC_DEF_DEVLOSS_TMO) {
- warned = 1;
- lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
- "%d:0402 Ignoring nodev_tmo module "
- "parameter because devloss_tmo is"
- " set.\n",
- phba->brd_no);
- }
+ if (vport->cfg_devloss_tmo != LPFC_DEF_DEVLOSS_TMO) {
+ vport->cfg_nodev_tmo = vport->cfg_devloss_tmo;
+ if (val != LPFC_DEF_DEVLOSS_TMO)
+ lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
+ "0402 Ignoring nodev_tmo module "
+ "parameter because devloss_tmo is "
+ "set.\n");
return 0;
}
if (val >= LPFC_MIN_DEVLOSS_TMO && val <= LPFC_MAX_DEVLOSS_TMO) {
- phba->cfg_nodev_tmo = val;
- phba->cfg_devloss_tmo = val;
+ vport->cfg_nodev_tmo = val;
+ vport->cfg_devloss_tmo = val;
return 0;
}
- lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
- "%d:0400 lpfc_nodev_tmo attribute cannot be set to %d, "
- "allowed range is [%d, %d]\n",
- phba->brd_no, val,
- LPFC_MIN_DEVLOSS_TMO, LPFC_MAX_DEVLOSS_TMO);
- phba->cfg_nodev_tmo = LPFC_DEF_DEVLOSS_TMO;
+ lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
+ "0400 lpfc_nodev_tmo attribute cannot be set to"
+ " %d, allowed range is [%d, %d]\n",
+ val, LPFC_MIN_DEVLOSS_TMO, LPFC_MAX_DEVLOSS_TMO);
+ vport->cfg_nodev_tmo = LPFC_DEF_DEVLOSS_TMO;
return -EINVAL;
}
static void
-lpfc_update_rport_devloss_tmo(struct lpfc_hba *phba)
+lpfc_update_rport_devloss_tmo(struct lpfc_vport *vport)
{
- struct lpfc_vport *vport;
struct Scsi_Host *shost;
struct lpfc_nodelist *ndlp;
- list_for_each_entry(vport, &phba->port_list, listentry) {
- shost = lpfc_shost_from_vport(vport);
- spin_lock_irq(shost->host_lock);
- list_for_each_entry(ndlp, &vport->fc_nodes, nlp_listp)
- if (ndlp->rport)
- ndlp->rport->dev_loss_tmo =
- phba->cfg_devloss_tmo;
- spin_unlock_irq(shost->host_lock);
- }
+ shost = lpfc_shost_from_vport(vport);
+ spin_lock_irq(shost->host_lock);
+ list_for_each_entry(ndlp, &vport->fc_nodes, nlp_listp)
+ if (ndlp->rport)
+ ndlp->rport->dev_loss_tmo = vport->cfg_devloss_tmo;
+ spin_unlock_irq(shost->host_lock);
}
static int
-lpfc_nodev_tmo_set(struct lpfc_hba *phba, int val)
+lpfc_nodev_tmo_set(struct lpfc_vport *vport, int val)
{
- if (phba->dev_loss_tmo_changed ||
- (lpfc_devloss_tmo != LPFC_DEF_DEVLOSS_TMO)) {
- lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
- "%d:0401 Ignoring change to nodev_tmo "
- "because devloss_tmo is set.\n",
- phba->brd_no);
+ if (vport->dev_loss_tmo_changed ||
+ (lpfc_devloss_tmo != LPFC_DEF_DEVLOSS_TMO)) {
+ lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
+ "0401 Ignoring change to nodev_tmo "
+ "because devloss_tmo is set.\n");
return 0;
}
-
if (val >= LPFC_MIN_DEVLOSS_TMO && val <= LPFC_MAX_DEVLOSS_TMO) {
- phba->cfg_nodev_tmo = val;
- phba->cfg_devloss_tmo = val;
- lpfc_update_rport_devloss_tmo(phba);
+ vport->cfg_nodev_tmo = val;
+ vport->cfg_devloss_tmo = val;
+ lpfc_update_rport_devloss_tmo(vport);
return 0;
}
-
- lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
- "%d:0403 lpfc_nodev_tmo attribute cannot be set to %d, "
- "allowed range is [%d, %d]\n",
- phba->brd_no, val, LPFC_MIN_DEVLOSS_TMO,
- LPFC_MAX_DEVLOSS_TMO);
+ lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
+ "0403 lpfc_nodev_tmo attribute cannot be set to"
+ "%d, allowed range is [%d, %d]\n",
+ val, LPFC_MIN_DEVLOSS_TMO, LPFC_MAX_DEVLOSS_TMO);
return -EINVAL;
}
-lpfc_param_store(nodev_tmo)
+lpfc_vport_param_store(nodev_tmo)
static CLASS_DEVICE_ATTR(lpfc_nodev_tmo, S_IRUGO | S_IWUSR,
lpfc_nodev_tmo_show, lpfc_nodev_tmo_store);
@@ -1116,29 +1201,28 @@
MODULE_PARM_DESC(lpfc_devloss_tmo,
"Seconds driver will hold I/O waiting "
"for a device to come back");
-lpfc_param_init(devloss_tmo, LPFC_DEF_DEVLOSS_TMO,
- LPFC_MIN_DEVLOSS_TMO, LPFC_MAX_DEVLOSS_TMO)
-lpfc_param_show(devloss_tmo)
+lpfc_vport_param_init(devloss_tmo, LPFC_DEF_DEVLOSS_TMO,
+ LPFC_MIN_DEVLOSS_TMO, LPFC_MAX_DEVLOSS_TMO)
+lpfc_vport_param_show(devloss_tmo)
static int
-lpfc_devloss_tmo_set(struct lpfc_hba *phba, int val)
+lpfc_devloss_tmo_set(struct lpfc_vport *vport, int val)
{
if (val >= LPFC_MIN_DEVLOSS_TMO && val <= LPFC_MAX_DEVLOSS_TMO) {
- phba->cfg_nodev_tmo = val;
- phba->cfg_devloss_tmo = val;
- phba->dev_loss_tmo_changed = 1;
- lpfc_update_rport_devloss_tmo(phba);
+ vport->cfg_nodev_tmo = val;
+ vport->cfg_devloss_tmo = val;
+ vport->dev_loss_tmo_changed = 1;
+ lpfc_update_rport_devloss_tmo(vport);
return 0;
}
- lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
- "%d:0404 lpfc_devloss_tmo attribute cannot be set to"
- " %d, allowed range is [%d, %d]\n",
- phba->brd_no, val, LPFC_MIN_DEVLOSS_TMO,
- LPFC_MAX_DEVLOSS_TMO);
+ lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
+ "0404 lpfc_devloss_tmo attribute cannot be set to"
+ " %d, allowed range is [%d, %d]\n",
+ val, LPFC_MIN_DEVLOSS_TMO, LPFC_MAX_DEVLOSS_TMO);
return -EINVAL;
}
-lpfc_param_store(devloss_tmo)
+lpfc_vport_param_store(devloss_tmo)
static CLASS_DEVICE_ATTR(lpfc_devloss_tmo, S_IRUGO | S_IWUSR,
lpfc_devloss_tmo_show, lpfc_devloss_tmo_store);
@@ -1160,14 +1244,15 @@
# LOG_LIBDFC 0x2000 LIBDFC events
# LOG_ALL_MSG 0xffff LOG all messages
*/
-LPFC_ATTR_HEX_RW(log_verbose, 0x0, 0x0, 0xffff, "Verbose logging bit-mask");
+LPFC_VPORT_ATTR_HEX_RW(log_verbose, 0x0, 0x0, 0xffff,
+ "Verbose logging bit-mask");
/*
# lun_queue_depth: This parameter is used to limit the number of outstanding
# commands per FCP LUN. Value range is [1,128]. Default value is 30.
*/
-LPFC_ATTR_R(lun_queue_depth, 30, 1, 128,
- "Max number of FCP commands we can queue to a specific LUN");
+LPFC_VPORT_ATTR_R(lun_queue_depth, 30, 1, 128,
+ "Max number of FCP commands we can queue to a specific LUN");
/*
# hba_queue_depth: This parameter is used to limit the number of outstanding
@@ -1188,12 +1273,12 @@
# are allowed to login to each other.
# Default value of this parameter is 0.
*/
-LPFC_ATTR_R(peer_port_login, 0, 0, 1,
- "Allow peer ports on the same physical port to login to each "
- "other.");
+LPFC_VPORT_ATTR_R(peer_port_login, 0, 0, 1,
+ "Allow peer ports on the same physical port to login to each "
+ "other.");
/*
-# vport_restrict_login: This parameter allows/prevents logins
+# restrict_login: This parameter allows/prevents logins
# between Virtual Ports and remote initiators.
# When this parameter is not set (0) Virtual Ports will accept PLOGIs from
# other initiators and will attempt to PLOGI all remote ports.
@@ -1203,8 +1288,55 @@
# This parameter does not restrict logins to Fabric resident remote ports.
# Default value of this parameter is 1.
*/
-LPFC_ATTR_RW(vport_restrict_login, 1, 0, 1,
- "Restrict virtual ports login to remote initiators.");
+static int lpfc_restrict_login = 1;
+module_param(lpfc_restrict_login, int, 0);
+MODULE_PARM_DESC(lpfc_restrict_login,
+ "Restrict virtual ports login to remote initiators.");
+lpfc_vport_param_show(restrict_login);
+
+static int
+lpfc_restrict_login_init(struct lpfc_vport *vport, int val)
+{
+ if (val < 0 || val > 1) {
+ lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
+ "0449 lpfc_restrict_login attribute cannot "
+ "be set to %d, allowed range is [0, 1]\n",
+ val);
+ vport->cfg_restrict_login = 1;
+ return -EINVAL;
+ }
+ if (vport->port_type == LPFC_PHYSICAL_PORT) {
+ vport->cfg_restrict_login = 0;
+ return 0;
+ }
+ vport->cfg_restrict_login = val;
+ return 0;
+}
+
+static int
+lpfc_restrict_login_set(struct lpfc_vport *vport, int val)
+{
+ if (val < 0 || val > 1) {
+ lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
+ "0450 lpfc_restrict_login attribute cannot "
+ "be set to %d, allowed range is [0, 1]\n",
+ val);
+ vport->cfg_restrict_login = 1;
+ return -EINVAL;
+ }
+ if (vport->port_type == LPFC_PHYSICAL_PORT && val != 0) {
+ lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
+ "0468 lpfc_restrict_login must be 0 for "
+ "Physical ports.\n");
+ vport->cfg_restrict_login = 0;
+ return 0;
+ }
+ vport->cfg_restrict_login = val;
+ return 0;
+}
+lpfc_vport_param_store(restrict_login);
+static CLASS_DEVICE_ATTR(lpfc_restrict_login, S_IRUGO | S_IWUSR,
+ lpfc_restrict_login_show, lpfc_restrict_login_store);
/*
# Some disk devices have a "select ID" or "select Target" capability.
@@ -1223,8 +1355,8 @@
# and will not work across a fabric. Also this parameter will take
# effect only in the case when ALPA map is not available.)
*/
-LPFC_ATTR_R(scan_down, 1, 0, 1,
- "Start scanning for devices from highest ALPA to lowest");
+LPFC_VPORT_ATTR_R(scan_down, 1, 0, 1,
+ "Start scanning for devices from highest ALPA to lowest");
/*
# lpfc_topology: link topology for init link
@@ -1255,15 +1387,15 @@
# lpfc_fcp_class: Determines FC class to use for the FCP protocol.
# Value range is [2,3]. Default value is 3.
*/
-LPFC_ATTR_R(fcp_class, 3, 2, 3,
- "Select Fibre Channel class of service for FCP sequences");
+LPFC_VPORT_ATTR_R(fcp_class, 3, 2, 3,
+ "Select Fibre Channel class of service for FCP sequences");
/*
# lpfc_use_adisc: Use ADISC for FCP rediscovery instead of PLOGI. Value range
# is [0,1]. Default value is 0.
*/
-LPFC_ATTR_RW(use_adisc, 0, 0, 1,
- "Use ADISC on rediscovery to authenticate FCP devices");
+LPFC_VPORT_ATTR_RW(use_adisc, 0, 0, 1,
+ "Use ADISC on rediscovery to authenticate FCP devices");
/*
# lpfc_ack0: Use ACK0, instead of ACK1 for class 2 acknowledgement. Value
@@ -1315,13 +1447,13 @@
# 2 = support FDMI with attribute of hostname
# Value range [0,2]. Default value is 0.
*/
-LPFC_ATTR_RW(fdmi_on, 0, 0, 2, "Enable FDMI support");
+LPFC_VPORT_ATTR_RW(fdmi_on, 0, 0, 2, "Enable FDMI support");
/*
# Specifies the maximum number of ELS cmds we can have outstanding (for
# discovery). Value range is [1,64]. Default value = 32.
*/
-LPFC_ATTR(discovery_threads, 32, 1, 64, "Maximum number of ELS commands "
+LPFC_VPORT_ATTR(discovery_threads, 32, 1, 64, "Maximum number of ELS commands "
"during discovery");
/*
@@ -1329,8 +1461,7 @@
# Value range is [0,65535]. Default value is 255.
# NOTE: The SCSI layer might probe all allowed LUN on some old targets.
*/
-LPFC_ATTR_R(max_luns, 255, 0, 65535,
- "Maximum allowed LUN");
+LPFC_VPORT_ATTR_R(max_luns, 255, 0, 65535, "Maximum allowed LUN");
/*
# lpfc_poll_tmo: .Milliseconds driver will wait between polling FCP ring.
@@ -1367,7 +1498,6 @@
&class_device_attr_lpfc_lun_queue_depth,
&class_device_attr_lpfc_hba_queue_depth,
&class_device_attr_lpfc_peer_port_login,
- &class_device_attr_lpfc_vport_restrict_login,
&class_device_attr_lpfc_nodev_tmo,
&class_device_attr_lpfc_devloss_tmo,
&class_device_attr_lpfc_fcp_class,
@@ -1383,9 +1513,8 @@
&class_device_attr_lpfc_multi_ring_type,
&class_device_attr_lpfc_fdmi_on,
&class_device_attr_lpfc_max_luns,
- &class_device_attr_lpfc_npiv_enable,
+ &class_device_attr_lpfc_enable_npiv,
&class_device_attr_nport_evt_cnt,
- &class_device_attr_management_version,
&class_device_attr_board_mode,
&class_device_attr_max_vpi,
&class_device_attr_used_vpi,
@@ -1404,6 +1533,28 @@
NULL,
};
+struct class_device_attribute *lpfc_vport_attrs[] = {
+ &class_device_attr_info,
+ &class_device_attr_state,
+ &class_device_attr_num_discovered_ports,
+ &class_device_attr_lpfc_drvr_version,
+
+ &class_device_attr_lpfc_log_verbose,
+ &class_device_attr_lpfc_lun_queue_depth,
+ &class_device_attr_lpfc_nodev_tmo,
+ &class_device_attr_lpfc_devloss_tmo,
+ &class_device_attr_lpfc_hba_queue_depth,
+ &class_device_attr_lpfc_peer_port_login,
+ &class_device_attr_lpfc_restrict_login,
+ &class_device_attr_lpfc_fcp_class,
+ &class_device_attr_lpfc_use_adisc,
+ &class_device_attr_lpfc_fdmi_on,
+ &class_device_attr_lpfc_max_luns,
+ &class_device_attr_nport_evt_cnt,
+ &class_device_attr_npiv_info,
+ NULL,
+};
+
static ssize_t
sysfs_ctlreg_write(struct kobject *kobj, struct bin_attribute *bin_attr,
char *buf, loff_t off, size_t count)
@@ -2243,7 +2394,6 @@
.get_starget_port_name = lpfc_get_starget_port_name,
.show_starget_port_name = 1,
- .issue_fc_host_lip = lpfc_issue_lip,
.dev_loss_tmo_callbk = lpfc_dev_loss_tmo_callbk,
.terminate_rport_io = lpfc_terminate_rport_io,
@@ -2253,39 +2403,25 @@
void
lpfc_get_cfgparam(struct lpfc_hba *phba)
{
- lpfc_log_verbose_init(phba, lpfc_log_verbose);
lpfc_cr_delay_init(phba, lpfc_cr_delay);
lpfc_cr_count_init(phba, lpfc_cr_count);
lpfc_multi_ring_support_init(phba, lpfc_multi_ring_support);
lpfc_multi_ring_rctl_init(phba, lpfc_multi_ring_rctl);
lpfc_multi_ring_type_init(phba, lpfc_multi_ring_type);
- lpfc_lun_queue_depth_init(phba, lpfc_lun_queue_depth);
- lpfc_fcp_class_init(phba, lpfc_fcp_class);
- lpfc_use_adisc_init(phba, lpfc_use_adisc);
lpfc_ack0_init(phba, lpfc_ack0);
lpfc_topology_init(phba, lpfc_topology);
- lpfc_scan_down_init(phba, lpfc_scan_down);
lpfc_link_speed_init(phba, lpfc_link_speed);
- lpfc_fdmi_on_init(phba, lpfc_fdmi_on);
- lpfc_discovery_threads_init(phba, lpfc_discovery_threads);
- lpfc_max_luns_init(phba, lpfc_max_luns);
lpfc_poll_tmo_init(phba, lpfc_poll_tmo);
- lpfc_peer_port_login_init(phba, lpfc_peer_port_login);
- lpfc_npiv_enable_init(phba, lpfc_npiv_enable);
- lpfc_vport_restrict_login_init(phba, lpfc_vport_restrict_login);
+ lpfc_enable_npiv_init(phba, lpfc_enable_npiv);
lpfc_use_msi_init(phba, lpfc_use_msi);
- lpfc_devloss_tmo_init(phba, lpfc_devloss_tmo);
- lpfc_nodev_tmo_init(phba, lpfc_nodev_tmo);
phba->cfg_poll = lpfc_poll;
phba->cfg_soft_wwnn = 0L;
phba->cfg_soft_wwpn = 0L;
-
/*
* The total number of segments is the configuration value plus 2
* since the IOCB need a command and response bde.
*/
phba->cfg_sg_seg_cnt = LPFC_SG_SEG_CNT + 2;
-
/*
* Since the sg_tablesize is module parameter, the sg_dma_buf_size
* used to create the sg_dma_buf_pool must be dynamically calculated
@@ -2293,9 +2429,24 @@
phba->cfg_sg_dma_buf_size = sizeof(struct fcp_cmnd) +
sizeof(struct fcp_rsp) +
(phba->cfg_sg_seg_cnt * sizeof(struct ulp_bde64));
-
-
lpfc_hba_queue_depth_init(phba, lpfc_hba_queue_depth);
+ return;
+}
+void
+lpfc_get_vport_cfgparam(struct lpfc_vport *vport)
+{
+ lpfc_log_verbose_init(vport, lpfc_log_verbose);
+ lpfc_lun_queue_depth_init(vport, lpfc_lun_queue_depth);
+ lpfc_devloss_tmo_init(vport, lpfc_devloss_tmo);
+ lpfc_nodev_tmo_init(vport, lpfc_nodev_tmo);
+ lpfc_peer_port_login_init(vport, lpfc_peer_port_login);
+ lpfc_restrict_login_init(vport, lpfc_restrict_login);
+ lpfc_fcp_class_init(vport, lpfc_fcp_class);
+ lpfc_use_adisc_init(vport, lpfc_use_adisc);
+ lpfc_fdmi_on_init(vport, lpfc_fdmi_on);
+ lpfc_discovery_threads_init(vport, lpfc_discovery_threads);
+ lpfc_max_luns_init(vport, lpfc_max_luns);
+ lpfc_scan_down_init(vport, lpfc_scan_down);
return;
}
diff --git a/drivers/scsi/lpfc/lpfc_crtn.h b/drivers/scsi/lpfc/lpfc_crtn.h
index e19d1a7..a599e15 100644
--- a/drivers/scsi/lpfc/lpfc_crtn.h
+++ b/drivers/scsi/lpfc/lpfc_crtn.h
@@ -40,6 +40,7 @@
void lpfc_unreg_vpi(struct lpfc_hba *, uint16_t, LPFC_MBOXQ_t *);
void lpfc_init_link(struct lpfc_hba *, LPFC_MBOXQ_t *, uint32_t, uint32_t);
+struct lpfc_vport *lpfc_find_vport_by_did(struct lpfc_hba *, uint32_t);
void lpfc_cleanup_rpis(struct lpfc_vport *vport, int remove);
int lpfc_linkdown(struct lpfc_hba *);
void lpfc_mbx_cmpl_read_la(struct lpfc_hba *, LPFC_MBOXQ_t *);
@@ -101,7 +102,7 @@
int lpfc_els_free_iocb(struct lpfc_hba *, struct lpfc_iocbq *);
int lpfc_ct_free_iocb(struct lpfc_hba *, struct lpfc_iocbq *);
int lpfc_els_rsp_acc(struct lpfc_vport *, uint32_t, struct lpfc_iocbq *,
- struct lpfc_nodelist *, LPFC_MBOXQ_t *, uint8_t);
+ struct lpfc_nodelist *, LPFC_MBOXQ_t *);
int lpfc_els_rsp_reject(struct lpfc_vport *, uint32_t, struct lpfc_iocbq *,
struct lpfc_nodelist *, LPFC_MBOXQ_t *);
int lpfc_els_rsp_adisc_acc(struct lpfc_vport *, struct lpfc_iocbq *,
@@ -117,6 +118,7 @@
int lpfc_els_handle_rscn(struct lpfc_vport *);
void lpfc_els_flush_rscn(struct lpfc_vport *);
int lpfc_rscn_payload_check(struct lpfc_vport *, uint32_t);
+void lpfc_els_flush_all_cmd(struct lpfc_hba *);
void lpfc_els_flush_cmd(struct lpfc_vport *);
int lpfc_els_disc_adisc(struct lpfc_vport *);
int lpfc_els_disc_plogi(struct lpfc_vport *);
@@ -161,9 +163,11 @@
void lpfc_mbox_cmpl_put(struct lpfc_hba *, LPFC_MBOXQ_t *);
int lpfc_mbox_tmo_val(struct lpfc_hba *, int);
-void lpfc_config_hbq(struct lpfc_hba *, struct lpfc_hbq_init *, uint32_t ,
- LPFC_MBOXQ_t *);
+void lpfc_config_hbq(struct lpfc_hba *, uint32_t, struct lpfc_hbq_init *,
+ uint32_t , LPFC_MBOXQ_t *);
struct lpfc_hbq_entry * lpfc_sli_next_hbq_slot(struct lpfc_hba *, uint32_t);
+struct hbq_dmabuf *lpfc_els_hbq_alloc(struct lpfc_hba *);
+void lpfc_els_hbq_free(struct lpfc_hba *, struct hbq_dmabuf *);
int lpfc_mem_alloc(struct lpfc_hba *);
void lpfc_mem_free(struct lpfc_hba *);
@@ -200,6 +204,7 @@
struct lpfc_dmabuf *lpfc_sli_ringpostbuf_get(struct lpfc_hba *,
struct lpfc_sli_ring *,
dma_addr_t);
+int lpfc_sli_hbq_count(void);
int lpfc_sli_hbqbuf_init_hbqs(struct lpfc_hba *, uint32_t);
int lpfc_sli_hbqbuf_add_hbqs(struct lpfc_hba *, uint32_t);
void lpfc_sli_hbqbuf_free_all(struct lpfc_hba *);
@@ -207,10 +212,9 @@
int lpfc_sli_hbq_size(void);
int lpfc_sli_issue_abort_iotag(struct lpfc_hba *, struct lpfc_sli_ring *,
struct lpfc_iocbq *);
-int lpfc_sli_sum_iocb(struct lpfc_hba *, struct lpfc_sli_ring *, uint16_t,
- uint64_t, lpfc_ctx_cmd);
-int lpfc_sli_abort_iocb(struct lpfc_hba *, struct lpfc_sli_ring *, uint16_t,
- uint64_t, uint32_t, lpfc_ctx_cmd);
+int lpfc_sli_sum_iocb(struct lpfc_vport *, uint16_t, uint64_t, lpfc_ctx_cmd);
+int lpfc_sli_abort_iocb(struct lpfc_vport *, struct lpfc_sli_ring *, uint16_t,
+ uint64_t, lpfc_ctx_cmd);
void lpfc_mbox_timeout(unsigned long);
void lpfc_mbox_timeout_handler(struct lpfc_hba *);
@@ -234,8 +238,6 @@
struct lpfc_iocbq * cmdiocb,
struct lpfc_iocbq * rspiocb);
-void *lpfc_hbq_alloc(struct lpfc_hba *, int, dma_addr_t *);
-void lpfc_hbq_free(struct lpfc_hba *, void *, dma_addr_t);
void lpfc_sli_free_hbq(struct lpfc_hba *, struct hbq_dmabuf *);
void *lpfc_mbuf_alloc(struct lpfc_hba *, int, dma_addr_t *);
@@ -248,10 +250,13 @@
int lpfc_scan_finished(struct Scsi_Host *, unsigned long);
void lpfc_get_cfgparam(struct lpfc_hba *);
+void lpfc_get_vport_cfgparam(struct lpfc_vport *);
int lpfc_alloc_sysfs_attr(struct lpfc_vport *);
void lpfc_free_sysfs_attr(struct lpfc_vport *);
extern struct class_device_attribute *lpfc_hba_attrs[];
+extern struct class_device_attribute *lpfc_vport_attrs[];
extern struct scsi_host_template lpfc_template;
+extern struct scsi_host_template lpfc_vport_template;
extern struct fc_function_template lpfc_transport_functions;
extern struct fc_function_template lpfc_vport_transport_functions;
extern int lpfc_sli_mode;
@@ -260,7 +265,7 @@
void lpfc_terminate_rport_io(struct fc_rport *);
void lpfc_dev_loss_tmo_callbk(struct fc_rport *rport);
-struct lpfc_vport *lpfc_create_port(struct lpfc_hba *, int, struct fc_vport *);
+struct lpfc_vport *lpfc_create_port(struct lpfc_hba *, int, struct device *);
int lpfc_vport_disable(struct fc_vport *fc_vport, bool disable);
void lpfc_mbx_unreg_vpi(struct lpfc_vport *);
void destroy_port(struct lpfc_vport *);
@@ -271,6 +276,9 @@
extern void lpfc_debugfs_terminate(struct lpfc_vport *);
extern void lpfc_debugfs_disc_trc(struct lpfc_vport *, int, char *, uint32_t,
uint32_t, uint32_t);
+extern void lpfc_debugfs_slow_ring_trc(struct lpfc_hba *, char *, uint32_t,
+ uint32_t, uint32_t);
+extern struct lpfc_hbq_init *lpfc_hbq_defs[];
/* Interface exported by fabric iocb scheduler */
int lpfc_issue_fabric_iocb(struct lpfc_hba *, struct lpfc_iocbq *);
diff --git a/drivers/scsi/lpfc/lpfc_ct.c b/drivers/scsi/lpfc/lpfc_ct.c
index ae9d6f38..c701e4d 100644
--- a/drivers/scsi/lpfc/lpfc_ct.c
+++ b/drivers/scsi/lpfc/lpfc_ct.c
@@ -257,6 +257,10 @@
{
struct lpfc_dmabuf *buf_ptr;
+ if (ctiocb->context_un.ndlp) {
+ lpfc_nlp_put(ctiocb->context_un.ndlp);
+ ctiocb->context_un.ndlp = NULL;
+ }
if (ctiocb->context1) {
buf_ptr = (struct lpfc_dmabuf *) ctiocb->context1;
lpfc_mbuf_free(phba, buf_ptr->virt, buf_ptr->phys);
@@ -314,6 +318,7 @@
/* Save for completion so we can release these resources */
geniocb->context1 = (uint8_t *) inp;
geniocb->context2 = (uint8_t *) outp;
+ geniocb->context_un.ndlp = ndlp;
/* Fill in payload, bp points to frame payload */
icmd->ulpCommand = CMD_GEN_REQUEST64_CR;
@@ -341,11 +346,11 @@
}
/* Issue GEN REQ IOCB for NPORT <did> */
- lpfc_printf_log(phba, KERN_INFO, LOG_ELS,
- "%d (%d):0119 Issue GEN REQ IOCB to NPORT x%x "
- "Data: x%x x%x\n", phba->brd_no, vport->vpi,
- ndlp->nlp_DID, icmd->ulpIoTag,
- vport->port_state);
+ lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
+ "0119 Issue GEN REQ IOCB to NPORT x%x "
+ "Data: x%x x%x\n",
+ ndlp->nlp_DID, icmd->ulpIoTag,
+ vport->port_state);
geniocb->iocb_cmpl = cmpl;
geniocb->drvrTimeout = icmd->ulpTimeout + LPFC_DRVR_TIMEOUT;
geniocb->vport = vport;
@@ -390,17 +395,19 @@
return 0;
}
-static struct lpfc_vport *
+struct lpfc_vport *
lpfc_find_vport_by_did(struct lpfc_hba *phba, uint32_t did) {
-
struct lpfc_vport *vport_curr;
+ unsigned long flags;
+ spin_lock_irqsave(&phba->hbalock, flags);
list_for_each_entry(vport_curr, &phba->port_list, listentry) {
- if ((vport_curr->fc_myDID) &&
- (vport_curr->fc_myDID == did))
+ if ((vport_curr->fc_myDID) && (vport_curr->fc_myDID == did)) {
+ spin_unlock_irqrestore(&phba->hbalock, flags);
return vport_curr;
+ }
}
-
+ spin_unlock_irqrestore(&phba->hbalock, flags);
return NULL;
}
@@ -449,10 +456,10 @@
*/
if ((Did != vport->fc_myDID) &&
((lpfc_find_vport_by_did(phba, Did) == NULL) ||
- phba->cfg_peer_port_login)) {
+ vport->cfg_peer_port_login)) {
if ((vport->port_type != LPFC_NPIV_PORT) ||
(vport->fc_flag & FC_RFF_NOT_SUPPORTED) ||
- (!phba->cfg_vport_restrict_login)) {
+ (!vport->cfg_restrict_login)) {
ndlp = lpfc_setup_disc_node(vport, Did);
if (ndlp) {
lpfc_debugfs_disc_trc(vport,
@@ -462,14 +469,13 @@
Did, ndlp->nlp_flag,
vport->fc_flag);
- lpfc_printf_log(phba, KERN_INFO,
+ lpfc_printf_vlog(vport,
+ KERN_INFO,
LOG_DISCOVERY,
- "%d (%d):0238 Process "
+ "0238 Process "
"x%x NameServer Rsp"
"Data: x%x x%x x%x\n",
- phba->brd_no,
- vport->vpi, Did,
- ndlp->nlp_flag,
+ Did, ndlp->nlp_flag,
vport->fc_flag,
vport->fc_rscn_id_cnt);
} else {
@@ -480,14 +486,13 @@
Did, vport->fc_flag,
vport->fc_rscn_id_cnt);
- lpfc_printf_log(phba, KERN_INFO,
+ lpfc_printf_vlog(vport,
+ KERN_INFO,
LOG_DISCOVERY,
- "%d (%d):0239 Skip x%x "
+ "0239 Skip x%x "
"NameServer Rsp Data: "
"x%x x%x\n",
- phba->brd_no,
- vport->vpi, Did,
- vport->fc_flag,
+ Did, vport->fc_flag,
vport->fc_rscn_id_cnt);
}
@@ -514,14 +519,13 @@
Did, vport->fc_flag,
vport->fc_rscn_id_cnt);
- lpfc_printf_log(phba, KERN_INFO,
+ lpfc_printf_vlog(vport,
+ KERN_INFO,
LOG_DISCOVERY,
- "%d (%d):0245 Skip x%x "
+ "0245 Skip x%x "
"NameServer Rsp Data: "
"x%x x%x\n",
- phba->brd_no,
- vport->vpi, Did,
- vport->fc_flag,
+ Did, vport->fc_flag,
vport->fc_rscn_id_cnt);
}
}
@@ -549,8 +553,12 @@
struct lpfc_dmabuf *bmp;
struct lpfc_dmabuf *outp;
struct lpfc_sli_ct_request *CTrsp;
+ struct lpfc_nodelist *ndlp;
int rc;
+ /* First save ndlp, before we overwrite it */
+ ndlp = cmdiocb->context_un.ndlp;
+
/* we pass cmdiocb to state machine which needs rspiocb as well */
cmdiocb->context_un.rsp_iocb = rspiocb;
@@ -568,9 +576,8 @@
if (lpfc_els_chk_latt(vport) || lpfc_error_lost_link(irsp)) {
- lpfc_printf_log(phba, KERN_INFO, LOG_DISCOVERY,
- "%d (%d):0216 Link event during NS query\n",
- phba->brd_no, vport->vpi);
+ lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,
+ "0216 Link event during NS query\n");
lpfc_vport_set_state(vport, FC_VPORT_FAILED);
goto out;
}
@@ -588,46 +595,61 @@
goto out;
}
lpfc_vport_set_state(vport, FC_VPORT_FAILED);
- lpfc_printf_log(phba, KERN_ERR, LOG_ELS,
- "%d (%d):0257 GID_FT Query error: 0x%x 0x%x\n",
- phba->brd_no, vport->vpi, irsp->ulpStatus,
- vport->fc_ns_retry);
+ lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS,
+ "0257 GID_FT Query error: 0x%x 0x%x\n",
+ irsp->ulpStatus, vport->fc_ns_retry);
} else {
/* Good status, continue checking */
CTrsp = (struct lpfc_sli_ct_request *) outp->virt;
if (CTrsp->CommandResponse.bits.CmdRsp ==
be16_to_cpu(SLI_CT_RESPONSE_FS_ACC)) {
- lpfc_printf_log(phba, KERN_INFO, LOG_DISCOVERY,
- "%d (%d):0208 NameServer Rsp "
- "Data: x%x\n",
- phba->brd_no, vport->vpi,
- vport->fc_flag);
+ lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,
+ "0208 NameServer Rsp Data: x%x\n",
+ vport->fc_flag);
lpfc_ns_rsp(vport, outp,
(uint32_t) (irsp->un.genreq64.bdl.bdeSize));
} else if (CTrsp->CommandResponse.bits.CmdRsp ==
be16_to_cpu(SLI_CT_RESPONSE_FS_RJT)) {
/* NameServer Rsp Error */
- lpfc_printf_log(phba, KERN_INFO, LOG_DISCOVERY,
- "%d (%d):0240 NameServer Rsp Error "
+ if ((CTrsp->ReasonCode == SLI_CT_UNABLE_TO_PERFORM_REQ)
+ && (CTrsp->Explanation == SLI_CT_NO_FC4_TYPES)) {
+ lpfc_printf_vlog(vport, KERN_INFO,
+ LOG_DISCOVERY,
+ "0269 No NameServer Entries "
"Data: x%x x%x x%x x%x\n",
- phba->brd_no, vport->vpi,
CTrsp->CommandResponse.bits.CmdRsp,
(uint32_t) CTrsp->ReasonCode,
(uint32_t) CTrsp->Explanation,
vport->fc_flag);
- lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_CT,
+ lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_CT,
+ "GID_FT no entry cmd:x%x rsn:x%x exp:x%x",
+ (uint32_t)CTrsp->CommandResponse.bits.CmdRsp,
+ (uint32_t) CTrsp->ReasonCode,
+ (uint32_t) CTrsp->Explanation);
+ } else {
+ lpfc_printf_vlog(vport, KERN_INFO,
+ LOG_DISCOVERY,
+ "0240 NameServer Rsp Error "
+ "Data: x%x x%x x%x x%x\n",
+ CTrsp->CommandResponse.bits.CmdRsp,
+ (uint32_t) CTrsp->ReasonCode,
+ (uint32_t) CTrsp->Explanation,
+ vport->fc_flag);
+
+ lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_CT,
"GID_FT rsp err1 cmd:x%x rsn:x%x exp:x%x",
(uint32_t)CTrsp->CommandResponse.bits.CmdRsp,
(uint32_t) CTrsp->ReasonCode,
(uint32_t) CTrsp->Explanation);
+ }
+
} else {
/* NameServer Rsp Error */
- lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY,
- "%d (%d):0241 NameServer Rsp Error "
+ lpfc_printf_vlog(vport, KERN_ERR, LOG_DISCOVERY,
+ "0241 NameServer Rsp Error "
"Data: x%x x%x x%x x%x\n",
- phba->brd_no, vport->vpi,
CTrsp->CommandResponse.bits.CmdRsp,
(uint32_t) CTrsp->ReasonCode,
(uint32_t) CTrsp->Explanation,
@@ -661,11 +683,12 @@
lpfc_disc_start(vport);
}
out:
+ cmdiocb->context_un.ndlp = ndlp; /* Now restore ndlp for free */
lpfc_ct_free_iocb(phba, cmdiocb);
return;
}
-void
+static void
lpfc_cmpl_ct_cmd_gff_id(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
struct lpfc_iocbq *rspiocb)
{
@@ -695,40 +718,37 @@
be16_to_cpu(SLI_CT_RESPONSE_FS_ACC)) {
if ((fbits & FC4_FEATURE_INIT) &&
!(fbits & FC4_FEATURE_TARGET)) {
- lpfc_printf_log(phba, KERN_INFO, LOG_DISCOVERY,
- "%d (%d):0245 Skip x%x GFF "
- "NameServer Rsp Data: (init) "
- "x%x x%x\n", phba->brd_no,
- vport->vpi, did, fbits,
- vport->fc_rscn_id_cnt);
+ lpfc_printf_vlog(vport, KERN_INFO,
+ LOG_DISCOVERY,
+ "0270 Skip x%x GFF "
+ "NameServer Rsp Data: (init) "
+ "x%x x%x\n", did, fbits,
+ vport->fc_rscn_id_cnt);
goto out;
}
}
}
else {
- lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY,
- "%d (%d):0267 NameServer GFF Rsp"
- " x%x Error (%d %d) Data: x%x x%x\n",
- phba->brd_no, vport->vpi, did,
- irsp->ulpStatus, irsp->un.ulpWord[4],
- vport->fc_flag, vport->fc_rscn_id_cnt)
+ lpfc_printf_vlog(vport, KERN_ERR, LOG_DISCOVERY,
+ "0267 NameServer GFF Rsp "
+ "x%x Error (%d %d) Data: x%x x%x\n",
+ did, irsp->ulpStatus, irsp->un.ulpWord[4],
+ vport->fc_flag, vport->fc_rscn_id_cnt)
}
/* This is a target port, unregistered port, or the GFF_ID failed */
ndlp = lpfc_setup_disc_node(vport, did);
if (ndlp) {
- lpfc_printf_log(phba, KERN_INFO, LOG_DISCOVERY,
- "%d (%d):0242 Process x%x GFF "
- "NameServer Rsp Data: x%x x%x x%x\n",
- phba->brd_no, vport->vpi,
- did, ndlp->nlp_flag, vport->fc_flag,
- vport->fc_rscn_id_cnt);
+ lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,
+ "0242 Process x%x GFF "
+ "NameServer Rsp Data: x%x x%x x%x\n",
+ did, ndlp->nlp_flag, vport->fc_flag,
+ vport->fc_rscn_id_cnt);
} else {
- lpfc_printf_log(phba, KERN_INFO, LOG_DISCOVERY,
- "%d (%d):0243 Skip x%x GFF "
- "NameServer Rsp Data: x%x x%x\n",
- phba->brd_no, vport->vpi, did,
- vport->fc_flag, vport->fc_rscn_id_cnt);
+ lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,
+ "0243 Skip x%x GFF "
+ "NameServer Rsp Data: x%x x%x\n", did,
+ vport->fc_flag, vport->fc_rscn_id_cnt);
}
out:
/* Link up / RSCN discovery */
@@ -766,10 +786,14 @@
struct lpfc_dmabuf *outp;
IOCB_t *irsp;
struct lpfc_sli_ct_request *CTrsp;
+ struct lpfc_nodelist *ndlp;
int cmdcode, rc;
uint8_t retry;
uint32_t latt;
+ /* First save ndlp, before we overwrite it */
+ ndlp = cmdiocb->context_un.ndlp;
+
/* we pass cmdiocb to state machine which needs rspiocb as well */
cmdiocb->context_un.rsp_iocb = rspiocb;
@@ -784,22 +808,21 @@
latt = lpfc_els_chk_latt(vport);
/* RFT request completes status <ulpStatus> CmdRsp <CmdRsp> */
- lpfc_printf_log(phba, KERN_INFO, LOG_DISCOVERY,
- "%d (%d):0209 RFT request completes, latt %d, "
- "ulpStatus x%x CmdRsp x%x, Context x%x, Tag x%x\n",
- phba->brd_no, vport->vpi, latt, irsp->ulpStatus,
- CTrsp->CommandResponse.bits.CmdRsp,
- cmdiocb->iocb.ulpContext, cmdiocb->iocb.ulpIoTag);
+ lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,
+ "0209 RFT request completes, latt %d, "
+ "ulpStatus x%x CmdRsp x%x, Context x%x, Tag x%x\n",
+ latt, irsp->ulpStatus,
+ CTrsp->CommandResponse.bits.CmdRsp,
+ cmdiocb->iocb.ulpContext, cmdiocb->iocb.ulpIoTag);
lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_CT,
"CT cmd cmpl: status:x%x/x%x cmd:x%x",
irsp->ulpStatus, irsp->un.ulpWord[4], cmdcode);
if (irsp->ulpStatus) {
- lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY,
- "%d (%d):0268 NS cmd %x Error (%d %d)\n",
- phba->brd_no, vport->vpi, cmdcode,
- irsp->ulpStatus, irsp->un.ulpWord[4]);
+ lpfc_printf_vlog(vport, KERN_ERR, LOG_DISCOVERY,
+ "0268 NS cmd %x Error (%d %d)\n",
+ cmdcode, irsp->ulpStatus, irsp->un.ulpWord[4]);
if ((irsp->ulpStatus == IOSTAT_LOCAL_REJECT) &&
((irsp->un.ulpWord[4] == IOERR_SLI_DOWN) ||
@@ -811,15 +834,15 @@
goto out;
retry++;
- lpfc_printf_log(phba, KERN_INFO, LOG_DISCOVERY,
- "%d (%d):0216 Retrying NS cmd %x\n",
- phba->brd_no, vport->vpi, cmdcode);
+ lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,
+ "0216 Retrying NS cmd %x\n", cmdcode);
rc = lpfc_ns_cmd(vport, cmdcode, retry, 0);
if (rc == 0)
goto out;
}
out:
+ cmdiocb->context_un.ndlp = ndlp; /* Now restore ndlp for free */
lpfc_ct_free_iocb(phba, cmdiocb);
return;
}
@@ -862,7 +885,7 @@
return;
}
-int
+static int
lpfc_vport_symbolic_port_name(struct lpfc_vport *vport, char *symbol,
size_t size)
{
@@ -957,10 +980,9 @@
}
/* NameServer Req */
- lpfc_printf_log(phba, KERN_INFO ,LOG_DISCOVERY,
- "%d (%d):0236 NameServer Req Data: x%x x%x x%x\n",
- phba->brd_no, vport->vpi, cmdcode, vport->fc_flag,
- vport->fc_rscn_id_cnt);
+ lpfc_printf_vlog(vport, KERN_INFO ,LOG_DISCOVERY,
+ "0236 NameServer Req Data: x%x x%x x%x\n",
+ cmdcode, vport->fc_flag, vport->fc_rscn_id_cnt);
bpl = (struct ulp_bde64 *) bmp->virt;
memset(bpl, 0, sizeof(struct ulp_bde64));
@@ -1059,6 +1081,7 @@
cmpl = lpfc_cmpl_ct_cmd_rff_id;
break;
}
+ lpfc_nlp_get(ndlp);
if (!lpfc_ct_cmd(vport, mp, bmp, ndlp, cmpl, rsp_size, retry)) {
/* On success, The cmpl function will free the buffers */
@@ -1069,6 +1092,7 @@
}
rc=6;
+ lpfc_nlp_put(ndlp);
lpfc_mbuf_free(phba, bmp->virt, bmp->phys);
ns_cmd_free_bmp:
kfree(bmp);
@@ -1077,10 +1101,9 @@
ns_cmd_free_mp:
kfree(mp);
ns_cmd_exit:
- lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY,
- "%d (%d):0266 Issue NameServer Req x%x err %d Data: x%x x%x\n",
- phba->brd_no, vport->vpi, cmdcode, rc, vport->fc_flag,
- vport->fc_rscn_id_cnt);
+ lpfc_printf_vlog(vport, KERN_ERR, LOG_DISCOVERY,
+ "0266 Issue NameServer Req x%x err %d Data: x%x x%x\n",
+ cmdcode, rc, vport->fc_flag, vport->fc_rscn_id_cnt);
return 1;
}
@@ -1106,12 +1129,11 @@
irsp->ulpStatus, irsp->un.ulpWord[4], latt);
if (latt || irsp->ulpStatus) {
- lpfc_printf_log(phba, KERN_INFO, LOG_DISCOVERY,
- "%d (%d):0229 FDMI cmd %04x failed, latt = %d "
- "ulpStatus: x%x, rid x%x\n",
- phba->brd_no, vport->vpi,
- be16_to_cpu(fdmi_cmd), latt, irsp->ulpStatus,
- irsp->un.ulpWord[4]);
+ lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,
+ "0229 FDMI cmd %04x failed, latt = %d "
+ "ulpStatus: x%x, rid x%x\n",
+ be16_to_cpu(fdmi_cmd), latt, irsp->ulpStatus,
+ irsp->un.ulpWord[4]);
lpfc_ct_free_iocb(phba, cmdiocb);
return;
}
@@ -1119,10 +1141,9 @@
ndlp = lpfc_findnode_did(vport, FDMI_DID);
if (fdmi_rsp == be16_to_cpu(SLI_CT_RESPONSE_FS_RJT)) {
/* FDMI rsp failed */
- lpfc_printf_log(phba, KERN_INFO, LOG_DISCOVERY,
- "%d (%d):0220 FDMI rsp failed Data: x%x\n",
- phba->brd_no, vport->vpi,
- be16_to_cpu(fdmi_cmd));
+ lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,
+ "0220 FDMI rsp failed Data: x%x\n",
+ be16_to_cpu(fdmi_cmd));
}
switch (be16_to_cpu(fdmi_cmd)) {
@@ -1185,11 +1206,9 @@
INIT_LIST_HEAD(&bmp->list);
/* FDMI request */
- lpfc_printf_log(phba, KERN_INFO, LOG_DISCOVERY,
- "%d (%d):0218 FDMI Request Data: x%x x%x x%x\n",
- phba->brd_no, vport->vpi, vport->fc_flag,
- vport->port_state, cmdcode);
-
+ lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,
+ "0218 FDMI Request Data: x%x x%x x%x\n",
+ vport->fc_flag, vport->port_state, cmdcode);
CtReq = (struct lpfc_sli_ct_request *) mp->virt;
memset(CtReq, 0, sizeof(struct lpfc_sli_ct_request));
@@ -1449,7 +1468,7 @@
pab->ab.EntryCnt++;
size += FOURBYTES + len;
- if (phba->cfg_fdmi_on == 2) {
+ if (vport->cfg_fdmi_on == 2) {
/* #6 Port attribute entry */
ae = (ATTRIBUTE_ENTRY *) ((uint8_t *) pab +
size);
@@ -1499,10 +1518,12 @@
bpl->tus.w = le32_to_cpu(bpl->tus.w);
cmpl = lpfc_cmpl_ct_cmd_fdmi;
+ lpfc_nlp_get(ndlp);
if (!lpfc_ct_cmd(vport, mp, bmp, ndlp, cmpl, FC_MAX_NS_RSP, 0))
return 0;
+ lpfc_nlp_put(ndlp);
lpfc_mbuf_free(phba, bmp->virt, bmp->phys);
fdmi_cmd_free_bmp:
kfree(bmp);
@@ -1512,9 +1533,9 @@
kfree(mp);
fdmi_cmd_exit:
/* Issue FDMI request failed */
- lpfc_printf_log(phba, KERN_INFO, LOG_DISCOVERY,
- "%d (%d):0244 Issue FDMI request failed Data: x%x\n",
- phba->brd_no, vport->vpi, cmdcode);
+ lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,
+ "0244 Issue FDMI request failed Data: x%x\n",
+ cmdcode);
return 1;
}
diff --git a/drivers/scsi/lpfc/lpfc_debugfs.c b/drivers/scsi/lpfc/lpfc_debugfs.c
index 673cfe1..2e3c01b 100644
--- a/drivers/scsi/lpfc/lpfc_debugfs.c
+++ b/drivers/scsi/lpfc/lpfc_debugfs.c
@@ -71,15 +71,22 @@
* lpfc_debugfs_mask_disc_trc=Y Where Y is an event mask as defined in
* lpfc_debugfs.h .
*/
-static int lpfc_debugfs_enable = 0;
+static int lpfc_debugfs_enable = 1;
module_param(lpfc_debugfs_enable, int, 0);
MODULE_PARM_DESC(lpfc_debugfs_enable, "Enable debugfs services");
-static int lpfc_debugfs_max_disc_trc = 0; /* This MUST be a power of 2 */
+/* This MUST be a power of 2 */
+static int lpfc_debugfs_max_disc_trc = 0;
module_param(lpfc_debugfs_max_disc_trc, int, 0);
MODULE_PARM_DESC(lpfc_debugfs_max_disc_trc,
"Set debugfs discovery trace depth");
+/* This MUST be a power of 2 */
+static int lpfc_debugfs_max_slow_ring_trc = 0;
+module_param(lpfc_debugfs_max_slow_ring_trc, int, 0);
+MODULE_PARM_DESC(lpfc_debugfs_max_slow_ring_trc,
+ "Set debugfs slow ring trace depth");
+
static int lpfc_debugfs_mask_disc_trc = 0;
module_param(lpfc_debugfs_mask_disc_trc, int, 0);
MODULE_PARM_DESC(lpfc_debugfs_mask_disc_trc,
@@ -87,28 +94,34 @@
#include <linux/debugfs.h>
-/* size of discovery_trace output line */
-#define LPFC_DISC_TRC_ENTRY_SIZE 80
+/* size of output line, for discovery_trace and slow_ring_trace */
+#define LPFC_DEBUG_TRC_ENTRY_SIZE 100
/* nodelist output buffer size */
#define LPFC_NODELIST_SIZE 8192
#define LPFC_NODELIST_ENTRY_SIZE 120
+/* dumpslim output buffer size */
+#define LPFC_DUMPSLIM_SIZE 4096
+
+/* hbqinfo output buffer size */
+#define LPFC_HBQINFO_SIZE 8192
+
struct lpfc_debug {
char *buffer;
int len;
};
-atomic_t lpfc_debugfs_disc_trc_cnt = ATOMIC_INIT(0);
-unsigned long lpfc_debugfs_start_time = 0L;
+static atomic_t lpfc_debugfs_seq_trc_cnt = ATOMIC_INIT(0);
+static unsigned long lpfc_debugfs_start_time = 0L;
static int
lpfc_debugfs_disc_trc_data(struct lpfc_vport *vport, char *buf, int size)
{
int i, index, len, enable;
uint32_t ms;
- struct lpfc_disc_trc *dtp;
- char buffer[80];
+ struct lpfc_debugfs_trc *dtp;
+ char buffer[LPFC_DEBUG_TRC_ENTRY_SIZE];
enable = lpfc_debugfs_enable;
@@ -122,7 +135,8 @@
if (!dtp->fmt)
continue;
ms = jiffies_to_msecs(dtp->jif - lpfc_debugfs_start_time);
- snprintf(buffer, 80, "%010d:%010d ms:%s\n",
+ snprintf(buffer,
+ LPFC_DEBUG_TRC_ENTRY_SIZE, "%010d:%010d ms:%s\n",
dtp->seq_cnt, ms, dtp->fmt);
len += snprintf(buf+len, size-len, buffer,
dtp->data1, dtp->data2, dtp->data3);
@@ -132,7 +146,8 @@
if (!dtp->fmt)
continue;
ms = jiffies_to_msecs(dtp->jif - lpfc_debugfs_start_time);
- snprintf(buffer, 80, "%010d:%010d ms:%s\n",
+ snprintf(buffer,
+ LPFC_DEBUG_TRC_ENTRY_SIZE, "%010d:%010d ms:%s\n",
dtp->seq_cnt, ms, dtp->fmt);
len += snprintf(buf+len, size-len, buffer,
dtp->data1, dtp->data2, dtp->data3);
@@ -143,6 +158,236 @@
}
static int
+lpfc_debugfs_slow_ring_trc_data(struct lpfc_hba *phba, char *buf, int size)
+{
+ int i, index, len, enable;
+ uint32_t ms;
+ struct lpfc_debugfs_trc *dtp;
+ char buffer[LPFC_DEBUG_TRC_ENTRY_SIZE];
+
+
+ enable = lpfc_debugfs_enable;
+ lpfc_debugfs_enable = 0;
+
+ len = 0;
+ index = (atomic_read(&phba->slow_ring_trc_cnt) + 1) &
+ (lpfc_debugfs_max_slow_ring_trc - 1);
+ for (i = index; i < lpfc_debugfs_max_slow_ring_trc; i++) {
+ dtp = phba->slow_ring_trc + i;
+ if (!dtp->fmt)
+ continue;
+ ms = jiffies_to_msecs(dtp->jif - lpfc_debugfs_start_time);
+ snprintf(buffer,
+ LPFC_DEBUG_TRC_ENTRY_SIZE, "%010d:%010d ms:%s\n",
+ dtp->seq_cnt, ms, dtp->fmt);
+ len += snprintf(buf+len, size-len, buffer,
+ dtp->data1, dtp->data2, dtp->data3);
+ }
+ for (i = 0; i < index; i++) {
+ dtp = phba->slow_ring_trc + i;
+ if (!dtp->fmt)
+ continue;
+ ms = jiffies_to_msecs(dtp->jif - lpfc_debugfs_start_time);
+ snprintf(buffer,
+ LPFC_DEBUG_TRC_ENTRY_SIZE, "%010d:%010d ms:%s\n",
+ dtp->seq_cnt, ms, dtp->fmt);
+ len += snprintf(buf+len, size-len, buffer,
+ dtp->data1, dtp->data2, dtp->data3);
+ }
+
+ lpfc_debugfs_enable = enable;
+ return len;
+}
+
+static int lpfc_debugfs_last_hbq = -1;
+
+static int
+lpfc_debugfs_hbqinfo_data(struct lpfc_hba *phba, char *buf, int size)
+{
+ int len = 0;
+ int cnt, i, j, found, posted, low;
+ uint32_t phys, raw_index, getidx;
+ struct lpfc_hbq_init *hip;
+ struct hbq_s *hbqs;
+ struct lpfc_hbq_entry *hbqe;
+ struct lpfc_dmabuf *d_buf;
+ struct hbq_dmabuf *hbq_buf;
+
+ cnt = LPFC_HBQINFO_SIZE;
+ spin_lock_irq(&phba->hbalock);
+
+ /* toggle between multiple hbqs, if any */
+ i = lpfc_sli_hbq_count();
+ if (i > 1) {
+ lpfc_debugfs_last_hbq++;
+ if (lpfc_debugfs_last_hbq >= i)
+ lpfc_debugfs_last_hbq = 0;
+ }
+ else
+ lpfc_debugfs_last_hbq = 0;
+
+ i = lpfc_debugfs_last_hbq;
+
+ len += snprintf(buf+len, size-len, "HBQ %d Info\n", i);
+
+ hbqs = &phba->hbqs[i];
+ posted = 0;
+ list_for_each_entry(d_buf, &hbqs->hbq_buffer_list, list)
+ posted++;
+
+ hip = lpfc_hbq_defs[i];
+ len += snprintf(buf+len, size-len,
+ "idx:%d prof:%d rn:%d bufcnt:%d icnt:%d acnt:%d posted %d\n",
+ hip->hbq_index, hip->profile, hip->rn,
+ hip->buffer_count, hip->init_count, hip->add_count, posted);
+
+ raw_index = phba->hbq_get[i];
+ getidx = le32_to_cpu(raw_index);
+ len += snprintf(buf+len, size-len,
+ "entrys:%d Put:%d nPut:%d localGet:%d hbaGet:%d\n",
+ hbqs->entry_count, hbqs->hbqPutIdx, hbqs->next_hbqPutIdx,
+ hbqs->local_hbqGetIdx, getidx);
+
+ hbqe = (struct lpfc_hbq_entry *) phba->hbqs[i].hbq_virt;
+ for (j=0; j<hbqs->entry_count; j++) {
+ len += snprintf(buf+len, size-len,
+ "%03d: %08x %04x %05x ", j,
+ hbqe->bde.addrLow, hbqe->bde.tus.w, hbqe->buffer_tag);
+
+ i = 0;
+ found = 0;
+
+ /* First calculate if slot has an associated posted buffer */
+ low = hbqs->hbqPutIdx - posted;
+ if (low >= 0) {
+ if ((j >= hbqs->hbqPutIdx) || (j < low)) {
+ len += snprintf(buf+len, size-len, "Unused\n");
+ goto skipit;
+ }
+ }
+ else {
+ if ((j >= hbqs->hbqPutIdx) &&
+ (j < (hbqs->entry_count+low))) {
+ len += snprintf(buf+len, size-len, "Unused\n");
+ goto skipit;
+ }
+ }
+
+ /* Get the Buffer info for the posted buffer */
+ list_for_each_entry(d_buf, &hbqs->hbq_buffer_list, list) {
+ hbq_buf = container_of(d_buf, struct hbq_dmabuf, dbuf);
+ phys = ((uint64_t)hbq_buf->dbuf.phys & 0xffffffff);
+ if (phys == hbqe->bde.addrLow) {
+ len += snprintf(buf+len, size-len,
+ "Buf%d: %p %06x\n", i,
+ hbq_buf->dbuf.virt, hbq_buf->tag);
+ found = 1;
+ break;
+ }
+ i++;
+ }
+ if (!found) {
+ len += snprintf(buf+len, size-len, "No DMAinfo?\n");
+ }
+skipit:
+ hbqe++;
+ if (len > LPFC_HBQINFO_SIZE - 54)
+ break;
+ }
+ spin_unlock_irq(&phba->hbalock);
+ return len;
+}
+
+static int
+lpfc_debugfs_dumpslim_data(struct lpfc_hba *phba, char *buf, int size)
+{
+ int len = 0;
+ int cnt, i, off;
+ uint32_t word0, word1, word2, word3;
+ uint32_t *ptr;
+ struct lpfc_pgp *pgpp;
+ struct lpfc_sli *psli = &phba->sli;
+ struct lpfc_sli_ring *pring;
+
+ cnt = LPFC_DUMPSLIM_SIZE;
+ off = 0;
+ spin_lock_irq(&phba->hbalock);
+
+ len += snprintf(buf+len, size-len, "SLIM Mailbox\n");
+ ptr = (uint32_t *)phba->slim2p;
+ i = sizeof(MAILBOX_t);
+ while (i > 0) {
+ len += snprintf(buf+len, size-len,
+ "%08x: %08x %08x %08x %08x %08x %08x %08x %08x\n",
+ off, *ptr, *(ptr+1), *(ptr+2), *(ptr+3), *(ptr+4),
+ *(ptr+5), *(ptr+6), *(ptr+7));
+ ptr += 8;
+ i -= (8 * sizeof(uint32_t));
+ off += (8 * sizeof(uint32_t));
+ }
+
+ len += snprintf(buf+len, size-len, "SLIM PCB\n");
+ ptr = (uint32_t *)&phba->slim2p->pcb;
+ i = sizeof(PCB_t);
+ while (i > 0) {
+ len += snprintf(buf+len, size-len,
+ "%08x: %08x %08x %08x %08x %08x %08x %08x %08x\n",
+ off, *ptr, *(ptr+1), *(ptr+2), *(ptr+3), *(ptr+4),
+ *(ptr+5), *(ptr+6), *(ptr+7));
+ ptr += 8;
+ i -= (8 * sizeof(uint32_t));
+ off += (8 * sizeof(uint32_t));
+ }
+
+ pgpp = (struct lpfc_pgp *)&phba->slim2p->mbx.us.s3_pgp.port;
+ pring = &psli->ring[0];
+ len += snprintf(buf+len, size-len,
+ "Ring 0: CMD GetInx:%d (Max:%d Next:%d Local:%d flg:x%x) "
+ "RSP PutInx:%d Max:%d\n",
+ pgpp->cmdGetInx, pring->numCiocb,
+ pring->next_cmdidx, pring->local_getidx, pring->flag,
+ pgpp->rspPutInx, pring->numRiocb);
+ pgpp++;
+
+ pring = &psli->ring[1];
+ len += snprintf(buf+len, size-len,
+ "Ring 1: CMD GetInx:%d (Max:%d Next:%d Local:%d flg:x%x) "
+ "RSP PutInx:%d Max:%d\n",
+ pgpp->cmdGetInx, pring->numCiocb,
+ pring->next_cmdidx, pring->local_getidx, pring->flag,
+ pgpp->rspPutInx, pring->numRiocb);
+ pgpp++;
+
+ pring = &psli->ring[2];
+ len += snprintf(buf+len, size-len,
+ "Ring 2: CMD GetInx:%d (Max:%d Next:%d Local:%d flg:x%x) "
+ "RSP PutInx:%d Max:%d\n",
+ pgpp->cmdGetInx, pring->numCiocb,
+ pring->next_cmdidx, pring->local_getidx, pring->flag,
+ pgpp->rspPutInx, pring->numRiocb);
+ pgpp++;
+
+ pring = &psli->ring[3];
+ len += snprintf(buf+len, size-len,
+ "Ring 3: CMD GetInx:%d (Max:%d Next:%d Local:%d flg:x%x) "
+ "RSP PutInx:%d Max:%d\n",
+ pgpp->cmdGetInx, pring->numCiocb,
+ pring->next_cmdidx, pring->local_getidx, pring->flag,
+ pgpp->rspPutInx, pring->numRiocb);
+
+
+ ptr = (uint32_t *)&phba->slim2p->mbx.us.s3_pgp.hbq_get;
+ word0 = readl(phba->HAregaddr);
+ word1 = readl(phba->CAregaddr);
+ word2 = readl(phba->HSregaddr);
+ word3 = readl(phba->HCregaddr);
+ len += snprintf(buf+len, size-len, "HA:%08x CA:%08x HS:%08x HC:%08x\n",
+ word0, word1, word2, word3);
+ spin_unlock_irq(&phba->hbalock);
+ return len;
+}
+
+static int
lpfc_debugfs_nodelist_data(struct lpfc_vport *vport, char *buf, int size)
{
int len = 0;
@@ -204,7 +449,7 @@
len += snprintf(buf+len, size-len, "RPI:%03d flag:x%08x ",
ndlp->nlp_rpi, ndlp->nlp_flag);
if (!ndlp->nlp_type)
- len += snprintf(buf+len, size-len, "UNKNOWN_TYPE");
+ len += snprintf(buf+len, size-len, "UNKNOWN_TYPE ");
if (ndlp->nlp_type & NLP_FC_NODE)
len += snprintf(buf+len, size-len, "FC_NODE ");
if (ndlp->nlp_type & NLP_FABRIC)
@@ -213,7 +458,9 @@
len += snprintf(buf+len, size-len, "FCP_TGT sid:%d ",
ndlp->nlp_sid);
if (ndlp->nlp_type & NLP_FCP_INITIATOR)
- len += snprintf(buf+len, size-len, "FCP_INITIATOR");
+ len += snprintf(buf+len, size-len, "FCP_INITIATOR ");
+ len += snprintf(buf+len, size-len, "refcnt:%x",
+ atomic_read(&ndlp->kref.refcount));
len += snprintf(buf+len, size-len, "\n");
}
spin_unlock_irq(shost->host_lock);
@@ -227,7 +474,7 @@
uint32_t data1, uint32_t data2, uint32_t data3)
{
#ifdef CONFIG_LPFC_DEBUG_FS
- struct lpfc_disc_trc *dtp;
+ struct lpfc_debugfs_trc *dtp;
int index;
if (!(lpfc_debugfs_mask_disc_trc & mask))
@@ -244,7 +491,32 @@
dtp->data1 = data1;
dtp->data2 = data2;
dtp->data3 = data3;
- dtp->seq_cnt = atomic_inc_return(&lpfc_debugfs_disc_trc_cnt);
+ dtp->seq_cnt = atomic_inc_return(&lpfc_debugfs_seq_trc_cnt);
+ dtp->jif = jiffies;
+#endif
+ return;
+}
+
+inline void
+lpfc_debugfs_slow_ring_trc(struct lpfc_hba *phba, char *fmt,
+ uint32_t data1, uint32_t data2, uint32_t data3)
+{
+#ifdef CONFIG_LPFC_DEBUG_FS
+ struct lpfc_debugfs_trc *dtp;
+ int index;
+
+ if (!lpfc_debugfs_enable || !lpfc_debugfs_max_slow_ring_trc ||
+ !phba || !phba->slow_ring_trc)
+ return;
+
+ index = atomic_inc_return(&phba->slow_ring_trc_cnt) &
+ (lpfc_debugfs_max_slow_ring_trc - 1);
+ dtp = phba->slow_ring_trc + index;
+ dtp->fmt = fmt;
+ dtp->data1 = data1;
+ dtp->data2 = data2;
+ dtp->data3 = data3;
+ dtp->seq_cnt = atomic_inc_return(&lpfc_debugfs_seq_trc_cnt);
dtp->jif = jiffies;
#endif
return;
@@ -269,7 +541,7 @@
goto out;
/* Round to page boundry */
- size = (lpfc_debugfs_max_disc_trc * LPFC_DISC_TRC_ENTRY_SIZE);
+ size = (lpfc_debugfs_max_disc_trc * LPFC_DEBUG_TRC_ENTRY_SIZE);
size = PAGE_ALIGN(size);
debug->buffer = kmalloc(size, GFP_KERNEL);
@@ -287,6 +559,95 @@
}
static int
+lpfc_debugfs_slow_ring_trc_open(struct inode *inode, struct file *file)
+{
+ struct lpfc_hba *phba = inode->i_private;
+ struct lpfc_debug *debug;
+ int size;
+ int rc = -ENOMEM;
+
+ if (!lpfc_debugfs_max_slow_ring_trc) {
+ rc = -ENOSPC;
+ goto out;
+ }
+
+ debug = kmalloc(sizeof(*debug), GFP_KERNEL);
+ if (!debug)
+ goto out;
+
+ /* Round to page boundry */
+ size = (lpfc_debugfs_max_slow_ring_trc * LPFC_DEBUG_TRC_ENTRY_SIZE);
+ size = PAGE_ALIGN(size);
+
+ debug->buffer = kmalloc(size, GFP_KERNEL);
+ if (!debug->buffer) {
+ kfree(debug);
+ goto out;
+ }
+
+ debug->len = lpfc_debugfs_slow_ring_trc_data(phba, debug->buffer, size);
+ file->private_data = debug;
+
+ rc = 0;
+out:
+ return rc;
+}
+
+static int
+lpfc_debugfs_hbqinfo_open(struct inode *inode, struct file *file)
+{
+ struct lpfc_hba *phba = inode->i_private;
+ struct lpfc_debug *debug;
+ int rc = -ENOMEM;
+
+ debug = kmalloc(sizeof(*debug), GFP_KERNEL);
+ if (!debug)
+ goto out;
+
+ /* Round to page boundry */
+ debug->buffer = kmalloc(LPFC_HBQINFO_SIZE, GFP_KERNEL);
+ if (!debug->buffer) {
+ kfree(debug);
+ goto out;
+ }
+
+ debug->len = lpfc_debugfs_hbqinfo_data(phba, debug->buffer,
+ LPFC_HBQINFO_SIZE);
+ file->private_data = debug;
+
+ rc = 0;
+out:
+ return rc;
+}
+
+static int
+lpfc_debugfs_dumpslim_open(struct inode *inode, struct file *file)
+{
+ struct lpfc_hba *phba = inode->i_private;
+ struct lpfc_debug *debug;
+ int rc = -ENOMEM;
+
+ debug = kmalloc(sizeof(*debug), GFP_KERNEL);
+ if (!debug)
+ goto out;
+
+ /* Round to page boundry */
+ debug->buffer = kmalloc(LPFC_DUMPSLIM_SIZE, GFP_KERNEL);
+ if (!debug->buffer) {
+ kfree(debug);
+ goto out;
+ }
+
+ debug->len = lpfc_debugfs_dumpslim_data(phba, debug->buffer,
+ LPFC_DUMPSLIM_SIZE);
+ file->private_data = debug;
+
+ rc = 0;
+out:
+ return rc;
+}
+
+static int
lpfc_debugfs_nodelist_open(struct inode *inode, struct file *file)
{
struct lpfc_vport *vport = inode->i_private;
@@ -372,6 +733,33 @@
.release = lpfc_debugfs_release,
};
+#undef lpfc_debugfs_op_hbqinfo
+static struct file_operations lpfc_debugfs_op_hbqinfo = {
+ .owner = THIS_MODULE,
+ .open = lpfc_debugfs_hbqinfo_open,
+ .llseek = lpfc_debugfs_lseek,
+ .read = lpfc_debugfs_read,
+ .release = lpfc_debugfs_release,
+};
+
+#undef lpfc_debugfs_op_dumpslim
+static struct file_operations lpfc_debugfs_op_dumpslim = {
+ .owner = THIS_MODULE,
+ .open = lpfc_debugfs_dumpslim_open,
+ .llseek = lpfc_debugfs_lseek,
+ .read = lpfc_debugfs_read,
+ .release = lpfc_debugfs_release,
+};
+
+#undef lpfc_debugfs_op_slow_ring_trc
+static struct file_operations lpfc_debugfs_op_slow_ring_trc = {
+ .owner = THIS_MODULE,
+ .open = lpfc_debugfs_slow_ring_trc_open,
+ .llseek = lpfc_debugfs_lseek,
+ .read = lpfc_debugfs_read,
+ .release = lpfc_debugfs_release,
+};
+
static struct dentry *lpfc_debugfs_root = NULL;
static atomic_t lpfc_debugfs_hba_count;
#endif
@@ -387,6 +775,116 @@
if (!lpfc_debugfs_enable)
return;
+ /* Setup lpfc root directory */
+ if (!lpfc_debugfs_root) {
+ lpfc_debugfs_root = debugfs_create_dir("lpfc", NULL);
+ atomic_set(&lpfc_debugfs_hba_count, 0);
+ if (!lpfc_debugfs_root) {
+ lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
+ "0409 Cannot create debugfs root\n");
+ goto debug_failed;
+ }
+ }
+ if (!lpfc_debugfs_start_time)
+ lpfc_debugfs_start_time = jiffies;
+
+ /* Setup lpfcX directory for specific HBA */
+ snprintf(name, sizeof(name), "lpfc%d", phba->brd_no);
+ if (!phba->hba_debugfs_root) {
+ phba->hba_debugfs_root =
+ debugfs_create_dir(name, lpfc_debugfs_root);
+ if (!phba->hba_debugfs_root) {
+ lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
+ "0409 Cannot create debugfs hba\n");
+ goto debug_failed;
+ }
+ atomic_inc(&lpfc_debugfs_hba_count);
+ atomic_set(&phba->debugfs_vport_count, 0);
+
+ /* Setup hbqinfo */
+ snprintf(name, sizeof(name), "hbqinfo");
+ phba->debug_hbqinfo =
+ debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
+ phba->hba_debugfs_root,
+ phba, &lpfc_debugfs_op_hbqinfo);
+ if (!phba->debug_hbqinfo) {
+ lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
+ "0409 Cannot create debugfs hbqinfo\n");
+ goto debug_failed;
+ }
+
+ /* Setup dumpslim */
+ snprintf(name, sizeof(name), "dumpslim");
+ phba->debug_dumpslim =
+ debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
+ phba->hba_debugfs_root,
+ phba, &lpfc_debugfs_op_dumpslim);
+ if (!phba->debug_dumpslim) {
+ lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
+ "0409 Cannot create debugfs dumpslim\n");
+ goto debug_failed;
+ }
+
+ /* Setup slow ring trace */
+ if (lpfc_debugfs_max_slow_ring_trc) {
+ num = lpfc_debugfs_max_slow_ring_trc - 1;
+ if (num & lpfc_debugfs_max_slow_ring_trc) {
+ /* Change to be a power of 2 */
+ num = lpfc_debugfs_max_slow_ring_trc;
+ i = 0;
+ while (num > 1) {
+ num = num >> 1;
+ i++;
+ }
+ lpfc_debugfs_max_slow_ring_trc = (1 << i);
+ printk(KERN_ERR
+ "lpfc_debugfs_max_disc_trc changed to "
+ "%d\n", lpfc_debugfs_max_disc_trc);
+ }
+ }
+
+
+ snprintf(name, sizeof(name), "slow_ring_trace");
+ phba->debug_slow_ring_trc =
+ debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
+ phba->hba_debugfs_root,
+ phba, &lpfc_debugfs_op_slow_ring_trc);
+ if (!phba->debug_slow_ring_trc) {
+ lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
+ "0409 Cannot create debugfs "
+ "slow_ring_trace\n");
+ goto debug_failed;
+ }
+ if (!phba->slow_ring_trc) {
+ phba->slow_ring_trc = kmalloc(
+ (sizeof(struct lpfc_debugfs_trc) *
+ lpfc_debugfs_max_slow_ring_trc),
+ GFP_KERNEL);
+ if (!phba->slow_ring_trc) {
+ lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
+ "0409 Cannot create debugfs "
+ "slow_ring buffer\n");
+ goto debug_failed;
+ }
+ atomic_set(&phba->slow_ring_trc_cnt, 0);
+ memset(phba->slow_ring_trc, 0,
+ (sizeof(struct lpfc_debugfs_trc) *
+ lpfc_debugfs_max_slow_ring_trc));
+ }
+ }
+
+ snprintf(name, sizeof(name), "vport%d", vport->vpi);
+ if (!vport->vport_debugfs_root) {
+ vport->vport_debugfs_root =
+ debugfs_create_dir(name, phba->hba_debugfs_root);
+ if (!vport->vport_debugfs_root) {
+ lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
+ "0409 Cant create debugfs");
+ goto debug_failed;
+ }
+ atomic_inc(&phba->debugfs_vport_count);
+ }
+
if (lpfc_debugfs_max_disc_trc) {
num = lpfc_debugfs_max_disc_trc - 1;
if (num & lpfc_debugfs_max_disc_trc) {
@@ -399,48 +897,24 @@
}
lpfc_debugfs_max_disc_trc = (1 << i);
printk(KERN_ERR
- "lpfc_debugfs_max_disc_trc changed to %d\n",
- lpfc_debugfs_max_disc_trc);
+ "lpfc_debugfs_max_disc_trc changed to %d\n",
+ lpfc_debugfs_max_disc_trc);
}
}
- if (!lpfc_debugfs_root) {
- lpfc_debugfs_root = debugfs_create_dir("lpfc", NULL);
- atomic_set(&lpfc_debugfs_hba_count, 0);
- if (!lpfc_debugfs_root)
- goto debug_failed;
- }
-
- snprintf(name, sizeof(name), "lpfc%d", phba->brd_no);
- if (!phba->hba_debugfs_root) {
- phba->hba_debugfs_root =
- debugfs_create_dir(name, lpfc_debugfs_root);
- if (!phba->hba_debugfs_root)
- goto debug_failed;
- atomic_inc(&lpfc_debugfs_hba_count);
- atomic_set(&phba->debugfs_vport_count, 0);
- }
-
- snprintf(name, sizeof(name), "vport%d", vport->vpi);
- if (!vport->vport_debugfs_root) {
- vport->vport_debugfs_root =
- debugfs_create_dir(name, phba->hba_debugfs_root);
- if (!vport->vport_debugfs_root)
- goto debug_failed;
- atomic_inc(&phba->debugfs_vport_count);
- }
-
- if (!lpfc_debugfs_start_time)
- lpfc_debugfs_start_time = jiffies;
-
vport->disc_trc = kmalloc(
- (sizeof(struct lpfc_disc_trc) * lpfc_debugfs_max_disc_trc),
+ (sizeof(struct lpfc_debugfs_trc) * lpfc_debugfs_max_disc_trc),
GFP_KERNEL);
- if (!vport->disc_trc)
+ if (!vport->disc_trc) {
+ lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
+ "0409 Cannot create debugfs disc trace "
+ "buffer\n");
goto debug_failed;
+ }
+ atomic_set(&vport->disc_trc_cnt, 0);
memset(vport->disc_trc, 0,
- (sizeof(struct lpfc_disc_trc) * lpfc_debugfs_max_disc_trc));
+ (sizeof(struct lpfc_debugfs_trc) * lpfc_debugfs_max_disc_trc));
snprintf(name, sizeof(name), "discovery_trace");
vport->debug_disc_trc =
@@ -448,9 +922,9 @@
vport->vport_debugfs_root,
vport, &lpfc_debugfs_op_disc_trc);
if (!vport->debug_disc_trc) {
- lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
- "%d:0409 Cannot create debugfs",
- phba->brd_no);
+ lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
+ "0409 Cannot create debugfs "
+ "discovery_trace\n");
goto debug_failed;
}
snprintf(name, sizeof(name), "nodelist");
@@ -459,9 +933,8 @@
vport->vport_debugfs_root,
vport, &lpfc_debugfs_op_nodelist);
if (!vport->debug_nodelist) {
- lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
- "%d:0409 Cannot create debugfs",
- phba->brd_no);
+ lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
+ "0409 Cant create debugfs nodelist");
goto debug_failed;
}
debug_failed:
@@ -488,21 +961,45 @@
debugfs_remove(vport->debug_nodelist); /* nodelist */
vport->debug_nodelist = NULL;
}
+
if (vport->vport_debugfs_root) {
debugfs_remove(vport->vport_debugfs_root); /* vportX */
vport->vport_debugfs_root = NULL;
atomic_dec(&phba->debugfs_vport_count);
}
if (atomic_read(&phba->debugfs_vport_count) == 0) {
- debugfs_remove(vport->phba->hba_debugfs_root); /* lpfcX */
- vport->phba->hba_debugfs_root = NULL;
- atomic_dec(&lpfc_debugfs_hba_count);
+
+ if (phba->debug_hbqinfo) {
+ debugfs_remove(phba->debug_hbqinfo); /* hbqinfo */
+ phba->debug_hbqinfo = NULL;
+ }
+ if (phba->debug_dumpslim) {
+ debugfs_remove(phba->debug_dumpslim); /* dumpslim */
+ phba->debug_dumpslim = NULL;
+ }
+ if (phba->slow_ring_trc) {
+ kfree(phba->slow_ring_trc);
+ phba->slow_ring_trc = NULL;
+ }
+ if (phba->debug_slow_ring_trc) {
+ /* slow_ring_trace */
+ debugfs_remove(phba->debug_slow_ring_trc);
+ phba->debug_slow_ring_trc = NULL;
+ }
+
+ if (phba->hba_debugfs_root) {
+ debugfs_remove(phba->hba_debugfs_root); /* lpfcX */
+ phba->hba_debugfs_root = NULL;
+ atomic_dec(&lpfc_debugfs_hba_count);
+ }
+
if (atomic_read(&lpfc_debugfs_hba_count) == 0) {
debugfs_remove(lpfc_debugfs_root); /* lpfc */
lpfc_debugfs_root = NULL;
}
}
#endif
+ return;
}
diff --git a/drivers/scsi/lpfc/lpfc_debugfs.h b/drivers/scsi/lpfc/lpfc_debugfs.h
index fffb678..31e86a5 100644
--- a/drivers/scsi/lpfc/lpfc_debugfs.h
+++ b/drivers/scsi/lpfc/lpfc_debugfs.h
@@ -22,7 +22,7 @@
#define _H_LPFC_DEBUG_FS
#ifdef CONFIG_LPFC_DEBUG_FS
-struct lpfc_disc_trc {
+struct lpfc_debugfs_trc {
char *fmt;
uint32_t data1;
uint32_t data2;
diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c
index 33fbc16..8085900 100644
--- a/drivers/scsi/lpfc/lpfc_els.c
+++ b/drivers/scsi/lpfc/lpfc_els.c
@@ -63,10 +63,10 @@
return 0;
/* Pending Link Event during Discovery */
- lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY,
- "%d (%d):0237 Pending Link Event during "
- "Discovery: State x%x\n",
- phba->brd_no, vport->vpi, phba->pport->port_state);
+ lpfc_printf_vlog(vport, KERN_ERR, LOG_DISCOVERY,
+ "0237 Pending Link Event during "
+ "Discovery: State x%x\n",
+ phba->pport->port_state);
/* CLEAR_LA should re-enable link attention events and
* we should then imediately take a LATT event. The
@@ -196,9 +196,7 @@
bpl->tus.w = le32_to_cpu(bpl->tus.w);
}
- /* Save for completion so we can release these resources */
- if (elscmd != ELS_CMD_LS_RJT)
- elsiocb->context1 = lpfc_nlp_get(ndlp);
+ elsiocb->context1 = lpfc_nlp_get(ndlp);
elsiocb->context2 = pcmd;
elsiocb->context3 = pbuflist;
elsiocb->retry = retry;
@@ -208,23 +206,21 @@
if (prsp) {
list_add(&prsp->list, &pcmd->list);
}
-
if (expectRsp) {
/* Xmit ELS command <elsCmd> to remote NPORT <did> */
- lpfc_printf_log(phba, KERN_INFO, LOG_ELS,
- "%d (%d):0116 Xmit ELS command x%x to remote "
- "NPORT x%x I/O tag: x%x, port state: x%x\n",
- phba->brd_no, vport->vpi, elscmd, did,
- elsiocb->iotag, vport->port_state);
+ lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
+ "0116 Xmit ELS command x%x to remote "
+ "NPORT x%x I/O tag: x%x, port state: x%x\n",
+ elscmd, did, elsiocb->iotag,
+ vport->port_state);
} else {
/* Xmit ELS response <elsCmd> to remote NPORT <did> */
- lpfc_printf_log(phba, KERN_INFO, LOG_ELS,
- "%d (%d):0117 Xmit ELS response x%x to remote "
- "NPORT x%x I/O tag: x%x, size: x%x\n",
- phba->brd_no, vport->vpi, elscmd,
- ndlp->nlp_DID, elsiocb->iotag, cmdSize);
+ lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
+ "0117 Xmit ELS response x%x to remote "
+ "NPORT x%x I/O tag: x%x, size: x%x\n",
+ elscmd, ndlp->nlp_DID, elsiocb->iotag,
+ cmdSize);
}
-
return elsiocb;
}
@@ -285,9 +281,8 @@
fail:
lpfc_vport_set_state(vport, FC_VPORT_FAILED);
- lpfc_printf_log(phba, KERN_ERR, LOG_ELS,
- "%d (%d):0249 Cannot issue Register Fabric login\n",
- phba->brd_no, vport->vpi);
+ lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS,
+ "0249 Cannot issue Register Fabric login\n");
return -ENXIO;
}
@@ -340,20 +335,19 @@
if (phba->sli3_options & LPFC_SLI3_NPIV_ENABLED) {
if (sp->cmn.response_multiple_NPort) {
- lpfc_printf_log(phba, KERN_WARNING, LOG_ELS | LOG_VPORT,
- "%d:1816 FLOGI NPIV supported, "
- "response data 0x%x\n",
- phba->brd_no,
- sp->cmn.response_multiple_NPort);
+ lpfc_printf_vlog(vport, KERN_WARNING,
+ LOG_ELS | LOG_VPORT,
+ "1816 FLOGI NPIV supported, "
+ "response data 0x%x\n",
+ sp->cmn.response_multiple_NPort);
phba->link_flag |= LS_NPIV_FAB_SUPPORTED;
-
} else {
/* Because we asked f/w for NPIV it still expects us
- to call reg_vnpid atleast for the physcial host */
- lpfc_printf_log(phba, KERN_WARNING, LOG_ELS | LOG_VPORT,
- "%d:1817 Fabric does not support NPIV "
- "- configuring single port mode.\n",
- phba->brd_no);
+ to call reg_vnpid atleast for the physcial host */
+ lpfc_printf_vlog(vport, KERN_WARNING,
+ LOG_ELS | LOG_VPORT,
+ "1817 Fabric does not support NPIV "
+ "- configuring single port mode.\n");
phba->link_flag &= ~LS_NPIV_FAB_SUPPORTED;
}
}
@@ -518,16 +512,15 @@
* alpa map would take too long otherwise.
*/
if (phba->alpa_map[0] == 0) {
- phba->cfg_discovery_threads = LPFC_MAX_DISC_THREADS;
+ vport->cfg_discovery_threads = LPFC_MAX_DISC_THREADS;
}
/* FLOGI failure */
- lpfc_printf_log(phba, KERN_INFO, LOG_ELS,
- "%d (%d):0100 FLOGI failure Data: x%x x%x "
- "x%x\n",
- phba->brd_no, vport->vpi,
- irsp->ulpStatus, irsp->un.ulpWord[4],
- irsp->ulpTimeout);
+ lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
+ "0100 FLOGI failure Data: x%x x%x "
+ "x%x\n",
+ irsp->ulpStatus, irsp->un.ulpWord[4],
+ irsp->ulpTimeout);
goto flogifail;
}
@@ -540,12 +533,11 @@
sp = prsp->virt + sizeof(uint32_t);
/* FLOGI completes successfully */
- lpfc_printf_log(phba, KERN_INFO, LOG_ELS,
- "%d (%d):0101 FLOGI completes sucessfully "
- "Data: x%x x%x x%x x%x\n",
- phba->brd_no, vport->vpi,
- irsp->un.ulpWord[4], sp->cmn.e_d_tov,
- sp->cmn.w2.r_a_tov, sp->cmn.edtovResolution);
+ lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
+ "0101 FLOGI completes sucessfully "
+ "Data: x%x x%x x%x x%x\n",
+ irsp->un.ulpWord[4], sp->cmn.e_d_tov,
+ sp->cmn.w2.r_a_tov, sp->cmn.edtovResolution);
if (vport->port_state == LPFC_FLOGI) {
/*
@@ -662,8 +654,8 @@
/* Abort outstanding I/O on NPort <nlp_DID> */
lpfc_printf_log(phba, KERN_INFO, LOG_DISCOVERY,
- "%d:0201 Abort outstanding I/O on NPort x%x\n",
- phba->brd_no, Fabric_DID);
+ "0201 Abort outstanding I/O on NPort x%x\n",
+ Fabric_DID);
pring = &phba->sli.ring[LPFC_ELS_RING];
@@ -736,18 +728,16 @@
lpfc_more_plogi(struct lpfc_vport *vport)
{
int sentplogi;
- struct lpfc_hba *phba = vport->phba;
if (vport->num_disc_nodes)
vport->num_disc_nodes--;
/* Continue discovery with <num_disc_nodes> PLOGIs to go */
- lpfc_printf_log(phba, KERN_INFO, LOG_DISCOVERY,
- "%d (%d):0232 Continue discovery with %d PLOGIs to go "
- "Data: x%x x%x x%x\n",
- phba->brd_no, vport->vpi, vport->num_disc_nodes,
- vport->fc_plogi_cnt, vport->fc_flag, vport->port_state);
-
+ lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,
+ "0232 Continue discovery with %d PLOGIs to go "
+ "Data: x%x x%x x%x\n",
+ vport->num_disc_nodes, vport->fc_plogi_cnt,
+ vport->fc_flag, vport->port_state);
/* Check to see if there are more PLOGIs to be sent */
if (vport->fc_flag & FC_NLP_MORE)
/* go thru NPR nodes and issue any remaining ELS PLOGIs */
@@ -833,11 +823,12 @@
ndlp = lpfc_findnode_did(vport, irsp->un.elsreq64.remoteID);
if (!ndlp) {
- lpfc_printf_log(phba, KERN_ERR, LOG_ELS,
- "%d (%d):0136 PLOGI completes to NPort x%x "
- "with no ndlp. Data: x%x x%x x%x\n",
- phba->brd_no, vport->vpi, irsp->un.elsreq64.remoteID,
- irsp->ulpStatus, irsp->un.ulpWord[4], irsp->ulpIoTag);
+ lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS,
+ "0136 PLOGI completes to NPort x%x "
+ "with no ndlp. Data: x%x x%x x%x\n",
+ irsp->un.elsreq64.remoteID,
+ irsp->ulpStatus, irsp->un.ulpWord[4],
+ irsp->ulpIoTag);
goto out;
}
@@ -851,13 +842,11 @@
rc = 0;
/* PLOGI completes to NPort <nlp_DID> */
- lpfc_printf_log(phba, KERN_INFO, LOG_ELS,
- "%d (%d):0102 PLOGI completes to NPort x%x "
- "Data: x%x x%x x%x x%x x%x\n",
- phba->brd_no, vport->vpi, ndlp->nlp_DID,
- irsp->ulpStatus, irsp->un.ulpWord[4],
- irsp->ulpTimeout, disc, vport->num_disc_nodes);
-
+ lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
+ "0102 PLOGI completes to NPort x%x "
+ "Data: x%x x%x x%x x%x x%x\n",
+ ndlp->nlp_DID, irsp->ulpStatus, irsp->un.ulpWord[4],
+ irsp->ulpTimeout, disc, vport->num_disc_nodes);
/* Check to see if link went down during discovery */
if (lpfc_els_chk_latt(vport)) {
spin_lock_irq(shost->host_lock);
@@ -881,17 +870,14 @@
}
goto out;
}
-
/* PLOGI failed */
if (ndlp->nlp_DID == NameServer_DID) {
lpfc_vport_set_state(vport, FC_VPORT_FAILED);
- lpfc_printf_log(phba, KERN_ERR, LOG_ELS,
- "%d (%d):0250 Nameserver login error: "
- "0x%x / 0x%x\n",
- phba->brd_no, vport->vpi,
- irsp->ulpStatus, irsp->un.ulpWord[4]);
+ lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS,
+ "0250 Nameserver login error: "
+ "0x%x / 0x%x\n",
+ irsp->ulpStatus, irsp->un.ulpWord[4]);
}
-
/* Do not call DSM for lpfc_els_abort'ed ELS cmds */
if (lpfc_error_lost_link(irsp)) {
rc = NLP_STE_FREED_NODE;
@@ -1017,14 +1003,12 @@
"PRLI cmpl: status:x%x/x%x did:x%x",
irsp->ulpStatus, irsp->un.ulpWord[4],
ndlp->nlp_DID);
-
/* PRLI completes to NPort <nlp_DID> */
- lpfc_printf_log(phba, KERN_INFO, LOG_ELS,
- "%d (%d):0103 PRLI completes to NPort x%x "
- "Data: x%x x%x x%x x%x\n",
- phba->brd_no, vport->vpi, ndlp->nlp_DID,
- irsp->ulpStatus, irsp->un.ulpWord[4], irsp->ulpTimeout,
- vport->num_disc_nodes);
+ lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
+ "0103 PRLI completes to NPort x%x "
+ "Data: x%x x%x x%x x%x\n",
+ ndlp->nlp_DID, irsp->ulpStatus, irsp->un.ulpWord[4],
+ irsp->ulpTimeout, vport->num_disc_nodes);
vport->fc_prli_sent--;
/* Check to see if link went down during discovery */
@@ -1129,18 +1113,15 @@
lpfc_more_adisc(struct lpfc_vport *vport)
{
int sentadisc;
- struct lpfc_hba *phba = vport->phba;
if (vport->num_disc_nodes)
vport->num_disc_nodes--;
-
/* Continue discovery with <num_disc_nodes> ADISCs to go */
- lpfc_printf_log(phba, KERN_INFO, LOG_DISCOVERY,
- "%d (%d):0210 Continue discovery with %d ADISCs to go "
- "Data: x%x x%x x%x\n",
- phba->brd_no, vport->vpi, vport->num_disc_nodes,
- vport->fc_adisc_cnt, vport->fc_flag, vport->port_state);
-
+ lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,
+ "0210 Continue discovery with %d ADISCs to go "
+ "Data: x%x x%x x%x\n",
+ vport->num_disc_nodes, vport->fc_adisc_cnt,
+ vport->fc_flag, vport->port_state);
/* Check to see if there are more ADISCs to be sent */
if (vport->fc_flag & FC_NLP_MORE) {
lpfc_set_disctmo(vport);
@@ -1206,15 +1187,12 @@
disc = (ndlp->nlp_flag & NLP_NPR_2B_DISC);
ndlp->nlp_flag &= ~(NLP_ADISC_SND | NLP_NPR_2B_DISC);
spin_unlock_irq(shost->host_lock);
-
/* ADISC completes to NPort <nlp_DID> */
- lpfc_printf_log(phba, KERN_INFO, LOG_ELS,
- "%d (%d):0104 ADISC completes to NPort x%x "
- "Data: x%x x%x x%x x%x x%x\n",
- phba->brd_no, vport->vpi, ndlp->nlp_DID,
- irsp->ulpStatus, irsp->un.ulpWord[4], irsp->ulpTimeout,
- disc, vport->num_disc_nodes);
-
+ lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
+ "0104 ADISC completes to NPort x%x "
+ "Data: x%x x%x x%x x%x x%x\n",
+ ndlp->nlp_DID, irsp->ulpStatus, irsp->un.ulpWord[4],
+ irsp->ulpTimeout, disc, vport->num_disc_nodes);
/* Check to see if link went down during discovery */
if (lpfc_els_chk_latt(vport)) {
spin_lock_irq(shost->host_lock);
@@ -1374,15 +1352,12 @@
"LOGO cmpl: status:x%x/x%x did:x%x",
irsp->ulpStatus, irsp->un.ulpWord[4],
ndlp->nlp_DID);
-
/* LOGO completes to NPort <nlp_DID> */
- lpfc_printf_log(phba, KERN_INFO, LOG_ELS,
- "%d (%d):0105 LOGO completes to NPort x%x "
- "Data: x%x x%x x%x x%x\n",
- phba->brd_no, vport->vpi, ndlp->nlp_DID,
- irsp->ulpStatus, irsp->un.ulpWord[4], irsp->ulpTimeout,
- vport->num_disc_nodes);
-
+ lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
+ "0105 LOGO completes to NPort x%x "
+ "Data: x%x x%x x%x x%x\n",
+ ndlp->nlp_DID, irsp->ulpStatus, irsp->un.ulpWord[4],
+ irsp->ulpTimeout, vport->num_disc_nodes);
/* Check to see if link went down during discovery */
if (lpfc_els_chk_latt(vport))
goto out;
@@ -1488,15 +1463,11 @@
"ELS cmd cmpl: status:x%x/x%x did:x%x",
irsp->ulpStatus, irsp->un.ulpWord[4],
irsp->un.elsreq64.remoteID);
-
/* ELS cmd tag <ulpIoTag> completes */
- lpfc_printf_log(phba, KERN_INFO, LOG_ELS,
- "%d (%d):0106 ELS cmd tag x%x completes Data: x%x x%x "
- "x%x\n",
- phba->brd_no, vport->vpi,
- irsp->ulpIoTag, irsp->ulpStatus,
- irsp->un.ulpWord[4], irsp->ulpTimeout);
-
+ lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
+ "0106 ELS cmd tag x%x completes Data: x%x x%x x%x\n",
+ irsp->ulpIoTag, irsp->ulpStatus,
+ irsp->un.ulpWord[4], irsp->ulpTimeout);
/* Check to see if link went down during discovery */
lpfc_els_chk_latt(vport);
lpfc_els_free_iocb(phba, cmdiocb);
@@ -1831,13 +1802,15 @@
case IOERR_ILLEGAL_COMMAND:
if ((phba->sli3_options & LPFC_SLI3_VPORT_TEARDOWN) &&
(cmd == ELS_CMD_FDISC)) {
- lpfc_printf_log(phba, KERN_ERR, LOG_ELS,
- "%d (%d):0124 FDISC failed (3/6) retrying...\n",
- phba->brd_no, vport->vpi);
+ lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS,
+ "0124 FDISC failed (3/6) "
+ "retrying...\n");
lpfc_mbx_unreg_vpi(vport);
retry = 1;
- /* Always retry for this case */
- cmdiocb->retry = 0;
+ /* FDISC retry policy */
+ maxretry = 48;
+ if (cmdiocb->retry >= 32)
+ delay = 1000;
}
break;
@@ -1898,10 +1871,10 @@
if ((phba->sli3_options & LPFC_SLI3_NPIV_ENABLED) &&
(cmd == ELS_CMD_FDISC) &&
(stat.un.b.lsRjtRsnCodeExp == LSEXP_OUT_OF_RESOURCE)){
- lpfc_printf_log(phba, KERN_ERR, LOG_ELS,
- "%d (%d):0125 FDISC Failed (x%x)."
- " Fabric out of resources\n",
- phba->brd_no, vport->vpi, stat.un.lsRjtError);
+ lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS,
+ "0125 FDISC Failed (x%x). "
+ "Fabric out of resources\n",
+ stat.un.lsRjtError);
lpfc_vport_set_state(vport,
FC_VPORT_NO_FABRIC_RSCS);
}
@@ -1913,8 +1886,10 @@
delay = 1000;
maxretry = 48;
} else if (cmd == ELS_CMD_FDISC) {
- /* Always retry for this case */
- cmdiocb->retry = 0;
+ /* FDISC retry policy */
+ maxretry = 48;
+ if (cmdiocb->retry >= 32)
+ delay = 1000;
}
retry = 1;
break;
@@ -1926,10 +1901,10 @@
((stat.un.b.lsRjtRsnCodeExp == LSEXP_INVALID_PNAME) ||
(stat.un.b.lsRjtRsnCodeExp == LSEXP_INVALID_NPORT_ID))
) {
- lpfc_printf_log(phba, KERN_ERR, LOG_ELS,
- "%d (%d):0123 FDISC Failed (x%x)."
- " Fabric Detected Bad WWN\n",
- phba->brd_no, vport->vpi, stat.un.lsRjtError);
+ lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS,
+ "0123 FDISC Failed (x%x). "
+ "Fabric Detected Bad WWN\n",
+ stat.un.lsRjtError);
lpfc_vport_set_state(vport,
FC_VPORT_FABRIC_REJ_WWN);
}
@@ -1959,11 +1934,10 @@
if (retry) {
/* Retry ELS command <elsCmd> to remote NPORT <did> */
- lpfc_printf_log(phba, KERN_INFO, LOG_ELS,
- "%d (%d):0107 Retry ELS command x%x to remote "
- "NPORT x%x Data: x%x x%x\n",
- phba->brd_no, vport->vpi,
- cmd, did, cmdiocb->retry, delay);
+ lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
+ "0107 Retry ELS command x%x to remote "
+ "NPORT x%x Data: x%x x%x\n",
+ cmd, did, cmdiocb->retry, delay);
if (((cmd == ELS_CMD_PLOGI) || (cmd == ELS_CMD_ADISC)) &&
((irsp->ulpStatus != IOSTAT_LOCAL_REJECT) ||
@@ -2031,14 +2005,12 @@
return 1;
}
}
-
/* No retry ELS command <elsCmd> to remote NPORT <did> */
- lpfc_printf_log(phba, KERN_INFO, LOG_ELS,
- "%d (%d):0108 No retry ELS command x%x to remote "
- "NPORT x%x Data: x%x\n",
- phba->brd_no, vport->vpi,
- cmd, did, cmdiocb->retry);
-
+ lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS,
+ "0108 No retry ELS command x%x to remote "
+ "NPORT x%x Retried:%d Error:x%x/%x\n",
+ cmd, did, cmdiocb->retry, irsp->ulpStatus,
+ irsp->un.ulpWord[4]);
return 0;
}
@@ -2087,14 +2059,12 @@
lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_RSP,
"ACC LOGO cmpl: status:x%x/x%x did:x%x",
irsp->ulpStatus, irsp->un.ulpWord[4], ndlp->nlp_DID);
-
/* ACC to LOGO completes to NPort <nlp_DID> */
- lpfc_printf_log(phba, KERN_INFO, LOG_ELS,
- "%d (%d):0109 ACC to LOGO completes to NPort x%x "
- "Data: x%x x%x x%x\n",
- phba->brd_no, vport->vpi, ndlp->nlp_DID,
- ndlp->nlp_flag, ndlp->nlp_state, ndlp->nlp_rpi);
-
+ lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
+ "0109 ACC to LOGO completes to NPort x%x "
+ "Data: x%x x%x x%x\n",
+ ndlp->nlp_DID, ndlp->nlp_flag, ndlp->nlp_state,
+ ndlp->nlp_rpi);
switch (ndlp->nlp_state) {
case NLP_STE_UNUSED_NODE: /* node is just allocated */
lpfc_drop_node(vport, ndlp);
@@ -2153,20 +2123,17 @@
}
lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_RSP,
- "ACC cmpl: status:x%x/x%x did:x%x",
+ "ELS rsp cmpl: status:x%x/x%x did:x%x",
irsp->ulpStatus, irsp->un.ulpWord[4],
- irsp->un.rcvels.remoteID);
-
+ cmdiocb->iocb.un.elsreq64.remoteID);
/* ELS response tag <ulpIoTag> completes */
- lpfc_printf_log(phba, KERN_INFO, LOG_ELS,
- "%d (%d):0110 ELS response tag x%x completes "
- "Data: x%x x%x x%x x%x x%x x%x x%x\n",
- phba->brd_no, vport->vpi,
- cmdiocb->iocb.ulpIoTag, rspiocb->iocb.ulpStatus,
- rspiocb->iocb.un.ulpWord[4], rspiocb->iocb.ulpTimeout,
- ndlp->nlp_DID, ndlp->nlp_flag, ndlp->nlp_state,
- ndlp->nlp_rpi);
-
+ lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
+ "0110 ELS response tag x%x completes "
+ "Data: x%x x%x x%x x%x x%x x%x x%x\n",
+ cmdiocb->iocb.ulpIoTag, rspiocb->iocb.ulpStatus,
+ rspiocb->iocb.un.ulpWord[4], rspiocb->iocb.ulpTimeout,
+ ndlp->nlp_DID, ndlp->nlp_flag, ndlp->nlp_state,
+ ndlp->nlp_rpi);
if (mbox) {
if ((rspiocb->iocb.ulpStatus == 0)
&& (ndlp->nlp_flag & NLP_ACC_REGLOGIN)) {
@@ -2219,7 +2186,7 @@
int
lpfc_els_rsp_acc(struct lpfc_vport *vport, uint32_t flag,
struct lpfc_iocbq *oldiocb, struct lpfc_nodelist *ndlp,
- LPFC_MBOXQ_t *mbox, uint8_t newnode)
+ LPFC_MBOXQ_t *mbox)
{
struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
struct lpfc_hba *phba = vport->phba;
@@ -2305,20 +2272,13 @@
default:
return 1;
}
-
- if (newnode) {
- lpfc_nlp_put(ndlp);
- elsiocb->context1 = NULL;
- }
-
/* Xmit ELS ACC response tag <ulpIoTag> */
- lpfc_printf_log(phba, KERN_INFO, LOG_ELS,
- "%d (%d):0128 Xmit ELS ACC response tag x%x, XRI: x%x, "
- "DID: x%x, nlp_flag: x%x nlp_state: x%x RPI: x%x\n",
- phba->brd_no, vport->vpi, elsiocb->iotag,
- elsiocb->iocb.ulpContext, ndlp->nlp_DID,
- ndlp->nlp_flag, ndlp->nlp_state, ndlp->nlp_rpi);
-
+ lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
+ "0128 Xmit ELS ACC response tag x%x, XRI: x%x, "
+ "DID: x%x, nlp_flag: x%x nlp_state: x%x RPI: x%x\n",
+ elsiocb->iotag, elsiocb->iocb.ulpContext,
+ ndlp->nlp_DID, ndlp->nlp_flag, ndlp->nlp_state,
+ ndlp->nlp_rpi);
if (ndlp->nlp_flag & NLP_LOGO_ACC) {
spin_lock_irq(shost->host_lock);
ndlp->nlp_flag &= ~NLP_LOGO_ACC;
@@ -2370,20 +2330,17 @@
pcmd += sizeof(uint32_t);
*((uint32_t *) (pcmd)) = rejectError;
- if (mbox) {
+ if (mbox)
elsiocb->context_un.mbox = mbox;
- elsiocb->context1 = lpfc_nlp_get(ndlp);
- }
/* Xmit ELS RJT <err> response tag <ulpIoTag> */
- lpfc_printf_log(phba, KERN_INFO, LOG_ELS,
- "%d (%d):0129 Xmit ELS RJT x%x response tag x%x "
- "xri x%x, did x%x, nlp_flag x%x, nlp_state x%x, "
- "rpi x%x\n",
- phba->brd_no, vport->vpi, rejectError, elsiocb->iotag,
- elsiocb->iocb.ulpContext, ndlp->nlp_DID,
- ndlp->nlp_flag, ndlp->nlp_state, ndlp->nlp_rpi);
-
+ lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
+ "0129 Xmit ELS RJT x%x response tag x%x "
+ "xri x%x, did x%x, nlp_flag x%x, nlp_state x%x, "
+ "rpi x%x\n",
+ rejectError, elsiocb->iotag,
+ elsiocb->iocb.ulpContext, ndlp->nlp_DID,
+ ndlp->nlp_flag, ndlp->nlp_state, ndlp->nlp_rpi);
lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_RSP,
"Issue LS_RJT: did:x%x flg:x%x err:x%x",
ndlp->nlp_DID, ndlp->nlp_flag, rejectError);
@@ -2391,6 +2348,15 @@
phba->fc_stat.elsXmitLSRJT++;
elsiocb->iocb_cmpl = lpfc_cmpl_els_rsp;
rc = lpfc_sli_issue_iocb(phba, pring, elsiocb, 0);
+
+ /* If the node is in the UNUSED state, and we are sending
+ * a reject, we are done with it. Release driver reference
+ * count here. The outstanding els will release its reference on
+ * completion and the node can be freed then.
+ */
+ if (ndlp->nlp_state == NLP_STE_UNUSED_NODE)
+ lpfc_nlp_put(ndlp);
+
if (rc == IOCB_ERROR) {
lpfc_els_free_iocb(phba, elsiocb);
return 1;
@@ -2423,13 +2389,12 @@
icmd->ulpContext = oldcmd->ulpContext; /* Xri */
/* Xmit ADISC ACC response tag <ulpIoTag> */
- lpfc_printf_log(phba, KERN_INFO, LOG_ELS,
- "%d (%d):0130 Xmit ADISC ACC response iotag x%x xri: "
- "x%x, did x%x, nlp_flag x%x, nlp_state x%x rpi x%x\n",
- phba->brd_no, vport->vpi, elsiocb->iotag,
- elsiocb->iocb.ulpContext, ndlp->nlp_DID,
- ndlp->nlp_flag, ndlp->nlp_state, ndlp->nlp_rpi);
-
+ lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
+ "0130 Xmit ADISC ACC response iotag x%x xri: "
+ "x%x, did x%x, nlp_flag x%x, nlp_state x%x rpi x%x\n",
+ elsiocb->iotag, elsiocb->iocb.ulpContext,
+ ndlp->nlp_DID, ndlp->nlp_flag, ndlp->nlp_state,
+ ndlp->nlp_rpi);
pcmd = (uint8_t *) (((struct lpfc_dmabuf *) elsiocb->context2)->virt);
*((uint32_t *) (pcmd)) = ELS_CMD_ACC;
@@ -2483,15 +2448,13 @@
icmd = &elsiocb->iocb;
oldcmd = &oldiocb->iocb;
icmd->ulpContext = oldcmd->ulpContext; /* Xri */
-
/* Xmit PRLI ACC response tag <ulpIoTag> */
- lpfc_printf_log(phba, KERN_INFO, LOG_ELS,
- "%d (%d):0131 Xmit PRLI ACC response tag x%x xri x%x, "
- "did x%x, nlp_flag x%x, nlp_state x%x, rpi x%x\n",
- phba->brd_no, vport->vpi, elsiocb->iotag,
- elsiocb->iocb.ulpContext, ndlp->nlp_DID,
- ndlp->nlp_flag, ndlp->nlp_state, ndlp->nlp_rpi);
-
+ lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
+ "0131 Xmit PRLI ACC response tag x%x xri x%x, "
+ "did x%x, nlp_flag x%x, nlp_state x%x, rpi x%x\n",
+ elsiocb->iotag, elsiocb->iocb.ulpContext,
+ ndlp->nlp_DID, ndlp->nlp_flag, ndlp->nlp_state,
+ ndlp->nlp_rpi);
pcmd = (uint8_t *) (((struct lpfc_dmabuf *) elsiocb->context2)->virt);
*((uint32_t *) (pcmd)) = (ELS_CMD_ACC | (ELS_CMD_PRLI & ~ELS_RSP_MASK));
@@ -2565,16 +2528,11 @@
icmd = &elsiocb->iocb;
oldcmd = &oldiocb->iocb;
icmd->ulpContext = oldcmd->ulpContext; /* Xri */
-
/* Xmit RNID ACC response tag <ulpIoTag> */
- lpfc_printf_log(phba, KERN_INFO, LOG_ELS,
- "%d (%d):0132 Xmit RNID ACC response tag x%x "
- "xri x%x\n",
- phba->brd_no, vport->vpi, elsiocb->iotag,
- elsiocb->iocb.ulpContext);
-
+ lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
+ "0132 Xmit RNID ACC response tag x%x xri x%x\n",
+ elsiocb->iotag, elsiocb->iocb.ulpContext);
pcmd = (uint8_t *) (((struct lpfc_dmabuf *) elsiocb->context2)->virt);
-
*((uint32_t *) (pcmd)) = ELS_CMD_ACC;
pcmd += sizeof(uint32_t);
@@ -2641,7 +2599,7 @@
sentadisc++;
vport->num_disc_nodes++;
if (vport->num_disc_nodes >=
- vport->phba->cfg_discovery_threads) {
+ vport->cfg_discovery_threads) {
spin_lock_irq(shost->host_lock);
vport->fc_flag |= FC_NLP_MORE;
spin_unlock_irq(shost->host_lock);
@@ -2676,7 +2634,7 @@
sentplogi++;
vport->num_disc_nodes++;
if (vport->num_disc_nodes >=
- vport->phba->cfg_discovery_threads) {
+ vport->cfg_discovery_threads) {
spin_lock_irq(shost->host_lock);
vport->fc_flag |= FC_NLP_MORE;
spin_unlock_irq(shost->host_lock);
@@ -2717,7 +2675,6 @@
D_ID rscn_did;
uint32_t *lp;
uint32_t payload_len, i;
- struct lpfc_hba *phba = vport->phba;
ns_did.un.word = did;
@@ -2752,12 +2709,10 @@
break;
default:
/* Unknown Identifier in RSCN node */
- lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY,
- "%d (%d):0217 Unknown "
- "Identifier in RSCN payload "
- "Data: x%x\n",
- phba->brd_no, vport->vpi,
- rscn_did.un.word);
+ lpfc_printf_vlog(vport, KERN_ERR, LOG_DISCOVERY,
+ "0217 Unknown Identifier in "
+ "RSCN payload Data: x%x\n",
+ rscn_did.un.word);
case 3: /* Whole Fabric effected */
return did;
}
@@ -2796,12 +2751,11 @@
static int
lpfc_els_rcv_rscn(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
- struct lpfc_nodelist *ndlp, uint8_t newnode)
+ struct lpfc_nodelist *ndlp)
{
struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
struct lpfc_hba *phba = vport->phba;
struct lpfc_dmabuf *pcmd;
- struct lpfc_vport *next_vport;
uint32_t *lp, *datap;
IOCB_t *icmd;
uint32_t payload_len, length, nportid, *cmd;
@@ -2815,13 +2769,10 @@
payload_len = be32_to_cpu(*lp++ & ~ELS_CMD_MASK);
payload_len -= sizeof(uint32_t); /* take off word 0 */
-
/* RSCN received */
- lpfc_printf_log(phba, KERN_INFO, LOG_DISCOVERY,
- "%d (%d):0214 RSCN received Data: x%x x%x x%x x%x\n",
- phba->brd_no, vport->vpi, vport->fc_flag, payload_len,
- *lp, rscn_cnt);
-
+ lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,
+ "0214 RSCN received Data: x%x x%x x%x x%x\n",
+ vport->fc_flag, payload_len, *lp, rscn_cnt);
for (i = 0; i < payload_len/sizeof(uint32_t); i++)
fc_host_post_event(shost, fc_get_event_number(),
FCH_EVT_RSCN, lp[i]);
@@ -2834,8 +2785,7 @@
"RCV RSCN ignore: did:x%x/ste:x%x flg:x%x",
ndlp->nlp_DID, vport->port_state, ndlp->nlp_flag);
- lpfc_els_rsp_acc(vport, ELS_CMD_ACC, cmdiocb, ndlp, NULL,
- newnode);
+ lpfc_els_rsp_acc(vport, ELS_CMD_ACC, cmdiocb, ndlp, NULL);
return 0;
}
@@ -2843,7 +2793,7 @@
* just ACC and ignore it.
*/
if ((phba->sli3_options & LPFC_SLI3_NPIV_ENABLED) &&
- !(phba->cfg_peer_port_login)) {
+ !(vport->cfg_peer_port_login)) {
i = payload_len;
datap = lp;
while (i > 0) {
@@ -2851,28 +2801,23 @@
nportid = ((be32_to_cpu(nportid)) & Mask_DID);
i -= sizeof(uint32_t);
rscn_id++;
- list_for_each_entry(next_vport, &phba->port_list,
- listentry) {
- if (nportid == next_vport->fc_myDID) {
- hba_id++;
- break;
- }
- }
+ if (lpfc_find_vport_by_did(phba, nportid))
+ hba_id++;
}
if (rscn_id == hba_id) {
/* ALL NPortIDs in RSCN are on HBA */
- lpfc_printf_log(phba, KERN_INFO, LOG_DISCOVERY,
- "%d (%d):0214 Ignore RSCN Data: x%x x%x x%x x%x\n",
- phba->brd_no, vport->vpi, vport->fc_flag, payload_len,
- *lp, rscn_cnt);
-
+ lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,
+ "0214 Ignore RSCN "
+ "Data: x%x x%x x%x x%x\n",
+ vport->fc_flag, payload_len,
+ *lp, rscn_cnt);
lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL,
"RCV RSCN vport: did:x%x/ste:x%x flg:x%x",
ndlp->nlp_DID, vport->port_state,
ndlp->nlp_flag);
lpfc_els_rsp_acc(vport, ELS_CMD_ACC, cmdiocb,
- ndlp, NULL, newnode);
+ ndlp, NULL);
return 0;
}
}
@@ -2911,27 +2856,24 @@
}
/* Deferred RSCN */
- lpfc_printf_log(phba, KERN_INFO, LOG_DISCOVERY,
- "%d (%d):0235 Deferred RSCN "
- "Data: x%x x%x x%x\n",
- phba->brd_no, vport->vpi,
- vport->fc_rscn_id_cnt, vport->fc_flag,
- vport->port_state);
+ lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,
+ "0235 Deferred RSCN "
+ "Data: x%x x%x x%x\n",
+ vport->fc_rscn_id_cnt, vport->fc_flag,
+ vport->port_state);
} else {
spin_lock_irq(shost->host_lock);
vport->fc_flag |= FC_RSCN_DISCOVERY;
spin_unlock_irq(shost->host_lock);
/* ReDiscovery RSCN */
- lpfc_printf_log(phba, KERN_INFO, LOG_DISCOVERY,
- "%d (%d):0234 ReDiscovery RSCN "
- "Data: x%x x%x x%x\n",
- phba->brd_no, vport->vpi,
- vport->fc_rscn_id_cnt, vport->fc_flag,
- vport->port_state);
+ lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,
+ "0234 ReDiscovery RSCN "
+ "Data: x%x x%x x%x\n",
+ vport->fc_rscn_id_cnt, vport->fc_flag,
+ vport->port_state);
}
/* Send back ACC */
- lpfc_els_rsp_acc(vport, ELS_CMD_ACC, cmdiocb, ndlp, NULL,
- newnode);
+ lpfc_els_rsp_acc(vport, ELS_CMD_ACC, cmdiocb, ndlp, NULL);
/* send RECOVERY event for ALL nodes that match RSCN payload */
lpfc_rscn_recovery_check(vport);
@@ -2956,7 +2898,7 @@
lpfc_set_disctmo(vport);
/* Send back ACC */
- lpfc_els_rsp_acc(vport, ELS_CMD_ACC, cmdiocb, ndlp, NULL, newnode);
+ lpfc_els_rsp_acc(vport, ELS_CMD_ACC, cmdiocb, ndlp, NULL);
/* send RECOVERY event for ALL nodes that match RSCN payload */
lpfc_rscn_recovery_check(vport);
@@ -2980,11 +2922,10 @@
lpfc_set_disctmo(vport);
/* RSCN processed */
- lpfc_printf_log(phba, KERN_INFO, LOG_DISCOVERY,
- "%d (%d):0215 RSCN processed Data: x%x x%x x%x x%x\n",
- phba->brd_no, vport->vpi,
- vport->fc_flag, 0, vport->fc_rscn_id_cnt,
- vport->port_state);
+ lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,
+ "0215 RSCN processed Data: x%x x%x x%x x%x\n",
+ vport->fc_flag, 0, vport->fc_rscn_id_cnt,
+ vport->port_state);
/* To process RSCN, first compare RSCN data with NameServer */
vport->fc_ns_retry = 0;
@@ -3026,7 +2967,7 @@
static int
lpfc_els_rcv_flogi(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
- struct lpfc_nodelist *ndlp, uint8_t newnode)
+ struct lpfc_nodelist *ndlp)
{
struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
struct lpfc_hba *phba = vport->phba;
@@ -3052,10 +2993,10 @@
/* An FLOGI ELS command <elsCmd> was received from DID <did> in
Loop Mode */
- lpfc_printf_log(phba, KERN_ERR, LOG_ELS,
- "%d (%d):0113 An FLOGI ELS command x%x was "
- "received from DID x%x in Loop Mode\n",
- phba->brd_no, vport->vpi, cmd, did);
+ lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS,
+ "0113 An FLOGI ELS command x%x was "
+ "received from DID x%x in Loop Mode\n",
+ cmd, did);
return 1;
}
@@ -3109,7 +3050,7 @@
}
/* Send back ACC */
- lpfc_els_rsp_acc(vport, ELS_CMD_PLOGI, cmdiocb, ndlp, NULL, newnode);
+ lpfc_els_rsp_acc(vport, ELS_CMD_PLOGI, cmdiocb, ndlp, NULL);
return 0;
}
@@ -3226,16 +3167,13 @@
rps_rsp->primSeqErrCnt = be32_to_cpu(mb->un.varRdLnk.primSeqErrCnt);
rps_rsp->invalidXmitWord = be32_to_cpu(mb->un.varRdLnk.invalidXmitWord);
rps_rsp->crcCnt = be32_to_cpu(mb->un.varRdLnk.crcCnt);
-
/* Xmit ELS RPS ACC response tag <ulpIoTag> */
- lpfc_printf_log(phba, KERN_INFO, LOG_ELS,
- "%d (%d):0118 Xmit ELS RPS ACC response tag x%x "
- "xri x%x, did x%x, nlp_flag x%x, nlp_state x%x, "
- "rpi x%x\n",
- phba->brd_no, ndlp->vport->vpi, elsiocb->iotag,
- elsiocb->iocb.ulpContext, ndlp->nlp_DID,
- ndlp->nlp_flag, ndlp->nlp_state, ndlp->nlp_rpi);
-
+ lpfc_printf_vlog(ndlp->vport, KERN_INFO, LOG_ELS,
+ "0118 Xmit ELS RPS ACC response tag x%x xri x%x, "
+ "did x%x, nlp_flag x%x, nlp_state x%x, rpi x%x\n",
+ elsiocb->iotag, elsiocb->iocb.ulpContext,
+ ndlp->nlp_DID, ndlp->nlp_flag, ndlp->nlp_state,
+ ndlp->nlp_rpi);
elsiocb->iocb_cmpl = lpfc_cmpl_els_rsp;
phba->fc_stat.elsXmitACC++;
if (lpfc_sli_issue_iocb(phba, pring, elsiocb, 0) == IOCB_ERROR)
@@ -3337,21 +3275,16 @@
rpl_rsp.port_num_blk.portID = be32_to_cpu(vport->fc_myDID);
memcpy(&rpl_rsp.port_num_blk.portName, &vport->fc_portname,
sizeof(struct lpfc_name));
-
memcpy(pcmd, &rpl_rsp, cmdsize - sizeof(uint32_t));
-
-
/* Xmit ELS RPL ACC response tag <ulpIoTag> */
- lpfc_printf_log(phba, KERN_INFO, LOG_ELS,
- "%d (%d):0120 Xmit ELS RPL ACC response tag x%x "
- "xri x%x, did x%x, nlp_flag x%x, nlp_state x%x, "
- "rpi x%x\n",
- phba->brd_no, vport->vpi, elsiocb->iotag,
- elsiocb->iocb.ulpContext, ndlp->nlp_DID,
- ndlp->nlp_flag, ndlp->nlp_state, ndlp->nlp_rpi);
-
+ lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
+ "0120 Xmit ELS RPL ACC response tag x%x "
+ "xri x%x, did x%x, nlp_flag x%x, nlp_state x%x, "
+ "rpi x%x\n",
+ elsiocb->iotag, elsiocb->iocb.ulpContext,
+ ndlp->nlp_DID, ndlp->nlp_flag, ndlp->nlp_state,
+ ndlp->nlp_rpi);
elsiocb->iocb_cmpl = lpfc_cmpl_els_rsp;
-
phba->fc_stat.elsXmitACC++;
if (lpfc_sli_issue_iocb(phba, pring, elsiocb, 0) == IOCB_ERROR) {
lpfc_els_free_iocb(phba, elsiocb);
@@ -3404,7 +3337,6 @@
lpfc_els_rcv_farp(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
struct lpfc_nodelist *ndlp)
{
- struct lpfc_hba *phba = vport->phba;
struct lpfc_dmabuf *pcmd;
uint32_t *lp;
IOCB_t *icmd;
@@ -3418,12 +3350,9 @@
cmd = *lp++;
fp = (FARP *) lp;
-
/* FARP-REQ received from DID <did> */
- lpfc_printf_log(phba, KERN_INFO, LOG_ELS,
- "%d (%d):0601 FARP-REQ received from DID x%x\n",
- phba->brd_no, vport->vpi, did);
-
+ lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
+ "0601 FARP-REQ received from DID x%x\n", did);
/* We will only support match on WWPN or WWNN */
if (fp->Mflags & ~(FARP_MATCH_NODE | FARP_MATCH_PORT)) {
return 0;
@@ -3471,7 +3400,6 @@
uint32_t *lp;
IOCB_t *icmd;
uint32_t cmd, did;
- struct lpfc_hba *phba = vport->phba;
icmd = &cmdiocb->iocb;
did = icmd->un.elsreq64.remoteID;
@@ -3480,11 +3408,10 @@
cmd = *lp++;
/* FARP-RSP received from DID <did> */
- lpfc_printf_log(phba, KERN_INFO, LOG_ELS,
- "%d (%d):0600 FARP-RSP received from DID x%x\n",
- phba->brd_no, vport->vpi, did);
+ lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
+ "0600 FARP-RSP received from DID x%x\n", did);
/* ACCEPT the Farp resp request */
- lpfc_els_rsp_acc(vport, ELS_CMD_ACC, cmdiocb, ndlp, NULL, 0);
+ lpfc_els_rsp_acc(vport, ELS_CMD_ACC, cmdiocb, ndlp, NULL);
return 0;
}
@@ -3502,10 +3429,8 @@
struct lpfc_hba *phba = vport->phba;
/* FAN received */
- lpfc_printf_log(phba, KERN_INFO, LOG_ELS,
- "%d (%d):0265 FAN received\n",
- phba->brd_no, vport->vpi);
-
+ lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
+ "0265 FAN received\n");
icmd = &cmdiocb->iocb;
did = icmd->un.elsreq64.remoteID;
pcmd = (struct lpfc_dmabuf *)cmdiocb->context2;
@@ -3664,13 +3589,10 @@
if (ndlp)
remote_ID = ndlp->nlp_DID;
}
-
- lpfc_printf_log(phba, KERN_ERR, LOG_ELS,
- "%d (%d):0127 ELS timeout Data: x%x x%x x%x "
- "x%x\n",
- phba->brd_no, vport->vpi, els_command,
- remote_ID, cmd->ulpCommand, cmd->ulpIoTag);
-
+ lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS,
+ "0127 ELS timeout Data: x%x x%x x%x "
+ "x%x\n", els_command,
+ remote_ID, cmd->ulpCommand, cmd->ulpIoTag);
lpfc_sli_issue_abort_iotag(phba, pring, piocb);
}
spin_unlock_irq(&phba->hbalock);
@@ -3741,6 +3663,50 @@
return;
}
+void
+lpfc_els_flush_all_cmd(struct lpfc_hba *phba)
+{
+ LIST_HEAD(completions);
+ struct lpfc_sli_ring *pring = &phba->sli.ring[LPFC_ELS_RING];
+ struct lpfc_iocbq *tmp_iocb, *piocb;
+ IOCB_t *cmd = NULL;
+
+ lpfc_fabric_abort_hba(phba);
+ spin_lock_irq(&phba->hbalock);
+ list_for_each_entry_safe(piocb, tmp_iocb, &pring->txq, list) {
+ cmd = &piocb->iocb;
+ if (piocb->iocb_flag & LPFC_IO_LIBDFC)
+ continue;
+ /* Do not flush out the QUE_RING and ABORT/CLOSE iocbs */
+ if (cmd->ulpCommand == CMD_QUE_RING_BUF_CN ||
+ cmd->ulpCommand == CMD_QUE_RING_BUF64_CN ||
+ cmd->ulpCommand == CMD_CLOSE_XRI_CN ||
+ cmd->ulpCommand == CMD_ABORT_XRI_CN)
+ continue;
+ list_move_tail(&piocb->list, &completions);
+ pring->txq_cnt--;
+ }
+ list_for_each_entry_safe(piocb, tmp_iocb, &pring->txcmplq, list) {
+ if (piocb->iocb_flag & LPFC_IO_LIBDFC)
+ continue;
+ lpfc_sli_issue_abort_iotag(phba, pring, piocb);
+ }
+ spin_unlock_irq(&phba->hbalock);
+ while (!list_empty(&completions)) {
+ piocb = list_get_first(&completions, struct lpfc_iocbq, list);
+ cmd = &piocb->iocb;
+ list_del_init(&piocb->list);
+ if (!piocb->iocb_cmpl)
+ lpfc_sli_release_iocbq(phba, piocb);
+ else {
+ cmd->ulpStatus = IOSTAT_LOCAL_REJECT;
+ cmd->un.ulpWord[4] = IOERR_SLI_ABORTED;
+ (piocb->iocb_cmpl) (phba, piocb, piocb);
+ }
+ }
+ return;
+}
+
static void
lpfc_els_unsol_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
struct lpfc_vport *vport, struct lpfc_iocbq *elsiocb)
@@ -3801,11 +3767,9 @@
cmd &= ELS_CMD_MASK;
}
/* ELS command <elsCmd> received from NPORT <did> */
- lpfc_printf_log(phba, KERN_INFO, LOG_ELS,
- "%d (%d):0112 ELS command x%x received from NPORT x%x "
- "Data: x%x\n", phba->brd_no, vport->vpi, cmd, did,
- vport->port_state);
-
+ lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
+ "0112 ELS command x%x received from NPORT x%x "
+ "Data: x%x\n", cmd, did, vport->port_state);
switch (cmd) {
case ELS_CMD_PLOGI:
lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL,
@@ -3829,7 +3793,7 @@
did, vport->port_state, ndlp->nlp_flag);
phba->fc_stat.elsRcvFLOGI++;
- lpfc_els_rcv_flogi(vport, elsiocb, ndlp, newnode);
+ lpfc_els_rcv_flogi(vport, elsiocb, ndlp);
if (newnode)
lpfc_drop_node(vport, ndlp);
break;
@@ -3859,7 +3823,7 @@
break;
case ELS_CMD_RSCN:
phba->fc_stat.elsRcvRSCN++;
- lpfc_els_rcv_rscn(vport, elsiocb, ndlp, newnode);
+ lpfc_els_rcv_rscn(vport, elsiocb, ndlp);
if (newnode)
lpfc_drop_node(vport, ndlp);
break;
@@ -3974,10 +3938,9 @@
rjt_err = LSRJT_INVALID_CMD;
/* Unknown ELS command <elsCmd> received from NPORT <did> */
- lpfc_printf_log(phba, KERN_ERR, LOG_ELS,
- "%d (%d):0115 Unknown ELS command x%x "
- "received from NPORT x%x\n",
- phba->brd_no, vport->vpi, cmd, did);
+ lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS,
+ "0115 Unknown ELS command x%x "
+ "received from NPORT x%x\n", cmd, did);
if (newnode)
lpfc_drop_node(vport, ndlp);
break;
@@ -3990,19 +3953,16 @@
stat.un.b.lsRjtRsnCodeExp = LSEXP_NOTHING_MORE;
lpfc_els_rsp_reject(vport, stat.un.lsRjtError, elsiocb, ndlp,
NULL);
- if (newnode)
- lpfc_drop_node(vport, ndlp);
}
return;
dropit:
lpfc_printf_log(phba, KERN_ERR, LOG_ELS,
- "%d (%d):0111 Dropping received ELS cmd "
+ "(%d):0111 Dropping received ELS cmd "
"Data: x%x x%x x%x\n",
- phba->brd_no, vport ? vport->vpi : 0xffff,
- icmd->ulpStatus, icmd->un.ulpWord[4],
- icmd->ulpTimeout);
+ vport ? vport->vpi : 0xffff, icmd->ulpStatus,
+ icmd->un.ulpWord[4], icmd->ulpTimeout);
phba->fc_stat.elsRcvDrop++;
}
@@ -4010,11 +3970,16 @@
lpfc_find_vport_by_vpid(struct lpfc_hba *phba, uint16_t vpi)
{
struct lpfc_vport *vport;
+ unsigned long flags;
+ spin_lock_irqsave(&phba->hbalock, flags);
list_for_each_entry(vport, &phba->port_list, listentry) {
- if (vport->vpi == vpi)
+ if (vport->vpi == vpi) {
+ spin_unlock_irqrestore(&phba->hbalock, flags);
return vport;
+ }
}
+ spin_unlock_irqrestore(&phba->hbalock, flags);
return NULL;
}
@@ -4109,9 +4074,8 @@
return;
}
lpfc_vport_set_state(vport, FC_VPORT_FAILED);
- lpfc_printf_log(phba, KERN_ERR, LOG_ELS,
- "%d (%d):0251 NameServer login: no memory\n",
- phba->brd_no, vport->vpi);
+ lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS,
+ "0251 NameServer login: no memory\n");
return;
}
lpfc_nlp_init(vport, ndlp, NameServer_DID);
@@ -4122,13 +4086,12 @@
if (lpfc_issue_els_plogi(vport, ndlp->nlp_DID, 0)) {
lpfc_vport_set_state(vport, FC_VPORT_FAILED);
- lpfc_printf_log(phba, KERN_ERR, LOG_ELS,
- "%d (%d):0252 Cannot issue NameServer login\n",
- phba->brd_no, vport->vpi);
+ lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS,
+ "0252 Cannot issue NameServer login\n");
return;
}
- if (phba->cfg_fdmi_on) {
+ if (vport->cfg_fdmi_on) {
ndlp_fdmi = mempool_alloc(phba->nlp_mem_pool,
GFP_KERNEL);
if (ndlp_fdmi) {
@@ -4155,9 +4118,9 @@
lpfc_nlp_put(ndlp);
if (mb->mbxStatus) {
- lpfc_printf_log(phba, KERN_ERR, LOG_MBOX,
- "%d (%d):0915 Register VPI failed: 0x%x\n",
- phba->brd_no, vport->vpi, mb->mbxStatus);
+ lpfc_printf_vlog(vport, KERN_ERR, LOG_MBOX,
+ "0915 Register VPI failed: 0x%x\n",
+ mb->mbxStatus);
switch (mb->mbxStatus) {
case 0x11: /* unsupported feature */
@@ -4206,17 +4169,14 @@
vport->fc_flag &= ~FC_VPORT_NEEDS_REG_VPI;
lpfc_vport_set_state(vport, FC_VPORT_FAILED);
-
- lpfc_printf_log(phba, KERN_ERR, LOG_MBOX,
- "%d (%d):0253 Register VPI: Cannot send mbox\n",
- phba->brd_no, vport->vpi);
+ lpfc_printf_vlog(vport, KERN_ERR, LOG_MBOX,
+ "0253 Register VPI: Can't send mbox\n");
}
} else {
lpfc_vport_set_state(vport, FC_VPORT_FAILED);
- lpfc_printf_log(phba, KERN_ERR, LOG_MBOX,
- "%d (%d):0254 Register VPI: no memory\n",
- phba->brd_no, vport->vpi);
+ lpfc_printf_vlog(vport, KERN_ERR, LOG_MBOX,
+ "0254 Register VPI: no memory\n");
vport->fc_flag &= ~FC_VPORT_NEEDS_REG_VPI;
lpfc_nlp_put(ndlp);
@@ -4235,11 +4195,10 @@
IOCB_t *irsp = &rspiocb->iocb;
struct lpfc_iocbq *piocb;
- lpfc_printf_log(phba, KERN_INFO, LOG_ELS,
- "%d (%d):0123 FDISC completes. x%x/x%x prevDID: x%x\n",
- phba->brd_no, vport->vpi,
- irsp->ulpStatus, irsp->un.ulpWord[4], vport->fc_prevDID);
-
+ lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
+ "0123 FDISC completes. x%x/x%x prevDID: x%x\n",
+ irsp->ulpStatus, irsp->un.ulpWord[4],
+ vport->fc_prevDID);
/* Since all FDISCs are being single threaded, we
* must reset the discovery timer for ALL vports
* waiting to send FDISC when one completes.
@@ -4256,13 +4215,10 @@
/* Check for retry */
if (lpfc_els_retry(phba, cmdiocb, rspiocb))
goto out;
-
/* FDISC failed */
- lpfc_printf_log(phba, KERN_ERR, LOG_ELS,
- "%d (%d):0124 FDISC failed. (%d/%d)\n",
- phba->brd_no, vport->vpi,
- irsp->ulpStatus, irsp->un.ulpWord[4]);
-
+ lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS,
+ "0124 FDISC failed. (%d/%d)\n",
+ irsp->ulpStatus, irsp->un.ulpWord[4]);
if (vport->fc_vport->vport_state == FC_VPORT_INITIALIZING)
lpfc_vport_set_state(vport, FC_VPORT_FAILED);
@@ -4328,10 +4284,8 @@
ELS_CMD_FDISC);
if (!elsiocb) {
lpfc_vport_set_state(vport, FC_VPORT_FAILED);
-
- lpfc_printf_log(phba, KERN_ERR, LOG_ELS,
- "%d (%d):0255 Issue FDISC: no IOCB\n",
- phba->brd_no, vport->vpi);
+ lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS,
+ "0255 Issue FDISC: no IOCB\n");
return 1;
}
@@ -4377,11 +4331,8 @@
if (rc == IOCB_ERROR) {
lpfc_els_free_iocb(phba, elsiocb);
lpfc_vport_set_state(vport, FC_VPORT_FAILED);
-
- lpfc_printf_log(phba, KERN_ERR, LOG_ELS,
- "%d (%d):0256 Issue FDISC: Cannot send IOCB\n",
- phba->brd_no, vport->vpi);
-
+ lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS,
+ "0256 Issue FDISC: Cannot send IOCB\n");
return 1;
}
lpfc_vport_set_state(vport, FC_VPORT_INITIALIZING);
diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c
index f2f4639..c81c2b3 100644
--- a/drivers/scsi/lpfc/lpfc_hbadisc.c
+++ b/drivers/scsi/lpfc/lpfc_hbadisc.c
@@ -83,10 +83,17 @@
ndlp->nlp_sid, ndlp->nlp_DID, ndlp->nlp_flag);
if (ndlp->nlp_sid != NLP_NO_SID) {
- lpfc_sli_abort_iocb(phba, &phba->sli.ring[phba->sli.fcp_ring],
- ndlp->nlp_sid, 0, 0, LPFC_CTX_TGT);
+ lpfc_sli_abort_iocb(ndlp->vport,
+ &phba->sli.ring[phba->sli.fcp_ring],
+ ndlp->nlp_sid, 0, LPFC_CTX_TGT);
}
+ /*
+ * A device is normally blocked for rediscovery and unblocked when
+ * devloss timeout happens. In case a vport is removed or driver
+ * unloaded before devloss timeout happens, we need to unblock here.
+ */
+ scsi_target_unblock(&rport->dev);
return;
}
@@ -194,32 +201,30 @@
if (ndlp->nlp_sid != NLP_NO_SID) {
warn_on = 1;
/* flush the target */
- lpfc_sli_abort_iocb(phba, &phba->sli.ring[phba->sli.fcp_ring],
- ndlp->nlp_sid, 0, 0, LPFC_CTX_TGT);
+ lpfc_sli_abort_iocb(vport, &phba->sli.ring[phba->sli.fcp_ring],
+ ndlp->nlp_sid, 0, LPFC_CTX_TGT);
}
if (vport->load_flag & FC_UNLOADING)
warn_on = 0;
if (warn_on) {
- lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY,
- "%d (%d):0203 Devloss timeout on "
- "WWPN %x:%x:%x:%x:%x:%x:%x:%x "
- "NPort x%x Data: x%x x%x x%x\n",
- phba->brd_no, vport->vpi,
- *name, *(name+1), *(name+2), *(name+3),
- *(name+4), *(name+5), *(name+6), *(name+7),
- ndlp->nlp_DID, ndlp->nlp_flag,
- ndlp->nlp_state, ndlp->nlp_rpi);
+ lpfc_printf_vlog(vport, KERN_ERR, LOG_DISCOVERY,
+ "0203 Devloss timeout on "
+ "WWPN %x:%x:%x:%x:%x:%x:%x:%x "
+ "NPort x%x Data: x%x x%x x%x\n",
+ *name, *(name+1), *(name+2), *(name+3),
+ *(name+4), *(name+5), *(name+6), *(name+7),
+ ndlp->nlp_DID, ndlp->nlp_flag,
+ ndlp->nlp_state, ndlp->nlp_rpi);
} else {
- lpfc_printf_log(phba, KERN_INFO, LOG_DISCOVERY,
- "%d (%d):0204 Devloss timeout on "
- "WWPN %x:%x:%x:%x:%x:%x:%x:%x "
- "NPort x%x Data: x%x x%x x%x\n",
- phba->brd_no, vport->vpi,
- *name, *(name+1), *(name+2), *(name+3),
- *(name+4), *(name+5), *(name+6), *(name+7),
- ndlp->nlp_DID, ndlp->nlp_flag,
- ndlp->nlp_state, ndlp->nlp_rpi);
+ lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,
+ "0204 Devloss timeout on "
+ "WWPN %x:%x:%x:%x:%x:%x:%x:%x "
+ "NPort x%x Data: x%x x%x x%x\n",
+ *name, *(name+1), *(name+2), *(name+3),
+ *(name+4), *(name+5), *(name+6), *(name+7),
+ ndlp->nlp_DID, ndlp->nlp_flag,
+ ndlp->nlp_state, ndlp->nlp_rpi);
}
if (!(vport->load_flag & FC_UNLOADING) &&
@@ -344,12 +349,14 @@
}
-void
+static void
lpfc_work_done(struct lpfc_hba *phba)
{
struct lpfc_sli_ring *pring;
uint32_t ha_copy, status, control, work_port_events;
+ struct lpfc_vport **vports;
struct lpfc_vport *vport;
+ int i;
spin_lock_irq(&phba->hbalock);
ha_copy = phba->work_ha;
@@ -364,48 +371,41 @@
if (ha_copy & HA_LATT)
lpfc_handle_latt(phba);
-
- spin_lock_irq(&phba->hbalock);
- list_for_each_entry(vport, &phba->port_list, listentry) {
- struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
-
- if (!scsi_host_get(shost)) {
- continue;
+ vports = lpfc_create_vport_work_array(phba);
+ if (vports != NULL)
+ for(i = 0; i < LPFC_MAX_VPORTS; i++) {
+ /*
+ * We could have no vports in array if unloading, so if
+ * this happens then just use the pport
+ */
+ if (vports[i] == NULL && i == 0)
+ vport = phba->pport;
+ else
+ vport = vports[i];
+ if (vport == NULL)
+ break;
+ work_port_events = vport->work_port_events;
+ if (work_port_events & WORKER_DISC_TMO)
+ lpfc_disc_timeout_handler(vport);
+ if (work_port_events & WORKER_ELS_TMO)
+ lpfc_els_timeout_handler(vport);
+ if (work_port_events & WORKER_HB_TMO)
+ lpfc_hb_timeout_handler(phba);
+ if (work_port_events & WORKER_MBOX_TMO)
+ lpfc_mbox_timeout_handler(phba);
+ if (work_port_events & WORKER_FABRIC_BLOCK_TMO)
+ lpfc_unblock_fabric_iocbs(phba);
+ if (work_port_events & WORKER_FDMI_TMO)
+ lpfc_fdmi_timeout_handler(vport);
+ if (work_port_events & WORKER_RAMP_DOWN_QUEUE)
+ lpfc_ramp_down_queue_handler(phba);
+ if (work_port_events & WORKER_RAMP_UP_QUEUE)
+ lpfc_ramp_up_queue_handler(phba);
+ spin_lock_irq(&vport->work_port_lock);
+ vport->work_port_events &= ~work_port_events;
+ spin_unlock_irq(&vport->work_port_lock);
}
- spin_unlock_irq(&phba->hbalock);
- work_port_events = vport->work_port_events;
-
- if (work_port_events & WORKER_DISC_TMO)
- lpfc_disc_timeout_handler(vport);
-
- if (work_port_events & WORKER_ELS_TMO)
- lpfc_els_timeout_handler(vport);
-
- if (work_port_events & WORKER_HB_TMO)
- lpfc_hb_timeout_handler(phba);
-
- if (work_port_events & WORKER_MBOX_TMO)
- lpfc_mbox_timeout_handler(phba);
-
- if (work_port_events & WORKER_FABRIC_BLOCK_TMO)
- lpfc_unblock_fabric_iocbs(phba);
-
- if (work_port_events & WORKER_FDMI_TMO)
- lpfc_fdmi_timeout_handler(vport);
-
- if (work_port_events & WORKER_RAMP_DOWN_QUEUE)
- lpfc_ramp_down_queue_handler(phba);
-
- if (work_port_events & WORKER_RAMP_UP_QUEUE)
- lpfc_ramp_up_queue_handler(phba);
-
- spin_lock_irq(&vport->work_port_lock);
- vport->work_port_events &= ~work_port_events;
- spin_unlock_irq(&vport->work_port_lock);
- scsi_host_put(shost);
- spin_lock_irq(&phba->hbalock);
- }
- spin_unlock_irq(&phba->hbalock);
+ lpfc_destroy_vport_work_array(vports);
pring = &phba->sli.ring[LPFC_ELS_RING];
status = (ha_copy & (HA_RXMASK << (4*LPFC_ELS_RING)));
@@ -426,10 +426,19 @@
spin_lock_irq(&phba->hbalock);
control = readl(phba->HCregaddr);
if (!(control & (HC_R0INT_ENA << LPFC_ELS_RING))) {
+ lpfc_debugfs_slow_ring_trc(phba,
+ "WRK Enable ring: cntl:x%x hacopy:x%x",
+ control, ha_copy, 0);
+
control |= (HC_R0INT_ENA << LPFC_ELS_RING);
writel(control, phba->HCregaddr);
readl(phba->HCregaddr); /* flush */
}
+ else {
+ lpfc_debugfs_slow_ring_trc(phba,
+ "WRK Ring ok: cntl:x%x hacopy:x%x",
+ control, ha_copy, 0);
+ }
spin_unlock_irq(&phba->hbalock);
}
lpfc_work_list_done(phba);
@@ -439,32 +448,22 @@
check_work_wait_done(struct lpfc_hba *phba)
{
struct lpfc_vport *vport;
- struct lpfc_sli_ring *pring;
+ struct lpfc_sli_ring *pring = &phba->sli.ring[LPFC_ELS_RING];
int rc = 0;
spin_lock_irq(&phba->hbalock);
list_for_each_entry(vport, &phba->port_list, listentry) {
if (vport->work_port_events) {
rc = 1;
- goto exit;
+ break;
}
}
-
- if (phba->work_ha || (!list_empty(&phba->work_list)) ||
- kthread_should_stop()) {
+ if (rc || phba->work_ha || (!list_empty(&phba->work_list)) ||
+ kthread_should_stop() || pring->flag & LPFC_DEFERRED_RING_EVENT) {
rc = 1;
- goto exit;
- }
-
- pring = &phba->sli.ring[LPFC_ELS_RING];
- if (pring->flag & LPFC_DEFERRED_RING_EVENT)
- rc = 1;
-exit:
- if (rc)
phba->work_found++;
- else
+ } else
phba->work_found = 0;
-
spin_unlock_irq(&phba->hbalock);
return rc;
}
@@ -592,7 +591,6 @@
/* free any ndlp's on unused list */
list_for_each_entry_safe(ndlp, next_ndlp, &vport->fc_nodes, nlp_listp)
- /* free any ndlp's in unused state */
if (ndlp->nlp_state == NLP_STE_UNUSED_NODE)
lpfc_drop_node(vport, ndlp);
@@ -605,8 +603,9 @@
{
struct lpfc_vport *vport = phba->pport;
struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
- struct lpfc_vport *port_iterator;
+ struct lpfc_vport **vports;
LPFC_MBOXQ_t *mb;
+ int i;
if (phba->link_state == LPFC_LINK_DOWN) {
return 0;
@@ -617,13 +616,13 @@
phba->pport->fc_flag &= ~FC_LBIT;
}
spin_unlock_irq(&phba->hbalock);
-
- list_for_each_entry(port_iterator, &phba->port_list, listentry) {
-
- /* Issue a LINK DOWN event to all nodes */
- lpfc_linkdown_port(port_iterator);
- }
-
+ vports = lpfc_create_vport_work_array(phba);
+ if (vports != NULL)
+ for(i = 0; i < LPFC_MAX_VPORTS && vports[i] != NULL; i++) {
+ /* Issue a LINK DOWN event to all nodes */
+ lpfc_linkdown_port(vports[i]);
+ }
+ lpfc_destroy_vport_work_array(vports);
/* Clean up any firmware default rpi's */
mb = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
if (mb) {
@@ -724,7 +723,8 @@
static int
lpfc_linkup(struct lpfc_hba *phba)
{
- struct lpfc_vport *vport;
+ struct lpfc_vport **vports;
+ int i;
phba->link_state = LPFC_LINK_UP;
@@ -732,9 +732,11 @@
clear_bit(FABRIC_COMANDS_BLOCKED, &phba->bit_flags);
del_timer_sync(&phba->fabric_block_timer);
- list_for_each_entry(vport, &phba->port_list, listentry) {
- lpfc_linkup_port(vport);
- }
+ vports = lpfc_create_vport_work_array(phba);
+ if (vports != NULL)
+ for(i = 0; i < LPFC_MAX_VPORTS && vports[i] != NULL; i++)
+ lpfc_linkup_port(vports[i]);
+ lpfc_destroy_vport_work_array(vports);
if (phba->sli3_options & LPFC_SLI3_NPIV_ENABLED)
lpfc_issue_clear_la(phba, phba->pport);
@@ -764,12 +766,10 @@
/* Check for error */
if ((mb->mbxStatus) && (mb->mbxStatus != 0x1601)) {
/* CLEAR_LA mbox error <mbxStatus> state <hba_state> */
- lpfc_printf_log(phba, KERN_ERR, LOG_MBOX,
- "%d (%d):0320 CLEAR_LA mbxStatus error x%x hba "
- "state x%x\n",
- phba->brd_no, vport->vpi, mb->mbxStatus,
- vport->port_state);
-
+ lpfc_printf_vlog(vport, KERN_ERR, LOG_MBOX,
+ "0320 CLEAR_LA mbxStatus error x%x hba "
+ "state x%x\n",
+ mb->mbxStatus, vport->port_state);
phba->link_state = LPFC_HBA_ERROR;
goto out;
}
@@ -801,10 +801,8 @@
out:
/* Device Discovery completes */
- lpfc_printf_log(phba, KERN_INFO, LOG_DISCOVERY,
- "%d (%d):0225 Device Discovery completes\n",
- phba->brd_no, vport->vpi);
-
+ lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,
+ "0225 Device Discovery completes\n");
mempool_free(pmb, phba->mbox_mem_pool);
spin_lock_irq(shost->host_lock);
@@ -861,19 +859,17 @@
return;
out:
- lpfc_printf_log(phba, KERN_ERR, LOG_MBOX,
- "%d (%d):0306 CONFIG_LINK mbxStatus error x%x "
- "HBA state x%x\n",
- phba->brd_no, vport->vpi, pmb->mb.mbxStatus,
- vport->port_state);
-
+ lpfc_printf_vlog(vport, KERN_ERR, LOG_MBOX,
+ "0306 CONFIG_LINK mbxStatus error x%x "
+ "HBA state x%x\n",
+ pmb->mb.mbxStatus, vport->port_state);
mempool_free(pmb, phba->mbox_mem_pool);
lpfc_linkdown(phba);
- lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY,
- "%d (%d):0200 CONFIG_LINK bad hba state x%x\n",
- phba->brd_no, vport->vpi, vport->port_state);
+ lpfc_printf_vlog(vport, KERN_ERR, LOG_DISCOVERY,
+ "0200 CONFIG_LINK bad hba state x%x\n",
+ vport->port_state);
lpfc_issue_clear_la(phba, vport);
return;
@@ -890,12 +886,10 @@
/* Check for error */
if (mb->mbxStatus) {
/* READ_SPARAM mbox error <mbxStatus> state <hba_state> */
- lpfc_printf_log(phba, KERN_ERR, LOG_MBOX,
- "%d (%d):0319 READ_SPARAM mbxStatus error x%x "
- "hba state x%x>\n",
- phba->brd_no, vport->vpi, mb->mbxStatus,
- vport->port_state);
-
+ lpfc_printf_vlog(vport, KERN_ERR, LOG_MBOX,
+ "0319 READ_SPARAM mbxStatus error x%x "
+ "hba state x%x>\n",
+ mb->mbxStatus, vport->port_state);
lpfc_linkdown(phba);
goto out;
}
@@ -978,7 +972,7 @@
if (i == 0) {
phba->alpa_map[0] = 0;
} else {
- if (phba->cfg_log_verbose & LOG_LINK_EVENT) {
+ if (vport->cfg_log_verbose & LOG_LINK_EVENT) {
int numalpa, j, k;
union {
uint8_t pamap[16];
@@ -1004,10 +998,9 @@
lpfc_printf_log(phba,
KERN_WARNING,
LOG_LINK_EVENT,
- "%d:1304 Link Up Event "
+ "1304 Link Up Event "
"ALPA map Data: x%x "
"x%x x%x x%x\n",
- phba->brd_no,
un.pa.wd1, un.pa.wd2,
un.pa.wd3, un.pa.wd4);
}
@@ -1015,7 +1008,7 @@
}
} else {
if (!(phba->sli3_options & LPFC_SLI3_NPIV_ENABLED)) {
- if (phba->max_vpi && phba->cfg_npiv_enable &&
+ if (phba->max_vpi && phba->cfg_enable_npiv &&
(phba->sli_rev == 3))
phba->sli3_options |= LPFC_SLI3_NPIV_ENABLED;
}
@@ -1055,11 +1048,9 @@
}
out:
lpfc_vport_set_state(vport, FC_VPORT_FAILED);
- lpfc_printf_log(phba, KERN_ERR, LOG_MBOX,
- "%d (%d):0263 Discovery Mailbox error: state: 0x%x : %p %p\n",
- phba->brd_no, vport->vpi,
- vport->port_state, sparam_mbox, cfglink_mbox);
-
+ lpfc_printf_vlog(vport, KERN_ERR, LOG_MBOX,
+ "0263 Discovery Mailbox error: state: 0x%x : %p %p\n",
+ vport->port_state, sparam_mbox, cfglink_mbox);
lpfc_issue_clear_la(phba, vport);
return;
}
@@ -1100,8 +1091,8 @@
/* Check for error */
if (mb->mbxStatus) {
lpfc_printf_log(phba, KERN_INFO, LOG_LINK_EVENT,
- "%d:1307 READ_LA mbox error x%x state x%x\n",
- phba->brd_no, mb->mbxStatus, vport->port_state);
+ "1307 READ_LA mbox error x%x state x%x\n",
+ mb->mbxStatus, vport->port_state);
lpfc_mbx_issue_link_down(phba);
phba->link_state = LPFC_HBA_ERROR;
goto lpfc_mbx_cmpl_read_la_free_mbuf;
@@ -1132,26 +1123,26 @@
phba->fc_stat.LinkUp++;
if (phba->link_flag & LS_LOOPBACK_MODE) {
lpfc_printf_log(phba, KERN_INFO, LOG_LINK_EVENT,
- "%d:1306 Link Up Event in loop back mode "
- "x%x received Data: x%x x%x x%x x%x\n",
- phba->brd_no, la->eventTag, phba->fc_eventTag,
- la->granted_AL_PA, la->UlnkSpeed,
- phba->alpa_map[0]);
+ "1306 Link Up Event in loop back mode "
+ "x%x received Data: x%x x%x x%x x%x\n",
+ la->eventTag, phba->fc_eventTag,
+ la->granted_AL_PA, la->UlnkSpeed,
+ phba->alpa_map[0]);
} else {
lpfc_printf_log(phba, KERN_ERR, LOG_LINK_EVENT,
- "%d:1303 Link Up Event x%x received "
- "Data: x%x x%x x%x x%x\n",
- phba->brd_no, la->eventTag, phba->fc_eventTag,
- la->granted_AL_PA, la->UlnkSpeed,
- phba->alpa_map[0]);
+ "1303 Link Up Event x%x received "
+ "Data: x%x x%x x%x x%x\n",
+ la->eventTag, phba->fc_eventTag,
+ la->granted_AL_PA, la->UlnkSpeed,
+ phba->alpa_map[0]);
}
lpfc_mbx_process_link_up(phba, la);
} else {
phba->fc_stat.LinkDown++;
lpfc_printf_log(phba, KERN_ERR, LOG_LINK_EVENT,
- "%d:1305 Link Down Event x%x received "
+ "1305 Link Down Event x%x received "
"Data: x%x x%x x%x\n",
- phba->brd_no, la->eventTag, phba->fc_eventTag,
+ la->eventTag, phba->fc_eventTag,
phba->pport->port_state, vport->fc_flag);
lpfc_mbx_issue_link_down(phba);
}
@@ -1199,10 +1190,9 @@
case 0x0011:
case 0x0020:
case 0x9700:
- lpfc_printf_log(phba, KERN_INFO, LOG_NODE,
- "%d (%d):0911 cmpl_unreg_vpi, "
- "mb status = 0x%x\n",
- phba->brd_no, vport->vpi, mb->mbxStatus);
+ lpfc_printf_vlog(vport, KERN_INFO, LOG_NODE,
+ "0911 cmpl_unreg_vpi, mb status = 0x%x\n",
+ mb->mbxStatus);
break;
}
vport->unreg_vpi_cmpl = VPORT_OK;
@@ -1231,9 +1221,8 @@
mbox->mbox_cmpl = lpfc_mbx_cmpl_unreg_vpi;
rc = lpfc_sli_issue_mbox(phba, mbox, (MBX_NOWAIT | MBX_STOP_IOCB));
if (rc == MBX_NOT_FINISHED) {
- lpfc_printf_log(phba, KERN_ERR, LOG_MBOX | LOG_VPORT,
- "%d (%d):1800 Could not issue unreg_vpi\n",
- phba->brd_no, vport->vpi);
+ lpfc_printf_vlog(vport, KERN_ERR, LOG_MBOX | LOG_VPORT,
+ "1800 Could not issue unreg_vpi\n");
mempool_free(mbox, phba->mbox_mem_pool);
vport->unreg_vpi_cmpl = VPORT_ERROR;
}
@@ -1250,9 +1239,9 @@
case 0x0011:
case 0x9601:
case 0x9602:
- lpfc_printf_log(phba, KERN_INFO, LOG_NODE,
- "%d (%d):0912 cmpl_reg_vpi, mb status = 0x%x\n",
- phba->brd_no, vport->vpi, mb->mbxStatus);
+ lpfc_printf_vlog(vport, KERN_INFO, LOG_NODE,
+ "0912 cmpl_reg_vpi, mb status = 0x%x\n",
+ mb->mbxStatus);
lpfc_vport_set_state(vport, FC_VPORT_FAILED);
spin_lock_irq(shost->host_lock);
vport->fc_flag &= ~(FC_FABRIC | FC_PUBLIC_LOOP);
@@ -1289,15 +1278,15 @@
lpfc_mbx_cmpl_fabric_reg_login(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
{
struct lpfc_vport *vport = pmb->vport;
- struct lpfc_vport *next_vport;
MAILBOX_t *mb = &pmb->mb;
struct lpfc_dmabuf *mp = (struct lpfc_dmabuf *) (pmb->context1);
struct lpfc_nodelist *ndlp;
- ndlp = (struct lpfc_nodelist *) pmb->context2;
+ struct lpfc_vport **vports;
+ int i;
+ ndlp = (struct lpfc_nodelist *) pmb->context2;
pmb->context1 = NULL;
pmb->context2 = NULL;
-
if (mb->mbxStatus) {
lpfc_mbuf_free(phba, mp->virt, mp->phys);
kfree(mp);
@@ -1314,10 +1303,9 @@
}
lpfc_vport_set_state(vport, FC_VPORT_FAILED);
- lpfc_printf_log(phba, KERN_ERR, LOG_MBOX,
- "%d (%d):0258 Register Fabric login error: 0x%x\n",
- phba->brd_no, vport->vpi, mb->mbxStatus);
-
+ lpfc_printf_vlog(vport, KERN_ERR, LOG_MBOX,
+ "0258 Register Fabric login error: 0x%x\n",
+ mb->mbxStatus);
return;
}
@@ -1328,21 +1316,26 @@
lpfc_nlp_put(ndlp); /* Drop the reference from the mbox */
if (vport->port_state == LPFC_FABRIC_CFG_LINK) {
- list_for_each_entry(next_vport, &phba->port_list, listentry) {
- if (next_vport->port_type == LPFC_PHYSICAL_PORT)
- continue;
-
- if (phba->link_flag & LS_NPIV_FAB_SUPPORTED)
- lpfc_initial_fdisc(next_vport);
- else if (phba->sli3_options & LPFC_SLI3_NPIV_ENABLED) {
- lpfc_vport_set_state(vport,
- FC_VPORT_NO_FABRIC_SUPP);
- lpfc_printf_log(phba, KERN_ERR, LOG_ELS,
- "%d (%d):0259 No NPIV Fabric "
- "support\n",
- phba->brd_no, vport->vpi);
+ vports = lpfc_create_vport_work_array(phba);
+ if (vports != NULL)
+ for(i = 0;
+ i < LPFC_MAX_VPORTS && vports[i] != NULL;
+ i++) {
+ if (vports[i]->port_type == LPFC_PHYSICAL_PORT)
+ continue;
+ if (phba->link_flag & LS_NPIV_FAB_SUPPORTED)
+ lpfc_initial_fdisc(vports[i]);
+ else if (phba->sli3_options &
+ LPFC_SLI3_NPIV_ENABLED) {
+ lpfc_vport_set_state(vports[i],
+ FC_VPORT_NO_FABRIC_SUPP);
+ lpfc_printf_vlog(vport, KERN_ERR,
+ LOG_ELS,
+ "0259 No NPIV "
+ "Fabric support\n");
+ }
}
- }
+ lpfc_destroy_vport_work_array(vports);
lpfc_do_scr_ns_plogi(phba, vport);
}
@@ -1386,9 +1379,9 @@
return;
}
lpfc_vport_set_state(vport, FC_VPORT_FAILED);
- lpfc_printf_log(phba, KERN_ERR, LOG_ELS,
- "%d (%d):0260 Register NameServer error: 0x%x\n",
- phba->brd_no, vport->vpi, mb->mbxStatus);
+ lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS,
+ "0260 Register NameServer error: 0x%x\n",
+ mb->mbxStatus);
return;
}
@@ -1598,7 +1591,7 @@
[NLP_STE_NPR_NODE] = "NPR",
};
- if (state < ARRAY_SIZE(states) && states[state])
+ if (state < NLP_STE_MAX_STATE && states[state])
strlcpy(buffer, states[state], size);
else
snprintf(buffer, size, "unknown (%d)", state);
@@ -1613,12 +1606,11 @@
int old_state = ndlp->nlp_state;
char name1[16], name2[16];
- lpfc_printf_log(vport->phba, KERN_INFO, LOG_NODE,
- "%d (%d):0904 NPort state transition x%06x, %s -> %s\n",
- vport->phba->brd_no, vport->vpi,
- ndlp->nlp_DID,
- lpfc_nlp_state_name(name1, sizeof(name1), old_state),
- lpfc_nlp_state_name(name2, sizeof(name2), state));
+ lpfc_printf_vlog(vport, KERN_INFO, LOG_NODE,
+ "0904 NPort state transition x%06x, %s -> %s\n",
+ ndlp->nlp_DID,
+ lpfc_nlp_state_name(name1, sizeof(name1), old_state),
+ lpfc_nlp_state_name(name2, sizeof(name2), state));
lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_NODE,
"node statechg did:x%x old:%d ste:%d",
@@ -1664,16 +1656,7 @@
void
lpfc_drop_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)
{
- struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
-
- if ((ndlp->nlp_flag & NLP_DELAY_TMO) != 0)
- lpfc_cancel_retry_delay_tmo(vport, ndlp);
- if (ndlp->nlp_state && !list_empty(&ndlp->nlp_listp))
- lpfc_nlp_counters(vport, ndlp->nlp_state, -1);
- spin_lock_irq(shost->host_lock);
- list_del_init(&ndlp->nlp_listp);
- ndlp->nlp_flag &= ~NLP_TARGET_REMOVE;
- spin_unlock_irq(shost->host_lock);
+ lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNUSED_NODE);
lpfc_nlp_put(ndlp);
}
@@ -1710,12 +1693,12 @@
spin_unlock_irq(shost->host_lock);
/* Start Discovery Timer state <hba_state> */
- lpfc_printf_log(phba, KERN_INFO, LOG_DISCOVERY,
- "%d (%d):0247 Start Discovery Timer state x%x "
- "Data: x%x x%lx x%x x%x\n",
- phba->brd_no, vport->vpi, vport->port_state, tmo,
- (unsigned long)&vport->fc_disctmo, vport->fc_plogi_cnt,
- vport->fc_adisc_cnt);
+ lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,
+ "0247 Start Discovery Timer state x%x "
+ "Data: x%x x%lx x%x x%x\n",
+ vport->port_state, tmo,
+ (unsigned long)&vport->fc_disctmo, vport->fc_plogi_cnt,
+ vport->fc_adisc_cnt);
return;
}
@@ -1727,7 +1710,6 @@
lpfc_can_disctmo(struct lpfc_vport *vport)
{
struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
- struct lpfc_hba *phba = vport->phba;
unsigned long iflags;
lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_CMD,
@@ -1746,13 +1728,11 @@
}
/* Cancel Discovery Timer state <hba_state> */
- lpfc_printf_log(phba, KERN_INFO, LOG_DISCOVERY,
- "%d (%d):0248 Cancel Discovery Timer state x%x "
- "Data: x%x x%x x%x\n",
- phba->brd_no, vport->vpi, vport->port_state,
- vport->fc_flag, vport->fc_plogi_cnt,
- vport->fc_adisc_cnt);
-
+ lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,
+ "0248 Cancel Discovery Timer state x%x "
+ "Data: x%x x%x x%x\n",
+ vport->port_state, vport->fc_flag,
+ vport->fc_plogi_cnt, vport->fc_adisc_cnt);
return 0;
}
@@ -1935,10 +1915,9 @@
rc = lpfc_sli_issue_mbox(phba, mbox,
(MBX_NOWAIT | MBX_STOP_IOCB));
if (rc == MBX_NOT_FINISHED) {
- lpfc_printf_log(phba, KERN_ERR, LOG_MBOX | LOG_VPORT,
- "%d (%d):1815 Could not issue "
- "unreg_did (default rpis)\n",
- phba->brd_no, vport->vpi);
+ lpfc_printf_vlog(vport, KERN_ERR, LOG_MBOX | LOG_VPORT,
+ "1815 Could not issue "
+ "unreg_did (default rpis)\n");
mempool_free(mbox, phba->mbox_mem_pool);
}
}
@@ -1957,12 +1936,11 @@
struct lpfc_dmabuf *mp;
/* Cleanup node for NPort <nlp_DID> */
- lpfc_printf_log(phba, KERN_INFO, LOG_NODE,
- "%d (%d):0900 Cleanup node for NPort x%x "
- "Data: x%x x%x x%x\n",
- phba->brd_no, vport->vpi, ndlp->nlp_DID, ndlp->nlp_flag,
- ndlp->nlp_state, ndlp->nlp_rpi);
-
+ lpfc_printf_vlog(vport, KERN_INFO, LOG_NODE,
+ "0900 Cleanup node for NPort x%x "
+ "Data: x%x x%x x%x\n",
+ ndlp->nlp_DID, ndlp->nlp_flag,
+ ndlp->nlp_state, ndlp->nlp_rpi);
lpfc_dequeue_node(vport, ndlp);
/* cleanup any ndlp on mbox q waiting for reglogin cmpl */
@@ -2094,7 +2072,6 @@
static struct lpfc_nodelist *
__lpfc_findnode_did(struct lpfc_vport *vport, uint32_t did)
{
- struct lpfc_hba *phba = vport->phba;
struct lpfc_nodelist *ndlp;
uint32_t data1;
@@ -2104,20 +2081,18 @@
((uint32_t) ndlp->nlp_xri << 16) |
((uint32_t) ndlp->nlp_type << 8) |
((uint32_t) ndlp->nlp_rpi & 0xff));
- lpfc_printf_log(phba, KERN_INFO, LOG_NODE,
- "%d (%d):0929 FIND node DID "
- " Data: x%p x%x x%x x%x\n",
- phba->brd_no, vport->vpi,
- ndlp, ndlp->nlp_DID,
- ndlp->nlp_flag, data1);
+ lpfc_printf_vlog(vport, KERN_INFO, LOG_NODE,
+ "0929 FIND node DID "
+ "Data: x%p x%x x%x x%x\n",
+ ndlp, ndlp->nlp_DID,
+ ndlp->nlp_flag, data1);
return ndlp;
}
}
/* FIND node did <did> NOT FOUND */
- lpfc_printf_log(phba, KERN_INFO, LOG_NODE,
- "%d (%d):0932 FIND node did x%x NOT FOUND.\n",
- phba->brd_no, vport->vpi, did);
+ lpfc_printf_vlog(vport, KERN_INFO, LOG_NODE,
+ "0932 FIND node did x%x NOT FOUND.\n", did);
return NULL;
}
@@ -2208,7 +2183,7 @@
/* If cfg_scan_down is set, start from highest
* ALPA (0xef) to lowest (0x1).
*/
- if (phba->cfg_scan_down)
+ if (vport->cfg_scan_down)
index = j;
else
index = FC_MAXLOOP - j - 1;
@@ -2309,12 +2284,11 @@
vport->num_disc_nodes = 0;
/* Start Discovery state <hba_state> */
- lpfc_printf_log(phba, KERN_INFO, LOG_DISCOVERY,
- "%d (%d):0202 Start Discovery hba state x%x "
- "Data: x%x x%x x%x\n",
- phba->brd_no, vport->vpi, vport->port_state,
- vport->fc_flag, vport->fc_plogi_cnt,
- vport->fc_adisc_cnt);
+ lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,
+ "0202 Start Discovery hba state x%x "
+ "Data: x%x x%x x%x\n",
+ vport->port_state, vport->fc_flag, vport->fc_plogi_cnt,
+ vport->fc_adisc_cnt);
/* First do ADISCs - if any */
num_sent = lpfc_els_disc_adisc(vport);
@@ -2532,10 +2506,8 @@
* FAN
*/
/* FAN timeout */
- lpfc_printf_log(phba, KERN_WARNING, LOG_DISCOVERY,
- "%d (%d):0221 FAN timeout\n",
- phba->brd_no, vport->vpi);
-
+ lpfc_printf_vlog(vport, KERN_WARNING, LOG_DISCOVERY,
+ "0221 FAN timeout\n");
/* Start discovery by sending FLOGI, clean up old rpis */
list_for_each_entry_safe(ndlp, next_ndlp, &vport->fc_nodes,
nlp_listp) {
@@ -2562,10 +2534,9 @@
case LPFC_FLOGI:
/* port_state is identically LPFC_FLOGI while waiting for FLOGI cmpl */
/* Initial FLOGI timeout */
- lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY,
- "%d (%d):0222 Initial %s timeout\n",
- phba->brd_no, vport->vpi,
- vport->vpi ? "FLOGI" : "FDISC");
+ lpfc_printf_vlog(vport, KERN_ERR, LOG_DISCOVERY,
+ "0222 Initial %s timeout\n",
+ vport->vpi ? "FLOGI" : "FDISC");
/* Assume no Fabric and go on with discovery.
* Check for outstanding ELS FLOGI to abort.
@@ -2581,11 +2552,9 @@
case LPFC_FABRIC_CFG_LINK:
/* hba_state is identically LPFC_FABRIC_CFG_LINK while waiting for
NameServer login */
- lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY,
- "%d (%d):0223 Timeout while waiting for "
- "NameServer login\n",
- phba->brd_no, vport->vpi);
-
+ lpfc_printf_vlog(vport, KERN_ERR, LOG_DISCOVERY,
+ "0223 Timeout while waiting for "
+ "NameServer login\n");
/* Next look for NameServer ndlp */
ndlp = lpfc_findnode_did(vport, NameServer_DID);
if (ndlp)
@@ -2596,11 +2565,10 @@
case LPFC_NS_QRY:
/* Check for wait for NameServer Rsp timeout */
- lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY,
- "%d (%d):0224 NameServer Query timeout "
- "Data: x%x x%x\n",
- phba->brd_no, vport->vpi,
- vport->fc_ns_retry, LPFC_MAX_NS_RETRY);
+ lpfc_printf_vlog(vport, KERN_ERR, LOG_DISCOVERY,
+ "0224 NameServer Query timeout "
+ "Data: x%x x%x\n",
+ vport->fc_ns_retry, LPFC_MAX_NS_RETRY);
if (vport->fc_ns_retry < LPFC_MAX_NS_RETRY) {
/* Try it one more time */
@@ -2627,10 +2595,9 @@
/* Setup and issue mailbox INITIALIZE LINK command */
initlinkmbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
if (!initlinkmbox) {
- lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY,
- "%d (%d):0206 Device Discovery "
- "completion error\n",
- phba->brd_no, vport->vpi);
+ lpfc_printf_vlog(vport, KERN_ERR, LOG_DISCOVERY,
+ "0206 Device Discovery "
+ "completion error\n");
phba->link_state = LPFC_HBA_ERROR;
break;
}
@@ -2651,9 +2618,8 @@
case LPFC_DISC_AUTH:
/* Node Authentication timeout */
- lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY,
- "%d (%d):0227 Node Authentication timeout\n",
- phba->brd_no, vport->vpi);
+ lpfc_printf_vlog(vport, KERN_ERR, LOG_DISCOVERY,
+ "0227 Node Authentication timeout\n");
lpfc_disc_flush_list(vport);
/*
@@ -2670,11 +2636,10 @@
case LPFC_VPORT_READY:
if (vport->fc_flag & FC_RSCN_MODE) {
- lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY,
- "%d (%d):0231 RSCN timeout Data: x%x "
- "x%x\n",
- phba->brd_no, vport->vpi,
- vport->fc_ns_retry, LPFC_MAX_NS_RETRY);
+ lpfc_printf_vlog(vport, KERN_ERR, LOG_DISCOVERY,
+ "0231 RSCN timeout Data: x%x "
+ "x%x\n",
+ vport->fc_ns_retry, LPFC_MAX_NS_RETRY);
/* Cleanup any outstanding ELS commands */
lpfc_els_flush_cmd(vport);
@@ -2685,20 +2650,17 @@
break;
default:
- lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY,
- "%d (%d):0229 Unexpected discovery timeout, "
- "vport State x%x\n",
- phba->brd_no, vport->vpi, vport->port_state);
-
+ lpfc_printf_vlog(vport, KERN_ERR, LOG_DISCOVERY,
+ "0229 Unexpected discovery timeout, "
+ "vport State x%x\n", vport->port_state);
break;
}
switch (phba->link_state) {
case LPFC_CLEAR_LA:
/* CLEAR LA timeout */
- lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY,
- "%d (%d):0228 CLEAR LA timeout\n",
- phba->brd_no, vport->vpi);
+ lpfc_printf_vlog(vport, KERN_ERR, LOG_DISCOVERY,
+ "0228 CLEAR LA timeout\n");
clrlaerr = 1;
break;
@@ -2709,10 +2671,9 @@
case LPFC_LINK_DOWN:
case LPFC_LINK_UP:
case LPFC_HBA_ERROR:
- lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY,
- "%d (%d):0230 Unexpected timeout, hba link "
- "state x%x\n",
- phba->brd_no, vport->vpi, phba->link_state);
+ lpfc_printf_vlog(vport, KERN_ERR, LOG_DISCOVERY,
+ "0230 Unexpected timeout, hba link "
+ "state x%x\n", phba->link_state);
clrlaerr = 1;
break;
@@ -2757,7 +2718,7 @@
* fdmi-on=2 (supporting RPA/hostnmae)
*/
- if (phba->cfg_fdmi_on == 1)
+ if (vport->cfg_fdmi_on == 1)
lpfc_fdmi_cmd(vport, ndlp, SLI_MGMT_DHBA);
else
mod_timer(&vport->fc_fdmitmo, jiffies + HZ * 60);
@@ -2854,32 +2815,6 @@
}
void
-lpfc_dev_loss_delay(unsigned long ptr)
-{
- struct lpfc_nodelist *ndlp = (struct lpfc_nodelist *) ptr;
- struct lpfc_vport *vport = ndlp->vport;
- struct lpfc_hba *phba = vport->phba;
- struct lpfc_work_evt *evtp = &ndlp->dev_loss_evt;
- unsigned long flags;
-
- evtp = &ndlp->dev_loss_evt;
-
- spin_lock_irqsave(&phba->hbalock, flags);
- if (!list_empty(&evtp->evt_listp)) {
- spin_unlock_irqrestore(&phba->hbalock, flags);
- return;
- }
-
- evtp->evt_arg1 = ndlp;
- evtp->evt = LPFC_EVT_DEV_LOSS_DELAY;
- list_add_tail(&evtp->evt_listp, &phba->work_list);
- if (phba->work_wait)
- lpfc_worker_wake_up(phba);
- spin_unlock_irqrestore(&phba->hbalock, flags);
- return;
-}
-
-void
lpfc_nlp_init(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
uint32_t did)
{
@@ -2902,7 +2837,7 @@
return;
}
-void
+static void
lpfc_nlp_release(struct kref *kref)
{
struct lpfc_nodelist *ndlp = container_of(kref, struct lpfc_nodelist,
diff --git a/drivers/scsi/lpfc/lpfc_hw.h b/drivers/scsi/lpfc/lpfc_hw.h
index c2fb59f..451accd 100644
--- a/drivers/scsi/lpfc/lpfc_hw.h
+++ b/drivers/scsi/lpfc/lpfc_hw.h
@@ -150,7 +150,11 @@
struct gff_acc {
uint8_t fbits[128];
} gff_acc;
+#ifdef __BIG_ENDIAN_BITFIELD
+#define FCP_TYPE_FEATURE_OFFSET 7
+#else /* __LITTLE_ENDIAN_BITFIELD */
#define FCP_TYPE_FEATURE_OFFSET 4
+#endif
struct rff {
uint32_t PortId;
uint8_t reserved[2];
@@ -805,7 +809,7 @@
} un;
} RNID;
-typedef struct _RPS { /* Structure is in Big Endian format */
+typedef struct _RPS { /* Structure is in Big Endian format */
union {
uint32_t portNum;
struct lpfc_name portName;
@@ -823,7 +827,7 @@
uint32_t crcCnt;
} RPS_RSP;
-typedef struct _RPL { /* Structure is in Big Endian format */
+typedef struct _RPL { /* Structure is in Big Endian format */
uint32_t maxsize;
uint32_t index;
} RPL;
@@ -834,7 +838,7 @@
struct lpfc_name portName;
} PORT_NUM_BLK;
-typedef struct _RPL_RSP { /* Structure is in Big Endian format */
+typedef struct _RPL_RSP { /* Structure is in Big Endian format */
uint32_t listLen;
uint32_t index;
PORT_NUM_BLK port_num_blk;
@@ -2613,8 +2617,8 @@
LOAD_SM_VAR varLdSM; /* cmd = 1 (LOAD_SM) */
READ_NV_VAR varRDnvp; /* cmd = 2 (READ_NVPARMS) */
WRITE_NV_VAR varWTnvp; /* cmd = 3 (WRITE_NVPARMS) */
- BIU_DIAG_VAR varBIUdiag; /* cmd = 4 (RUN_BIU_DIAG) */
- INIT_LINK_VAR varInitLnk; /* cmd = 5 (INIT_LINK) */
+ BIU_DIAG_VAR varBIUdiag; /* cmd = 4 (RUN_BIU_DIAG) */
+ INIT_LINK_VAR varInitLnk; /* cmd = 5 (INIT_LINK) */
DOWN_LINK_VAR varDwnLnk; /* cmd = 6 (DOWN_LINK) */
CONFIG_LINK varCfgLnk; /* cmd = 7 (CONFIG_LINK) */
PART_SLIM_VAR varSlim; /* cmd = 8 (PART_SLIM) */
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c
index 07bd0dc..414350a 100644
--- a/drivers/scsi/lpfc/lpfc_init.c
+++ b/drivers/scsi/lpfc/lpfc_init.c
@@ -53,8 +53,6 @@
static struct scsi_transport_template *lpfc_vport_transport_template = NULL;
static DEFINE_IDR(lpfc_hba_index);
-
-
/************************************************************************/
/* */
/* lpfc_config_port_prep */
@@ -107,10 +105,9 @@
if (rc != MBX_SUCCESS) {
lpfc_printf_log(phba, KERN_ERR, LOG_MBOX,
- "%d:0324 Config Port initialization "
+ "0324 Config Port initialization "
"error, mbxCmd x%x READ_NVPARM, "
"mbxStatus x%x\n",
- phba->brd_no,
mb->mbxCommand, mb->mbxStatus);
mempool_free(pmb, phba->mbox_mem_pool);
return -ERESTART;
@@ -128,9 +125,8 @@
rc = lpfc_sli_issue_mbox(phba, pmb, MBX_POLL);
if (rc != MBX_SUCCESS) {
lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
- "%d:0439 Adapter failed to init, mbxCmd x%x "
+ "0439 Adapter failed to init, mbxCmd x%x "
"READ_REV, mbxStatus x%x\n",
- phba->brd_no,
mb->mbxCommand, mb->mbxStatus);
mempool_free( pmb, phba->mbox_mem_pool);
return -ERESTART;
@@ -144,9 +140,8 @@
if (mb->un.varRdRev.rr == 0) {
vp->rev.rBit = 0;
lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
- "%d:0440 Adapter failed to init, READ_REV has "
- "missing revision information.\n",
- phba->brd_no);
+ "0440 Adapter failed to init, READ_REV has "
+ "missing revision information.\n");
mempool_free(pmb, phba->mbox_mem_pool);
return -ERESTART;
}
@@ -197,9 +192,8 @@
if (rc != MBX_SUCCESS) {
lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
- "%d:0441 VPD not present on adapter, "
+ "0441 VPD not present on adapter, "
"mbxCmd x%x DUMP VPD, mbxStatus x%x\n",
- phba->brd_no,
mb->mbxCommand, mb->mbxStatus);
mb->un.varDmp.word_cnt = 0;
}
@@ -253,9 +247,8 @@
pmb->vport = vport;
if (lpfc_sli_issue_mbox(phba, pmb, MBX_POLL) != MBX_SUCCESS) {
lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
- "%d:0448 Adapter failed init, mbxCmd x%x "
+ "0448 Adapter failed init, mbxCmd x%x "
"READ_SPARM mbxStatus x%x\n",
- phba->brd_no,
mb->mbxCommand, mb->mbxStatus);
phba->link_state = LPFC_HBA_ERROR;
mp = (struct lpfc_dmabuf *) pmb->context1;
@@ -312,9 +305,8 @@
pmb->vport = vport;
if (lpfc_sli_issue_mbox(phba, pmb, MBX_POLL) != MBX_SUCCESS) {
lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
- "%d:0453 Adapter failed to init, mbxCmd x%x "
+ "0453 Adapter failed to init, mbxCmd x%x "
"READ_CONFIG, mbxStatus x%x\n",
- phba->brd_no,
mb->mbxCommand, mb->mbxStatus);
phba->link_state = LPFC_HBA_ERROR;
mempool_free( pmb, phba->mbox_mem_pool);
@@ -344,9 +336,8 @@
&& !(phba->lmt & LMT_10Gb))) {
/* Reset link speed to auto */
lpfc_printf_log(phba, KERN_WARNING, LOG_LINK_EVENT,
- "%d:1302 Invalid speed for this board: "
+ "1302 Invalid speed for this board: "
"Reset link speed to auto: x%x\n",
- phba->brd_no,
phba->cfg_link_speed);
phba->cfg_link_speed = LINK_SPEED_AUTO;
}
@@ -402,9 +393,8 @@
lpfc_set_loopback_flag(phba);
if (rc != MBX_SUCCESS) {
lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
- "%d:0454 Adapter failed to init, mbxCmd x%x "
+ "0454 Adapter failed to init, mbxCmd x%x "
"INIT_LINK, mbxStatus x%x\n",
- phba->brd_no,
mb->mbxCommand, mb->mbxStatus);
/* Clear all interrupt enable conditions */
@@ -437,16 +427,11 @@
int
lpfc_hba_down_prep(struct lpfc_hba *phba)
{
- struct lpfc_vport *vport = phba->pport;
-
/* Disable interrupts */
writel(0, phba->HCregaddr);
readl(phba->HCregaddr); /* flush */
- list_for_each_entry(vport, &phba->port_list, listentry) {
- lpfc_cleanup_discovery_resources(vport);
- }
-
+ lpfc_cleanup_discovery_resources(phba->pport);
return 0;
}
@@ -518,7 +503,7 @@
mempool_free(pmboxq, phba->mbox_mem_pool);
if (!(phba->pport->fc_flag & FC_OFFLINE_MODE) &&
!(phba->link_state == LPFC_HBA_ERROR) &&
- !(phba->pport->fc_flag & FC_UNLOADING))
+ !(phba->pport->load_flag & FC_UNLOADING))
mod_timer(&phba->hb_tmofunc,
jiffies + HZ * LPFC_HB_MBOX_INTERVAL);
return;
@@ -532,7 +517,7 @@
struct lpfc_sli *psli = &phba->sli;
if ((phba->link_state == LPFC_HBA_ERROR) ||
- (phba->pport->fc_flag & FC_UNLOADING) ||
+ (phba->pport->load_flag & FC_UNLOADING) ||
(phba->pport->fc_flag & FC_OFFLINE_MODE))
return;
@@ -586,8 +571,8 @@
* need to take the HBA offline.
*/
lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
- "%d:0459 Adapter heartbeat failure, taking "
- "this port offline.\n", phba->brd_no);
+ "0459 Adapter heartbeat failure, taking "
+ "this port offline.\n");
spin_lock_irq(&phba->hbalock);
psli->sli_flag &= ~LPFC_SLI2_ACTIVE;
@@ -615,9 +600,10 @@
struct lpfc_vport *vport = phba->pport;
struct lpfc_sli *psli = &phba->sli;
struct lpfc_sli_ring *pring;
- struct lpfc_vport *port_iterator;
+ struct lpfc_vport **vports;
uint32_t event_data;
struct Scsi_Host *shost;
+ int i;
/* If the pci channel is offline, ignore possible errors,
* since we cannot communicate with the pci card anyway. */
@@ -628,18 +614,21 @@
phba->work_hs & HS_FFER5) {
/* Re-establishing Link */
lpfc_printf_log(phba, KERN_INFO, LOG_LINK_EVENT,
- "%d:1301 Re-establishing Link "
+ "1301 Re-establishing Link "
"Data: x%x x%x x%x\n",
- phba->brd_no, phba->work_hs,
+ phba->work_hs,
phba->work_status[0], phba->work_status[1]);
- list_for_each_entry(port_iterator, &phba->port_list,
- listentry) {
- shost = lpfc_shost_from_vport(port_iterator);
-
- spin_lock_irq(shost->host_lock);
- port_iterator->fc_flag |= FC_ESTABLISH_LINK;
- spin_unlock_irq(shost->host_lock);
- }
+ vports = lpfc_create_vport_work_array(phba);
+ if (vports != NULL)
+ for(i = 0;
+ i < LPFC_MAX_VPORTS && vports[i] != NULL;
+ i++){
+ shost = lpfc_shost_from_vport(vports[i]);
+ spin_lock_irq(shost->host_lock);
+ vports[i]->fc_flag |= FC_ESTABLISH_LINK;
+ spin_unlock_irq(shost->host_lock);
+ }
+ lpfc_destroy_vport_work_array(vports);
spin_lock_irq(&phba->hbalock);
psli->sli_flag &= ~LPFC_SLI2_ACTIVE;
spin_unlock_irq(&phba->hbalock);
@@ -673,9 +662,9 @@
* twice. This is the adapter hardware error path.
*/
lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
- "%d:0457 Adapter Hardware Error "
+ "0457 Adapter Hardware Error "
"Data: x%x x%x x%x\n",
- phba->brd_no, phba->work_hs,
+ phba->work_hs,
phba->work_status[0], phba->work_status[1]);
event_data = FC_REG_DUMP_EVENT;
@@ -708,7 +697,6 @@
{
struct lpfc_vport *vport = phba->pport;
struct lpfc_sli *psli = &phba->sli;
- struct lpfc_vport *port_iterator;
LPFC_MBOXQ_t *pmb;
volatile uint32_t control;
struct lpfc_dmabuf *mp;
@@ -729,8 +717,7 @@
rc = -EIO;
/* Cleanup any outstanding ELS commands */
- list_for_each_entry(port_iterator, &phba->port_list, listentry)
- lpfc_els_flush_cmd(port_iterator);
+ lpfc_els_flush_all_cmd(phba);
psli->slistat.link_event++;
lpfc_read_la(phba, pmb, mp);
@@ -773,8 +760,7 @@
/* The other case is an error from issue_mbox */
if (rc == -ENOMEM)
lpfc_printf_log(phba, KERN_WARNING, LOG_MBOX,
- "%d:0300 READ_LA: no buffers\n",
- phba->brd_no);
+ "0300 READ_LA: no buffers\n");
return;
}
@@ -799,8 +785,7 @@
/* Vital Product */
lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
- "%d:0455 Vital Product Data: x%x x%x x%x x%x\n",
- phba->brd_no,
+ "0455 Vital Product Data: x%x x%x x%x x%x\n",
(uint32_t) vpd[0], (uint32_t) vpd[1], (uint32_t) vpd[2],
(uint32_t) vpd[3]);
while (!finished && (index < (len - 4))) {
@@ -1313,22 +1298,25 @@
lpfc_establish_link_tmo(unsigned long ptr)
{
struct lpfc_hba *phba = (struct lpfc_hba *) ptr;
- struct lpfc_vport *vport = phba->pport;
+ struct lpfc_vport **vports;
unsigned long iflag;
+ int i;
/* Re-establishing Link, timer expired */
lpfc_printf_log(phba, KERN_ERR, LOG_LINK_EVENT,
- "%d:1300 Re-establishing Link, timer expired "
+ "1300 Re-establishing Link, timer expired "
"Data: x%x x%x\n",
- phba->brd_no, vport->fc_flag,
- vport->port_state);
- list_for_each_entry(vport, &phba->port_list, listentry) {
- struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
-
- spin_lock_irqsave(shost->host_lock, iflag);
- vport->fc_flag &= ~FC_ESTABLISH_LINK;
- spin_unlock_irqrestore(shost->host_lock, iflag);
- }
+ phba->pport->fc_flag, phba->pport->port_state);
+ vports = lpfc_create_vport_work_array(phba);
+ if (vports != NULL)
+ for(i = 0; i < LPFC_MAX_VPORTS && vports[i] != NULL; i++) {
+ struct Scsi_Host *shost;
+ shost = lpfc_shost_from_vport(vports[i]);
+ spin_lock_irqsave(shost->host_lock, iflag);
+ vports[i]->fc_flag &= ~FC_ESTABLISH_LINK;
+ spin_unlock_irqrestore(shost->host_lock, iflag);
+ }
+ lpfc_destroy_vport_work_array(vports);
}
void
@@ -1343,12 +1331,9 @@
static void
lpfc_stop_phba_timers(struct lpfc_hba *phba)
{
- struct lpfc_vport *vport;
-
del_timer_sync(&phba->fcp_poll_timer);
del_timer_sync(&phba->fc_estabtmo);
- list_for_each_entry(vport, &phba->port_list, listentry)
- lpfc_stop_vport_timers(vport);
+ lpfc_stop_vport_timers(phba->pport);
del_timer_sync(&phba->sli.mbox_tmo);
del_timer_sync(&phba->fabric_block_timer);
phba->hb_outstanding = 0;
@@ -1360,6 +1345,8 @@
lpfc_online(struct lpfc_hba *phba)
{
struct lpfc_vport *vport = phba->pport;
+ struct lpfc_vport **vports;
+ int i;
if (!phba)
return 0;
@@ -1368,8 +1355,7 @@
return 0;
lpfc_printf_log(phba, KERN_WARNING, LOG_INIT,
- "%d:0458 Bring Adapter online\n",
- phba->brd_no);
+ "0458 Bring Adapter online\n");
lpfc_block_mgmt_io(phba);
@@ -1383,14 +1369,18 @@
return 1;
}
- list_for_each_entry(vport, &phba->port_list, listentry) {
- struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
- spin_lock_irq(shost->host_lock);
- vport->fc_flag &= ~FC_OFFLINE_MODE;
- if (phba->sli3_options & LPFC_SLI3_NPIV_ENABLED)
- vport->fc_flag |= FC_VPORT_NEEDS_REG_VPI;
- spin_unlock_irq(shost->host_lock);
- }
+ vports = lpfc_create_vport_work_array(phba);
+ if (vports != NULL)
+ for(i = 0; i < LPFC_MAX_VPORTS && vports[i] != NULL; i++) {
+ struct Scsi_Host *shost;
+ shost = lpfc_shost_from_vport(vports[i]);
+ spin_lock_irq(shost->host_lock);
+ vports[i]->fc_flag &= ~FC_OFFLINE_MODE;
+ if (phba->sli3_options & LPFC_SLI3_NPIV_ENABLED)
+ vports[i]->fc_flag |= FC_VPORT_NEEDS_REG_VPI;
+ spin_unlock_irq(shost->host_lock);
+ }
+ lpfc_destroy_vport_work_array(vports);
lpfc_unblock_mgmt_io(phba);
return 0;
@@ -1440,39 +1430,39 @@
void
lpfc_offline(struct lpfc_hba *phba)
{
- struct lpfc_vport *vport = phba->pport;
- struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
- struct lpfc_vport *port_iterator;
+ struct Scsi_Host *shost;
+ struct lpfc_vport **vports;
+ int i;
- if (vport->fc_flag & FC_OFFLINE_MODE)
+ if (phba->pport->fc_flag & FC_OFFLINE_MODE)
return;
/* stop all timers associated with this hba */
lpfc_stop_phba_timers(phba);
- list_for_each_entry(port_iterator, &phba->port_list, listentry) {
- port_iterator->work_port_events = 0;
- }
-
+ vports = lpfc_create_vport_work_array(phba);
+ if (vports != NULL)
+ for(i = 0; i < LPFC_MAX_VPORTS && vports[i] != NULL; i++)
+ lpfc_stop_vport_timers(vports[i]);
+ lpfc_destroy_vport_work_array(vports);
lpfc_printf_log(phba, KERN_WARNING, LOG_INIT,
- "%d:0460 Bring Adapter offline\n",
- phba->brd_no);
-
+ "0460 Bring Adapter offline\n");
/* Bring down the SLI Layer and cleanup. The HBA is offline
now. */
lpfc_sli_hba_down(phba);
spin_lock_irq(&phba->hbalock);
phba->work_ha = 0;
- vport->fc_flag |= FC_OFFLINE_MODE;
spin_unlock_irq(&phba->hbalock);
- list_for_each_entry(port_iterator, &phba->port_list, listentry) {
- shost = lpfc_shost_from_vport(port_iterator);
-
- lpfc_cleanup(port_iterator);
- spin_lock_irq(shost->host_lock);
- vport->work_port_events = 0;
- vport->fc_flag |= FC_OFFLINE_MODE;
- spin_unlock_irq(shost->host_lock);
- }
+ vports = lpfc_create_vport_work_array(phba);
+ if (vports != NULL)
+ for(i = 0; i < LPFC_MAX_VPORTS && vports[i] != NULL; i++) {
+ shost = lpfc_shost_from_vport(vports[i]);
+ lpfc_cleanup(vports[i]);
+ spin_lock_irq(shost->host_lock);
+ vports[i]->work_port_events = 0;
+ vports[i]->fc_flag |= FC_OFFLINE_MODE;
+ spin_unlock_irq(shost->host_lock);
+ }
+ lpfc_destroy_vport_work_array(vports);
}
/******************************************************************************
@@ -1509,15 +1499,19 @@
return 0;
}
-
struct lpfc_vport *
-lpfc_create_port(struct lpfc_hba *phba, int instance, struct fc_vport *fc_vport)
+lpfc_create_port(struct lpfc_hba *phba, int instance, struct device *dev)
{
struct lpfc_vport *vport;
struct Scsi_Host *shost;
int error = 0;
- shost = scsi_host_alloc(&lpfc_template, sizeof(struct lpfc_vport));
+ if (dev != &phba->pcidev->dev)
+ shost = scsi_host_alloc(&lpfc_vport_template,
+ sizeof(struct lpfc_vport));
+ else
+ shost = scsi_host_alloc(&lpfc_template,
+ sizeof(struct lpfc_vport));
if (!shost)
goto out;
@@ -1527,9 +1521,10 @@
vport->load_flag |= FC_LOADING;
vport->fc_flag |= FC_VPORT_NEEDS_REG_VPI;
+ lpfc_get_vport_cfgparam(vport);
shost->unique_id = instance;
shost->max_id = LPFC_MAX_TARGET;
- shost->max_lun = phba->cfg_max_luns;
+ shost->max_lun = vport->cfg_max_luns;
shost->this_id = -1;
shost->max_cmd_len = 16;
/*
@@ -1538,7 +1533,7 @@
* max xri value determined in hba setup.
*/
shost->can_queue = phba->cfg_hba_queue_depth - 10;
- if (fc_vport != NULL) {
+ if (dev != &phba->pcidev->dev) {
shost->transportt = lpfc_vport_transport_template;
vport->port_type = LPFC_NPIV_PORT;
} else {
@@ -1562,15 +1557,13 @@
vport->els_tmofunc.function = lpfc_els_timeout;
vport->els_tmofunc.data = (unsigned long)vport;
- if (fc_vport != NULL) {
- error = scsi_add_host(shost, &fc_vport->dev);
- } else {
- error = scsi_add_host(shost, &phba->pcidev->dev);
- }
+ error = scsi_add_host(shost, dev);
if (error)
goto out_put_shost;
+ spin_lock_irq(&phba->hbalock);
list_add_tail(&vport->listentry, &phba->port_list);
+ spin_unlock_irq(&phba->hbalock);
return vport;
out_put_shost:
@@ -1625,23 +1618,21 @@
spin_lock_irq(shost->host_lock);
- if (vport->fc_flag & FC_UNLOADING) {
+ if (vport->load_flag & FC_UNLOADING) {
stat = 1;
goto finished;
}
if (time >= 30 * HZ) {
lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
- "%d:0461 Scanning longer than 30 "
- "seconds. Continuing initialization\n",
- phba->brd_no);
+ "0461 Scanning longer than 30 "
+ "seconds. Continuing initialization\n");
stat = 1;
goto finished;
}
if (time >= 15 * HZ && phba->link_state <= LPFC_LINK_DOWN) {
lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
- "%d:0465 Link down longer than 15 "
- "seconds. Continuing initialization\n",
- phba->brd_no);
+ "0465 Link down longer than 15 "
+ "seconds. Continuing initialization\n");
stat = 1;
goto finished;
}
@@ -1704,7 +1695,7 @@
fc_host_max_npiv_vports(shost) = phba->max_vpi;
spin_lock_irq(shost->host_lock);
- vport->fc_flag &= ~FC_LOADING;
+ vport->load_flag &= ~FC_LOADING;
spin_unlock_irq(shost->host_lock);
}
@@ -1716,9 +1707,10 @@
struct lpfc_sli *psli;
struct lpfc_iocbq *iocbq_entry = NULL, *iocbq_next = NULL;
struct Scsi_Host *shost = NULL;
+ void *ptr;
unsigned long bar0map_len, bar2map_len;
int error = -ENODEV;
- int i;
+ int i, hbq_count;
uint16_t iotag;
if (pci_enable_device(pdev))
@@ -1739,7 +1731,6 @@
goto out_free_phba;
INIT_LIST_HEAD(&phba->port_list);
- INIT_LIST_HEAD(&phba->hbq_buffer_list);
/*
* Get all the module params for configuring this host and then
* establish the host.
@@ -1817,6 +1808,17 @@
if (!phba->hbqslimp.virt)
goto out_free_slim;
+ hbq_count = lpfc_sli_hbq_count();
+ ptr = phba->hbqslimp.virt;
+ for (i = 0; i < hbq_count; ++i) {
+ phba->hbqs[i].hbq_virt = ptr;
+ INIT_LIST_HEAD(&phba->hbqs[i].hbq_buffer_list);
+ ptr += (lpfc_hbq_defs[i]->entry_count *
+ sizeof(struct lpfc_hbq_entry));
+ }
+ phba->hbqs[LPFC_ELS_HBQ].hbq_alloc_buffer = lpfc_els_hbq_alloc;
+ phba->hbqs[LPFC_ELS_HBQ].hbq_free_buffer = lpfc_els_hbq_free;
+
memset(phba->hbqslimp.virt, 0, lpfc_sli_hbq_size());
/* Initialize the SLI Layer to run with lpfc HBAs. */
@@ -1880,7 +1882,7 @@
/* Initialize list of fabric iocbs */
INIT_LIST_HEAD(&phba->fabric_iocb_list);
- vport = lpfc_create_port(phba, phba->brd_no, NULL);
+ vport = lpfc_create_port(phba, phba->brd_no, &phba->pcidev->dev);
if (!vport)
goto out_kthread_stop;
@@ -1892,18 +1894,19 @@
if (phba->cfg_use_msi) {
error = pci_enable_msi(phba->pcidev);
- if (error)
- lpfc_printf_log(phba, KERN_INFO, LOG_INIT, "%d:0452 "
- "Enable MSI failed, continuing with "
- "IRQ\n", phba->brd_no);
+ if (!error)
+ phba->using_msi = 1;
+ else
+ lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
+ "0452 Enable MSI failed, continuing "
+ "with IRQ\n");
}
error = request_irq(phba->pcidev->irq, lpfc_intr_handler, IRQF_SHARED,
LPFC_DRIVER_NAME, phba);
if (error) {
lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
- "%d:0451 Enable interrupt handler failed\n",
- phba->brd_no);
+ "0451 Enable interrupt handler failed\n");
goto out_disable_msi;
}
@@ -1940,14 +1943,15 @@
out_remove_device:
lpfc_free_sysfs_attr(vport);
spin_lock_irq(shost->host_lock);
- vport->fc_flag |= FC_UNLOADING;
+ vport->load_flag |= FC_UNLOADING;
spin_unlock_irq(shost->host_lock);
out_free_irq:
lpfc_stop_phba_timers(phba);
phba->pport->work_port_events = 0;
free_irq(phba->pcidev->irq, phba);
out_disable_msi:
- pci_disable_msi(phba->pcidev);
+ if (phba->using_msi)
+ pci_disable_msi(phba->pcidev);
destroy_port(vport);
out_kthread_stop:
kthread_stop(phba->worker_thread);
@@ -1989,16 +1993,15 @@
struct Scsi_Host *shost = pci_get_drvdata(pdev);
struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
struct lpfc_hba *phba = vport->phba;
- struct lpfc_vport *port_iterator;
- list_for_each_entry(port_iterator, &phba->port_list, listentry)
- port_iterator->load_flag |= FC_UNLOADING;
+ spin_lock_irq(&phba->hbalock);
+ vport->load_flag |= FC_UNLOADING;
+ spin_unlock_irq(&phba->hbalock);
kfree(vport->vname);
lpfc_free_sysfs_attr(vport);
fc_remove_host(shost);
scsi_remove_host(shost);
-
/*
* Bring down the SLI Layer. This step disable all interrupts,
* clears the rings, discards all mailbox commands, and resets
@@ -2012,7 +2015,6 @@
list_del_init(&vport->listentry);
spin_unlock_irq(&phba->hbalock);
-
lpfc_debugfs_terminate(vport);
lpfc_cleanup(vport);
@@ -2020,7 +2022,8 @@
/* Release the irq reservation */
free_irq(phba->pcidev->irq, phba);
- pci_disable_msi(phba->pcidev);
+ if (phba->using_msi)
+ pci_disable_msi(phba->pcidev);
pci_set_drvdata(pdev, NULL);
scsi_host_put(shost);
@@ -2062,8 +2065,8 @@
static pci_ers_result_t lpfc_io_error_detected(struct pci_dev *pdev,
pci_channel_state_t state)
{
- struct Scsi_Host *host = pci_get_drvdata(pdev);
- struct lpfc_hba *phba = (struct lpfc_hba *)host->hostdata;
+ struct Scsi_Host *shost = pci_get_drvdata(pdev);
+ struct lpfc_hba *phba = ((struct lpfc_vport *)shost->hostdata)->phba;
struct lpfc_sli *psli = &phba->sli;
struct lpfc_sli_ring *pring;
@@ -2079,6 +2082,11 @@
pring = &psli->ring[psli->fcp_ring];
lpfc_sli_abort_iocb_ring(phba, pring);
+ /* Release the irq reservation */
+ free_irq(phba->pcidev->irq, phba);
+ if (phba->using_msi)
+ pci_disable_msi(phba->pcidev);
+
/* Request a slot reset. */
return PCI_ERS_RESULT_NEED_RESET;
}
@@ -2091,8 +2099,8 @@
*/
static pci_ers_result_t lpfc_io_slot_reset(struct pci_dev *pdev)
{
- struct Scsi_Host *host = pci_get_drvdata(pdev);
- struct lpfc_hba *phba = (struct lpfc_hba *)host->hostdata;
+ struct Scsi_Host *shost = pci_get_drvdata(pdev);
+ struct lpfc_hba *phba = ((struct lpfc_vport *)shost->hostdata)->phba;
struct lpfc_sli *psli = &phba->sli;
int bars = pci_select_bars(pdev, IORESOURCE_MEM);
@@ -2106,9 +2114,9 @@
pci_set_master(pdev);
/* Re-establishing Link */
- spin_lock_irq(host->host_lock);
+ spin_lock_irq(shost->host_lock);
phba->pport->fc_flag |= FC_ESTABLISH_LINK;
- spin_unlock_irq(host->host_lock);
+ spin_unlock_irq(shost->host_lock);
spin_lock_irq(&phba->hbalock);
psli->sli_flag &= ~LPFC_SLI2_ACTIVE;
@@ -2131,8 +2139,8 @@
*/
static void lpfc_io_resume(struct pci_dev *pdev)
{
- struct Scsi_Host *host = pci_get_drvdata(pdev);
- struct lpfc_hba *phba = (struct lpfc_hba *)host->hostdata;
+ struct Scsi_Host *shost = pci_get_drvdata(pdev);
+ struct lpfc_hba *phba = ((struct lpfc_vport *)shost->hostdata)->phba;
if (lpfc_online(phba) == 0) {
mod_timer(&phba->fc_estabtmo, jiffies + HZ * 60);
diff --git a/drivers/scsi/lpfc/lpfc_logmsg.h b/drivers/scsi/lpfc/lpfc_logmsg.h
index 8a6ceff..626e4d8 100644
--- a/drivers/scsi/lpfc/lpfc_logmsg.h
+++ b/drivers/scsi/lpfc/lpfc_logmsg.h
@@ -33,6 +33,12 @@
#define LOG_VPORT 0x4000 /* NPIV events */
#define LOG_ALL_MSG 0xffff /* LOG all messages */
+#define lpfc_printf_vlog(vport, level, mask, fmt, arg...) \
+ { if (((mask) &(vport)->cfg_log_verbose) || (level[1] <= '3')) \
+ dev_printk(level, &((vport)->phba->pcidev)->dev, "%d:(%d):" \
+ fmt, (vport)->phba->brd_no, vport->vpi, ##arg); }
+
#define lpfc_printf_log(phba, level, mask, fmt, arg...) \
- { if (((mask) &(phba)->cfg_log_verbose) || (level[1] <= '3')) \
- dev_printk(level, &((phba)->pcidev)->dev, fmt, ##arg); }
+ { if (((mask) &(phba)->pport->cfg_log_verbose) || (level[1] <= '3')) \
+ dev_printk(level, &((phba)->pcidev)->dev, "%d:" \
+ fmt, phba->brd_no, ##arg); }
diff --git a/drivers/scsi/lpfc/lpfc_mbox.c b/drivers/scsi/lpfc/lpfc_mbox.c
index 8f42fbf..a5927336 100644
--- a/drivers/scsi/lpfc/lpfc_mbox.c
+++ b/drivers/scsi/lpfc/lpfc_mbox.c
@@ -275,11 +275,8 @@
kfree(mp);
mb->mbxCommand = MBX_READ_SPARM64;
/* READ_SPARAM: no buffers */
- lpfc_printf_log(phba,
- KERN_WARNING,
- LOG_MBOX,
- "%d:0301 READ_SPARAM: no buffers\n",
- phba->brd_no);
+ lpfc_printf_log(phba, KERN_WARNING, LOG_MBOX,
+ "0301 READ_SPARAM: no buffers\n");
return (1);
}
INIT_LIST_HEAD(&mp->list);
@@ -378,9 +375,8 @@
mb->mbxCommand = MBX_REG_LOGIN64;
/* REG_LOGIN: no buffers */
lpfc_printf_log(phba, KERN_WARNING, LOG_MBOX,
- "%d (%d):0302 REG_LOGIN: no buffers, DID x%x, "
- "flag x%x\n",
- phba->brd_no, vpi, did, flag);
+ "0302 REG_LOGIN: no buffers, VPI:%d DID:x%x, "
+ "flag x%x\n", vpi, did, flag);
return (1);
}
INIT_LIST_HEAD(&mp->list);
@@ -564,7 +560,8 @@
}
void
-lpfc_config_hbq(struct lpfc_hba *phba, struct lpfc_hbq_init *hbq_desc,
+lpfc_config_hbq(struct lpfc_hba *phba, uint32_t id,
+ struct lpfc_hbq_init *hbq_desc,
uint32_t hbq_entry_index, LPFC_MBOXQ_t *pmb)
{
int i;
@@ -572,6 +569,7 @@
struct config_hbq_var *hbqmb = &mb->un.varCfgHbq;
memset(pmb, 0, sizeof (LPFC_MBOXQ_t));
+ hbqmb->hbqId = id;
hbqmb->entry_count = hbq_desc->entry_count; /* # entries in HBQ */
hbqmb->recvNotify = hbq_desc->rn; /* Receive
* Notification */
@@ -691,8 +689,8 @@
if (phba->sli_rev == 3 && phba->vpd.sli3Feat.cerbm) {
mb->un.varCfgPort.cerbm = 1; /* Request HBQs */
- mb->un.varCfgPort.max_hbq = 1; /* Requesting 2 HBQs */
- if (phba->max_vpi && phba->cfg_npiv_enable &&
+ mb->un.varCfgPort.max_hbq = lpfc_sli_hbq_count();
+ if (phba->max_vpi && phba->cfg_enable_npiv &&
phba->vpd.sli3Feat.cmv) {
mb->un.varCfgPort.max_vpi = phba->max_vpi;
mb->un.varCfgPort.cmv = 1;
diff --git a/drivers/scsi/lpfc/lpfc_mem.c b/drivers/scsi/lpfc/lpfc_mem.c
index 3594c46..43c3b8a 100644
--- a/drivers/scsi/lpfc/lpfc_mem.c
+++ b/drivers/scsi/lpfc/lpfc_mem.c
@@ -231,21 +231,34 @@
return;
}
-void *
-lpfc_hbq_alloc(struct lpfc_hba *phba, int mem_flags, dma_addr_t *handle)
+struct hbq_dmabuf *
+lpfc_els_hbq_alloc(struct lpfc_hba *phba)
{
- void *ret;
- ret = pci_pool_alloc(phba->lpfc_hbq_pool, GFP_ATOMIC, handle);
- return ret;
+ struct hbq_dmabuf *hbqbp;
+
+ hbqbp = kmalloc(sizeof(struct hbq_dmabuf), GFP_KERNEL);
+ if (!hbqbp)
+ return NULL;
+
+ hbqbp->dbuf.virt = pci_pool_alloc(phba->lpfc_hbq_pool, GFP_KERNEL,
+ &hbqbp->dbuf.phys);
+ if (!hbqbp->dbuf.virt) {
+ kfree(hbqbp);
+ return NULL;
+ }
+ hbqbp->size = LPFC_BPL_SIZE;
+ return hbqbp;
}
void
-lpfc_hbq_free(struct lpfc_hba *phba, void *virt, dma_addr_t dma)
+lpfc_els_hbq_free(struct lpfc_hba *phba, struct hbq_dmabuf *hbqbp)
{
- pci_pool_free(phba->lpfc_hbq_pool, virt, dma);
+ pci_pool_free(phba->lpfc_hbq_pool, hbqbp->dbuf.virt, hbqbp->dbuf.phys);
+ kfree(hbqbp);
return;
}
+/* This is ONLY called for the LPFC_ELS_HBQ */
void
lpfc_in_buf_free(struct lpfc_hba *phba, struct lpfc_dmabuf *mp)
{
@@ -254,9 +267,8 @@
if (phba->sli3_options & LPFC_SLI3_HBQ_ENABLED) {
hbq_entry = container_of(mp, struct hbq_dmabuf, dbuf);
if (hbq_entry->tag == -1) {
- lpfc_hbq_free(phba, hbq_entry->dbuf.virt,
- hbq_entry->dbuf.phys);
- kfree(hbq_entry);
+ (phba->hbqs[LPFC_ELS_HBQ].hbq_free_buffer)
+ (phba, hbq_entry);
} else {
lpfc_sli_free_hbq(phba, hbq_entry);
}
diff --git a/drivers/scsi/lpfc/lpfc_nportdisc.c b/drivers/scsi/lpfc/lpfc_nportdisc.c
index bca2f5c..880af0c 100644
--- a/drivers/scsi/lpfc/lpfc_nportdisc.c
+++ b/drivers/scsi/lpfc/lpfc_nportdisc.c
@@ -133,15 +133,15 @@
memcpy(&ndlp->nlp_portname, &sp->portName, sizeof (struct lpfc_name));
return 1;
bad_service_param:
- lpfc_printf_log(vport->phba, KERN_ERR, LOG_DISCOVERY,
- "%d (%d):0207 Device %x "
- "(%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x) sent "
- "invalid service parameters. Ignoring device.\n",
- vport->phba->brd_no, ndlp->vport->vpi, ndlp->nlp_DID,
- sp->nodeName.u.wwn[0], sp->nodeName.u.wwn[1],
- sp->nodeName.u.wwn[2], sp->nodeName.u.wwn[3],
- sp->nodeName.u.wwn[4], sp->nodeName.u.wwn[5],
- sp->nodeName.u.wwn[6], sp->nodeName.u.wwn[7]);
+ lpfc_printf_vlog(vport, KERN_ERR, LOG_DISCOVERY,
+ "0207 Device %x "
+ "(%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x) sent "
+ "invalid service parameters. Ignoring device.\n",
+ ndlp->nlp_DID,
+ sp->nodeName.u.wwn[0], sp->nodeName.u.wwn[1],
+ sp->nodeName.u.wwn[2], sp->nodeName.u.wwn[3],
+ sp->nodeName.u.wwn[4], sp->nodeName.u.wwn[5],
+ sp->nodeName.u.wwn[6], sp->nodeName.u.wwn[7]);
return 0;
}
@@ -194,11 +194,11 @@
IOCB_t *cmd;
/* Abort outstanding I/O on NPort <nlp_DID> */
- lpfc_printf_log(phba, KERN_INFO, LOG_DISCOVERY,
- "%d (%d):0205 Abort outstanding I/O on NPort x%x "
- "Data: x%x x%x x%x\n",
- phba->brd_no, ndlp->vport->vpi, ndlp->nlp_DID,
- ndlp->nlp_flag, ndlp->nlp_state, ndlp->nlp_rpi);
+ lpfc_printf_vlog(ndlp->vport, KERN_INFO, LOG_DISCOVERY,
+ "0205 Abort outstanding I/O on NPort x%x "
+ "Data: x%x x%x x%x\n",
+ ndlp->nlp_DID, ndlp->nlp_flag, ndlp->nlp_state,
+ ndlp->nlp_rpi);
lpfc_fabric_abort_nport(ndlp);
@@ -298,13 +298,12 @@
icmd = &cmdiocb->iocb;
/* PLOGI chkparm OK */
- lpfc_printf_log(phba, KERN_INFO, LOG_ELS,
- "%d (%d):0114 PLOGI chkparm OK Data: x%x x%x x%x x%x\n",
- phba->brd_no, vport->vpi,
- ndlp->nlp_DID, ndlp->nlp_state, ndlp->nlp_flag,
- ndlp->nlp_rpi);
+ lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
+ "0114 PLOGI chkparm OK Data: x%x x%x x%x x%x\n",
+ ndlp->nlp_DID, ndlp->nlp_state, ndlp->nlp_flag,
+ ndlp->nlp_rpi);
- if (phba->cfg_fcp_class == 2 && sp->cls2.classValid)
+ if (vport->cfg_fcp_class == 2 && sp->cls2.classValid)
ndlp->nlp_fcp_info |= CLASS2;
else
ndlp->nlp_fcp_info |= CLASS3;
@@ -330,7 +329,7 @@
case NLP_STE_PRLI_ISSUE:
case NLP_STE_UNMAPPED_NODE:
case NLP_STE_MAPPED_NODE:
- lpfc_els_rsp_acc(vport, ELS_CMD_PLOGI, cmdiocb, ndlp, NULL, 0);
+ lpfc_els_rsp_acc(vport, ELS_CMD_PLOGI, cmdiocb, ndlp, NULL);
return 1;
}
@@ -392,7 +391,7 @@
}
if ((vport->port_type == LPFC_NPIV_PORT &&
- phba->cfg_vport_restrict_login)) {
+ vport->cfg_restrict_login)) {
/* In order to preserve RPIs, we want to cleanup
* the default RPI the firmware created to rcv
@@ -408,7 +407,7 @@
ndlp, mbox);
return 1;
}
- lpfc_els_rsp_acc(vport, ELS_CMD_PLOGI, cmdiocb, ndlp, mbox, 0);
+ lpfc_els_rsp_acc(vport, ELS_CMD_PLOGI, cmdiocb, ndlp, mbox);
return 1;
out:
@@ -452,7 +451,7 @@
lpfc_els_rsp_adisc_acc(vport, cmdiocb, ndlp);
} else {
lpfc_els_rsp_acc(vport, ELS_CMD_PLOGI, cmdiocb, ndlp,
- NULL, 0);
+ NULL);
}
return 1;
}
@@ -489,9 +488,9 @@
ndlp->nlp_flag |= NLP_LOGO_ACC;
spin_unlock_irq(shost->host_lock);
if (els_cmd == ELS_CMD_PRLO)
- lpfc_els_rsp_acc(vport, ELS_CMD_PRLO, cmdiocb, ndlp, NULL, 0);
+ lpfc_els_rsp_acc(vport, ELS_CMD_PRLO, cmdiocb, ndlp, NULL);
else
- lpfc_els_rsp_acc(vport, ELS_CMD_ACC, cmdiocb, ndlp, NULL, 0);
+ lpfc_els_rsp_acc(vport, ELS_CMD_ACC, cmdiocb, ndlp, NULL);
if (!(ndlp->nlp_type & NLP_FABRIC) ||
(ndlp->nlp_state == NLP_STE_ADISC_ISSUE)) {
@@ -564,10 +563,14 @@
lpfc_disc_set_adisc(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)
{
struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
- struct lpfc_hba *phba = vport->phba;
+
+ if (!ndlp->nlp_rpi) {
+ ndlp->nlp_flag &= ~NLP_NPR_ADISC;
+ return 0;
+ }
/* Check config parameter use-adisc or FCP-2 */
- if ((phba->cfg_use_adisc && (vport->fc_flag & FC_RSCN_MODE)) ||
+ if ((vport->cfg_use_adisc && (vport->fc_flag & FC_RSCN_MODE)) ||
ndlp->nlp_fcp_info & NLP_FCP_2_DEVICE) {
spin_lock_irq(shost->host_lock);
ndlp->nlp_flag |= NLP_NPR_ADISC;
@@ -583,12 +586,11 @@
lpfc_disc_illegal(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
void *arg, uint32_t evt)
{
- lpfc_printf_log(vport->phba, KERN_ERR, LOG_DISCOVERY,
- "%d (%d):0253 Illegal State Transition: node x%x "
- "event x%x, state x%x Data: x%x x%x\n",
- vport->phba->brd_no, vport->vpi,
- ndlp->nlp_DID, evt, ndlp->nlp_state, ndlp->nlp_rpi,
- ndlp->nlp_flag);
+ lpfc_printf_vlog(vport, KERN_ERR, LOG_DISCOVERY,
+ "0253 Illegal State Transition: node x%x "
+ "event x%x, state x%x Data: x%x x%x\n",
+ ndlp->nlp_DID, evt, ndlp->nlp_state, ndlp->nlp_rpi,
+ ndlp->nlp_flag);
return ndlp->nlp_state;
}
@@ -630,7 +632,7 @@
spin_lock_irq(shost->host_lock);
ndlp->nlp_flag |= NLP_LOGO_ACC;
spin_unlock_irq(shost->host_lock);
- lpfc_els_rsp_acc(vport, ELS_CMD_ACC, cmdiocb, ndlp, NULL, 0);
+ lpfc_els_rsp_acc(vport, ELS_CMD_ACC, cmdiocb, ndlp, NULL);
lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNUSED_NODE);
return ndlp->nlp_state;
@@ -726,7 +728,7 @@
lpfc_els_abort(phba, ndlp);
if (evt == NLP_EVT_RCV_LOGO) {
- lpfc_els_rsp_acc(vport, ELS_CMD_ACC, cmdiocb, ndlp, NULL, 0);
+ lpfc_els_rsp_acc(vport, ELS_CMD_ACC, cmdiocb, ndlp, NULL);
} else {
lpfc_issue_els_logo(vport, ndlp, 0);
}
@@ -778,16 +780,12 @@
sp = (struct serv_parm *) ((uint8_t *) lp + sizeof (uint32_t));
if (!lpfc_check_sparm(vport, ndlp, sp, CLASS3))
goto out;
-
/* PLOGI chkparm OK */
- lpfc_printf_log(phba, KERN_INFO, LOG_ELS,
- "%d (%d):0121 PLOGI chkparm OK "
- "Data: x%x x%x x%x x%x\n",
- phba->brd_no, vport->vpi,
- ndlp->nlp_DID, ndlp->nlp_state,
- ndlp->nlp_flag, ndlp->nlp_rpi);
-
- if (phba->cfg_fcp_class == 2 && (sp->cls2.classValid))
+ lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
+ "0121 PLOGI chkparm OK Data: x%x x%x x%x x%x\n",
+ ndlp->nlp_DID, ndlp->nlp_state,
+ ndlp->nlp_flag, ndlp->nlp_rpi);
+ if (vport->cfg_fcp_class == 2 && (sp->cls2.classValid))
ndlp->nlp_fcp_info |= CLASS2;
else
ndlp->nlp_fcp_info |= CLASS3;
@@ -806,10 +804,9 @@
mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
if (!mbox) {
- lpfc_printf_log(phba, KERN_ERR, LOG_ELS,
- "%d (%d):0133 PLOGI: no memory for reg_login "
+ lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS,
+ "0133 PLOGI: no memory for reg_login "
"Data: x%x x%x x%x x%x\n",
- phba->brd_no, vport->vpi,
ndlp->nlp_DID, ndlp->nlp_state,
ndlp->nlp_flag, ndlp->nlp_rpi);
goto out;
@@ -844,30 +841,27 @@
kfree(mp);
mempool_free(mbox, phba->mbox_mem_pool);
- lpfc_printf_log(phba, KERN_ERR, LOG_ELS,
- "%d (%d):0134 PLOGI: cannot issue reg_login "
- "Data: x%x x%x x%x x%x\n",
- phba->brd_no, vport->vpi,
- ndlp->nlp_DID, ndlp->nlp_state,
- ndlp->nlp_flag, ndlp->nlp_rpi);
+ lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS,
+ "0134 PLOGI: cannot issue reg_login "
+ "Data: x%x x%x x%x x%x\n",
+ ndlp->nlp_DID, ndlp->nlp_state,
+ ndlp->nlp_flag, ndlp->nlp_rpi);
} else {
mempool_free(mbox, phba->mbox_mem_pool);
- lpfc_printf_log(phba, KERN_ERR, LOG_ELS,
- "%d (%d):0135 PLOGI: cannot format reg_login "
- "Data: x%x x%x x%x x%x\n",
- phba->brd_no, vport->vpi,
- ndlp->nlp_DID, ndlp->nlp_state,
- ndlp->nlp_flag, ndlp->nlp_rpi);
+ lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS,
+ "0135 PLOGI: cannot format reg_login "
+ "Data: x%x x%x x%x x%x\n",
+ ndlp->nlp_DID, ndlp->nlp_state,
+ ndlp->nlp_flag, ndlp->nlp_rpi);
}
out:
if (ndlp->nlp_DID == NameServer_DID) {
lpfc_vport_set_state(vport, FC_VPORT_FAILED);
- lpfc_printf_log(phba, KERN_ERR, LOG_ELS,
- "%d (%d):0261 Cannot Register NameServer login\n",
- phba->brd_no, vport->vpi);
+ lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS,
+ "0261 Cannot Register NameServer login\n");
}
/* Free this node since the driver cannot login or has the wrong
@@ -1178,7 +1172,7 @@
struct lpfc_iocbq *cmdiocb;
cmdiocb = (struct lpfc_iocbq *) arg;
- lpfc_els_rsp_acc(vport, ELS_CMD_PRLO, cmdiocb, ndlp, NULL, 0);
+ lpfc_els_rsp_acc(vport, ELS_CMD_PRLO, cmdiocb, ndlp, NULL);
return ndlp->nlp_state;
}
@@ -1189,19 +1183,15 @@
uint32_t evt)
{
struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
- struct lpfc_hba *phba = vport->phba;
LPFC_MBOXQ_t *pmb = (LPFC_MBOXQ_t *) arg;
MAILBOX_t *mb = &pmb->mb;
uint32_t did = mb->un.varWords[1];
if (mb->mbxStatus) {
/* RegLogin failed */
- lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY,
- "%d (%d):0246 RegLogin failed Data: x%x x%x "
- "x%x\n",
- phba->brd_no, vport->vpi,
+ lpfc_printf_vlog(vport, KERN_ERR, LOG_DISCOVERY,
+ "0246 RegLogin failed Data: x%x x%x x%x\n",
did, mb->mbxStatus, vport->port_state);
-
/*
* If RegLogin failed due to lack of HBA resources do not
* retry discovery.
@@ -1337,7 +1327,7 @@
{
struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg;
- lpfc_els_rsp_acc(vport, ELS_CMD_PRLO, cmdiocb, ndlp, NULL, 0);
+ lpfc_els_rsp_acc(vport, ELS_CMD_PRLO, cmdiocb, ndlp, NULL);
return ndlp->nlp_state;
}
@@ -1358,7 +1348,7 @@
irsp = &rspiocb->iocb;
if (irsp->ulpStatus) {
if ((vport->port_type == LPFC_NPIV_PORT) &&
- phba->cfg_vport_restrict_login) {
+ vport->cfg_restrict_login) {
goto out;
}
ndlp->nlp_prev_state = NLP_STE_PRLI_ISSUE;
@@ -1380,7 +1370,7 @@
}
if (!(ndlp->nlp_type & NLP_FCP_TARGET) &&
(vport->port_type == LPFC_NPIV_PORT) &&
- phba->cfg_vport_restrict_login) {
+ vport->cfg_restrict_login) {
out:
spin_lock_irq(shost->host_lock);
ndlp->nlp_flag |= NLP_TARGET_REMOVE;
@@ -1529,7 +1519,7 @@
{
struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg;
- lpfc_els_rsp_acc(vport, ELS_CMD_PRLO, cmdiocb, ndlp, NULL, 0);
+ lpfc_els_rsp_acc(vport, ELS_CMD_PRLO, cmdiocb, ndlp, NULL);
return ndlp->nlp_state;
}
@@ -1600,8 +1590,8 @@
struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg;
/* flush the target */
- lpfc_sli_abort_iocb(phba, &phba->sli.ring[phba->sli.fcp_ring],
- ndlp->nlp_sid, 0, 0, LPFC_CTX_TGT);
+ lpfc_sli_abort_iocb(vport, &phba->sli.ring[phba->sli.fcp_ring],
+ ndlp->nlp_sid, 0, LPFC_CTX_TGT);
/* Treat like rcv logo */
lpfc_rcv_logo(vport, ndlp, cmdiocb, ELS_CMD_PRLO);
@@ -1734,7 +1724,7 @@
ndlp->nlp_flag |= NLP_LOGO_ACC;
spin_unlock_irq(shost->host_lock);
- lpfc_els_rsp_acc(vport, ELS_CMD_ACC, cmdiocb, ndlp, NULL, 0);
+ lpfc_els_rsp_acc(vport, ELS_CMD_ACC, cmdiocb, ndlp, NULL);
if ((ndlp->nlp_flag & NLP_DELAY_TMO) == 0) {
mod_timer(&ndlp->nlp_delayfunc, jiffies + HZ * 1);
@@ -2047,7 +2037,6 @@
lpfc_disc_state_machine(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
void *arg, uint32_t evt)
{
- struct lpfc_hba *phba = vport->phba;
uint32_t cur_state, rc;
uint32_t(*func) (struct lpfc_vport *, struct lpfc_nodelist *, void *,
uint32_t);
@@ -2056,11 +2045,10 @@
cur_state = ndlp->nlp_state;
/* DSM in event <evt> on NPort <nlp_DID> in state <cur_state> */
- lpfc_printf_log(phba, KERN_INFO, LOG_DISCOVERY,
- "%d (%d):0211 DSM in event x%x on NPort x%x in "
- "state %d Data: x%x\n",
- phba->brd_no, vport->vpi,
- evt, ndlp->nlp_DID, cur_state, ndlp->nlp_flag);
+ lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,
+ "0211 DSM in event x%x on NPort x%x in "
+ "state %d Data: x%x\n",
+ evt, ndlp->nlp_DID, cur_state, ndlp->nlp_flag);
lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_DSM,
"DSM in: evt:%d ste:%d did:x%x",
@@ -2070,11 +2058,9 @@
rc = (func) (vport, ndlp, arg, evt);
/* DSM out state <rc> on NPort <nlp_DID> */
- lpfc_printf_log(phba, KERN_INFO, LOG_DISCOVERY,
- "%d (%d):0212 DSM out state %d on NPort x%x "
- "Data: x%x\n",
- phba->brd_no, vport->vpi,
- rc, ndlp->nlp_DID, ndlp->nlp_flag);
+ lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,
+ "0212 DSM out state %d on NPort x%x Data: x%x\n",
+ rc, ndlp->nlp_DID, ndlp->nlp_flag);
lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_DSM,
"DSM out: ste:%d did:x%x flg:x%x",
diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c
index 8f45bbc..17d7dc0 100644
--- a/drivers/scsi/lpfc/lpfc_scsi.c
+++ b/drivers/scsi/lpfc/lpfc_scsi.c
@@ -84,22 +84,21 @@
* SCSI command completion.
*/
static inline void
-lpfc_rampup_queue_depth(struct lpfc_hba *phba,
+lpfc_rampup_queue_depth(struct lpfc_vport *vport,
struct scsi_device *sdev)
{
unsigned long flags;
+ struct lpfc_hba *phba = vport->phba;
atomic_inc(&phba->num_cmd_success);
- if (phba->cfg_lun_queue_depth <= sdev->queue_depth)
+ if (vport->cfg_lun_queue_depth <= sdev->queue_depth)
return;
-
spin_lock_irqsave(&phba->hbalock, flags);
if (((phba->last_ramp_up_time + QUEUE_RAMP_UP_INTERVAL) > jiffies) ||
((phba->last_rsrc_error_time + QUEUE_RAMP_UP_INTERVAL ) > jiffies)) {
spin_unlock_irqrestore(&phba->hbalock, flags);
return;
}
-
phba->last_ramp_up_time = jiffies;
spin_unlock_irqrestore(&phba->hbalock, flags);
@@ -119,43 +118,40 @@
void
lpfc_ramp_down_queue_handler(struct lpfc_hba *phba)
{
- struct lpfc_vport *vport;
- struct Scsi_Host *host;
+ struct lpfc_vport **vports;
+ struct Scsi_Host *shost;
struct scsi_device *sdev;
unsigned long new_queue_depth;
unsigned long num_rsrc_err, num_cmd_success;
+ int i;
num_rsrc_err = atomic_read(&phba->num_rsrc_err);
num_cmd_success = atomic_read(&phba->num_cmd_success);
- spin_lock_irq(&phba->hbalock);
- list_for_each_entry(vport, &phba->port_list, listentry) {
- host = lpfc_shost_from_vport(vport);
- if (!scsi_host_get(host))
- continue;
-
- spin_unlock_irq(&phba->hbalock);
-
- shost_for_each_device(sdev, host) {
- new_queue_depth = sdev->queue_depth * num_rsrc_err /
- (num_rsrc_err + num_cmd_success);
- if (!new_queue_depth)
- new_queue_depth = sdev->queue_depth - 1;
- else
+ vports = lpfc_create_vport_work_array(phba);
+ if (vports != NULL)
+ for(i = 0; i < LPFC_MAX_VPORTS && vports[i] != NULL; i++) {
+ shost = lpfc_shost_from_vport(vports[i]);
+ shost_for_each_device(sdev, shost) {
new_queue_depth =
- sdev->queue_depth - new_queue_depth;
-
- if (sdev->ordered_tags)
- scsi_adjust_queue_depth(sdev, MSG_ORDERED_TAG,
- new_queue_depth);
- else
- scsi_adjust_queue_depth(sdev, MSG_SIMPLE_TAG,
- new_queue_depth);
+ sdev->queue_depth * num_rsrc_err /
+ (num_rsrc_err + num_cmd_success);
+ if (!new_queue_depth)
+ new_queue_depth = sdev->queue_depth - 1;
+ else
+ new_queue_depth = sdev->queue_depth -
+ new_queue_depth;
+ if (sdev->ordered_tags)
+ scsi_adjust_queue_depth(sdev,
+ MSG_ORDERED_TAG,
+ new_queue_depth);
+ else
+ scsi_adjust_queue_depth(sdev,
+ MSG_SIMPLE_TAG,
+ new_queue_depth);
+ }
}
- spin_lock_irq(&phba->hbalock);
- scsi_host_put(host);
- }
- spin_unlock_irq(&phba->hbalock);
+ lpfc_destroy_vport_work_array(vports);
atomic_set(&phba->num_rsrc_err, 0);
atomic_set(&phba->num_cmd_success, 0);
}
@@ -163,29 +159,27 @@
void
lpfc_ramp_up_queue_handler(struct lpfc_hba *phba)
{
- struct lpfc_vport *vport;
- struct Scsi_Host *host;
+ struct lpfc_vport **vports;
+ struct Scsi_Host *shost;
struct scsi_device *sdev;
+ int i;
- spin_lock_irq(&phba->hbalock);
- list_for_each_entry(vport, &phba->port_list, listentry) {
- host = lpfc_shost_from_vport(vport);
- if (!scsi_host_get(host))
- continue;
-
- spin_unlock_irq(&phba->hbalock);
- shost_for_each_device(sdev, host) {
- if (sdev->ordered_tags)
- scsi_adjust_queue_depth(sdev, MSG_ORDERED_TAG,
- sdev->queue_depth+1);
- else
- scsi_adjust_queue_depth(sdev, MSG_SIMPLE_TAG,
- sdev->queue_depth+1);
+ vports = lpfc_create_vport_work_array(phba);
+ if (vports != NULL)
+ for(i = 0; i < LPFC_MAX_VPORTS && vports[i] != NULL; i++) {
+ shost = lpfc_shost_from_vport(vports[i]);
+ shost_for_each_device(sdev, shost) {
+ if (sdev->ordered_tags)
+ scsi_adjust_queue_depth(sdev,
+ MSG_ORDERED_TAG,
+ sdev->queue_depth+1);
+ else
+ scsi_adjust_queue_depth(sdev,
+ MSG_SIMPLE_TAG,
+ sdev->queue_depth+1);
+ }
}
- spin_lock_irq(&phba->hbalock);
- scsi_host_put(host);
- }
- spin_unlock_irq(&phba->hbalock);
+ lpfc_destroy_vport_work_array(vports);
atomic_set(&phba->num_rsrc_err, 0);
atomic_set(&phba->num_cmd_success, 0);
}
@@ -411,9 +405,7 @@
struct scsi_cmnd *cmnd = lpfc_cmd->pCmd;
struct fcp_cmnd *fcpcmd = lpfc_cmd->fcp_cmnd;
struct fcp_rsp *fcprsp = lpfc_cmd->fcp_rsp;
- struct lpfc_hba *phba = vport->phba;
uint32_t fcpi_parm = rsp_iocb->iocb.un.fcpi.fcpi_parm;
- uint32_t vpi = vport->vpi;
uint32_t resp_info = fcprsp->rspStatus2;
uint32_t scsi_status = fcprsp->rspStatus3;
uint32_t *lp;
@@ -445,15 +437,15 @@
if (!scsi_status && (resp_info & RESID_UNDER))
logit = LOG_FCP;
- lpfc_printf_log(phba, KERN_WARNING, logit,
- "%d (%d):0730 FCP command x%x failed: x%x SNS x%x x%x "
- "Data: x%x x%x x%x x%x x%x\n",
- phba->brd_no, vpi, cmnd->cmnd[0], scsi_status,
- be32_to_cpu(*lp), be32_to_cpu(*(lp + 3)), resp_info,
- be32_to_cpu(fcprsp->rspResId),
- be32_to_cpu(fcprsp->rspSnsLen),
- be32_to_cpu(fcprsp->rspRspLen),
- fcprsp->rspInfo3);
+ lpfc_printf_vlog(vport, KERN_WARNING, logit,
+ "0730 FCP command x%x failed: x%x SNS x%x x%x "
+ "Data: x%x x%x x%x x%x x%x\n",
+ cmnd->cmnd[0], scsi_status,
+ be32_to_cpu(*lp), be32_to_cpu(*(lp + 3)), resp_info,
+ be32_to_cpu(fcprsp->rspResId),
+ be32_to_cpu(fcprsp->rspSnsLen),
+ be32_to_cpu(fcprsp->rspRspLen),
+ fcprsp->rspInfo3);
if (resp_info & RSP_LEN_VALID) {
rsplen = be32_to_cpu(fcprsp->rspRspLen);
@@ -468,12 +460,12 @@
if (resp_info & RESID_UNDER) {
scsi_set_resid(cmnd, be32_to_cpu(fcprsp->rspResId));
- lpfc_printf_log(phba, KERN_INFO, LOG_FCP,
- "%d (%d):0716 FCP Read Underrun, expected %d, "
- "residual %d Data: x%x x%x x%x\n",
- phba->brd_no, vpi, be32_to_cpu(fcpcmd->fcpDl),
- scsi_get_resid(cmnd), fcpi_parm, cmnd->cmnd[0],
- cmnd->underflow);
+ lpfc_printf_vlog(vport, KERN_INFO, LOG_FCP,
+ "0716 FCP Read Underrun, expected %d, "
+ "residual %d Data: x%x x%x x%x\n",
+ be32_to_cpu(fcpcmd->fcpDl),
+ scsi_get_resid(cmnd), fcpi_parm, cmnd->cmnd[0],
+ cmnd->underflow);
/*
* If there is an under run check if under run reported by
@@ -483,14 +475,13 @@
if ((cmnd->sc_data_direction == DMA_FROM_DEVICE) &&
fcpi_parm &&
(scsi_get_resid(cmnd) != fcpi_parm)) {
- lpfc_printf_log(phba, KERN_WARNING,
- LOG_FCP | LOG_FCP_ERROR,
- "%d (%d):0735 FCP Read Check Error "
- "and Underrun Data: x%x x%x x%x x%x\n",
- phba->brd_no, vpi,
- be32_to_cpu(fcpcmd->fcpDl),
- scsi_get_resid(cmnd), fcpi_parm,
- cmnd->cmnd[0]);
+ lpfc_printf_vlog(vport, KERN_WARNING,
+ LOG_FCP | LOG_FCP_ERROR,
+ "0735 FCP Read Check Error "
+ "and Underrun Data: x%x x%x x%x x%x\n",
+ be32_to_cpu(fcpcmd->fcpDl),
+ scsi_get_resid(cmnd), fcpi_parm,
+ cmnd->cmnd[0]);
scsi_set_resid(cmnd, scsi_bufflen(cmnd));
host_status = DID_ERROR;
}
@@ -504,21 +495,19 @@
(scsi_status == SAM_STAT_GOOD) &&
(scsi_bufflen(cmnd) - scsi_get_resid(cmnd)
< cmnd->underflow)) {
- lpfc_printf_log(phba, KERN_INFO, LOG_FCP,
- "%d (%d):0717 FCP command x%x residual "
- "underrun converted to error "
- "Data: x%x x%x x%x\n",
- phba->brd_no, vpi, cmnd->cmnd[0],
- scsi_bufflen(cmnd),
- scsi_get_resid(cmnd), cmnd->underflow);
+ lpfc_printf_vlog(vport, KERN_INFO, LOG_FCP,
+ "0717 FCP command x%x residual "
+ "underrun converted to error "
+ "Data: x%x x%x x%x\n",
+ cmnd->cmnd[0], scsi_bufflen(cmnd),
+ scsi_get_resid(cmnd), cmnd->underflow);
host_status = DID_ERROR;
}
} else if (resp_info & RESID_OVER) {
- lpfc_printf_log(phba, KERN_WARNING, LOG_FCP,
- "%d (%d):0720 FCP command x%x residual "
- "overrun error. Data: x%x x%x \n",
- phba->brd_no, vpi, cmnd->cmnd[0],
- scsi_bufflen(cmnd), scsi_get_resid(cmnd));
+ lpfc_printf_vlog(vport, KERN_WARNING, LOG_FCP,
+ "0720 FCP command x%x residual overrun error. "
+ "Data: x%x x%x \n", cmnd->cmnd[0],
+ scsi_bufflen(cmnd), scsi_get_resid(cmnd));
host_status = DID_ERROR;
/*
@@ -527,13 +516,12 @@
*/
} else if ((scsi_status == SAM_STAT_GOOD) && fcpi_parm &&
(cmnd->sc_data_direction == DMA_FROM_DEVICE)) {
- lpfc_printf_log(phba, KERN_WARNING, LOG_FCP | LOG_FCP_ERROR,
- "%d (%d):0734 FCP Read Check Error Data: "
- "x%x x%x x%x x%x\n",
- phba->brd_no, vpi,
- be32_to_cpu(fcpcmd->fcpDl),
- be32_to_cpu(fcprsp->rspResId),
- fcpi_parm, cmnd->cmnd[0]);
+ lpfc_printf_vlog(vport, KERN_WARNING, LOG_FCP | LOG_FCP_ERROR,
+ "0734 FCP Read Check Error Data: "
+ "x%x x%x x%x x%x\n",
+ be32_to_cpu(fcpcmd->fcpDl),
+ be32_to_cpu(fcprsp->rspResId),
+ fcpi_parm, cmnd->cmnd[0]);
host_status = DID_ERROR;
scsi_set_resid(cmnd, scsi_bufflen(cmnd));
}
@@ -552,9 +540,6 @@
struct lpfc_rport_data *rdata = lpfc_cmd->rdata;
struct lpfc_nodelist *pnode = rdata->pnode;
struct scsi_cmnd *cmd = lpfc_cmd->pCmd;
- uint32_t vpi = (lpfc_cmd->cur_iocbq.vport
- ? lpfc_cmd->cur_iocbq.vport->vpi
- : 0);
int result;
struct scsi_device *sdev, *tmp_sdev;
int depth = 0;
@@ -569,15 +554,15 @@
else if (lpfc_cmd->status >= IOSTAT_CNT)
lpfc_cmd->status = IOSTAT_DEFAULT;
- lpfc_printf_log(phba, KERN_WARNING, LOG_FCP,
- "%d (%d):0729 FCP cmd x%x failed <%d/%d> "
- "status: x%x result: x%x Data: x%x x%x\n",
- phba->brd_no, vpi, cmd->cmnd[0],
- cmd->device ? cmd->device->id : 0xffff,
- cmd->device ? cmd->device->lun : 0xffff,
- lpfc_cmd->status, lpfc_cmd->result,
- pIocbOut->iocb.ulpContext,
- lpfc_cmd->cur_iocbq.iocb.ulpIoTag);
+ lpfc_printf_vlog(vport, KERN_WARNING, LOG_FCP,
+ "0729 FCP cmd x%x failed <%d/%d> "
+ "status: x%x result: x%x Data: x%x x%x\n",
+ cmd->cmnd[0],
+ cmd->device ? cmd->device->id : 0xffff,
+ cmd->device ? cmd->device->lun : 0xffff,
+ lpfc_cmd->status, lpfc_cmd->result,
+ pIocbOut->iocb.ulpContext,
+ lpfc_cmd->cur_iocbq.iocb.ulpIoTag);
switch (lpfc_cmd->status) {
case IOSTAT_FCP_RSP_ERROR:
@@ -610,13 +595,12 @@
if (cmd->result || lpfc_cmd->fcp_rsp->rspSnsLen) {
uint32_t *lp = (uint32_t *)cmd->sense_buffer;
- lpfc_printf_log(phba, KERN_INFO, LOG_FCP,
- "%d (%d):0710 Iodone <%d/%d> cmd %p, error "
- "x%x SNS x%x x%x Data: x%x x%x\n",
- phba->brd_no, vpi, cmd->device->id,
- cmd->device->lun, cmd, cmd->result,
- *lp, *(lp + 3), cmd->retries,
- scsi_get_resid(cmd));
+ lpfc_printf_vlog(vport, KERN_INFO, LOG_FCP,
+ "0710 Iodone <%d/%d> cmd %p, error "
+ "x%x SNS x%x x%x Data: x%x x%x\n",
+ cmd->device->id, cmd->device->lun, cmd,
+ cmd->result, *lp, *(lp + 3), cmd->retries,
+ scsi_get_resid(cmd));
}
result = cmd->result;
@@ -631,16 +615,16 @@
if (!result)
- lpfc_rampup_queue_depth(phba, sdev);
+ lpfc_rampup_queue_depth(vport, sdev);
if (!result && pnode != NULL &&
((jiffies - pnode->last_ramp_up_time) >
LPFC_Q_RAMP_UP_INTERVAL * HZ) &&
((jiffies - pnode->last_q_full_time) >
LPFC_Q_RAMP_UP_INTERVAL * HZ) &&
- (phba->cfg_lun_queue_depth > sdev->queue_depth)) {
+ (vport->cfg_lun_queue_depth > sdev->queue_depth)) {
shost_for_each_device(tmp_sdev, sdev->host) {
- if (phba->cfg_lun_queue_depth > tmp_sdev->queue_depth) {
+ if (vport->cfg_lun_queue_depth > tmp_sdev->queue_depth){
if (tmp_sdev->id != sdev->id)
continue;
if (tmp_sdev->ordered_tags)
@@ -680,10 +664,9 @@
depth = sdev->host->cmd_per_lun;
if (depth) {
- lpfc_printf_log(phba, KERN_WARNING, LOG_FCP,
- "%d (%d):0711 detected queue full - "
- "lun queue depth adjusted to %d.\n",
- phba->brd_no, vpi, depth);
+ lpfc_printf_vlog(vport, KERN_WARNING, LOG_FCP,
+ "0711 detected queue full - lun queue "
+ "depth adjusted to %d.\n", depth);
}
}
@@ -853,12 +836,9 @@
return FAILED;
/* Issue Target Reset to TGT <num> */
- lpfc_printf_log(phba, KERN_INFO, LOG_FCP,
- "%d (%d):0702 Issue Target Reset to TGT %d "
- "Data: x%x x%x\n",
- phba->brd_no, vport->vpi, tgt_id,
- rdata->pnode->nlp_rpi, rdata->pnode->nlp_flag);
-
+ lpfc_printf_vlog(vport, KERN_INFO, LOG_FCP,
+ "0702 Issue Target Reset to TGT %d Data: x%x x%x\n",
+ tgt_id, rdata->pnode->nlp_rpi, rdata->pnode->nlp_flag);
ret = lpfc_sli_issue_iocb_wait(phba,
&phba->sli.ring[phba->sli.fcp_ring],
iocbq, iocbqrsp, lpfc_cmd->timeout);
@@ -965,10 +945,9 @@
if (lpfc_cmd == NULL) {
lpfc_adjust_queue_depth(phba);
- lpfc_printf_log(phba, KERN_INFO, LOG_FCP,
- "%d (%d):0707 driver's buffer pool is empty, "
- "IO busied\n",
- phba->brd_no, vport->vpi);
+ lpfc_printf_vlog(vport, KERN_INFO, LOG_FCP,
+ "0707 driver's buffer pool is empty, "
+ "IO busied\n");
goto out_host_busy;
}
@@ -1103,28 +1082,25 @@
schedule_timeout_uninterruptible(LPFC_ABORT_WAIT * HZ);
if (++loop_count
- > (2 * phba->cfg_devloss_tmo)/LPFC_ABORT_WAIT)
+ > (2 * vport->cfg_devloss_tmo)/LPFC_ABORT_WAIT)
break;
}
if (lpfc_cmd->pCmd == cmnd) {
ret = FAILED;
- lpfc_printf_log(phba, KERN_ERR, LOG_FCP,
- "%d (%d):0748 abort handler timed out waiting "
- "for abort to complete: ret %#x, ID %d, "
- "LUN %d, snum %#lx\n",
- phba->brd_no, vport->vpi, ret,
- cmnd->device->id, cmnd->device->lun,
- cmnd->serial_number);
+ lpfc_printf_vlog(vport, KERN_ERR, LOG_FCP,
+ "0748 abort handler timed out waiting "
+ "for abort to complete: ret %#x, ID %d, "
+ "LUN %d, snum %#lx\n",
+ ret, cmnd->device->id, cmnd->device->lun,
+ cmnd->serial_number);
}
out:
- lpfc_printf_log(phba, KERN_WARNING, LOG_FCP,
- "%d (%d):0749 SCSI Layer I/O Abort Request "
- "Status x%x ID %d LUN %d snum %#lx\n",
- phba->brd_no, vport->vpi, ret, cmnd->device->id,
- cmnd->device->lun, cmnd->serial_number);
-
+ lpfc_printf_vlog(vport, KERN_WARNING, LOG_FCP,
+ "0749 SCSI Layer I/O Abort Request Status x%x ID %d "
+ "LUN %d snum %#lx\n", ret, cmnd->device->id,
+ cmnd->device->lun, cmnd->serial_number);
return ret;
}
@@ -1158,12 +1134,11 @@
loopcnt++;
rdata = cmnd->device->hostdata;
if (!rdata ||
- (loopcnt > ((phba->cfg_devloss_tmo * 2) + 1))) {
- lpfc_printf_log(phba, KERN_ERR, LOG_FCP,
- "%d (%d):0721 LUN Reset rport "
- "failure: cnt x%x rdata x%p\n",
- phba->brd_no, vport->vpi,
- loopcnt, rdata);
+ (loopcnt > ((vport->cfg_devloss_tmo * 2) + 1))){
+ lpfc_printf_vlog(vport, KERN_ERR, LOG_FCP,
+ "0721 LUN Reset rport "
+ "failure: cnt x%x rdata x%p\n",
+ loopcnt, rdata);
goto out;
}
pnode = rdata->pnode;
@@ -1193,12 +1168,10 @@
if (iocbqrsp == NULL)
goto out_free_scsi_buf;
- lpfc_printf_log(phba, KERN_INFO, LOG_FCP,
- "%d (%d):0703 Issue target reset to TGT %d LUN %d "
- "rpi x%x nlp_flag x%x\n",
- phba->brd_no, vport->vpi, cmnd->device->id,
- cmnd->device->lun, pnode->nlp_rpi, pnode->nlp_flag);
-
+ lpfc_printf_vlog(vport, KERN_INFO, LOG_FCP,
+ "0703 Issue target reset to TGT %d LUN %d "
+ "rpi x%x nlp_flag x%x\n", cmnd->device->id,
+ cmnd->device->lun, pnode->nlp_rpi, pnode->nlp_flag);
iocb_status = lpfc_sli_issue_iocb_wait(phba,
&phba->sli.ring[phba->sli.fcp_ring],
iocbq, iocbqrsp, lpfc_cmd->timeout);
@@ -1221,33 +1194,28 @@
* Unfortunately, some targets do not abide by this forcing the driver
* to double check.
*/
- cnt = lpfc_sli_sum_iocb(phba, &phba->sli.ring[phba->sli.fcp_ring],
- cmnd->device->id, cmnd->device->lun,
+ cnt = lpfc_sli_sum_iocb(vport, cmnd->device->id, cmnd->device->lun,
LPFC_CTX_LUN);
if (cnt)
- lpfc_sli_abort_iocb(phba,
- &phba->sli.ring[phba->sli.fcp_ring],
+ lpfc_sli_abort_iocb(vport, &phba->sli.ring[phba->sli.fcp_ring],
cmnd->device->id, cmnd->device->lun,
- 0, LPFC_CTX_LUN);
+ LPFC_CTX_LUN);
loopcnt = 0;
while(cnt) {
schedule_timeout_uninterruptible(LPFC_RESET_WAIT*HZ);
if (++loopcnt
- > (2 * phba->cfg_devloss_tmo)/LPFC_RESET_WAIT)
+ > (2 * vport->cfg_devloss_tmo)/LPFC_RESET_WAIT)
break;
- cnt = lpfc_sli_sum_iocb(phba,
- &phba->sli.ring[phba->sli.fcp_ring],
- cmnd->device->id, cmnd->device->lun,
- LPFC_CTX_LUN);
+ cnt = lpfc_sli_sum_iocb(vport, cmnd->device->id,
+ cmnd->device->lun, LPFC_CTX_LUN);
}
if (cnt) {
- lpfc_printf_log(phba, KERN_ERR, LOG_FCP,
- "%d (%d):0719 device reset I/O flush failure: "
- "cnt x%x\n",
- phba->brd_no, vport->vpi, cnt);
+ lpfc_printf_vlog(vport, KERN_ERR, LOG_FCP,
+ "0719 device reset I/O flush failure: "
+ "cnt x%x\n", cnt);
ret = FAILED;
}
@@ -1255,12 +1223,11 @@
if (iocb_status != IOCB_TIMEDOUT) {
lpfc_release_scsi_buf(phba, lpfc_cmd);
}
- lpfc_printf_log(phba, KERN_ERR, LOG_FCP,
- "%d (%d):0713 SCSI layer issued device reset (%d, %d) "
- "return x%x status x%x result x%x\n",
- phba->brd_no, vport->vpi, cmnd->device->id,
- cmnd->device->lun, ret, cmd_status, cmd_result);
-
+ lpfc_printf_vlog(vport, KERN_ERR, LOG_FCP,
+ "0713 SCSI layer issued device reset (%d, %d) "
+ "return x%x status x%x result x%x\n",
+ cmnd->device->id, cmnd->device->lun, ret,
+ cmd_status, cmd_result);
out:
return ret;
}
@@ -1311,10 +1278,9 @@
cmnd->device->lun,
ndlp->rport->dd_data);
if (ret != SUCCESS) {
- lpfc_printf_log(phba, KERN_ERR, LOG_FCP,
- "%d (%d):0700 Bus Reset on target %d "
- "failed\n",
- phba->brd_no, vport->vpi, i);
+ lpfc_printf_vlog(vport, KERN_ERR, LOG_FCP,
+ "0700 Bus Reset on target %d failed\n",
+ i);
err_count++;
break;
}
@@ -1333,35 +1299,30 @@
* the targets. Unfortunately, some targets do not abide by
* this forcing the driver to double check.
*/
- cnt = lpfc_sli_sum_iocb(phba, &phba->sli.ring[phba->sli.fcp_ring],
- 0, 0, LPFC_CTX_HOST);
+ cnt = lpfc_sli_sum_iocb(vport, 0, 0, LPFC_CTX_HOST);
if (cnt)
- lpfc_sli_abort_iocb(phba, &phba->sli.ring[phba->sli.fcp_ring],
- 0, 0, 0, LPFC_CTX_HOST);
+ lpfc_sli_abort_iocb(vport, &phba->sli.ring[phba->sli.fcp_ring],
+ 0, 0, LPFC_CTX_HOST);
loopcnt = 0;
while(cnt) {
schedule_timeout_uninterruptible(LPFC_RESET_WAIT*HZ);
if (++loopcnt
- > (2 * phba->cfg_devloss_tmo)/LPFC_RESET_WAIT)
+ > (2 * vport->cfg_devloss_tmo)/LPFC_RESET_WAIT)
break;
- cnt = lpfc_sli_sum_iocb(phba,
- &phba->sli.ring[phba->sli.fcp_ring],
- 0, 0, LPFC_CTX_HOST);
+ cnt = lpfc_sli_sum_iocb(vport, 0, 0, LPFC_CTX_HOST);
}
if (cnt) {
- lpfc_printf_log(phba, KERN_ERR, LOG_FCP,
- "%d (%d):0715 Bus Reset I/O flush failure: "
- "cnt x%x left x%x\n",
- phba->brd_no, vport->vpi, cnt, i);
+ lpfc_printf_vlog(vport, KERN_ERR, LOG_FCP,
+ "0715 Bus Reset I/O flush failure: "
+ "cnt x%x left x%x\n", cnt, i);
ret = FAILED;
}
- lpfc_printf_log(phba, KERN_ERR, LOG_FCP,
- "%d (%d):0714 SCSI layer issued Bus Reset Data: x%x\n",
- phba->brd_no, vport->vpi, ret);
+ lpfc_printf_vlog(vport, KERN_ERR, LOG_FCP,
+ "0714 SCSI layer issued Bus Reset Data: x%x\n", ret);
out:
return ret;
}
@@ -1390,36 +1351,32 @@
* extra. This list of scsi bufs exists for the lifetime of the driver.
*/
total = phba->total_scsi_bufs;
- num_to_alloc = phba->cfg_lun_queue_depth + 2;
+ num_to_alloc = vport->cfg_lun_queue_depth + 2;
/* Allow some exchanges to be available always to complete discovery */
if (total >= phba->cfg_hba_queue_depth - LPFC_DISC_IOCB_BUFF_COUNT ) {
- lpfc_printf_log(phba, KERN_WARNING, LOG_FCP,
- "%d (%d):0704 At limitation of %d "
- "preallocated command buffers\n",
- phba->brd_no, vport->vpi, total);
+ lpfc_printf_vlog(vport, KERN_WARNING, LOG_FCP,
+ "0704 At limitation of %d preallocated "
+ "command buffers\n", total);
return 0;
-
/* Allow some exchanges to be available always to complete discovery */
} else if (total + num_to_alloc >
phba->cfg_hba_queue_depth - LPFC_DISC_IOCB_BUFF_COUNT ) {
- lpfc_printf_log(phba, KERN_WARNING, LOG_FCP,
- "%d (%d):0705 Allocation request of %d "
- "command buffers will exceed max of %d. "
- "Reducing allocation request to %d.\n",
- phba->brd_no, vport->vpi, num_to_alloc,
- phba->cfg_hba_queue_depth,
- (phba->cfg_hba_queue_depth - total));
+ lpfc_printf_vlog(vport, KERN_WARNING, LOG_FCP,
+ "0705 Allocation request of %d "
+ "command buffers will exceed max of %d. "
+ "Reducing allocation request to %d.\n",
+ num_to_alloc, phba->cfg_hba_queue_depth,
+ (phba->cfg_hba_queue_depth - total));
num_to_alloc = phba->cfg_hba_queue_depth - total;
}
for (i = 0; i < num_to_alloc; i++) {
scsi_buf = lpfc_new_scsi_buf(vport);
if (!scsi_buf) {
- lpfc_printf_log(phba, KERN_ERR, LOG_FCP,
- "%d (%d):0706 Failed to allocate "
- "command buffer\n",
- phba->brd_no, vport->vpi);
+ lpfc_printf_vlog(vport, KERN_ERR, LOG_FCP,
+ "0706 Failed to allocate "
+ "command buffer\n");
break;
}
@@ -1439,9 +1396,9 @@
struct fc_rport *rport = starget_to_rport(sdev->sdev_target);
if (sdev->tagged_supported)
- scsi_activate_tcq(sdev, phba->cfg_lun_queue_depth);
+ scsi_activate_tcq(sdev, vport->cfg_lun_queue_depth);
else
- scsi_deactivate_tcq(sdev, phba->cfg_lun_queue_depth);
+ scsi_deactivate_tcq(sdev, vport->cfg_lun_queue_depth);
/*
* Initialize the fc transport attributes for the target
@@ -1449,7 +1406,7 @@
* target pointer is stored in the starget_data for the
* driver's sysfs entry point functions.
*/
- rport->dev_loss_tmo = phba->cfg_devloss_tmo;
+ rport->dev_loss_tmo = vport->cfg_devloss_tmo;
if (phba->cfg_poll & ENABLE_FCP_RING_POLLING) {
lpfc_sli_poll_fcp_ring(phba);
@@ -1487,3 +1444,23 @@
.shost_attrs = lpfc_hba_attrs,
.max_sectors = 0xFFFF,
};
+
+struct scsi_host_template lpfc_vport_template = {
+ .module = THIS_MODULE,
+ .name = LPFC_DRIVER_NAME,
+ .info = lpfc_info,
+ .queuecommand = lpfc_queuecommand,
+ .eh_abort_handler = lpfc_abort_handler,
+ .eh_device_reset_handler= lpfc_device_reset_handler,
+ .eh_bus_reset_handler = lpfc_bus_reset_handler,
+ .slave_alloc = lpfc_slave_alloc,
+ .slave_configure = lpfc_slave_configure,
+ .slave_destroy = lpfc_slave_destroy,
+ .scan_finished = lpfc_scan_finished,
+ .this_id = -1,
+ .sg_tablesize = LPFC_SG_SEG_CNT,
+ .cmd_per_lun = LPFC_CMD_PER_LUN,
+ .use_clustering = ENABLE_CLUSTERING,
+ .shost_attrs = lpfc_vport_attrs,
+ .max_sectors = 0xFFFF,
+};
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c
index f4d5a6b..ce5ff2b 100644
--- a/drivers/scsi/lpfc/lpfc_sli.c
+++ b/drivers/scsi/lpfc/lpfc_sli.c
@@ -49,9 +49,8 @@
lpfc_printf_log(phba, \
KERN_INFO, \
LOG_MBOX | LOG_SLI, \
- "%d (%d):0311 Mailbox command x%x cannot " \
+ "(%d):0311 Mailbox command x%x cannot " \
"issue Data: x%x x%x x%x\n", \
- phba->brd_no, \
pmbox->vport ? pmbox->vport->vpi : 0, \
pmbox->mb.mbxCommand, \
phba->pport->port_state, \
@@ -231,13 +230,11 @@
rc = lpfc_sli_issue_mbox(phba, pmb, MBX_POLL);
if (rc != MBX_SUCCESS) {
lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
- "%d:0446 Adapter failed to init (%d), "
+ "0446 Adapter failed to init (%d), "
"mbxCmd x%x CFG_RING, mbxStatus x%x, "
"ring %d\n",
- phba->brd_no, rc,
- pmbox->mbxCommand,
- pmbox->mbxStatus,
- i);
+ rc, pmbox->mbxCommand,
+ pmbox->mbxStatus, i);
phba->link_state = LPFC_HBA_ERROR;
ret = -ENXIO;
break;
@@ -296,9 +293,9 @@
if (unlikely(pring->local_getidx >= max_cmd_idx)) {
lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
- "%d:0315 Ring %d issue: portCmdGet %d "
+ "0315 Ring %d issue: portCmdGet %d "
"is bigger then cmd ring %d\n",
- phba->brd_no, pring->ringno,
+ pring->ringno,
pring->local_getidx, max_cmd_idx);
phba->link_state = LPFC_HBA_ERROR;
@@ -366,7 +363,7 @@
if (psli->iocbq_lookup)
memcpy(new_arr, old_arr,
((psli->last_iotag + 1) *
- sizeof (struct lpfc_iocbq *)));
+ sizeof (struct lpfc_iocbq *)));
psli->iocbq_lookup = new_arr;
psli->iocbq_lookup_len = new_len;
psli->last_iotag = iotag;
@@ -380,8 +377,8 @@
spin_unlock_irq(&phba->hbalock);
lpfc_printf_log(phba, KERN_ERR,LOG_SLI,
- "%d:0318 Failed to allocate IOTAG.last IOTAG is %d\n",
- phba->brd_no, psli->last_iotag);
+ "0318 Failed to allocate IOTAG.last IOTAG is %d\n",
+ psli->last_iotag);
return 0;
}
@@ -395,6 +392,14 @@
*/
nextiocb->iocb.ulpIoTag = (nextiocb->iocb_cmpl) ? nextiocb->iotag : 0;
+ if (pring->ringno == LPFC_ELS_RING) {
+ lpfc_debugfs_slow_ring_trc(phba,
+ "IOCB cmd ring: wd4:x%08x wd6:x%08x wd7:x%08x",
+ *(((uint32_t *) &nextiocb->iocb) + 4),
+ *(((uint32_t *) &nextiocb->iocb) + 6),
+ *(((uint32_t *) &nextiocb->iocb) + 7));
+ }
+
/*
* Issue iocb command to adapter
*/
@@ -527,10 +532,9 @@
if (unlikely(hbqp->local_hbqGetIdx >= hbqp->entry_count)) {
lpfc_printf_log(phba, KERN_ERR,
LOG_SLI | LOG_VPORT,
- "%d:1802 HBQ %d: local_hbqGetIdx "
+ "1802 HBQ %d: local_hbqGetIdx "
"%u is > than hbqp->entry_count %u\n",
- phba->brd_no, hbqno,
- hbqp->local_hbqGetIdx,
+ hbqno, hbqp->local_hbqGetIdx,
hbqp->entry_count);
phba->link_state = LPFC_HBA_ERROR;
@@ -541,7 +545,8 @@
return NULL;
}
- return (struct lpfc_hbq_entry *) phba->hbqslimp.virt + hbqp->hbqPutIdx;
+ return (struct lpfc_hbq_entry *) phba->hbqs[hbqno].hbq_virt +
+ hbqp->hbqPutIdx;
}
void
@@ -549,18 +554,21 @@
{
struct lpfc_dmabuf *dmabuf, *next_dmabuf;
struct hbq_dmabuf *hbq_buf;
+ int i, hbq_count;
+ hbq_count = lpfc_sli_hbq_count();
/* Return all memory used by all HBQs */
- list_for_each_entry_safe(dmabuf, next_dmabuf,
- &phba->hbq_buffer_list, list) {
- hbq_buf = container_of(dmabuf, struct hbq_dmabuf, dbuf);
- list_del(&hbq_buf->dbuf.list);
- lpfc_hbq_free(phba, hbq_buf->dbuf.virt, hbq_buf->dbuf.phys);
- kfree(hbq_buf);
+ for (i = 0; i < hbq_count; ++i) {
+ list_for_each_entry_safe(dmabuf, next_dmabuf,
+ &phba->hbqs[i].hbq_buffer_list, list) {
+ hbq_buf = container_of(dmabuf, struct hbq_dmabuf, dbuf);
+ list_del(&hbq_buf->dbuf.list);
+ (phba->hbqs[i].hbq_free_buffer)(phba, hbq_buf);
+ }
}
}
-static void
+static struct lpfc_hbq_entry *
lpfc_sli_hbq_to_firmware(struct lpfc_hba *phba, uint32_t hbqno,
struct hbq_dmabuf *hbq_buf)
{
@@ -574,7 +582,7 @@
hbqe->bde.addrHigh = le32_to_cpu(putPaddrHigh(physaddr));
hbqe->bde.addrLow = le32_to_cpu(putPaddrLow(physaddr));
- hbqe->bde.tus.f.bdeSize = FCELSSIZE;
+ hbqe->bde.tus.f.bdeSize = hbq_buf->size;
hbqe->bde.tus.f.bdeFlags = 0;
hbqe->bde.tus.w = le32_to_cpu(hbqe->bde.tus.w);
hbqe->buffer_tag = le32_to_cpu(hbq_buf->tag);
@@ -583,8 +591,9 @@
writel(hbqp->hbqPutIdx, phba->hbq_put + hbqno);
/* flush */
readl(phba->hbq_put + hbqno);
- list_add_tail(&hbq_buf->dbuf.list, &phba->hbq_buffer_list);
+ list_add_tail(&hbq_buf->dbuf.list, &hbqp->hbq_buffer_list);
}
+ return hbqe;
}
static struct lpfc_hbq_init lpfc_els_hbq = {
@@ -592,22 +601,38 @@
.entry_count = 200,
.mask_count = 0,
.profile = 0,
- .ring_mask = 1 << LPFC_ELS_RING,
+ .ring_mask = (1 << LPFC_ELS_RING),
.buffer_count = 0,
.init_count = 20,
.add_count = 5,
};
-static struct lpfc_hbq_init *lpfc_hbq_defs[] = {
- &lpfc_els_hbq,
+static struct lpfc_hbq_init lpfc_extra_hbq = {
+ .rn = 1,
+ .entry_count = 200,
+ .mask_count = 0,
+ .profile = 0,
+ .ring_mask = (1 << LPFC_EXTRA_RING),
+ .buffer_count = 0,
+ .init_count = 0,
+ .add_count = 5,
};
-int
+struct lpfc_hbq_init *lpfc_hbq_defs[] = {
+ &lpfc_els_hbq,
+ &lpfc_extra_hbq,
+};
+
+static int
lpfc_sli_hbqbuf_fill_hbqs(struct lpfc_hba *phba, uint32_t hbqno, uint32_t count)
{
uint32_t i, start, end;
struct hbq_dmabuf *hbq_buffer;
+ if (!phba->hbqs[hbqno].hbq_alloc_buffer) {
+ return 0;
+ }
+
start = lpfc_hbq_defs[hbqno]->buffer_count;
end = count + lpfc_hbq_defs[hbqno]->buffer_count;
if (end > lpfc_hbq_defs[hbqno]->entry_count) {
@@ -616,17 +641,14 @@
/* Populate HBQ entries */
for (i = start; i < end; i++) {
- hbq_buffer = kmalloc(sizeof(struct hbq_dmabuf),
- GFP_KERNEL);
+ hbq_buffer = (phba->hbqs[hbqno].hbq_alloc_buffer)(phba);
if (!hbq_buffer)
return 1;
- hbq_buffer->dbuf.virt = lpfc_hbq_alloc(phba, MEM_PRI,
- &hbq_buffer->dbuf.phys);
- if (hbq_buffer->dbuf.virt == NULL)
- return 1;
hbq_buffer->tag = (i | (hbqno << 16));
- lpfc_sli_hbq_to_firmware(phba, hbqno, hbq_buffer);
- lpfc_hbq_defs[hbqno]->buffer_count++;
+ if (lpfc_sli_hbq_to_firmware(phba, hbqno, hbq_buffer))
+ lpfc_hbq_defs[hbqno]->buffer_count++;
+ else
+ (phba->hbqs[hbqno].hbq_free_buffer)(phba, hbq_buffer);
}
return 0;
}
@@ -650,28 +672,34 @@
{
struct lpfc_dmabuf *d_buf;
struct hbq_dmabuf *hbq_buf;
+ uint32_t hbqno;
- list_for_each_entry(d_buf, &phba->hbq_buffer_list, list) {
+ hbqno = tag >> 16;
+ if (hbqno > LPFC_MAX_HBQS)
+ return NULL;
+
+ list_for_each_entry(d_buf, &phba->hbqs[hbqno].hbq_buffer_list, list) {
hbq_buf = container_of(d_buf, struct hbq_dmabuf, dbuf);
- if ((hbq_buf->tag & 0xffff) == tag) {
+ if (hbq_buf->tag == tag) {
return hbq_buf;
}
}
lpfc_printf_log(phba, KERN_ERR, LOG_SLI | LOG_VPORT,
- "%d:1803 Bad hbq tag. Data: x%x x%x\n",
- phba->brd_no, tag,
- lpfc_hbq_defs[tag >> 16]->buffer_count);
+ "1803 Bad hbq tag. Data: x%x x%x\n",
+ tag, lpfc_hbq_defs[tag >> 16]->buffer_count);
return NULL;
}
void
-lpfc_sli_free_hbq(struct lpfc_hba *phba, struct hbq_dmabuf *sp)
+lpfc_sli_free_hbq(struct lpfc_hba *phba, struct hbq_dmabuf *hbq_buffer)
{
uint32_t hbqno;
- if (sp) {
- hbqno = sp->tag >> 16;
- lpfc_sli_hbq_to_firmware(phba, hbqno, sp);
+ if (hbq_buffer) {
+ hbqno = hbq_buffer->tag >> 16;
+ if (!lpfc_sli_hbq_to_firmware(phba, hbqno, hbq_buffer)) {
+ (phba->hbqs[hbqno].hbq_free_buffer)(phba, hbq_buffer);
+ }
}
}
@@ -837,12 +865,10 @@
*/
if (lpfc_sli_chk_mbx_command(pmbox->mbxCommand) ==
MBX_SHUTDOWN) {
-
/* Unknow mailbox command compl */
lpfc_printf_log(phba, KERN_ERR, LOG_MBOX | LOG_SLI,
- "%d (%d):0323 Unknown Mailbox command "
+ "(%d):0323 Unknown Mailbox command "
"%x Cmpl\n",
- phba->brd_no,
pmb->vport ? pmb->vport->vpi : 0,
pmbox->mbxCommand);
phba->link_state = LPFC_HBA_ERROR;
@@ -857,10 +883,9 @@
/* Mbox cmd cmpl error - RETRYing */
lpfc_printf_log(phba, KERN_INFO,
LOG_MBOX | LOG_SLI,
- "%d (%d):0305 Mbox cmd cmpl "
+ "(%d):0305 Mbox cmd cmpl "
"error - RETRYing Data: x%x "
"x%x x%x x%x\n",
- phba->brd_no,
pmb->vport ? pmb->vport->vpi :0,
pmbox->mbxCommand,
pmbox->mbxStatus,
@@ -879,9 +904,8 @@
/* Mailbox cmd <cmd> Cmpl <cmpl> */
lpfc_printf_log(phba, KERN_INFO, LOG_MBOX | LOG_SLI,
- "%d (%d):0307 Mailbox cmd x%x Cmpl x%p "
+ "(%d):0307 Mailbox cmd x%x Cmpl x%p "
"Data: x%x x%x x%x x%x x%x x%x x%x x%x x%x\n",
- phba->brd_no,
pmb->vport ? pmb->vport->vpi : 0,
pmbox->mbxCommand,
pmb->mbox_cmpl,
@@ -905,21 +929,26 @@
lpfc_sli_replace_hbqbuff(struct lpfc_hba *phba, uint32_t tag)
{
struct hbq_dmabuf *hbq_entry, *new_hbq_entry;
+ uint32_t hbqno;
+ void *virt; /* virtual address ptr */
+ dma_addr_t phys; /* mapped address */
hbq_entry = lpfc_sli_hbqbuf_find(phba, tag);
if (hbq_entry == NULL)
return NULL;
list_del(&hbq_entry->dbuf.list);
- new_hbq_entry = kmalloc(sizeof(struct hbq_dmabuf), GFP_ATOMIC);
+
+ hbqno = tag >> 16;
+ new_hbq_entry = (phba->hbqs[hbqno].hbq_alloc_buffer)(phba);
if (new_hbq_entry == NULL)
return &hbq_entry->dbuf;
- new_hbq_entry->dbuf = hbq_entry->dbuf;
new_hbq_entry->tag = -1;
- hbq_entry->dbuf.virt = lpfc_hbq_alloc(phba, 0, &hbq_entry->dbuf.phys);
- if (hbq_entry->dbuf.virt == NULL) {
- kfree(new_hbq_entry);
- return &hbq_entry->dbuf;
- }
+ phys = new_hbq_entry->dbuf.phys;
+ virt = new_hbq_entry->dbuf.virt;
+ new_hbq_entry->dbuf.phys = hbq_entry->dbuf.phys;
+ new_hbq_entry->dbuf.virt = hbq_entry->dbuf.virt;
+ hbq_entry->dbuf.phys = phys;
+ hbq_entry->dbuf.virt = virt;
lpfc_sli_free_hbq(phba, hbq_entry);
return &new_hbq_entry->dbuf;
}
@@ -965,7 +994,7 @@
irsp->un.ulpWord[3]);
if (irsp->ulpBdeCount == 2)
saveq->context3 = lpfc_sli_replace_hbqbuff(phba,
- irsp->un.ulpWord[15]);
+ irsp->unsli3.sli3Words[7]);
}
/* unSolicited Responses */
@@ -996,12 +1025,9 @@
/* Ring <ringno> handler: unexpected
Rctl <Rctl> Type <Type> received */
lpfc_printf_log(phba, KERN_WARNING, LOG_SLI,
- "%d:0313 Ring %d handler: unexpected Rctl x%x "
+ "0313 Ring %d handler: unexpected Rctl x%x "
"Type x%x received\n",
- phba->brd_no,
- pring->ringno,
- Rctl,
- Type);
+ pring->ringno, Rctl, Type);
}
return 1;
}
@@ -1024,10 +1050,9 @@
}
lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
- "%d:0317 iotag x%x is out off "
+ "0317 iotag x%x is out off "
"range: max iotag x%x wd0 x%x\n",
- phba->brd_no, iotag,
- phba->sli.last_iotag,
+ iotag, phba->sli.last_iotag,
*(((uint32_t *) &prspiocb->iocb) + 7));
return NULL;
}
@@ -1075,18 +1100,16 @@
* Ring <ringno> handler: unexpected completion IoTag
* <IoTag>
*/
- lpfc_printf_log(phba, KERN_WARNING, LOG_SLI,
- "%d (%d):0322 Ring %d handler: "
- "unexpected completion IoTag x%x "
- "Data: x%x x%x x%x x%x\n",
- phba->brd_no,
- cmdiocbp->vport->vpi,
- pring->ringno,
- saveq->iocb.ulpIoTag,
- saveq->iocb.ulpStatus,
- saveq->iocb.un.ulpWord[4],
- saveq->iocb.ulpCommand,
- saveq->iocb.ulpContext);
+ lpfc_printf_vlog(cmdiocbp->vport, KERN_WARNING, LOG_SLI,
+ "0322 Ring %d handler: "
+ "unexpected completion IoTag x%x "
+ "Data: x%x x%x x%x x%x\n",
+ pring->ringno,
+ saveq->iocb.ulpIoTag,
+ saveq->iocb.ulpStatus,
+ saveq->iocb.un.ulpWord[4],
+ saveq->iocb.ulpCommand,
+ saveq->iocb.ulpContext);
}
}
@@ -1104,10 +1127,9 @@
* rsp ring <portRspMax>
*/
lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
- "%d:0312 Ring %d handler: portRspPut %d "
+ "0312 Ring %d handler: portRspPut %d "
"is bigger then rsp ring %d\n",
- phba->brd_no, pring->ringno,
- le32_to_cpu(pgp->rspPutInx),
+ pring->ringno, le32_to_cpu(pgp->rspPutInx),
pring->numRiocb);
phba->link_state = LPFC_HBA_ERROR;
@@ -1177,9 +1199,9 @@
if (unlikely(irsp->ulpStatus)) {
/* Rsp ring <ringno> error: IOCB */
lpfc_printf_log(phba, KERN_WARNING, LOG_SLI,
- "%d:0326 Rsp Ring %d error: IOCB Data: "
+ "0326 Rsp Ring %d error: IOCB Data: "
"x%x x%x x%x x%x x%x x%x x%x x%x\n",
- phba->brd_no, pring->ringno,
+ pring->ringno,
irsp->un.ulpWord[0],
irsp->un.ulpWord[1],
irsp->un.ulpWord[2],
@@ -1199,9 +1221,9 @@
*/
if (unlikely(irsp->ulpCommand == CMD_XRI_ABORTED_CX)) {
lpfc_printf_log(phba, KERN_INFO, LOG_SLI,
- "%d:0314 IOCB cmd 0x%x"
- " processed. Skipping"
- " completion", phba->brd_no,
+ "0314 IOCB cmd 0x%x "
+ "processed. Skipping "
+ "completion",
irsp->ulpCommand);
break;
}
@@ -1226,10 +1248,9 @@
} else {
/* Unknown IOCB command */
lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
- "%d:0321 Unknown IOCB command "
+ "0321 Unknown IOCB command "
"Data: x%x, x%x x%x x%x x%x\n",
- phba->brd_no, type,
- irsp->ulpCommand,
+ type, irsp->ulpCommand,
irsp->ulpStatus,
irsp->ulpIoTag,
irsp->ulpContext);
@@ -1353,9 +1374,9 @@
/* Rsp ring <ringno> error: IOCB */
lpfc_printf_log(phba, KERN_WARNING, LOG_SLI,
- "%d:0336 Rsp Ring %d error: IOCB Data: "
+ "0336 Rsp Ring %d error: IOCB Data: "
"x%x x%x x%x x%x x%x x%x x%x x%x\n",
- phba->brd_no, pring->ringno,
+ pring->ringno,
irsp->un.ulpWord[0],
irsp->un.ulpWord[1],
irsp->un.ulpWord[2],
@@ -1375,10 +1396,9 @@
*/
if (unlikely(irsp->ulpCommand == CMD_XRI_ABORTED_CX)) {
lpfc_printf_log(phba, KERN_INFO, LOG_SLI,
- "%d:0333 IOCB cmd 0x%x"
+ "0333 IOCB cmd 0x%x"
" processed. Skipping"
" completion\n",
- phba->brd_no,
irsp->ulpCommand);
break;
}
@@ -1415,10 +1435,9 @@
} else {
/* Unknown IOCB command */
lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
- "%d:0334 Unknown IOCB command "
+ "0334 Unknown IOCB command "
"Data: x%x, x%x x%x x%x x%x\n",
- phba->brd_no, type,
- irsp->ulpCommand,
+ type, irsp->ulpCommand,
irsp->ulpStatus,
irsp->ulpIoTag,
irsp->ulpContext);
@@ -1496,10 +1515,9 @@
* rsp ring <portRspMax>
*/
lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
- "%d:0303 Ring %d handler: portRspPut %d "
+ "0303 Ring %d handler: portRspPut %d "
"is bigger then rsp ring %d\n",
- phba->brd_no, pring->ringno, portRspPut,
- portRspMax);
+ pring->ringno, portRspPut, portRspMax);
phba->link_state = LPFC_HBA_ERROR;
spin_unlock_irqrestore(&phba->hbalock, iflag);
@@ -1542,6 +1560,14 @@
if (++pring->rspidx >= portRspMax)
pring->rspidx = 0;
+ if (pring->ringno == LPFC_ELS_RING) {
+ lpfc_debugfs_slow_ring_trc(phba,
+ "IOCB rsp ring: wd4:x%08x wd6:x%08x wd7:x%08x",
+ *(((uint32_t *) irsp) + 4),
+ *(((uint32_t *) irsp) + 6),
+ *(((uint32_t *) irsp) + 7));
+ }
+
writel(pring->rspidx, &phba->host_gp[pring->ringno].rspGetInx);
if (list_empty(&(pring->iocb_continueq))) {
@@ -1580,13 +1606,12 @@
if (irsp->ulpStatus) {
/* Rsp ring <ringno> error: IOCB */
lpfc_printf_log(phba, KERN_WARNING, LOG_SLI,
- "%d:0328 Rsp Ring %d error: "
+ "0328 Rsp Ring %d error: "
"IOCB Data: "
"x%x x%x x%x x%x "
"x%x x%x x%x x%x "
"x%x x%x x%x x%x "
"x%x x%x x%x x%x\n",
- phba->brd_no,
pring->ringno,
irsp->un.ulpWord[0],
irsp->un.ulpWord[1],
@@ -1661,10 +1686,9 @@
} else {
/* Unknown IOCB command */
lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
- "%d:0335 Unknown IOCB "
+ "0335 Unknown IOCB "
"command Data: x%x "
"x%x x%x x%x\n",
- phba->brd_no,
irsp->ulpCommand,
irsp->ulpStatus,
irsp->ulpIoTag,
@@ -1892,8 +1916,8 @@
/* Kill HBA */
lpfc_printf_log(phba, KERN_INFO, LOG_SLI,
- "%d:0329 Kill HBA Data: x%x x%x\n",
- phba->brd_no, phba->pport->port_state, psli->sli_flag);
+ "0329 Kill HBA Data: x%x x%x\n",
+ phba->pport->port_state, psli->sli_flag);
if ((pmb = (LPFC_MBOXQ_t *) mempool_alloc(phba->mbox_mem_pool,
GFP_KERNEL)) == 0)
@@ -1966,7 +1990,7 @@
/* Reset HBA */
lpfc_printf_log(phba, KERN_INFO, LOG_SLI,
- "%d:0325 Reset HBA Data: x%x x%x\n", phba->brd_no,
+ "0325 Reset HBA Data: x%x x%x\n",
phba->pport->port_state, psli->sli_flag);
/* perform board reset */
@@ -2021,7 +2045,7 @@
/* Restart HBA */
lpfc_printf_log(phba, KERN_INFO, LOG_SLI,
- "%d:0337 Restart HBA Data: x%x x%x\n", phba->brd_no,
+ "0337 Restart HBA Data: x%x x%x\n",
phba->pport->port_state, psli->sli_flag);
word0 = 0;
@@ -2086,9 +2110,8 @@
/* Adapter failed to init, timeout, status reg
<status> */
lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
- "%d:0436 Adapter failed to init, "
- "timeout, status reg x%x\n",
- phba->brd_no, status);
+ "0436 Adapter failed to init, "
+ "timeout, status reg x%x\n", status);
phba->link_state = LPFC_HBA_ERROR;
return -ETIMEDOUT;
}
@@ -2099,10 +2122,8 @@
/* Adapter failed to init, chipset, status reg
<status> */
lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
- "%d:0437 Adapter failed to init, "
- "chipset, status reg x%x\n",
- phba->brd_no,
- status);
+ "0437 Adapter failed to init, "
+ "chipset, status reg x%x\n", status);
phba->link_state = LPFC_HBA_ERROR;
return -EIO;
}
@@ -2129,10 +2150,8 @@
/* ERROR: During chipset initialization */
/* Adapter failed to init, chipset, status reg <status> */
lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
- "%d:0438 Adapter failed to init, chipset, "
- "status reg x%x\n",
- phba->brd_no,
- status);
+ "0438 Adapter failed to init, chipset, "
+ "status reg x%x\n", status);
phba->link_state = LPFC_HBA_ERROR;
return -EIO;
}
@@ -2147,7 +2166,7 @@
return 0;
}
-static int
+int
lpfc_sli_hbq_count(void)
{
return ARRAY_SIZE(lpfc_hbq_defs);
@@ -2200,8 +2219,8 @@
phba->hbqs[hbqno].local_hbqGetIdx = 0;
phba->hbqs[hbqno].entry_count =
lpfc_hbq_defs[hbqno]->entry_count;
- lpfc_config_hbq(phba, lpfc_hbq_defs[hbqno], hbq_entry_index,
- pmb);
+ lpfc_config_hbq(phba, hbqno, lpfc_hbq_defs[hbqno],
+ hbq_entry_index, pmb);
hbq_entry_index += phba->hbqs[hbqno].entry_count;
if (lpfc_sli_issue_mbox(phba, pmb, MBX_POLL) != MBX_SUCCESS) {
@@ -2210,9 +2229,9 @@
lpfc_printf_log(phba, KERN_ERR,
LOG_SLI | LOG_VPORT,
- "%d:1805 Adapter failed to init. "
+ "1805 Adapter failed to init. "
"Data: x%x x%x x%x\n",
- phba->brd_no, pmbox->mbxCommand,
+ pmbox->mbxCommand,
pmbox->mbxStatus, hbqno);
phba->link_state = LPFC_HBA_ERROR;
@@ -2279,10 +2298,9 @@
rc = lpfc_sli_issue_mbox(phba, pmb, MBX_POLL);
if (rc != MBX_SUCCESS) {
lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
- "%d:0442 Adapter failed to init, mbxCmd x%x "
+ "0442 Adapter failed to init, mbxCmd x%x "
"CONFIG_PORT, mbxStatus x%x Data: x%x\n",
- phba->brd_no, pmb->mb.mbxCommand,
- pmb->mb.mbxStatus, 0);
+ pmb->mb.mbxCommand, pmb->mb.mbxStatus, 0);
spin_lock_irq(&phba->hbalock);
phba->sli.sli_flag &= ~LPFC_SLI2_ACTIVE;
spin_unlock_irq(&phba->hbalock);
@@ -2321,11 +2339,11 @@
switch (lpfc_sli_mode) {
case 2:
- if (phba->cfg_npiv_enable) {
+ if (phba->cfg_enable_npiv) {
lpfc_printf_log(phba, KERN_ERR, LOG_INIT | LOG_VPORT,
- "%d:1824 NPIV enabled: Override lpfc_sli_mode "
+ "1824 NPIV enabled: Override lpfc_sli_mode "
"parameter (%d) to auto (0).\n",
- phba->brd_no, lpfc_sli_mode);
+ lpfc_sli_mode);
break;
}
mode = 2;
@@ -2335,9 +2353,8 @@
break;
default:
lpfc_printf_log(phba, KERN_ERR, LOG_INIT | LOG_VPORT,
- "%d:1819 Unrecognized lpfc_sli_mode "
- "parameter: %d.\n",
- phba->brd_no, lpfc_sli_mode);
+ "1819 Unrecognized lpfc_sli_mode "
+ "parameter: %d.\n", lpfc_sli_mode);
break;
}
@@ -2345,9 +2362,8 @@
rc = lpfc_do_config_port(phba, mode);
if (rc && lpfc_sli_mode == 3)
lpfc_printf_log(phba, KERN_ERR, LOG_INIT | LOG_VPORT,
- "%d:1820 Unable to select SLI-3. "
- "Not supported by adapter.\n",
- phba->brd_no);
+ "1820 Unable to select SLI-3. "
+ "Not supported by adapter.\n");
if (rc && mode != 2)
rc = lpfc_do_config_port(phba, 2);
if (rc)
@@ -2366,8 +2382,8 @@
}
lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
- "%d:0444 Firmware in SLI %x mode. Max_vpi %d\n",
- phba->brd_no, phba->sli_rev, phba->max_vpi);
+ "0444 Firmware in SLI %x mode. Max_vpi %d\n",
+ phba->sli_rev, phba->max_vpi);
rc = lpfc_sli_ring_map(phba);
if (rc)
@@ -2392,8 +2408,7 @@
lpfc_sli_hba_setup_error:
phba->link_state = LPFC_HBA_ERROR;
lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
- "%d:0445 Firmware initialization failed\n",
- phba->brd_no);
+ "0445 Firmware initialization failed\n");
return rc;
}
@@ -2445,9 +2460,7 @@
/* Mbox cmd <mbxCommand> timeout */
lpfc_printf_log(phba, KERN_ERR, LOG_MBOX | LOG_SLI,
- "%d:0310 Mailbox command x%x timeout Data: x%x x%x "
- "x%p\n",
- phba->brd_no,
+ "0310 Mailbox command x%x timeout Data: x%x x%x x%p\n",
mb->mbxCommand,
phba->pport->port_state,
phba->sli.sli_flag,
@@ -2470,8 +2483,7 @@
lpfc_sli_abort_iocb_ring(phba, pring);
lpfc_printf_log(phba, KERN_ERR, LOG_MBOX | LOG_SLI,
- "%d:0316 Resetting board due to mailbox timeout\n",
- phba->brd_no);
+ "0316 Resetting board due to mailbox timeout\n");
/*
* lpfc_offline calls lpfc_sli_hba_down which will clean up
* on oustanding mailbox commands.
@@ -2502,8 +2514,7 @@
if(!pmbox->vport) {
lpfc_printf_log(phba, KERN_ERR,
LOG_MBOX | LOG_VPORT,
- "%d:1806 Mbox x%x failed. No vport\n",
- phba->brd_no,
+ "1806 Mbox x%x failed. No vport\n",
pmbox->mb.mbxCommand);
dump_stack();
return MBXERR_ERROR;
@@ -2580,9 +2591,8 @@
/* Mbox cmd issue - BUSY */
lpfc_printf_log(phba, KERN_INFO, LOG_MBOX | LOG_SLI,
- "%d (%d):0308 Mbox cmd issue - BUSY Data: "
+ "(%d):0308 Mbox cmd issue - BUSY Data: "
"x%x x%x x%x x%x\n",
- phba->brd_no,
pmbox->vport ? pmbox->vport->vpi : 0xffffff,
mb->mbxCommand, phba->pport->port_state,
psli->sli_flag, flag);
@@ -2644,9 +2654,9 @@
/* Mailbox cmd <cmd> issue */
lpfc_printf_log(phba, KERN_INFO, LOG_MBOX | LOG_SLI,
- "%d (%d):0309 Mailbox cmd x%x issue Data: x%x x%x "
+ "(%d):0309 Mailbox cmd x%x issue Data: x%x x%x "
"x%x\n",
- phba->brd_no, pmbox->vport ? pmbox->vport->vpi : 0,
+ pmbox->vport ? pmbox->vport->vpi : 0,
mb->mbxCommand, phba->pport->port_state,
psli->sli_flag, flag);
@@ -2848,8 +2858,7 @@
(piocb->iocb.ulpCommand != CMD_CLOSE_XRI_CN)) {
lpfc_printf_log(phba, KERN_ERR,
LOG_SLI | LOG_VPORT,
- "%d:1807 IOCB x%x failed. No vport\n",
- phba->brd_no,
+ "1807 IOCB x%x failed. No vport\n",
piocb->iocb.ulpCommand);
dump_stack();
return IOCB_ERROR;
@@ -3080,11 +3089,10 @@
}
if (totiocbsize > MAX_SLIM_IOCB_SIZE) {
/* Too many cmd / rsp ring entries in SLI2 SLIM */
- lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
- "%d:0462 Too many cmd / rsp ring entries in "
- "SLI2 SLIM Data: x%x x%lx\n",
- phba->brd_no, totiocbsize,
- (unsigned long) MAX_SLIM_IOCB_SIZE);
+ printk(KERN_ERR "%d:0462 Too many cmd / rsp ring entries in "
+ "SLI2 SLIM Data: x%x x%lx\n",
+ phba->brd_no, totiocbsize,
+ (unsigned long) MAX_SLIM_IOCB_SIZE);
}
if (phba->cfg_multi_ring_support == 2)
lpfc_extra_ring_setup(phba);
@@ -3305,9 +3313,9 @@
spin_unlock_irq(&phba->hbalock);
lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
- "%d:0410 Cannot find virtual addr for mapped buf on "
+ "0410 Cannot find virtual addr for mapped buf on "
"ring %d Data x%llx x%p x%p x%x\n",
- phba->brd_no, pring->ringno, (unsigned long long)phys,
+ pring->ringno, (unsigned long long)phys,
slp->next, slp->prev, pring->postbufq_cnt);
return NULL;
}
@@ -3332,12 +3340,11 @@
abort_iocb = phba->sli.iocbq_lookup[abort_iotag];
lpfc_printf_log(phba, KERN_INFO, LOG_ELS | LOG_SLI,
- "%d:0327 Cannot abort els iocb %p "
+ "0327 Cannot abort els iocb %p "
"with tag %x context %x, abort status %x, "
"abort code %x\n",
- phba->brd_no, abort_iocb, abort_iotag,
- abort_context, irsp->ulpStatus,
- irsp->un.ulpWord[4]);
+ abort_iocb, abort_iotag, abort_context,
+ irsp->ulpStatus, irsp->un.ulpWord[4]);
/*
* make sure we have the right iocbq before taking it
@@ -3371,9 +3378,9 @@
/* ELS cmd tag <ulpIoTag> completes */
lpfc_printf_log(phba, KERN_INFO, LOG_ELS,
- "%d (X):0133 Ignoring ELS cmd tag x%x completion Data: "
+ "0133 Ignoring ELS cmd tag x%x completion Data: "
"x%x x%x x%x\n",
- phba->brd_no, irsp->ulpIoTag, irsp->ulpStatus,
+ irsp->ulpIoTag, irsp->ulpStatus,
irsp->un.ulpWord[4], irsp->ulpTimeout);
if (cmdiocb->iocb.ulpCommand == CMD_GEN_REQUEST64_CR)
lpfc_ct_free_iocb(phba, cmdiocb);
@@ -3439,12 +3446,11 @@
abtsiocbp->iocb_cmpl = lpfc_sli_abort_els_cmpl;
- lpfc_printf_log(phba, KERN_INFO, LOG_SLI,
- "%d (%d):0339 Abort xri x%x, original iotag x%x, "
- "abort cmd iotag x%x\n",
- phba->brd_no, vport->vpi,
- iabt->un.acxri.abortContextTag,
- iabt->un.acxri.abortIoTag, abtsiocbp->iotag);
+ lpfc_printf_vlog(vport, KERN_INFO, LOG_SLI,
+ "0339 Abort xri x%x, original iotag x%x, "
+ "abort cmd iotag x%x\n",
+ iabt->un.acxri.abortContextTag,
+ iabt->un.acxri.abortIoTag, abtsiocbp->iotag);
retval = __lpfc_sli_issue_iocb(phba, pring, abtsiocbp, 0);
abort_iotag_exit:
@@ -3457,8 +3463,8 @@
}
static int
-lpfc_sli_validate_fcp_iocb(struct lpfc_iocbq *iocbq, uint16_t tgt_id,
- uint64_t lun_id, uint32_t ctx,
+lpfc_sli_validate_fcp_iocb(struct lpfc_iocbq *iocbq, struct lpfc_vport *vport,
+ uint16_t tgt_id, uint64_t lun_id,
lpfc_ctx_cmd ctx_cmd)
{
struct lpfc_scsi_buf *lpfc_cmd;
@@ -3468,6 +3474,9 @@
if (!(iocbq->iocb_flag & LPFC_IO_FCP))
return rc;
+ if (iocbq->vport != vport)
+ return rc;
+
lpfc_cmd = container_of(iocbq, struct lpfc_scsi_buf, cur_iocbq);
cmnd = lpfc_cmd->pCmd;
@@ -3484,10 +3493,6 @@
if (cmnd->device->id == tgt_id)
rc = 0;
break;
- case LPFC_CTX_CTX:
- if (iocbq->iocb.ulpContext == ctx)
- rc = 0;
- break;
case LPFC_CTX_HOST:
rc = 0;
break;
@@ -3501,17 +3506,18 @@
}
int
-lpfc_sli_sum_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
- uint16_t tgt_id, uint64_t lun_id, lpfc_ctx_cmd ctx_cmd)
+lpfc_sli_sum_iocb(struct lpfc_vport *vport, uint16_t tgt_id, uint64_t lun_id,
+ lpfc_ctx_cmd ctx_cmd)
{
+ struct lpfc_hba *phba = vport->phba;
struct lpfc_iocbq *iocbq;
int sum, i;
for (i = 1, sum = 0; i <= phba->sli.last_iotag; i++) {
iocbq = phba->sli.iocbq_lookup[i];
- if (lpfc_sli_validate_fcp_iocb (iocbq, tgt_id, lun_id,
- 0, ctx_cmd) == 0)
+ if (lpfc_sli_validate_fcp_iocb (iocbq, vport, tgt_id, lun_id,
+ ctx_cmd) == 0)
sum++;
}
@@ -3527,10 +3533,10 @@
}
int
-lpfc_sli_abort_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
- uint16_t tgt_id, uint64_t lun_id, uint32_t ctx,
- lpfc_ctx_cmd abort_cmd)
+lpfc_sli_abort_iocb(struct lpfc_vport *vport, struct lpfc_sli_ring *pring,
+ uint16_t tgt_id, uint64_t lun_id, lpfc_ctx_cmd abort_cmd)
{
+ struct lpfc_hba *phba = vport->phba;
struct lpfc_iocbq *iocbq;
struct lpfc_iocbq *abtsiocb;
IOCB_t *cmd = NULL;
@@ -3540,7 +3546,7 @@
for (i = 1; i <= phba->sli.last_iotag; i++) {
iocbq = phba->sli.iocbq_lookup[i];
- if (lpfc_sli_validate_fcp_iocb(iocbq, tgt_id, lun_id, 0,
+ if (lpfc_sli_validate_fcp_iocb(iocbq, vport, tgt_id, lun_id,
abort_cmd) != 0)
continue;
@@ -3647,25 +3653,23 @@
if (piocb->iocb_flag & LPFC_IO_WAKE) {
lpfc_printf_log(phba, KERN_INFO, LOG_SLI,
- "%d:0331 IOCB wake signaled\n",
- phba->brd_no);
+ "0331 IOCB wake signaled\n");
} else if (timeleft == 0) {
lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
- "%d:0338 IOCB wait timeout error - no "
- "wake response Data x%x\n",
- phba->brd_no, timeout);
+ "0338 IOCB wait timeout error - no "
+ "wake response Data x%x\n", timeout);
retval = IOCB_TIMEDOUT;
} else {
lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
- "%d:0330 IOCB wake NOT set, "
- "Data x%x x%lx\n", phba->brd_no,
+ "0330 IOCB wake NOT set, "
+ "Data x%x x%lx\n",
timeout, (timeleft / jiffies));
retval = IOCB_TIMEDOUT;
}
} else {
lpfc_printf_log(phba, KERN_INFO, LOG_SLI,
- "%d:0332 IOCB wait issue failed, Data x%x\n",
- phba->brd_no, retval);
+ ":0332 IOCB wait issue failed, Data x%x\n",
+ retval);
retval = IOCB_ERROR;
}
@@ -3850,12 +3854,33 @@
if (status & HA_RXMASK) {
spin_lock(&phba->hbalock);
control = readl(phba->HCregaddr);
+
+ lpfc_debugfs_slow_ring_trc(phba,
+ "ISR slow ring: ctl:x%x stat:x%x isrcnt:x%x",
+ control, status,
+ (uint32_t)phba->sli.slistat.sli_intr);
+
if (control & (HC_R0INT_ENA << LPFC_ELS_RING)) {
+ lpfc_debugfs_slow_ring_trc(phba,
+ "ISR Disable ring:"
+ "pwork:x%x hawork:x%x wait:x%x",
+ phba->work_ha, work_ha_copy,
+ (uint32_t)((unsigned long)
+ phba->work_wait));
+
control &=
~(HC_R0INT_ENA << LPFC_ELS_RING);
writel(control, phba->HCregaddr);
readl(phba->HCregaddr); /* flush */
}
+ else {
+ lpfc_debugfs_slow_ring_trc(phba,
+ "ISR slow ring: pwork:"
+ "x%x hawork:x%x wait:x%x",
+ phba->work_ha, work_ha_copy,
+ (uint32_t)((unsigned long)
+ phba->work_wait));
+ }
spin_unlock(&phba->hbalock);
}
}
@@ -3895,12 +3920,10 @@
*/
lpfc_printf_log(phba, KERN_WARNING, LOG_MBOX |
LOG_SLI,
- "%d (%d):0304 Stray Mailbox "
+ "(%d):0304 Stray Mailbox "
"Interrupt mbxCommand x%x "
"mbxStatus x%x\n",
- phba->brd_no,
- (vport
- ? vport->vpi : 0),
+ (vport ? vport->vpi : 0),
pmbox->mbxCommand,
pmbox->mbxStatus);
}
diff --git a/drivers/scsi/lpfc/lpfc_sli.h b/drivers/scsi/lpfc/lpfc_sli.h
index 7605850..51b2b6b 100644
--- a/drivers/scsi/lpfc/lpfc_sli.h
+++ b/drivers/scsi/lpfc/lpfc_sli.h
@@ -26,7 +26,6 @@
typedef enum _lpfc_ctx_cmd {
LPFC_CTX_LUN,
LPFC_CTX_TGT,
- LPFC_CTX_CTX,
LPFC_CTX_HOST
} lpfc_ctx_cmd;
@@ -54,9 +53,10 @@
void *context2; /* caller context information */
void *context3; /* caller context information */
union {
- wait_queue_head_t *wait_queue;
- struct lpfc_iocbq *rsp_iocb;
- struct lpfcMboxq *mbox;
+ wait_queue_head_t *wait_queue;
+ struct lpfc_iocbq *rsp_iocb;
+ struct lpfcMboxq *mbox;
+ struct lpfc_nodelist *ndlp;
} context_un;
void (*fabric_iocb_cmpl) (struct lpfc_hba *, struct lpfc_iocbq *,
@@ -143,7 +143,7 @@
uint16_t numCiocb; /* number of command iocb's per ring */
uint16_t numRiocb; /* number of rsp iocb's per ring */
uint16_t sizeCiocb; /* Size of command iocb's in this ring */
- uint16_t sizeRiocb; /* Size of response iocb's in this ring */
+ uint16_t sizeRiocb; /* Size of response iocb's in this ring */
uint32_t fast_iotag; /* max fastlookup based iotag */
uint32_t iotag_ctr; /* keeps track of the next iotag to use */
diff --git a/drivers/scsi/lpfc/lpfc_version.h b/drivers/scsi/lpfc/lpfc_version.h
index a5bc79e..0081f49 100644
--- a/drivers/scsi/lpfc/lpfc_version.h
+++ b/drivers/scsi/lpfc/lpfc_version.h
@@ -18,12 +18,10 @@
* included with this package. *
*******************************************************************/
-#define LPFC_DRIVER_VERSION "8.2.1"
+#define LPFC_DRIVER_VERSION "8.2.2"
#define LPFC_DRIVER_NAME "lpfc"
#define LPFC_MODULE_DESC "Emulex LightPulse Fibre Channel SCSI driver " \
LPFC_DRIVER_VERSION
#define LPFC_COPYRIGHT "Copyright(c) 2004-2007 Emulex. All rights reserved."
-
-#define DFC_API_VERSION "0.0.0"
diff --git a/drivers/scsi/lpfc/lpfc_vport.c b/drivers/scsi/lpfc/lpfc_vport.c
index 85797db..dcb415e 100644
--- a/drivers/scsi/lpfc/lpfc_vport.c
+++ b/drivers/scsi/lpfc/lpfc_vport.c
@@ -125,11 +125,10 @@
pmb->vport = vport;
rc = lpfc_sli_issue_mbox_wait(phba, pmb, phba->fc_ratov * 2);
if (rc != MBX_SUCCESS) {
- lpfc_printf_log(phba, KERN_ERR, LOG_INIT | LOG_VPORT,
- "%d (%d):1818 VPort failed init, mbxCmd x%x "
- "READ_SPARM mbxStatus x%x, rc = x%x\n",
- phba->brd_no, vport->vpi,
- mb->mbxCommand, mb->mbxStatus, rc);
+ lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT | LOG_VPORT,
+ "1818 VPort failed init, mbxCmd x%x "
+ "READ_SPARM mbxStatus x%x, rc = x%x\n",
+ mb->mbxCommand, mb->mbxStatus, rc);
lpfc_mbuf_free(phba, mp->virt, mp->phys);
kfree(mp);
if (rc != MBX_TIMEOUT)
@@ -162,9 +161,9 @@
return 1;
lpfc_printf_log(phba, KERN_ERR, LOG_VPORT,
- "%d:1822 Invalid %s: %02x:%02x:%02x:%02x:"
+ "1822 Invalid %s: %02x:%02x:%02x:%02x:"
"%02x:%02x:%02x:%02x\n",
- phba->brd_no, name_type,
+ name_type,
wwn->u.wwn[0], wwn->u.wwn[1],
wwn->u.wwn[2], wwn->u.wwn[3],
wwn->u.wwn[4], wwn->u.wwn[5],
@@ -176,16 +175,21 @@
lpfc_unique_wwpn(struct lpfc_hba *phba, struct lpfc_vport *new_vport)
{
struct lpfc_vport *vport;
+ unsigned long flags;
+ spin_lock_irqsave(&phba->hbalock, flags);
list_for_each_entry(vport, &phba->port_list, listentry) {
if (vport == new_vport)
continue;
/* If they match, return not unique */
if (memcmp(&vport->fc_sparam.portName,
- &new_vport->fc_sparam.portName,
- sizeof(struct lpfc_name)) == 0)
+ &new_vport->fc_sparam.portName,
+ sizeof(struct lpfc_name)) == 0) {
+ spin_unlock_irqrestore(&phba->hbalock, flags);
return 0;
+ }
}
+ spin_unlock_irqrestore(&phba->hbalock, flags);
return 1;
}
@@ -193,8 +197,8 @@
lpfc_vport_create(struct fc_vport *fc_vport, bool disable)
{
struct lpfc_nodelist *ndlp;
- struct lpfc_vport *pport =
- (struct lpfc_vport *) fc_vport->shost->hostdata;
+ struct Scsi_Host *shost = fc_vport->shost;
+ struct lpfc_vport *pport = (struct lpfc_vport *) shost->hostdata;
struct lpfc_hba *phba = pport->phba;
struct lpfc_vport *vport = NULL;
int instance;
@@ -204,9 +208,9 @@
if ((phba->sli_rev < 3) ||
!(phba->sli3_options & LPFC_SLI3_NPIV_ENABLED)) {
lpfc_printf_log(phba, KERN_ERR, LOG_VPORT,
- "%d:1808 Create VPORT failed: "
+ "1808 Create VPORT failed: "
"NPIV is not enabled: SLImode:%d\n",
- phba->brd_no, phba->sli_rev);
+ phba->sli_rev);
rc = VPORT_INVAL;
goto error_out;
}
@@ -214,9 +218,9 @@
vpi = lpfc_alloc_vpi(phba);
if (vpi == 0) {
lpfc_printf_log(phba, KERN_ERR, LOG_VPORT,
- "%d:1809 Create VPORT failed: "
+ "1809 Create VPORT failed: "
"Max VPORTs (%d) exceeded\n",
- phba->brd_no, phba->max_vpi);
+ phba->max_vpi);
rc = VPORT_NORESOURCES;
goto error_out;
}
@@ -225,18 +229,17 @@
/* Assign an unused board number */
if ((instance = lpfc_get_instance()) < 0) {
lpfc_printf_log(phba, KERN_ERR, LOG_VPORT,
- "%d:1810 Create VPORT failed: Cannot get "
- "instance number\n", phba->brd_no);
+ "1810 Create VPORT failed: Cannot get "
+ "instance number\n");
lpfc_free_vpi(phba, vpi);
rc = VPORT_NORESOURCES;
goto error_out;
}
- vport = lpfc_create_port(phba, instance, fc_vport);
+ vport = lpfc_create_port(phba, instance, &fc_vport->dev);
if (!vport) {
lpfc_printf_log(phba, KERN_ERR, LOG_VPORT,
- "%d:1811 Create VPORT failed: vpi x%x\n",
- phba->brd_no, vpi);
+ "1811 Create VPORT failed: vpi x%x\n", vpi);
lpfc_free_vpi(phba, vpi);
rc = VPORT_NORESOURCES;
goto error_out;
@@ -246,10 +249,9 @@
lpfc_debugfs_initialize(vport);
if (lpfc_vport_sparm(phba, vport)) {
- lpfc_printf_log(phba, KERN_ERR, LOG_VPORT,
- "%d:1813 Create VPORT failed: vpi:%d "
- "Cannot get sparam\n",
- phba->brd_no, vpi);
+ lpfc_printf_vlog(vport, KERN_ERR, LOG_VPORT,
+ "1813 Create VPORT failed. "
+ "Cannot get sparam\n");
lpfc_free_vpi(phba, vpi);
destroy_port(vport);
rc = VPORT_NORESOURCES;
@@ -269,10 +271,9 @@
if (!lpfc_valid_wwn_format(phba, &vport->fc_sparam.nodeName, "WWNN") ||
!lpfc_valid_wwn_format(phba, &vport->fc_sparam.portName, "WWPN")) {
- lpfc_printf_log(phba, KERN_ERR, LOG_VPORT,
- "%d:1821 Create VPORT failed: vpi:%d "
- "Invalid WWN format\n",
- phba->brd_no, vpi);
+ lpfc_printf_vlog(vport, KERN_ERR, LOG_VPORT,
+ "1821 Create VPORT failed. "
+ "Invalid WWN format\n");
lpfc_free_vpi(phba, vpi);
destroy_port(vport);
rc = VPORT_INVAL;
@@ -280,10 +281,9 @@
}
if (!lpfc_unique_wwpn(phba, vport)) {
- lpfc_printf_log(phba, KERN_ERR, LOG_VPORT,
- "%d:1823 Create VPORT failed: vpi:%d "
- "Duplicate WWN on HBA\n",
- phba->brd_no, vpi);
+ lpfc_printf_vlog(vport, KERN_ERR, LOG_VPORT,
+ "1823 Create VPORT failed. "
+ "Duplicate WWN on HBA\n");
lpfc_free_vpi(phba, vpi);
destroy_port(vport);
rc = VPORT_INVAL;
@@ -315,10 +315,8 @@
lpfc_initial_fdisc(vport);
} else {
lpfc_vport_set_state(vport, FC_VPORT_NO_FABRIC_SUPP);
- lpfc_printf_log(phba, KERN_ERR, LOG_ELS,
- "%d (%d):0262 No NPIV Fabric "
- "support\n",
- phba->brd_no, vport->vpi);
+ lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS,
+ "0262 No NPIV Fabric support\n");
}
} else {
lpfc_vport_set_state(vport, FC_VPORT_FAILED);
@@ -326,12 +324,14 @@
rc = VPORT_OK;
out:
+ lpfc_printf_vlog(vport, KERN_ERR, LOG_VPORT,
+ "1825 Vport Created.\n");
lpfc_host_attrib_init(lpfc_shost_from_vport(vport));
error_out:
return rc;
}
-int
+static int
disable_vport(struct fc_vport *fc_vport)
{
struct lpfc_vport *vport = *(struct lpfc_vport **)fc_vport->dd_data;
@@ -371,10 +371,12 @@
lpfc_mbx_unreg_vpi(vport);
lpfc_vport_set_state(vport, FC_VPORT_DISABLED);
+ lpfc_printf_vlog(vport, KERN_ERR, LOG_VPORT,
+ "1826 Vport Disabled.\n");
return VPORT_OK;
}
-int
+static int
enable_vport(struct fc_vport *fc_vport)
{
struct lpfc_vport *vport = *(struct lpfc_vport **)fc_vport->dd_data;
@@ -400,15 +402,14 @@
lpfc_initial_fdisc(vport);
} else {
lpfc_vport_set_state(vport, FC_VPORT_NO_FABRIC_SUPP);
- lpfc_printf_log(phba, KERN_ERR, LOG_ELS,
- "%d (%d):0264 No NPIV Fabric "
- "support\n",
- phba->brd_no, vport->vpi);
+ lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS,
+ "0264 No NPIV Fabric support\n");
}
} else {
lpfc_vport_set_state(vport, FC_VPORT_FAILED);
}
-
+ lpfc_printf_vlog(vport, KERN_ERR, LOG_VPORT,
+ "1827 Vport Enabled.\n");
return VPORT_OK;
}
@@ -431,8 +432,29 @@
struct lpfc_vport *vport = *(struct lpfc_vport **)fc_vport->dd_data;
struct lpfc_hba *phba = vport->phba;
long timeout;
- int rc = VPORT_ERROR;
+ if (vport->port_type == LPFC_PHYSICAL_PORT) {
+ lpfc_printf_vlog(vport, KERN_ERR, LOG_VPORT,
+ "1812 vport_delete failed: Cannot delete "
+ "physical host\n");
+ return VPORT_ERROR;
+ }
+ /*
+ * If we are not unloading the driver then prevent the vport_delete
+ * from happening until after this vport's discovery is finished.
+ */
+ if (!(phba->pport->load_flag & FC_UNLOADING)) {
+ int check_count = 0;
+ while (check_count < ((phba->fc_ratov * 3) + 3) &&
+ vport->port_state > LPFC_VPORT_FAILED &&
+ vport->port_state < LPFC_VPORT_READY) {
+ check_count++;
+ msleep(1000);
+ }
+ if (vport->port_state > LPFC_VPORT_FAILED &&
+ vport->port_state < LPFC_VPORT_READY)
+ return -EAGAIN;
+ }
/*
* This is a bit of a mess. We want to ensure the shost doesn't get
* torn down until we're done with the embedded lpfc_vport structure.
@@ -450,16 +472,9 @@
*/
if (!scsi_host_get(shost) || !scsi_host_get(shost))
return VPORT_INVAL;
-
- if (vport->port_type == LPFC_PHYSICAL_PORT) {
- lpfc_printf_log(phba, KERN_ERR, LOG_VPORT,
- "%d:1812 vport_delete failed: Cannot delete "
- "physical host\n", phba->brd_no);
- goto out;
- }
-
+ spin_lock_irq(&phba->hbalock);
vport->load_flag |= FC_UNLOADING;
-
+ spin_unlock_irq(&phba->hbalock);
kfree(vport->vname);
lpfc_debugfs_terminate(vport);
fc_remove_host(lpfc_shost_from_vport(vport));
@@ -511,13 +526,46 @@
spin_lock_irq(&phba->hbalock);
list_del_init(&vport->listentry);
spin_unlock_irq(&phba->hbalock);
-
- rc = VPORT_OK;
-out:
+ lpfc_printf_vlog(vport, KERN_ERR, LOG_VPORT,
+ "1828 Vport Deleted.\n");
scsi_host_put(shost);
- return rc;
+ return VPORT_OK;
}
-
EXPORT_SYMBOL(lpfc_vport_create);
EXPORT_SYMBOL(lpfc_vport_delete);
+
+struct lpfc_vport **
+lpfc_create_vport_work_array(struct lpfc_hba *phba)
+{
+ struct lpfc_vport *port_iterator;
+ struct lpfc_vport **vports;
+ int index = 0;
+ vports = kzalloc(LPFC_MAX_VPORTS * sizeof(struct lpfc_vport *),
+ GFP_KERNEL);
+ if (vports == NULL)
+ return NULL;
+ spin_lock_irq(&phba->hbalock);
+ list_for_each_entry(port_iterator, &phba->port_list, listentry) {
+ if (!scsi_host_get(lpfc_shost_from_vport(port_iterator))) {
+ lpfc_printf_vlog(port_iterator, KERN_WARNING, LOG_VPORT,
+ "1801 Create vport work array FAILED: "
+ "cannot do scsi_host_get\n");
+ continue;
+ }
+ vports[index++] = port_iterator;
+ }
+ spin_unlock_irq(&phba->hbalock);
+ return vports;
+}
+
+void
+lpfc_destroy_vport_work_array(struct lpfc_vport **vports)
+{
+ int i;
+ if (vports == NULL)
+ return;
+ for (i=0; vports[i] != NULL && i < LPFC_MAX_VPORTS; i++)
+ scsi_host_put(lpfc_shost_from_vport(vports[i]));
+ kfree(vports);
+}
diff --git a/drivers/scsi/lpfc/lpfc_vport.h b/drivers/scsi/lpfc/lpfc_vport.h
index f223550..91da177 100644
--- a/drivers/scsi/lpfc/lpfc_vport.h
+++ b/drivers/scsi/lpfc/lpfc_vport.h
@@ -88,6 +88,8 @@
int lpfc_vport_delete(struct fc_vport *);
int lpfc_vport_getinfo(struct Scsi_Host *, struct vport_info *);
int lpfc_vport_tgt_remove(struct Scsi_Host *, uint, uint);
+struct lpfc_vport **lpfc_create_vport_work_array(struct lpfc_hba *);
+void lpfc_destroy_vport_work_array(struct lpfc_vport **);
/*
* queuecommand VPORT-specific return codes. Specified in the host byte code.
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
index c488996..93c0c7e 100644
--- a/drivers/scsi/qla2xxx/qla_os.c
+++ b/drivers/scsi/qla2xxx/qla_os.c
@@ -2154,6 +2154,19 @@
}
}
+ /* Get memory for cached NVRAM */
+ ha->nvram = kzalloc(MAX_NVRAM_SIZE, GFP_KERNEL);
+ if (ha->nvram == NULL) {
+ /* error */
+ qla_printk(KERN_WARNING, ha,
+ "Memory Allocation failed - nvram cache\n");
+
+ qla2x00_mem_free(ha);
+ msleep(100);
+
+ continue;
+ }
+
/* Done all allocations without any error. */
status = 0;
@@ -2266,6 +2279,7 @@
ha->fw_dump_reading = 0;
vfree(ha->optrom_buffer);
+ kfree(ha->nvram);
}
/*
diff --git a/drivers/scsi/qlogicpti.c b/drivers/scsi/qlogicpti.c
index c4195ea..5948872 100644
--- a/drivers/scsi/qlogicpti.c
+++ b/drivers/scsi/qlogicpti.c
@@ -193,7 +193,8 @@
cpu_relax();
}
if (!loop_count)
- printk(KERN_EMERG "qlogicpti: mbox_command loop timeout #1\n");
+ printk(KERN_EMERG "qlogicpti%d: mbox_command loop timeout #1\n",
+ qpti->qpti_id);
/* Write mailbox command registers. */
switch (mbox_param[param[0]] >> 4) {
@@ -224,8 +225,8 @@
(sbus_readw(qpti->qregs + HCCTRL) & HCCTRL_CRIRQ))
udelay(20);
if (!loop_count)
- printk(KERN_EMERG "qlogicpti: mbox_command[%04x] loop timeout #2\n",
- param[0]);
+ printk(KERN_EMERG "qlogicpti%d: mbox_command[%04x] loop timeout #2\n",
+ qpti->qpti_id, param[0]);
/* Wait for SBUS semaphore to get set. */
loop_count = DEFAULT_LOOP_COUNT;
@@ -238,16 +239,16 @@
break;
}
if (!loop_count)
- printk(KERN_EMERG "qlogicpti: mbox_command[%04x] loop timeout #3\n",
- param[0]);
+ printk(KERN_EMERG "qlogicpti%d: mbox_command[%04x] loop timeout #3\n",
+ qpti->qpti_id, param[0]);
/* Wait for MBOX busy condition to go away. */
loop_count = DEFAULT_LOOP_COUNT;
while (--loop_count && (sbus_readw(qpti->qregs + MBOX0) == 0x04))
udelay(20);
if (!loop_count)
- printk(KERN_EMERG "qlogicpti: mbox_command[%04x] loop timeout #4\n",
- param[0]);
+ printk(KERN_EMERG "qlogicpti%d: mbox_command[%04x] loop timeout #4\n",
+ qpti->qpti_id, param[0]);
/* Read back output parameters. */
switch (mbox_param[param[0]] & 0xf) {
@@ -342,7 +343,8 @@
while (--loop_count && ((sbus_readw(qpti->qregs + MBOX0) & 0xff) == 0x04))
udelay(20);
if (!loop_count)
- printk(KERN_EMERG "qlogicpti: reset_hardware loop timeout\n");
+ printk(KERN_EMERG "qlogicpti%d: reset_hardware loop timeout\n",
+ qpti->qpti_id);
sbus_writew(HCCTRL_PAUSE, qpti->qregs + HCCTRL);
set_sbus_cfg1(qpti);
@@ -721,12 +723,12 @@
IRQF_SHARED, "Qlogic/PTI", qpti))
goto fail;
- printk("qpti%d: IRQ %d ", qpti->qpti_id, qpti->irq);
+ printk("qlogicpti%d: IRQ %d ", qpti->qpti_id, qpti->irq);
return 0;
fail:
- printk("qpti%d: Cannot acquire irq line\n", qpti->qpti_id);
+ printk("qlogicpti%d: Cannot acquire irq line\n", qpti->qpti_id);
return -1;
}
@@ -1210,7 +1212,7 @@
host_status = DID_OK;
break;
default:
- printk(KERN_EMERG "qpti%d: unknown completion status 0x%04x\n",
+ printk(KERN_EMERG "qlogicpti%d: unknown completion status 0x%04x\n",
id, sts->completion_status);
host_status = DID_ERROR;
break;
@@ -1329,8 +1331,8 @@
u32 cmd_cookie;
int i;
- printk(KERN_WARNING "qlogicpti : Aborting cmd for tgt[%d] lun[%d]\n",
- (int)Cmnd->device->id, (int)Cmnd->device->lun);
+ printk(KERN_WARNING "qlogicpti%d: Aborting cmd for tgt[%d] lun[%d]\n",
+ qpti->qpti_id, (int)Cmnd->device->id, (int)Cmnd->device->lun);
qlogicpti_disable_irqs(qpti);
@@ -1348,7 +1350,8 @@
param[3] = cmd_cookie & 0xffff;
if (qlogicpti_mbox_command(qpti, param, 0) ||
(param[0] != MBOX_COMMAND_COMPLETE)) {
- printk(KERN_EMERG "qlogicpti : scsi abort failure: %x\n", param[0]);
+ printk(KERN_EMERG "qlogicpti%d: scsi abort failure: %x\n",
+ qpti->qpti_id, param[0]);
return_status = FAILED;
}
@@ -1364,7 +1367,8 @@
struct qlogicpti *qpti = (struct qlogicpti *) host->hostdata;
int return_status = SUCCESS;
- printk(KERN_WARNING "qlogicpti : Resetting SCSI bus!\n");
+ printk(KERN_WARNING "qlogicpti%d: Resetting SCSI bus!\n",
+ qpti->qpti_id);
qlogicpti_disable_irqs(qpti);
@@ -1372,7 +1376,8 @@
param[1] = qpti->host_param.bus_reset_delay;
if (qlogicpti_mbox_command(qpti, param, 0) ||
(param[0] != MBOX_COMMAND_COMPLETE)) {
- printk(KERN_EMERG "qlogicisp : scsi bus reset failure: %x\n", param[0]);
+ printk(KERN_EMERG "qlogicisp%d: scsi bus reset failure: %x\n",
+ qpti->qpti_id, param[0]);
return_status = FAILED;
}
@@ -1454,22 +1459,25 @@
if (qlogicpti_reset_hardware(host))
goto fail_unmap_queues;
- if (scsi_add_host(host, &dev->dev))
- goto fail_unmap_queues;
-
printk("(Firmware v%d.%d.%d)", qpti->fware_majrev,
qpti->fware_minrev, qpti->fware_micrev);
fcode = of_get_property(dp, "isp-fcode", NULL);
if (fcode && fcode[0])
- printk("(Firmware %s)", fcode);
+ printk("(FCode %s)", fcode);
if (of_find_property(dp, "differential", NULL) != NULL)
qpti->differential = 1;
- printk (" [%s Wide, using %s interface]\n",
+ printk("\nqlogicpti%d: [%s Wide, using %s interface]\n",
+ qpti->qpti_id,
(qpti->ultra ? "Ultra" : "Fast"),
(qpti->differential ? "differential" : "single ended"));
+ if (scsi_add_host(host, &dev->dev)) {
+ printk("qlogicpti%d: Failed scsi_add_host\n", qpti->qpti_id);
+ goto fail_unmap_queues;
+ }
+
dev_set_drvdata(&sdev->ofdev.dev, qpti);
qpti_chain_add(qpti);
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
index 21c075d..a417a6ff 100644
--- a/drivers/scsi/scsi_lib.c
+++ b/drivers/scsi/scsi_lib.c
@@ -1038,22 +1038,6 @@
return BLKPREP_KILL;
}
-static int scsi_issue_flush_fn(struct request_queue *q, struct gendisk *disk,
- sector_t *error_sector)
-{
- struct scsi_device *sdev = q->queuedata;
- struct scsi_driver *drv;
-
- if (sdev->sdev_state != SDEV_RUNNING)
- return -ENXIO;
-
- drv = *(struct scsi_driver **) disk->private_data;
- if (drv->issue_flush)
- return drv->issue_flush(&sdev->sdev_gendev, error_sector);
-
- return -EOPNOTSUPP;
-}
-
static struct scsi_cmnd *scsi_get_cmd_from_req(struct scsi_device *sdev,
struct request *req)
{
@@ -1596,7 +1580,6 @@
return NULL;
blk_queue_prep_rq(q, scsi_prep_fn);
- blk_queue_issue_flush_fn(q, scsi_issue_flush_fn);
blk_queue_softirq_done(q, scsi_softirq_done);
return q;
}
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
index e21c714..2c6116f 100644
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
@@ -241,7 +241,6 @@
},
.rescan = sd_rescan,
.init_command = sd_init_command,
- .issue_flush = sd_issue_flush,
};
/*
@@ -800,10 +799,17 @@
return 0;
}
-static int sd_issue_flush(struct device *dev, sector_t *error_sector)
+static int sd_issue_flush(struct request_queue *q, struct gendisk *disk,
+ sector_t *error_sector)
{
int ret = 0;
- struct scsi_disk *sdkp = scsi_disk_get_from_dev(dev);
+ struct scsi_device *sdp = q->queuedata;
+ struct scsi_disk *sdkp;
+
+ if (sdp->sdev_state != SDEV_RUNNING)
+ return -ENXIO;
+
+ sdkp = scsi_disk_get_from_dev(&sdp->sdev_gendev);
if (!sdkp)
return -ENODEV;
@@ -1663,6 +1669,8 @@
sd_revalidate_disk(gd);
+ blk_queue_issue_flush_fn(sdp->request_queue, sd_issue_flush);
+
gd->driverfs_dev = &sdp->sdev_gendev;
gd->flags = GENHD_FL_DRIVERFS;
if (sdp->removable)
diff --git a/drivers/scsi/st.c b/drivers/scsi/st.c
index a4f7b84..73c44cb 100644
--- a/drivers/scsi/st.c
+++ b/drivers/scsi/st.c
@@ -1485,7 +1485,7 @@
struct st_buffer *STbp;
char *name = tape_name(STp);
- if (down_interruptible(&STp->lock))
+ if (mutex_lock_interruptible(&STp->lock))
return -ERESTARTSYS;
retval = rw_checks(STp, filp, count);
@@ -1736,7 +1736,7 @@
if (SRpnt != NULL)
st_release_request(SRpnt);
release_buffering(STp, 0);
- up(&STp->lock);
+ mutex_unlock(&STp->lock);
return retval;
}
@@ -1942,7 +1942,7 @@
struct st_buffer *STbp = STp->buffer;
DEB( char *name = tape_name(STp); )
- if (down_interruptible(&STp->lock))
+ if (mutex_lock_interruptible(&STp->lock))
return -ERESTARTSYS;
retval = rw_checks(STp, filp, count);
@@ -2069,7 +2069,7 @@
release_buffering(STp, 1);
STbp->buffer_bytes = 0;
}
- up(&STp->lock);
+ mutex_unlock(&STp->lock);
return retval;
}
@@ -3226,7 +3226,7 @@
char *name = tape_name(STp);
void __user *p = (void __user *)arg;
- if (down_interruptible(&STp->lock))
+ if (mutex_lock_interruptible(&STp->lock))
return -ERESTARTSYS;
DEB(
@@ -3537,7 +3537,7 @@
retval = (-EFAULT);
goto out;
}
- up(&STp->lock);
+ mutex_unlock(&STp->lock);
switch (cmd_in) {
case SCSI_IOCTL_GET_IDLUN:
case SCSI_IOCTL_GET_BUS_NUMBER:
@@ -3563,7 +3563,7 @@
return retval;
out:
- up(&STp->lock);
+ mutex_unlock(&STp->lock);
return retval;
}
@@ -4029,7 +4029,7 @@
tpnt->density_changed = tpnt->compression_changed =
tpnt->blksize_changed = 0;
- init_MUTEX(&tpnt->lock);
+ mutex_init(&tpnt->lock);
st_nr_dev++;
write_unlock(&st_dev_arr_lock);
diff --git a/drivers/scsi/st.h b/drivers/scsi/st.h
index 50f3deb..6c80757 100644
--- a/drivers/scsi/st.h
+++ b/drivers/scsi/st.h
@@ -3,6 +3,7 @@
#define _ST_H
#include <linux/completion.h>
+#include <linux/mutex.h>
#include <linux/kref.h>
#include <scsi/scsi_cmnd.h>
@@ -98,7 +99,7 @@
struct scsi_tape {
struct scsi_driver *driver;
struct scsi_device *device;
- struct semaphore lock; /* For serialization */
+ struct mutex lock; /* For serialization */
struct completion wait; /* For SCSI commands */
struct st_buffer *buffer;
diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c
index 3013130..f94109c 100644
--- a/drivers/serial/8250.c
+++ b/drivers/serial/8250.c
@@ -129,7 +129,16 @@
unsigned char mcr;
unsigned char mcr_mask; /* mask of user bits */
unsigned char mcr_force; /* mask of forced bits */
- unsigned char lsr_break_flag;
+
+ /*
+ * Some bits in registers are cleared on a read, so they must
+ * be saved whenever the register is read but the bits will not
+ * be immediately processed.
+ */
+#define LSR_SAVE_FLAGS UART_LSR_BRK_ERROR_BITS
+ unsigned char lsr_saved_flags;
+#define MSR_SAVE_FLAGS UART_MSR_ANY_DELTA
+ unsigned char msr_saved_flags;
/*
* We provide a per-port pm hook.
@@ -1238,6 +1247,7 @@
if (up->bugs & UART_BUG_TXEN) {
unsigned char lsr, iir;
lsr = serial_in(up, UART_LSR);
+ up->lsr_saved_flags |= lsr & LSR_SAVE_FLAGS;
iir = serial_in(up, UART_IIR) & 0x0f;
if ((up->port.type == PORT_RM9000) ?
(lsr & UART_LSR_THRE &&
@@ -1290,18 +1300,10 @@
flag = TTY_NORMAL;
up->port.icount.rx++;
-#ifdef CONFIG_SERIAL_8250_CONSOLE
- /*
- * Recover the break flag from console xmit
- */
- if (up->port.line == up->port.cons->index) {
- lsr |= up->lsr_break_flag;
- up->lsr_break_flag = 0;
- }
-#endif
+ lsr |= up->lsr_saved_flags;
+ up->lsr_saved_flags = 0;
- if (unlikely(lsr & (UART_LSR_BI | UART_LSR_PE |
- UART_LSR_FE | UART_LSR_OE))) {
+ if (unlikely(lsr & UART_LSR_BRK_ERROR_BITS)) {
/*
* For statistics only
*/
@@ -1392,6 +1394,8 @@
{
unsigned int status = serial_in(up, UART_MSR);
+ status |= up->msr_saved_flags;
+ up->msr_saved_flags = 0;
if (status & UART_MSR_ANY_DELTA && up->ier & UART_IER_MSI &&
up->port.info != NULL) {
if (status & UART_MSR_TERI)
@@ -1591,7 +1595,8 @@
static void serial8250_backup_timeout(unsigned long data)
{
struct uart_8250_port *up = (struct uart_8250_port *)data;
- unsigned int iir, ier = 0;
+ unsigned int iir, ier = 0, lsr;
+ unsigned long flags;
/*
* Must disable interrupts or else we risk racing with the interrupt
@@ -1610,9 +1615,13 @@
* the "Diva" UART used on the management processor on many HP
* ia64 and parisc boxes.
*/
+ spin_lock_irqsave(&up->port.lock, flags);
+ lsr = serial_in(up, UART_LSR);
+ up->lsr_saved_flags |= lsr & LSR_SAVE_FLAGS;
+ spin_unlock_irqrestore(&up->port.lock, flags);
if ((iir & UART_IIR_NO_INT) && (up->ier & UART_IER_THRI) &&
(!uart_circ_empty(&up->port.info->xmit) || up->port.x_char) &&
- (serial_in(up, UART_LSR) & UART_LSR_THRE)) {
+ (lsr & UART_LSR_THRE)) {
iir &= ~(UART_IIR_ID | UART_IIR_NO_INT);
iir |= UART_IIR_THRI;
}
@@ -1631,13 +1640,14 @@
{
struct uart_8250_port *up = (struct uart_8250_port *)port;
unsigned long flags;
- unsigned int ret;
+ unsigned int lsr;
spin_lock_irqsave(&up->port.lock, flags);
- ret = serial_in(up, UART_LSR) & UART_LSR_TEMT ? TIOCSER_TEMT : 0;
+ lsr = serial_in(up, UART_LSR);
+ up->lsr_saved_flags |= lsr & LSR_SAVE_FLAGS;
spin_unlock_irqrestore(&up->port.lock, flags);
- return ret;
+ return lsr & UART_LSR_TEMT ? TIOCSER_TEMT : 0;
}
static unsigned int serial8250_get_mctrl(struct uart_port *port)
@@ -1708,8 +1718,7 @@
do {
status = serial_in(up, UART_LSR);
- if (status & UART_LSR_BI)
- up->lsr_break_flag = UART_LSR_BI;
+ up->lsr_saved_flags |= status & LSR_SAVE_FLAGS;
if (--tmout == 0)
break;
@@ -1718,8 +1727,12 @@
/* Wait up to 1s for flow control if necessary */
if (up->port.flags & UPF_CONS_FLOW) {
- tmout = 1000000;
- while (!(serial_in(up, UART_MSR) & UART_MSR_CTS) && --tmout) {
+ unsigned int tmout;
+ for (tmout = 1000000; tmout; tmout--) {
+ unsigned int msr = serial_in(up, UART_MSR);
+ up->msr_saved_flags |= msr & MSR_SAVE_FLAGS;
+ if (msr & UART_MSR_CTS)
+ break;
udelay(1);
touch_nmi_watchdog();
}
@@ -1889,6 +1902,18 @@
spin_unlock_irqrestore(&up->port.lock, flags);
/*
+ * Clear the interrupt registers again for luck, and clear the
+ * saved flags to avoid getting false values from polling
+ * routines or the previous session.
+ */
+ serial_inp(up, UART_LSR);
+ serial_inp(up, UART_RX);
+ serial_inp(up, UART_IIR);
+ serial_inp(up, UART_MSR);
+ up->lsr_saved_flags = 0;
+ up->msr_saved_flags = 0;
+
+ /*
* Finally, enable interrupts. Note: Modem status interrupts
* are set via set_termios(), which will be occurring imminently
* anyway, so we don't enable them here.
@@ -1906,14 +1931,6 @@
(void) inb_p(icp);
}
- /*
- * And clear the interrupt registers again for luck.
- */
- (void) serial_inp(up, UART_LSR);
- (void) serial_inp(up, UART_RX);
- (void) serial_inp(up, UART_IIR);
- (void) serial_inp(up, UART_MSR);
-
return 0;
}
@@ -2484,6 +2501,16 @@
wait_for_xmitr(up, BOTH_EMPTY);
serial_out(up, UART_IER, ier);
+ /*
+ * The receive handling will happen properly because the
+ * receive ready bit will still be set; it is not cleared
+ * on read. However, modem control will not, we must
+ * call it if we have saved something in the saved flags
+ * while processing with interrupts off.
+ */
+ if (up->msr_saved_flags)
+ check_modem_status(up);
+
if (locked)
spin_unlock(&up->port.lock);
local_irq_restore(flags);
diff --git a/drivers/serial/8250_pci.c b/drivers/serial/8250_pci.c
index 5e48587..bd66339 100644
--- a/drivers/serial/8250_pci.c
+++ b/drivers/serial/8250_pci.c
@@ -580,6 +580,138 @@
return num_serial;
}
+/*
+ * ITE support by Niels de Vos <niels.devos@wincor-nixdorf.com>
+ *
+ * These chips are available with optionally one parallel port and up to
+ * two serial ports. Unfortunately they all have the same product id.
+ *
+ * Basic configuration is done over a region of 32 I/O ports. The base
+ * ioport is called INTA or INTC, depending on docs/other drivers.
+ *
+ * The region of the 32 I/O ports is configured in POSIO0R...
+ */
+
+/* registers */
+#define ITE_887x_MISCR 0x9c
+#define ITE_887x_INTCBAR 0x78
+#define ITE_887x_UARTBAR 0x7c
+#define ITE_887x_PS0BAR 0x10
+#define ITE_887x_POSIO0 0x60
+
+/* I/O space size */
+#define ITE_887x_IOSIZE 32
+/* I/O space size (bits 26-24; 8 bytes = 011b) */
+#define ITE_887x_POSIO_IOSIZE_8 (3 << 24)
+/* I/O space size (bits 26-24; 32 bytes = 101b) */
+#define ITE_887x_POSIO_IOSIZE_32 (5 << 24)
+/* Decoding speed (1 = slow, 2 = medium, 3 = fast) */
+#define ITE_887x_POSIO_SPEED (3 << 29)
+/* enable IO_Space bit */
+#define ITE_887x_POSIO_ENABLE (1 << 31)
+
+static int __devinit pci_ite887x_init(struct pci_dev *dev)
+{
+ /* inta_addr are the configuration addresses of the ITE */
+ static const short inta_addr[] = { 0x2a0, 0x2c0, 0x220, 0x240, 0x1e0,
+ 0x200, 0x280, 0 };
+ int ret, i, type;
+ struct resource *iobase = NULL;
+ u32 miscr, uartbar, ioport;
+
+ /* search for the base-ioport */
+ i = 0;
+ while (inta_addr[i] && iobase == NULL) {
+ iobase = request_region(inta_addr[i], ITE_887x_IOSIZE,
+ "ite887x");
+ if (iobase != NULL) {
+ /* write POSIO0R - speed | size | ioport */
+ pci_write_config_dword(dev, ITE_887x_POSIO0,
+ ITE_887x_POSIO_ENABLE | ITE_887x_POSIO_SPEED |
+ ITE_887x_POSIO_IOSIZE_32 | inta_addr[i]);
+ /* write INTCBAR - ioport */
+ pci_write_config_dword(dev, ITE_887x_INTCBAR, inta_addr[i]);
+ ret = inb(inta_addr[i]);
+ if (ret != 0xff) {
+ /* ioport connected */
+ break;
+ }
+ release_region(iobase->start, ITE_887x_IOSIZE);
+ iobase = NULL;
+ }
+ i++;
+ }
+
+ if (!inta_addr[i]) {
+ printk(KERN_ERR "ite887x: could not find iobase\n");
+ return -ENODEV;
+ }
+
+ /* start of undocumented type checking (see parport_pc.c) */
+ type = inb(iobase->start + 0x18) & 0x0f;
+
+ switch (type) {
+ case 0x2: /* ITE8871 (1P) */
+ case 0xa: /* ITE8875 (1P) */
+ ret = 0;
+ break;
+ case 0xe: /* ITE8872 (2S1P) */
+ ret = 2;
+ break;
+ case 0x6: /* ITE8873 (1S) */
+ ret = 1;
+ break;
+ case 0x8: /* ITE8874 (2S) */
+ ret = 2;
+ break;
+ default:
+ moan_device("Unknown ITE887x", dev);
+ ret = -ENODEV;
+ }
+
+ /* configure all serial ports */
+ for (i = 0; i < ret; i++) {
+ /* read the I/O port from the device */
+ pci_read_config_dword(dev, ITE_887x_PS0BAR + (0x4 * (i + 1)),
+ &ioport);
+ ioport &= 0x0000FF00; /* the actual base address */
+ pci_write_config_dword(dev, ITE_887x_POSIO0 + (0x4 * (i + 1)),
+ ITE_887x_POSIO_ENABLE | ITE_887x_POSIO_SPEED |
+ ITE_887x_POSIO_IOSIZE_8 | ioport);
+
+ /* write the ioport to the UARTBAR */
+ pci_read_config_dword(dev, ITE_887x_UARTBAR, &uartbar);
+ uartbar &= ~(0xffff << (16 * i)); /* clear half the reg */
+ uartbar |= (ioport << (16 * i)); /* set the ioport */
+ pci_write_config_dword(dev, ITE_887x_UARTBAR, uartbar);
+
+ /* get current config */
+ pci_read_config_dword(dev, ITE_887x_MISCR, &miscr);
+ /* disable interrupts (UARTx_Routing[3:0]) */
+ miscr &= ~(0xf << (12 - 4 * i));
+ /* activate the UART (UARTx_En) */
+ miscr |= 1 << (23 - i);
+ /* write new config with activated UART */
+ pci_write_config_dword(dev, ITE_887x_MISCR, miscr);
+ }
+
+ if (ret <= 0) {
+ /* the device has no UARTs if we get here */
+ release_region(iobase->start, ITE_887x_IOSIZE);
+ }
+
+ return ret;
+}
+
+static void __devexit pci_ite887x_exit(struct pci_dev *dev)
+{
+ u32 ioport;
+ /* the ioport is bit 0-15 in POSIO0R */
+ pci_read_config_dword(dev, ITE_887x_POSIO0, &ioport);
+ ioport &= 0xffff;
+ release_region(ioport, ITE_887x_IOSIZE);
+}
+
static int
pci_default_setup(struct serial_private *priv, struct pciserial_board *board,
struct uart_port *port, int idx)
@@ -653,6 +785,18 @@
.setup = pci_default_setup,
},
/*
+ * ITE
+ */
+ {
+ .vendor = PCI_VENDOR_ID_ITE,
+ .device = PCI_DEVICE_ID_ITE_8872,
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
+ .init = pci_ite887x_init,
+ .setup = pci_default_setup,
+ .exit = __devexit_p(pci_ite887x_exit),
+ },
+ /*
* Panacom
*/
{
@@ -933,6 +1077,7 @@
pbn_b1_2_1250000,
+ pbn_b1_bt_1_115200,
pbn_b1_bt_2_921600,
pbn_b1_1_1382400,
@@ -983,6 +1128,7 @@
pbn_exar_XR17C152,
pbn_exar_XR17C154,
pbn_exar_XR17C158,
+ pbn_pasemi_1682M,
};
/*
@@ -1211,6 +1357,13 @@
.uart_offset = 8,
},
+ [pbn_b1_bt_1_115200] = {
+ .flags = FL_BASE1|FL_BASE_BARS,
+ .num_ports = 1,
+ .base_baud = 115200,
+ .uart_offset = 8,
+ },
+
[pbn_b1_bt_2_921600] = {
.flags = FL_BASE1|FL_BASE_BARS,
.num_ports = 2,
@@ -1498,6 +1651,18 @@
.base_baud = 921600,
.uart_offset = 0x200,
},
+ /*
+ * PA Semi PWRficient PA6T-1682M on-chip UART
+ */
+ [pbn_pasemi_1682M] = {
+ .flags = FL_BASE0,
+ .num_ports = 1,
+ .base_baud = 8333333,
+ },
+};
+
+static const struct pci_device_id softmodem_blacklist[] = {
+ { PCI_VDEVICE ( AL, 0x5457 ), }, /* ALi Corporation M5457 AC'97 Modem */
};
/*
@@ -1508,6 +1673,7 @@
static int __devinit
serial_pci_guess_board(struct pci_dev *dev, struct pciserial_board *board)
{
+ const struct pci_device_id *blacklist;
int num_iomem, num_port, first_port = -1, i;
/*
@@ -1522,6 +1688,18 @@
(dev->class & 0xff) > 6)
return -ENODEV;
+ /*
+ * Do not access blacklisted devices that are known not to
+ * feature serial ports.
+ */
+ for (blacklist = softmodem_blacklist;
+ blacklist < softmodem_blacklist + ARRAY_SIZE(softmodem_blacklist);
+ blacklist++) {
+ if (dev->vendor == blacklist->vendor &&
+ dev->device == blacklist->device)
+ return -ENODEV;
+ }
+
num_iomem = num_port = 0;
for (i = 0; i < PCI_NUM_BAR_RESOURCES; i++) {
if (pci_resource_flags(dev, i) & IORESOURCE_IO) {
@@ -2364,6 +2542,13 @@
{ PCI_VENDOR_ID_TOPIC, PCI_DEVICE_ID_TOPIC_TP560,
PCI_ANY_ID, PCI_ANY_ID, 0, 0,
pbn_b0_1_115200 },
+ /*
+ * ITE
+ */
+ { PCI_VENDOR_ID_ITE, PCI_DEVICE_ID_ITE_8872,
+ PCI_ANY_ID, PCI_ANY_ID,
+ 0, 0,
+ pbn_b1_bt_1_115200 },
/*
* IntaShield IS-200
@@ -2382,6 +2567,13 @@
PCI_SUBVENDOR_ID_PERLE, PCI_SUBDEVICE_ID_PCI_RAS8,
0, 0, pbn_b2_8_921600 },
/*
+ * PA Semi PA6T-1682M on-chip UART
+ */
+ { PCI_VENDOR_ID_PASEMI, 0xa004,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_pasemi_1682M },
+
+ /*
* These entries match devices with class COMMUNICATION_SERIAL,
* COMMUNICATION_MODEM or COMMUNICATION_MULTISERIAL
*/
diff --git a/drivers/serial/serial_core.c b/drivers/serial/serial_core.c
index 030a606..a055f58 100644
--- a/drivers/serial/serial_core.c
+++ b/drivers/serial/serial_core.c
@@ -1146,11 +1146,14 @@
/*
* These are the bits that are used to setup various
- * flags in the low level driver.
+ * flags in the low level driver. We can ignore the Bfoo
+ * bits in c_cflag; c_[io]speed will always be set
+ * appropriately by set_termios() in tty_ioctl.c
*/
#define RELEVANT_IFLAG(iflag) ((iflag) & (IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK))
-
if ((cflag ^ old_termios->c_cflag) == 0 &&
+ tty->termios->c_ospeed == old_termios->c_ospeed &&
+ tty->termios->c_ispeed == old_termios->c_ispeed &&
RELEVANT_IFLAG(tty->termios->c_iflag ^ old_termios->c_iflag) == 0)
return;
diff --git a/drivers/serial/serial_txx9.c b/drivers/serial/serial_txx9.c
index b8f91e0..0930e2a 100644
--- a/drivers/serial/serial_txx9.c
+++ b/drivers/serial/serial_txx9.c
@@ -37,7 +37,7 @@
#include <asm/io.h>
-static char *serial_version = "1.09";
+static char *serial_version = "1.10";
static char *serial_name = "TX39/49 Serial driver";
#define PASS_LIMIT 256
@@ -436,8 +436,10 @@
struct uart_txx9_port *up = (struct uart_txx9_port *)port;
unsigned int ret;
- ret = ((sio_in(up, TXX9_SIFLCR) & TXX9_SIFLCR_RTSSC) ? 0 : TIOCM_RTS)
- | ((sio_in(up, TXX9_SICISR) & TXX9_SICISR_CTSS) ? 0 : TIOCM_CTS);
+ /* no modem control lines */
+ ret = TIOCM_CAR | TIOCM_DSR;
+ ret |= (sio_in(up, TXX9_SIFLCR) & TXX9_SIFLCR_RTSSC) ? 0 : TIOCM_RTS;
+ ret |= (sio_in(up, TXX9_SICISR) & TXX9_SICISR_CTSS) ? 0 : TIOCM_CTS;
return ret;
}
@@ -557,6 +559,12 @@
unsigned long flags;
unsigned int baud, quot;
+ /*
+ * We don't support modem control lines.
+ */
+ termios->c_cflag &= ~(HUPCL | CMSPAR);
+ termios->c_cflag |= CLOCAL;
+
cval = sio_in(up, TXX9_SILCR);
/* byte size and parity */
cval &= ~TXX9_SILCR_UMODE_MASK;
diff --git a/drivers/spi/spi_mpc83xx.c b/drivers/spi/spi_mpc83xx.c
index 0c16a2b..2adf856 100644
--- a/drivers/spi/spi_mpc83xx.c
+++ b/drivers/spi/spi_mpc83xx.c
@@ -86,7 +86,7 @@
unsigned nsecs; /* (clock cycle time)/2 */
- u32 sysclk;
+ u32 spibrg; /* SPIBRG input clock */
u32 rx_shift; /* RX data reg shift when in qe mode */
u32 tx_shift; /* TX data reg shift when in qe mode */
@@ -148,6 +148,8 @@
if (value == BITBANG_CS_ACTIVE) {
u32 regval = mpc83xx_spi_read_reg(&mpc83xx_spi->base->mode);
u32 len = spi->bits_per_word;
+ u8 pm;
+
if (len == 32)
len = 0;
else
@@ -169,17 +171,20 @@
regval |= SPMODE_LEN(len);
- if ((mpc83xx_spi->sysclk / spi->max_speed_hz) >= 64) {
- u8 pm = mpc83xx_spi->sysclk / (spi->max_speed_hz * 64);
+ if ((mpc83xx_spi->spibrg / spi->max_speed_hz) >= 64) {
+ pm = mpc83xx_spi->spibrg / (spi->max_speed_hz * 64) - 1;
if (pm > 0x0f) {
- printk(KERN_WARNING "MPC83xx SPI: SPICLK can't be less then a SYSCLK/1024!\n"
- "Requested SPICLK is %d Hz. Will use %d Hz instead.\n",
- spi->max_speed_hz, mpc83xx_spi->sysclk / 1024);
+ dev_err(&spi->dev, "Requested speed is too "
+ "low: %d Hz. Will use %d Hz instead.\n",
+ spi->max_speed_hz,
+ mpc83xx_spi->spibrg / 1024);
pm = 0x0f;
}
regval |= SPMODE_PM(pm) | SPMODE_DIV16;
} else {
- u8 pm = mpc83xx_spi->sysclk / (spi->max_speed_hz * 4);
+ pm = mpc83xx_spi->spibrg / (spi->max_speed_hz * 4);
+ if (pm)
+ pm--;
regval |= SPMODE_PM(pm);
}
@@ -429,13 +434,17 @@
mpc83xx_spi->bitbang.chipselect = mpc83xx_spi_chipselect;
mpc83xx_spi->bitbang.setup_transfer = mpc83xx_spi_setup_transfer;
mpc83xx_spi->bitbang.txrx_bufs = mpc83xx_spi_bufs;
- mpc83xx_spi->sysclk = pdata->sysclk;
mpc83xx_spi->activate_cs = pdata->activate_cs;
mpc83xx_spi->deactivate_cs = pdata->deactivate_cs;
mpc83xx_spi->qe_mode = pdata->qe_mode;
mpc83xx_spi->get_rx = mpc83xx_spi_rx_buf_u8;
mpc83xx_spi->get_tx = mpc83xx_spi_tx_buf_u8;
+ if (mpc83xx_spi->qe_mode)
+ mpc83xx_spi->spibrg = pdata->sysclk / 2;
+ else
+ mpc83xx_spi->spibrg = pdata->sysclk;
+
mpc83xx_spi->rx_shift = 0;
mpc83xx_spi->tx_shift = 0;
if (mpc83xx_spi->qe_mode) {
diff --git a/drivers/spi/spidev.c b/drivers/spi/spidev.c
index 630f781..c55459c 100644
--- a/drivers/spi/spidev.c
+++ b/drivers/spi/spidev.c
@@ -183,7 +183,9 @@
if (u_tmp->rx_buf) {
k_tmp->rx_buf = buf;
- if (!access_ok(VERIFY_WRITE, u_tmp->rx_buf, u_tmp->len))
+ if (!access_ok(VERIFY_WRITE, (u8 __user *)
+ (ptrdiff_t) u_tmp->rx_buf,
+ u_tmp->len))
goto done;
}
if (u_tmp->tx_buf) {
diff --git a/drivers/usb/Kconfig b/drivers/usb/Kconfig
index 7dd7354..7580aa5d 100644
--- a/drivers/usb/Kconfig
+++ b/drivers/usb/Kconfig
@@ -6,6 +6,9 @@
bool "USB support"
depends on HAS_IOMEM
default y
+ ---help---
+ This option adds core support for Universal Serial Bus (USB).
+ You will also need drivers from the following menu to make use of it.
if USB_SUPPORT
@@ -18,6 +21,7 @@
default y if USB_ARCH_HAS_EHCI
default y if PCMCIA && !M32R # sl811_cs
default y if ARM # SL-811
+ default y if SUPERH # r8a66597-hcd
default PCI
# many non-PCI SOC chips embed OHCI
diff --git a/drivers/usb/atm/cxacru.c b/drivers/usb/atm/cxacru.c
index 02c52f8..a73e714 100644
--- a/drivers/usb/atm/cxacru.c
+++ b/drivers/usb/atm/cxacru.c
@@ -456,7 +456,6 @@
int* actual_length)
{
struct timer_list timer;
- int status = urb->status;
init_timer(&timer);
timer.expires = jiffies + msecs_to_jiffies(CMD_TIMEOUT);
@@ -468,7 +467,7 @@
if (actual_length)
*actual_length = urb->actual_length;
- return status;
+ return urb->status; /* must read status after completion */
}
static int cxacru_cm(struct cxacru_data *instance, enum cxacru_cm_request cm,
diff --git a/drivers/usb/atm/ueagle-atm.c b/drivers/usb/atm/ueagle-atm.c
index a1a1c9d..29807d0 100644
--- a/drivers/usb/atm/ueagle-atm.c
+++ b/drivers/usb/atm/ueagle-atm.c
@@ -1721,9 +1721,12 @@
ret = uea_boot(sc);
if (ret < 0)
- goto error;
+ goto error_rm_grp;
return 0;
+
+error_rm_grp:
+ sysfs_remove_group(&intf->dev.kobj, &attr_grp);
error:
kfree(sc);
return ret;
diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c
index fe940e0..f51e224 100644
--- a/drivers/usb/class/cdc-acm.c
+++ b/drivers/usb/class/cdc-acm.c
@@ -921,6 +921,10 @@
return -EINVAL;
}
}
+
+ /* Accept probe requests only for the control interface */
+ if (intf != control_interface)
+ return -ENODEV;
if (usb_interface_claimed(data_interface)) { /* valid in this context */
dev_dbg(&intf->dev,"The data interface isn't available");
@@ -1109,10 +1113,12 @@
return;
}
if (acm->country_codes){
- device_remove_file(&intf->dev, &dev_attr_wCountryCodes);
- device_remove_file(&intf->dev, &dev_attr_iCountryCodeRelDate);
+ device_remove_file(&acm->control->dev,
+ &dev_attr_wCountryCodes);
+ device_remove_file(&acm->control->dev,
+ &dev_attr_iCountryCodeRelDate);
}
- device_remove_file(&intf->dev, &dev_attr_bmCapabilities);
+ device_remove_file(&acm->control->dev, &dev_attr_bmCapabilities);
acm->dev = NULL;
usb_set_intfdata(acm->control, NULL);
usb_set_intfdata(acm->data, NULL);
diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c
index 6548574..a1ad11d 100644
--- a/drivers/usb/core/driver.c
+++ b/drivers/usb/core/driver.c
@@ -1224,6 +1224,8 @@
udev->auto_pm = 1;
udev->pm_usage_cnt += inc_usage_cnt;
WARN_ON(udev->pm_usage_cnt < 0);
+ if (inc_usage_cnt)
+ udev->last_busy = jiffies;
if (inc_usage_cnt >= 0 && udev->pm_usage_cnt > 0) {
if (udev->state == USB_STATE_SUSPENDED)
status = usb_resume_both(udev);
@@ -1232,8 +1234,6 @@
else if (inc_usage_cnt)
udev->last_busy = jiffies;
} else if (inc_usage_cnt <= 0 && udev->pm_usage_cnt <= 0) {
- if (inc_usage_cnt)
- udev->last_busy = jiffies;
status = usb_suspend_both(udev, PMSG_SUSPEND);
}
usb_pm_unlock(udev);
@@ -1342,16 +1342,15 @@
else {
udev->auto_pm = 1;
intf->pm_usage_cnt += inc_usage_cnt;
+ udev->last_busy = jiffies;
if (inc_usage_cnt >= 0 && intf->pm_usage_cnt > 0) {
if (udev->state == USB_STATE_SUSPENDED)
status = usb_resume_both(udev);
if (status != 0)
intf->pm_usage_cnt -= inc_usage_cnt;
- else if (inc_usage_cnt)
+ else
udev->last_busy = jiffies;
} else if (inc_usage_cnt <= 0 && intf->pm_usage_cnt <= 0) {
- if (inc_usage_cnt)
- udev->last_busy = jiffies;
status = usb_suspend_both(udev, PMSG_SUSPEND);
}
}
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index e341a1d..f7b337f 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -1644,9 +1644,10 @@
* and device drivers will know about any resume quirks.
*/
if (status == 0) {
+ devstatus = 0;
status = usb_get_status(udev, USB_RECIP_DEVICE, 0, &devstatus);
if (status >= 0)
- status = (status == 2 ? 0 : -ENODEV);
+ status = (status > 0 ? 0 : -ENODEV);
}
if (status) {
diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c
index b6bd05e..d8f7b08 100644
--- a/drivers/usb/core/message.c
+++ b/drivers/usb/core/message.c
@@ -637,12 +637,12 @@
memset(buf,0,size); // Make sure we parse really received data
for (i = 0; i < 3; ++i) {
- /* retry on length 0 or stall; some devices are flakey */
+ /* retry on length 0 or error; some devices are flakey */
result = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
USB_REQ_GET_DESCRIPTOR, USB_DIR_IN,
(type << 8) + index, 0, buf, size,
USB_CTRL_GET_TIMEOUT);
- if (result == 0 || result == -EPIPE)
+ if (result <= 0 && result != -ETIMEDOUT)
continue;
if (result > 1 && ((u8 *)buf)[1] != type) {
result = -EPROTO;
@@ -1358,6 +1358,30 @@
usb_dev = interface_to_usbdev(intf);
alt = intf->cur_altsetting;
+#ifdef CONFIG_USB_DEVICEFS
+ if (add_uevent_var(envp, num_envp, &i,
+ buffer, buffer_size, &length,
+ "DEVICE=/proc/bus/usb/%03d/%03d",
+ usb_dev->bus->busnum, usb_dev->devnum))
+ return -ENOMEM;
+#endif
+
+ if (add_uevent_var(envp, num_envp, &i,
+ buffer, buffer_size, &length,
+ "PRODUCT=%x/%x/%x",
+ le16_to_cpu(usb_dev->descriptor.idVendor),
+ le16_to_cpu(usb_dev->descriptor.idProduct),
+ le16_to_cpu(usb_dev->descriptor.bcdDevice)))
+ return -ENOMEM;
+
+ if (add_uevent_var(envp, num_envp, &i,
+ buffer, buffer_size, &length,
+ "TYPE=%d/%d/%d",
+ usb_dev->descriptor.bDeviceClass,
+ usb_dev->descriptor.bDeviceSubClass,
+ usb_dev->descriptor.bDeviceProtocol))
+ return -ENOMEM;
+
if (add_uevent_var(envp, num_envp, &i,
buffer, buffer_size, &length,
"INTERFACE=%d/%d/%d",
diff --git a/drivers/usb/core/quirks.c b/drivers/usb/core/quirks.c
index b7917c5..9e46711 100644
--- a/drivers/usb/core/quirks.c
+++ b/drivers/usb/core/quirks.c
@@ -30,6 +30,8 @@
static const struct usb_device_id usb_quirk_list[] = {
/* HP 5300/5370C scanner */
{ USB_DEVICE(0x03f0, 0x0701), .driver_info = USB_QUIRK_STRING_FETCH_255 },
+ /* Hewlett-Packard PhotoSmart 720 / PhotoSmart 935 (storage) */
+ { USB_DEVICE(0x03f0, 0x4002), .driver_info = USB_QUIRK_NO_AUTOSUSPEND },
/* Acer Peripherals Inc. (now BenQ Corp.) Prisa 640BU */
{ USB_DEVICE(0x04a5, 0x207e), .driver_info = USB_QUIRK_NO_AUTOSUSPEND },
/* Benq S2W 3300U */
@@ -56,6 +58,8 @@
{ USB_DEVICE(0x04b8, 0x0121), .driver_info = USB_QUIRK_NO_AUTOSUSPEND },
/* Seiko Epson Corp.*/
{ USB_DEVICE(0x04b8, 0x0122), .driver_info = USB_QUIRK_NO_AUTOSUSPEND },
+ /* Samsung ML-2010 printer */
+ { USB_DEVICE(0x04e8, 0x326c), .driver_info = USB_QUIRK_NO_AUTOSUSPEND },
/* Samsung ML-2510 Series printer */
{ USB_DEVICE(0x04e8, 0x327e), .driver_info = USB_QUIRK_NO_AUTOSUSPEND },
/* Elsa MicroLink 56k (V.250) */
@@ -64,12 +68,20 @@
{ USB_DEVICE(0x05d8, 0x4005), .driver_info = USB_QUIRK_NO_AUTOSUSPEND },
/* Agfa Snapscan1212u */
{ USB_DEVICE(0x06bd, 0x2061), .driver_info = USB_QUIRK_NO_AUTOSUSPEND },
+ /* Seagate RSS LLC */
+ { USB_DEVICE(0x0bc2, 0x3000), .driver_info = USB_QUIRK_NO_AUTOSUSPEND },
/* Umax [hex] Astra 3400U */
{ USB_DEVICE(0x1606, 0x0060), .driver_info = USB_QUIRK_NO_AUTOSUSPEND },
/* Philips PSC805 audio device */
{ USB_DEVICE(0x0471, 0x0155), .driver_info = USB_QUIRK_RESET_RESUME },
+ /* Alcor multi-card reader */
+ { USB_DEVICE(0x058f, 0x6366), .driver_info = USB_QUIRK_NO_AUTOSUSPEND },
+
+ /* Canon EOS 5D in PC Connection mode */
+ { USB_DEVICE(0x04a9, 0x3101), .driver_info = USB_QUIRK_NO_AUTOSUSPEND },
+
/* RIM Blackberry */
{ USB_DEVICE(0x0fca, 0x0001), .driver_info = USB_QUIRK_NO_AUTOSUSPEND },
{ USB_DEVICE(0x0fca, 0x0004), .driver_info = USB_QUIRK_NO_AUTOSUSPEND },
diff --git a/drivers/usb/gadget/dummy_hcd.c b/drivers/usb/gadget/dummy_hcd.c
index f2fbdc7..d008d13 100644
--- a/drivers/usb/gadget/dummy_hcd.c
+++ b/drivers/usb/gadget/dummy_hcd.c
@@ -34,8 +34,6 @@
* bypassing some hardware (and driver) issues. UML could help too.
*/
-#define DEBUG
-
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/delay.h>
diff --git a/drivers/usb/gadget/file_storage.c b/drivers/usb/gadget/file_storage.c
index be7a1bd..965ad7b 100644
--- a/drivers/usb/gadget/file_storage.c
+++ b/drivers/usb/gadget/file_storage.c
@@ -599,7 +599,6 @@
struct fsg_buffhd {
void *buf;
- dma_addr_t dma;
enum fsg_buffer_state state;
struct fsg_buffhd *next;
@@ -1295,6 +1294,7 @@
struct usb_request *req = fsg->ep0req;
int value = -EOPNOTSUPP;
u16 w_index = le16_to_cpu(ctrl->wIndex);
+ u16 w_value = le16_to_cpu(ctrl->wValue);
u16 w_length = le16_to_cpu(ctrl->wLength);
if (!fsg->config)
@@ -1308,7 +1308,7 @@
if (ctrl->bRequestType != (USB_DIR_OUT |
USB_TYPE_CLASS | USB_RECIP_INTERFACE))
break;
- if (w_index != 0) {
+ if (w_index != 0 || w_value != 0) {
value = -EDOM;
break;
}
@@ -1324,7 +1324,7 @@
if (ctrl->bRequestType != (USB_DIR_IN |
USB_TYPE_CLASS | USB_RECIP_INTERFACE))
break;
- if (w_index != 0) {
+ if (w_index != 0 || w_value != 0) {
value = -EDOM;
break;
}
@@ -1343,7 +1343,7 @@
if (ctrl->bRequestType != (USB_DIR_OUT |
USB_TYPE_CLASS | USB_RECIP_INTERFACE))
break;
- if (w_index != 0) {
+ if (w_index != 0 || w_value != 0) {
value = -EDOM;
break;
}
@@ -2611,7 +2611,6 @@
fsg->intr_buffhd = bh; // Point to the right buffhd
fsg->intreq->buf = bh->inreq->buf;
- fsg->intreq->dma = bh->inreq->dma;
fsg->intreq->context = bh;
start_transfer(fsg, fsg->intr_in, fsg->intreq,
&fsg->intreq_busy, &bh->state);
@@ -3200,7 +3199,6 @@
if ((rc = alloc_request(fsg, fsg->bulk_out, &bh->outreq)) != 0)
goto reset;
bh->inreq->buf = bh->outreq->buf = bh->buf;
- bh->inreq->dma = bh->outreq->dma = bh->dma;
bh->inreq->context = bh->outreq->context = bh;
bh->inreq->complete = bulk_in_complete;
bh->outreq->complete = bulk_out_complete;
diff --git a/drivers/usb/gadget/fsl_usb2_udc.c b/drivers/usb/gadget/fsl_usb2_udc.c
index 10b2b33..d57bcfb 100644
--- a/drivers/usb/gadget/fsl_usb2_udc.c
+++ b/drivers/usb/gadget/fsl_usb2_udc.c
@@ -1277,31 +1277,32 @@
udc_reset_ep_queue(udc, 0);
+ /* We process some stardard setup requests here */
switch (setup->bRequest) {
- /* Request that need Data+Status phase from udc */
case USB_REQ_GET_STATUS:
- if ((setup->bRequestType & (USB_DIR_IN | USB_TYPE_STANDARD))
+ /* Data+Status phase from udc */
+ if ((setup->bRequestType & (USB_DIR_IN | USB_TYPE_MASK))
!= (USB_DIR_IN | USB_TYPE_STANDARD))
break;
ch9getstatus(udc, setup->bRequestType, wValue, wIndex, wLength);
- break;
+ return;
- /* Requests that need Status phase from udc */
case USB_REQ_SET_ADDRESS:
+ /* Status phase from udc */
if (setup->bRequestType != (USB_DIR_OUT | USB_TYPE_STANDARD
| USB_RECIP_DEVICE))
break;
ch9setaddress(udc, wValue, wIndex, wLength);
- break;
+ return;
- /* Handled by udc, no data, status by udc */
case USB_REQ_CLEAR_FEATURE:
case USB_REQ_SET_FEATURE:
- { /* status transaction */
+ /* Status phase from udc */
+ {
int rc = -EOPNOTSUPP;
- if ((setup->bRequestType & USB_RECIP_MASK)
- == USB_RECIP_ENDPOINT) {
+ if ((setup->bRequestType & (USB_RECIP_MASK | USB_TYPE_MASK))
+ == (USB_RECIP_ENDPOINT | USB_TYPE_STANDARD)) {
int pipe = get_pipe_by_windex(wIndex);
struct fsl_ep *ep;
@@ -1315,8 +1316,9 @@
? 1 : 0);
spin_lock(&udc->lock);
- } else if ((setup->bRequestType & USB_RECIP_MASK)
- == USB_RECIP_DEVICE) {
+ } else if ((setup->bRequestType & (USB_RECIP_MASK
+ | USB_TYPE_MASK)) == (USB_RECIP_DEVICE
+ | USB_TYPE_STANDARD)) {
/* Note: The driver has not include OTG support yet.
* This will be set when OTG support is added */
if (!udc->gadget.is_otg)
@@ -1329,38 +1331,41 @@
USB_DEVICE_A_ALT_HNP_SUPPORT)
udc->gadget.a_alt_hnp_support = 1;
rc = 0;
- }
+ } else
+ break;
+
if (rc == 0) {
if (ep0_prime_status(udc, EP_DIR_IN))
ep0stall(udc);
}
+ return;
+ }
+
+ default:
break;
}
- /* Requests handled by gadget */
- default:
- if (wLength) {
- /* Data phase from gadget, status phase from udc */
- udc->ep0_dir = (setup->bRequestType & USB_DIR_IN)
- ? USB_DIR_IN : USB_DIR_OUT;
- spin_unlock(&udc->lock);
- if (udc->driver->setup(&udc->gadget,
- &udc->local_setup_buff) < 0)
- ep0stall(udc);
- spin_lock(&udc->lock);
- udc->ep0_state = (setup->bRequestType & USB_DIR_IN)
- ? DATA_STATE_XMIT : DATA_STATE_RECV;
- } else {
- /* No data phase, IN status from gadget */
- udc->ep0_dir = USB_DIR_IN;
- spin_unlock(&udc->lock);
- if (udc->driver->setup(&udc->gadget,
- &udc->local_setup_buff) < 0)
- ep0stall(udc);
- spin_lock(&udc->lock);
- udc->ep0_state = WAIT_FOR_OUT_STATUS;
- }
- break;
+ /* Requests handled by gadget */
+ if (wLength) {
+ /* Data phase from gadget, status phase from udc */
+ udc->ep0_dir = (setup->bRequestType & USB_DIR_IN)
+ ? USB_DIR_IN : USB_DIR_OUT;
+ spin_unlock(&udc->lock);
+ if (udc->driver->setup(&udc->gadget,
+ &udc->local_setup_buff) < 0)
+ ep0stall(udc);
+ spin_lock(&udc->lock);
+ udc->ep0_state = (setup->bRequestType & USB_DIR_IN)
+ ? DATA_STATE_XMIT : DATA_STATE_RECV;
+ } else {
+ /* No data phase, IN status from gadget */
+ udc->ep0_dir = USB_DIR_IN;
+ spin_unlock(&udc->lock);
+ if (udc->driver->setup(&udc->gadget,
+ &udc->local_setup_buff) < 0)
+ ep0stall(udc);
+ spin_lock(&udc->lock);
+ udc->ep0_state = WAIT_FOR_OUT_STATUS;
}
}
diff --git a/drivers/usb/gadget/pxa2xx_udc.c b/drivers/usb/gadget/pxa2xx_udc.c
index 72b4ebb..1407ad1 100644
--- a/drivers/usb/gadget/pxa2xx_udc.c
+++ b/drivers/usb/gadget/pxa2xx_udc.c
@@ -967,7 +967,7 @@
udc = container_of(_gadget, struct pxa2xx_udc, gadget);
/* not all boards support pullup control */
- if (!udc->mach->udc_command)
+ if (!udc->mach->gpio_pullup && !udc->mach->udc_command)
return -EOPNOTSUPP;
is_active = (is_active != 0);
@@ -2309,7 +2309,7 @@
{
struct pxa2xx_udc *udc = platform_get_drvdata(dev);
- if (!udc->mach->udc_command)
+ if (!udc->mach->gpio_pullup && !udc->mach->udc_command)
WARN("USB host won't detect disconnect!\n");
pullup(udc, 0);
diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
index 2f52982..565d6ef 100644
--- a/drivers/usb/host/Kconfig
+++ b/drivers/usb/host/Kconfig
@@ -237,7 +237,7 @@
module will be called "sl811_cs".
config USB_R8A66597_HCD
- tristate "R8A66597 HCD suppoort"
+ tristate "R8A66597 HCD support"
depends on USB
help
The R8A66597 is a USB 2.0 host and peripheral controller.
diff --git a/drivers/usb/host/ehci-au1xxx.c b/drivers/usb/host/ehci-au1xxx.c
index 5d1b12a..b1d1926 100644
--- a/drivers/usb/host/ehci-au1xxx.c
+++ b/drivers/usb/host/ehci-au1xxx.c
@@ -1,8 +1,6 @@
/*
* EHCI HCD (Host Controller Driver) for USB.
*
- * (C) Copyright 2000-2004 David Brownell <dbrownell@users.sourceforge.net>
- *
* Bus Glue for AMD Alchemy Au1xxx
*
* Based on "ohci-au1xxx.c" by Matt Porter <mporter@kernel.crashing.org>
@@ -196,6 +194,9 @@
/*
* basic lifecycle operations
+ *
+ * FIXME -- ehci_init() doesn't do enough here.
+ * See ehci-ppc-soc for a complete implementation.
*/
.reset = ehci_init,
.start = ehci_run,
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index c4e15ed..35cdba1 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -275,58 +275,6 @@
/*-------------------------------------------------------------------------*/
-#ifdef CONFIG_CPU_FREQ
-
-#include <linux/cpufreq.h>
-
-static void ehci_cpufreq_pause (struct ehci_hcd *ehci)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&ehci->lock, flags);
- if (!ehci->cpufreq_changing++)
- qh_inactivate_split_intr_qhs(ehci);
- spin_unlock_irqrestore(&ehci->lock, flags);
-}
-
-static void ehci_cpufreq_unpause (struct ehci_hcd *ehci)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&ehci->lock, flags);
- if (!--ehci->cpufreq_changing)
- qh_reactivate_split_intr_qhs(ehci);
- spin_unlock_irqrestore(&ehci->lock, flags);
-}
-
-/*
- * ehci_cpufreq_notifier is needed to avoid MMF errors that occur when
- * EHCI controllers that don't cache many uframes get delayed trying to
- * read main memory during CPU frequency transitions. This can cause
- * split interrupt transactions to not be completed in the required uframe.
- * This has been observed on the Broadcom/ServerWorks HT1000 controller.
- */
-static int ehci_cpufreq_notifier(struct notifier_block *nb, unsigned long val,
- void *data)
-{
- struct ehci_hcd *ehci = container_of(nb, struct ehci_hcd,
- cpufreq_transition);
-
- switch (val) {
- case CPUFREQ_PRECHANGE:
- ehci_cpufreq_pause(ehci);
- break;
- case CPUFREQ_POSTCHANGE:
- ehci_cpufreq_unpause(ehci);
- break;
- }
- return 0;
-}
-
-#endif
-
-/*-------------------------------------------------------------------------*/
-
static void ehci_watchdog (unsigned long param)
{
struct ehci_hcd *ehci = (struct ehci_hcd *) param;
@@ -460,10 +408,6 @@
ehci_writel(ehci, 0, &ehci->regs->intr_enable);
spin_unlock_irq(&ehci->lock);
-#ifdef CONFIG_CPU_FREQ
- cpufreq_unregister_notifier(&ehci->cpufreq_transition,
- CPUFREQ_TRANSITION_NOTIFIER);
-#endif
/* let companion controllers work when we aren't */
ehci_writel(ehci, 0, &ehci->regs->configured_flag);
@@ -569,17 +513,6 @@
}
ehci->command = temp;
-#ifdef CONFIG_CPU_FREQ
- INIT_LIST_HEAD(&ehci->split_intr_qhs);
- /*
- * If the EHCI controller caches enough uframes, this probably
- * isn't needed unless there are so many low/full speed devices
- * that the controller's can't cache it all.
- */
- ehci->cpufreq_transition.notifier_call = ehci_cpufreq_notifier;
- cpufreq_register_notifier(&ehci->cpufreq_transition,
- CPUFREQ_TRANSITION_NOTIFIER);
-#endif
return 0;
}
diff --git a/drivers/usb/host/ehci-mem.c b/drivers/usb/host/ehci-mem.c
index 8816d09..0431397 100644
--- a/drivers/usb/host/ehci-mem.c
+++ b/drivers/usb/host/ehci-mem.c
@@ -94,9 +94,6 @@
qh->qh_dma = dma;
// INIT_LIST_HEAD (&qh->qh_list);
INIT_LIST_HEAD (&qh->qtd_list);
-#ifdef CONFIG_CPU_FREQ
- INIT_LIST_HEAD (&qh->split_intr_qhs);
-#endif
/* dummy td enables safe urb queuing */
qh->dummy = ehci_qtd_alloc (ehci, flags);
diff --git a/drivers/usb/host/ehci-ppc-soc.c b/drivers/usb/host/ehci-ppc-soc.c
index c2cedb0..4f99b0e 100644
--- a/drivers/usb/host/ehci-ppc-soc.c
+++ b/drivers/usb/host/ehci-ppc-soc.c
@@ -6,7 +6,7 @@
* Bus Glue for PPC On-Chip EHCI driver
* Tested on AMCC 440EPx
*
- * Based on "ehci-au12xx.c" by David Brownell <dbrownell@users.sourceforge.net>
+ * Based on "ehci-au1xxx.c" by K.Boge <karsten.boge@amd.com>
*
* This file is licenced under the GPL.
*/
@@ -15,6 +15,24 @@
extern int usb_disabled(void);
+/* called during probe() after chip reset completes */
+static int ehci_ppc_soc_setup(struct usb_hcd *hcd)
+{
+ struct ehci_hcd *ehci = hcd_to_ehci(hcd);
+ int retval;
+
+ retval = ehci_halt(ehci);
+ if (retval)
+ return retval;
+
+ retval = ehci_init(hcd);
+ if (retval)
+ return retval;
+
+ ehci->sbrn = 0x20;
+ return ehci_reset(ehci);
+}
+
/**
* usb_ehci_ppc_soc_probe - initialize PPC-SoC-based HCDs
* Context: !in_interrupt()
@@ -120,7 +138,7 @@
/*
* basic lifecycle operations
*/
- .reset = ehci_init,
+ .reset = ehci_ppc_soc_setup,
.start = ehci_run,
.stop = ehci_stop,
.shutdown = ehci_shutdown,
diff --git a/drivers/usb/host/ehci-q.c b/drivers/usb/host/ehci-q.c
index 2284028..140bfa4 100644
--- a/drivers/usb/host/ehci-q.c
+++ b/drivers/usb/host/ehci-q.c
@@ -312,10 +312,6 @@
struct urb *urb;
u32 token = 0;
- /* ignore QHs that are currently inactive */
- if (qh->hw_info1 & __constant_cpu_to_le32(QH_INACTIVATE))
- break;
-
qtd = list_entry (entry, struct ehci_qtd, qtd_list);
urb = qtd->urb;
diff --git a/drivers/usb/host/ehci-sched.c b/drivers/usb/host/ehci-sched.c
index d4a8ace..e682f23 100644
--- a/drivers/usb/host/ehci-sched.c
+++ b/drivers/usb/host/ehci-sched.c
@@ -479,109 +479,6 @@
}
/*-------------------------------------------------------------------------*/
-#ifdef CONFIG_CPU_FREQ
-
-static int safe_to_modify_i (struct ehci_hcd *ehci, struct ehci_qh *qh)
-{
- int now; /* current (frame * 8) + uframe */
- int prev_start, next_start; /* uframes from/to split start */
- int start_uframe = ffs(le32_to_cpup (&qh->hw_info2) & QH_SMASK);
- int end_uframe = fls((le32_to_cpup (&qh->hw_info2) & QH_CMASK) >> 8);
- int split_duration = end_uframe - start_uframe;
-
- now = readl(&ehci->regs->frame_index) % (ehci->periodic_size << 3);
-
- next_start = ((1024 << 3) + (qh->start << 3) + start_uframe - now)
- % (qh->period << 3);
- prev_start = (qh->period << 3) - next_start;
-
- /*
- * Make sure there will be at least one uframe when qh is safe.
- */
- if ((qh->period << 3) <= (ehci->i_thresh + 2 + split_duration))
- /* never safe */
- return -EINVAL;
-
- /*
- * Wait 1 uframe after transaction should have started, to make
- * sure controller has time to write back overlay, so we can
- * check QTD_STS_STS to see if transaction is in progress.
- */
- if ((next_start > ehci->i_thresh) && (prev_start > 1))
- /* safe to set "i" bit if split isn't in progress */
- return (qh->hw_token & STATUS_BIT(ehci)) ? 0 : 1;
- else
- return 0;
-}
-
-/* Set inactivate bit for all the split interrupt QHs. */
-static void qh_inactivate_split_intr_qhs (struct ehci_hcd *ehci)
-{
- struct ehci_qh *qh;
- int not_done, safe;
- u32 inactivate = INACTIVATE_BIT(ehci);
- u32 active = ACTIVE_BIT(ehci);
-
- do {
- not_done = 0;
- list_for_each_entry(qh, &ehci->split_intr_qhs,
- split_intr_qhs) {
- if (qh->hw_info1 & inactivate)
- /* already off */
- continue;
- /*
- * To avoid setting "I" after the start split happens,
- * don't set it if the QH might be cached in the
- * controller. Some HCs (Broadcom/ServerWorks HT1000)
- * will stop in the middle of a split transaction when
- * the "I" bit is set.
- */
- safe = safe_to_modify_i(ehci, qh);
- if (safe == 0) {
- not_done = 1;
- } else if (safe > 0) {
- qh->was_active = qh->hw_token & active;
- qh->hw_info1 |= inactivate;
- }
- }
- } while (not_done);
- wmb();
-}
-
-static void qh_reactivate_split_intr_qhs (struct ehci_hcd *ehci)
-{
- struct ehci_qh *qh;
- u32 token;
- int not_done, safe;
- u32 inactivate = INACTIVATE_BIT(ehci);
- u32 active = ACTIVE_BIT(ehci);
- u32 halt = HALT_BIT(ehci);
-
- do {
- not_done = 0;
- list_for_each_entry(qh, &ehci->split_intr_qhs, split_intr_qhs) {
- if (!(qh->hw_info1 & inactivate)) /* already on */
- continue;
- /*
- * Don't reactivate if cached, or controller might
- * overwrite overlay after we modify it!
- */
- safe = safe_to_modify_i(ehci, qh);
- if (safe == 0) {
- not_done = 1;
- } else if (safe > 0) {
- /* See EHCI 1.0 section 4.15.2.4. */
- token = qh->hw_token;
- qh->hw_token = (token | halt) & ~active;
- wmb();
- qh->hw_info1 &= ~inactivate;
- wmb();
- qh->hw_token = (token & ~halt) | qh->was_active;
- }
- }
- } while (not_done);
-}
-#endif
/* periodic schedule slots have iso tds (normal or split) first, then a
* sparse tree for active interrupt transfers.
@@ -599,17 +496,6 @@
period, hc32_to_cpup(ehci, &qh->hw_info2) & (QH_CMASK | QH_SMASK),
qh, qh->start, qh->usecs, qh->c_usecs);
-#ifdef CONFIG_CPU_FREQ
- /*
- * If low/full speed interrupt QHs are inactive (because of
- * cpufreq changing processor speeds), start QH with I flag set--
- * it will automatically be cleared when cpufreq is done.
- */
- if (ehci->cpufreq_changing)
- if (!(qh->hw_info1 & (cpu_to_le32(1 << 13))))
- qh->hw_info1 |= INACTIVATE_BIT(ehci);
-#endif
-
/* high bandwidth, or otherwise every microframe */
if (period == 0)
period = 1;
@@ -658,12 +544,6 @@
? ((qh->usecs + qh->c_usecs) / qh->period)
: (qh->usecs * 8);
-#ifdef CONFIG_CPU_FREQ
- /* add qh to list of low/full speed interrupt QHs, if applicable */
- if (!(qh->hw_info1 & (cpu_to_le32(1 << 13)))) {
- list_add(&qh->split_intr_qhs, &ehci->split_intr_qhs);
- }
-#endif
/* maybe enable periodic schedule processing */
if (!ehci->periodic_sched++)
return enable_periodic (ehci);
@@ -683,13 +563,6 @@
// THEN
// qh->hw_info1 |= __constant_cpu_to_hc32(1 << 7 /* "ignore" */);
-#ifdef CONFIG_CPU_FREQ
- /* remove qh from list of low/full speed interrupt QHs */
- if (!(qh->hw_info1 & (cpu_to_le32(1 << 13)))) {
- list_del_init(&qh->split_intr_qhs);
- }
-#endif
-
/* high bandwidth, or otherwise part of every microframe */
if ((period = qh->period) == 0)
period = 1;
diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h
index 2c68a04..951d69f 100644
--- a/drivers/usb/host/ehci.h
+++ b/drivers/usb/host/ehci.h
@@ -71,12 +71,6 @@
__u32 hcs_params; /* cached register copy */
spinlock_t lock;
-#ifdef CONFIG_CPU_FREQ
- struct notifier_block cpufreq_transition;
- int cpufreq_changing;
- struct list_head split_intr_qhs;
-#endif
-
/* async schedule support */
struct ehci_qh *async;
struct ehci_qh *reclaim;
@@ -439,10 +433,6 @@
__hc32 hw_next; /* see EHCI 3.6.1 */
__hc32 hw_info1; /* see EHCI 3.6.2 */
#define QH_HEAD 0x00008000
-#define QH_INACTIVATE 0x00000080
-
-#define INACTIVATE_BIT(ehci) cpu_to_hc32(ehci, QH_INACTIVATE)
-
__hc32 hw_info2; /* see EHCI 3.6.2 */
#define QH_SMASK 0x000000ff
#define QH_CMASK 0x0000ff00
@@ -492,10 +482,6 @@
unsigned short start; /* where polling starts */
#define NO_FRAME ((unsigned short)~0) /* pick new start */
struct usb_device *dev; /* access to TT */
-#ifdef CONFIG_CPU_FREQ
- struct list_head split_intr_qhs; /* list of split qhs */
- __le32 was_active; /* active bit before "i" set */
-#endif
} __attribute__ ((aligned (32)));
/*-------------------------------------------------------------------------*/
diff --git a/drivers/usb/host/ohci-dbg.c b/drivers/usb/host/ohci-dbg.c
index 6f9e43e..f61c6cd 100644
--- a/drivers/usb/host/ohci-dbg.c
+++ b/drivers/usb/host/ohci-dbg.c
@@ -74,7 +74,7 @@
#define ohci_dbg_sw(ohci, next, size, format, arg...) \
do { \
- if (next) { \
+ if (next != NULL) { \
unsigned s_len; \
s_len = scnprintf (*next, *size, format, ## arg ); \
*size -= s_len; *next += s_len; \
diff --git a/drivers/usb/host/r8a66597-hcd.c b/drivers/usb/host/r8a66597-hcd.c
index d60f198..40a1de4 100644
--- a/drivers/usb/host/r8a66597-hcd.c
+++ b/drivers/usb/host/r8a66597-hcd.c
@@ -2208,8 +2208,6 @@
clean_up:
if (reg)
iounmap(reg);
- if (res)
- release_mem_region(res->start, 1);
return ret;
}
diff --git a/drivers/usb/host/u132-hcd.c b/drivers/usb/host/u132-hcd.c
index 7f765ec..b88eb3c 100644
--- a/drivers/usb/host/u132-hcd.c
+++ b/drivers/usb/host/u132-hcd.c
@@ -1520,12 +1520,15 @@
}
}
}
+#ifdef CONFIG_PM
static void port_power(struct u132 *u132, int pn, int is_on)
{
u132->port[pn].power = is_on;
}
+#endif
+
static void u132_power(struct u132 *u132, int is_on)
{
struct usb_hcd *hcd = u132_to_hcd(u132)
diff --git a/drivers/usb/serial/airprime.c b/drivers/usb/serial/airprime.c
index cff6fd1..77bb893 100644
--- a/drivers/usb/serial/airprime.c
+++ b/drivers/usb/serial/airprime.c
@@ -18,7 +18,6 @@
static struct usb_device_id id_table [] = {
{ USB_DEVICE(0x0c88, 0x17da) }, /* Kyocera Wireless KPC650/Passport */
- { USB_DEVICE(0x413c, 0x8115) }, /* Dell Wireless HSDPA 5500 */
{ },
};
MODULE_DEVICE_TABLE(usb, id_table);
diff --git a/drivers/usb/serial/belkin_sa.c b/drivers/usb/serial/belkin_sa.c
index e67ce25..86724e8 100644
--- a/drivers/usb/serial/belkin_sa.c
+++ b/drivers/usb/serial/belkin_sa.c
@@ -383,6 +383,10 @@
}
baud = tty_get_baud_rate(port->tty);
+ if (baud == 0) {
+ dbg("%s - tty_get_baud_rate says 0 baud", __FUNCTION__);
+ return;
+ }
urb_value = BELKIN_SA_BAUD(baud);
/* Clip to maximum speed */
if (urb_value == 0)
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c
index 7b1673a..1370c42 100644
--- a/drivers/usb/serial/ftdi_sio.c
+++ b/drivers/usb/serial/ftdi_sio.c
@@ -538,6 +538,8 @@
{ USB_DEVICE(FTDI_VID, FTDI_TERATRONIK_VCP_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_TERATRONIK_D2XX_PID) },
{ USB_DEVICE(EVOLUTION_VID, EVOLUTION_ER1_PID) },
+ { USB_DEVICE(EVOLUTION_VID, EVO_HYBRID_PID) },
+ { USB_DEVICE(EVOLUTION_VID, EVO_RCM4_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_ARTEMIS_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_ATIK_ATK16_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_ATIK_ATK16C_PID) },
diff --git a/drivers/usb/serial/ftdi_sio.h b/drivers/usb/serial/ftdi_sio.h
index d9e4971..c70e1de 100644
--- a/drivers/usb/serial/ftdi_sio.h
+++ b/drivers/usb/serial/ftdi_sio.h
@@ -430,6 +430,9 @@
*/
#define EVOLUTION_VID 0xDEEE /* Vendor ID */
#define EVOLUTION_ER1_PID 0x0300 /* ER1 Control Module */
+#define EVO_8U232AM_PID 0x02FF /* Evolution robotics RCM2 (FT232AM)*/
+#define EVO_HYBRID_PID 0x0302 /* Evolution robotics RCM4 PID (FT232BM)*/
+#define EVO_RCM4_PID 0x0303 /* Evolution robotics RCM4 PID */
/* Pyramid Computer GmbH */
#define FTDI_PYRAMID_PID 0xE6C8 /* Pyramid Appliance Display */
diff --git a/drivers/usb/serial/garmin_gps.c b/drivers/usb/serial/garmin_gps.c
index 04bd3b7..f1c90cf 100644
--- a/drivers/usb/serial/garmin_gps.c
+++ b/drivers/usb/serial/garmin_gps.c
@@ -1,7 +1,7 @@
/*
* Garmin GPS driver
*
- * Copyright (C) 2006 Hermann Kneissel herkne@users.sourceforge.net
+ * Copyright (C) 2006,2007 Hermann Kneissel herkne@users.sourceforge.net
*
* The latest version of the driver can be found at
* http://sourceforge.net/projects/garmin-gps/
@@ -34,6 +34,7 @@
#include <linux/module.h>
#include <linux/spinlock.h>
#include <asm/uaccess.h>
+#include <asm/atomic.h>
#include <linux/usb.h>
#include <linux/usb/serial.h>
@@ -52,7 +53,7 @@
*/
#define VERSION_MAJOR 0
-#define VERSION_MINOR 28
+#define VERSION_MINOR 31
#define _STR(s) #s
#define _DRIVER_VERSION(a,b) "v" _STR(a) "." _STR(b)
@@ -141,6 +142,8 @@
__u8 inbuffer [GPS_IN_BUFSIZ]; /* tty -> usb */
__u8 outbuffer[GPS_OUT_BUFSIZ]; /* usb -> tty */
__u8 privpkt[4*6];
+ atomic_t req_count;
+ atomic_t resp_count;
spinlock_t lock;
struct list_head pktlist;
};
@@ -171,8 +174,6 @@
#define CLEAR_HALT_REQUIRED 0x0001
#define FLAGS_QUEUING 0x0100
-#define FLAGS_APP_RESP_SEEN 0x0200
-#define FLAGS_APP_REQ_SEEN 0x0400
#define FLAGS_DROP_DATA 0x0800
#define FLAGS_GSP_SKIP 0x1000
@@ -186,7 +187,8 @@
/* function prototypes */
static void gsp_next_packet(struct garmin_data * garmin_data_p);
static int garmin_write_bulk(struct usb_serial_port *port,
- const unsigned char *buf, int count);
+ const unsigned char *buf, int count,
+ int dismiss_ack);
/* some special packets to be send or received */
static unsigned char const GARMIN_START_SESSION_REQ[]
@@ -233,9 +235,7 @@
static inline int noResponseFromAppLayer(struct garmin_data * garmin_data_p)
{
- return ((garmin_data_p->flags
- & (FLAGS_APP_REQ_SEEN|FLAGS_APP_RESP_SEEN))
- == FLAGS_APP_REQ_SEEN);
+ return atomic_read(&garmin_data_p->req_count) == atomic_read(&garmin_data_p->resp_count);
}
@@ -463,7 +463,7 @@
usbdata[2] = __cpu_to_le32(size);
garmin_write_bulk (garmin_data_p->port, garmin_data_p->inbuffer,
- GARMIN_PKTHDR_LENGTH+size);
+ GARMIN_PKTHDR_LENGTH+size, 0);
/* if this was an abort-transfer command, flush all
queued data. */
@@ -818,7 +818,7 @@
if (garmin_data_p->insize >= len) {
garmin_write_bulk (garmin_data_p->port,
garmin_data_p->inbuffer,
- len);
+ len, 0);
garmin_data_p->insize = 0;
/* if this was an abort-transfer command,
@@ -893,10 +893,11 @@
struct usb_serial_port *port = garmin_data_p->port;
- if (port != NULL && garmin_data_p->flags & FLAGS_APP_RESP_SEEN) {
+ if (port != NULL && atomic_read(&garmin_data_p->resp_count)) {
/* send a terminate command */
status = garmin_write_bulk(port, GARMIN_STOP_TRANSFER_REQ,
- sizeof(GARMIN_STOP_TRANSFER_REQ));
+ sizeof(GARMIN_STOP_TRANSFER_REQ),
+ 1);
}
/* flush all queued data */
@@ -939,7 +940,8 @@
dbg("%s - starting session ...", __FUNCTION__);
garmin_data_p->state = STATE_ACTIVE;
status = garmin_write_bulk(port, GARMIN_START_SESSION_REQ,
- sizeof(GARMIN_START_SESSION_REQ));
+ sizeof(GARMIN_START_SESSION_REQ),
+ 0);
if (status >= 0) {
@@ -950,7 +952,8 @@
/* not needed, but the win32 driver does it too ... */
status = garmin_write_bulk(port,
GARMIN_START_SESSION_REQ2,
- sizeof(GARMIN_START_SESSION_REQ2));
+ sizeof(GARMIN_START_SESSION_REQ2),
+ 0);
if (status >= 0) {
status = 0;
spin_lock_irqsave(&garmin_data_p->lock, flags);
@@ -987,6 +990,8 @@
garmin_data_p->mode = initial_mode;
garmin_data_p->count = 0;
garmin_data_p->flags = 0;
+ atomic_set(&garmin_data_p->req_count, 0);
+ atomic_set(&garmin_data_p->resp_count, 0);
spin_unlock_irqrestore(&garmin_data_p->lock, flags);
/* shutdown any bulk reads that might be going on */
@@ -1035,28 +1040,39 @@
{
unsigned long flags;
struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
- struct garmin_data * garmin_data_p = usb_get_serial_port_data(port);
int status = urb->status;
+ if (port) {
+ struct garmin_data * garmin_data_p = usb_get_serial_port_data(port);
+
+ dbg("%s - port %d", __FUNCTION__, port->number);
+
+ if (GARMIN_LAYERID_APPL == getLayerId(urb->transfer_buffer)
+ && (garmin_data_p->mode == MODE_GARMIN_SERIAL)) {
+ gsp_send_ack(garmin_data_p, ((__u8 *)urb->transfer_buffer)[4]);
+ }
+
+ if (status) {
+ dbg("%s - nonzero write bulk status received: %d",
+ __FUNCTION__, urb->status);
+ spin_lock_irqsave(&garmin_data_p->lock, flags);
+ garmin_data_p->flags |= CLEAR_HALT_REQUIRED;
+ spin_unlock_irqrestore(&garmin_data_p->lock, flags);
+ }
+
+ usb_serial_port_softint(port);
+ }
+
+ /* Ignore errors that resulted from garmin_write_bulk with dismiss_ack=1 */
+
/* free up the transfer buffer, as usb_free_urb() does not do this */
kfree (urb->transfer_buffer);
-
- dbg("%s - port %d", __FUNCTION__, port->number);
-
- if (status) {
- dbg("%s - nonzero write bulk status received: %d",
- __FUNCTION__, status);
- spin_lock_irqsave(&garmin_data_p->lock, flags);
- garmin_data_p->flags |= CLEAR_HALT_REQUIRED;
- spin_unlock_irqrestore(&garmin_data_p->lock, flags);
- }
-
- usb_serial_port_softint(port);
}
static int garmin_write_bulk (struct usb_serial_port *port,
- const unsigned char *buf, int count)
+ const unsigned char *buf, int count,
+ int dismiss_ack)
{
unsigned long flags;
struct usb_serial *serial = port->serial;
@@ -1093,13 +1109,12 @@
usb_sndbulkpipe (serial->dev,
port->bulk_out_endpointAddress),
buffer, count,
- garmin_write_bulk_callback, port);
+ garmin_write_bulk_callback,
+ dismiss_ack ? NULL : port);
urb->transfer_flags |= URB_ZERO_PACKET;
if (GARMIN_LAYERID_APPL == getLayerId(buffer)) {
- spin_lock_irqsave(&garmin_data_p->lock, flags);
- garmin_data_p->flags |= FLAGS_APP_REQ_SEEN;
- spin_unlock_irqrestore(&garmin_data_p->lock, flags);
+ atomic_inc(&garmin_data_p->req_count);
if (garmin_data_p->mode == MODE_GARMIN_SERIAL) {
pkt_clear(garmin_data_p);
garmin_data_p->state = STATE_GSP_WAIT_DATA;
@@ -1114,13 +1129,6 @@
"failed with status = %d\n",
__FUNCTION__, status);
count = status;
- } else {
-
- if (GARMIN_LAYERID_APPL == getLayerId(buffer)
- && (garmin_data_p->mode == MODE_GARMIN_SERIAL)) {
-
- gsp_send_ack(garmin_data_p, buffer[4]);
- }
}
/* we are done with this urb, so let the host driver
@@ -1135,7 +1143,6 @@
static int garmin_write (struct usb_serial_port *port,
const unsigned char *buf, int count)
{
- unsigned long flags;
int pktid, pktsiz, len;
struct garmin_data * garmin_data_p = usb_get_serial_port_data(port);
__le32 *privpkt = (__le32 *)garmin_data_p->privpkt;
@@ -1186,9 +1193,7 @@
break;
case PRIV_PKTID_RESET_REQ:
- spin_lock_irqsave(&garmin_data_p->lock, flags);
- garmin_data_p->flags |= FLAGS_APP_REQ_SEEN;
- spin_unlock_irqrestore(&garmin_data_p->lock, flags);
+ atomic_inc(&garmin_data_p->req_count);
break;
case PRIV_PKTID_SET_DEF_MODE:
@@ -1241,8 +1246,6 @@
static void garmin_read_process(struct garmin_data * garmin_data_p,
unsigned char *data, unsigned data_length)
{
- unsigned long flags;
-
if (garmin_data_p->flags & FLAGS_DROP_DATA) {
/* abort-transfer cmd is actice */
dbg("%s - pkt dropped", __FUNCTION__);
@@ -1254,9 +1257,7 @@
the device */
if (0 == memcmp(data, GARMIN_APP_LAYER_REPLY,
sizeof(GARMIN_APP_LAYER_REPLY))) {
- spin_lock_irqsave(&garmin_data_p->lock, flags);
- garmin_data_p->flags |= FLAGS_APP_RESP_SEEN;
- spin_unlock_irqrestore(&garmin_data_p->lock, flags);
+ atomic_inc(&garmin_data_p->resp_count);
}
/* if throttling is active or postprecessing is required
diff --git a/drivers/usb/serial/ipaq.c b/drivers/usb/serial/ipaq.c
index 0455c15..6a3a704 100644
--- a/drivers/usb/serial/ipaq.c
+++ b/drivers/usb/serial/ipaq.c
@@ -545,6 +545,7 @@
{ USB_DEVICE(0x413C, 0x4009) }, /* Dell Axim USB Sync */
{ USB_DEVICE(0x4505, 0x0010) }, /* Smartphone */
{ USB_DEVICE(0x5E04, 0xCE00) }, /* SAGEM Wireless Assistant */
+ { USB_DEVICE(0x0BB4, 0x00CF) }, /* HTC smartphone modems */
{ } /* Terminating entry */
};
diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c
index 84c12b5..4cb3c16 100644
--- a/drivers/usb/serial/option.c
+++ b/drivers/usb/serial/option.c
@@ -110,6 +110,7 @@
#define HUAWEI_PRODUCT_E220 0x1003
#define NOVATELWIRELESS_VENDOR_ID 0x1410
+#define DELL_VENDOR_ID 0x413C
#define ANYDATA_VENDOR_ID 0x16d5
#define ANYDATA_PRODUCT_ADU_E100A 0x6501
@@ -119,8 +120,6 @@
#define BANDRICH_PRODUCT_C100_1 0x1002
#define BANDRICH_PRODUCT_C100_2 0x1003
-#define DELL_VENDOR_ID 0x413C
-
static struct usb_device_id option_ids[] = {
{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COLT) },
{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_RICOLA) },
@@ -171,11 +170,16 @@
{ USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, 0x2110) }, /* Novatel Merlin ES620 / Merlin ES720 / Ovation U720 */
{ USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, 0x2130) }, /* Novatel Merlin ES620 SM Bus */
{ USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, 0x2410) }, /* Novatel EU740 */
+ { USB_DEVICE(DELL_VENDOR_ID, 0x8114) }, /* Dell Wireless 5700 Mobile Broadband CDMA/EVDO Mini-Card == Novatel Expedite EV620 CDMA/EV-DO */
+ { USB_DEVICE(DELL_VENDOR_ID, 0x8115) }, /* Dell Wireless 5500 Mobile Broadband HSDPA Mini-Card == Novatel Expedite EU740 HSDPA/3G */
+ { USB_DEVICE(DELL_VENDOR_ID, 0x8116) }, /* Dell Wireless 5505 Mobile Broadband HSDPA Mini-Card == Novatel Expedite EU740 HSDPA/3G */
+ { USB_DEVICE(DELL_VENDOR_ID, 0x8117) }, /* Dell Wireless 5700 Mobile Broadband CDMA/EVDO ExpressCard == Novatel Merlin XV620 CDMA/EV-DO */
+ { USB_DEVICE(DELL_VENDOR_ID, 0x8118) }, /* Dell Wireless 5510 Mobile Broadband HSDPA ExpressCard == Novatel Merlin XU870 HSDPA/3G */
+ { USB_DEVICE(DELL_VENDOR_ID, 0x8128) }, /* Dell Wireless 5700 Mobile Broadband CDMA/EVDO Mini-Card == Novatel Expedite E720 CDMA/EV-DO */
{ USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_E100A) },
{ USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_500A) },
{ USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_C100_1) },
{ USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_C100_2) },
- { USB_DEVICE(DELL_VENDOR_ID, 0x8118) }, /* Dell Wireless 5510 Mobile Broadband HSDPA ExpressCard */
{ } /* Terminating entry */
};
MODULE_DEVICE_TABLE(usb, option_ids);
diff --git a/drivers/usb/serial/oti6858.c b/drivers/usb/serial/oti6858.c
index d7db71e..833ada4 100644
--- a/drivers/usb/serial/oti6858.c
+++ b/drivers/usb/serial/oti6858.c
@@ -818,19 +818,17 @@
switch (cmd) {
case TCGETS:
- if (copy_to_user(user_arg, port->tty->termios,
- sizeof(struct ktermios))) {
+ if (kernel_termios_to_user_termios((struct ktermios __user *)arg,
+ port->tty->termios))
return -EFAULT;
- }
return 0;
case TCSETS:
case TCSETSW: /* FIXME: this is not the same! */
case TCSETSF: /* FIXME: this is not the same! */
- if (copy_from_user(port->tty->termios, user_arg,
- sizeof(struct ktermios))) {
+ if (user_termios_to_kernel_termios(port->tty->termios,
+ (struct ktermios __user *)arg))
return -EFAULT;
- }
oti6858_set_termios(port, NULL);
return 0;
diff --git a/drivers/usb/serial/safe_serial.c b/drivers/usb/serial/safe_serial.c
index 86899d5..51669b7 100644
--- a/drivers/usb/serial/safe_serial.c
+++ b/drivers/usb/serial/safe_serial.c
@@ -74,13 +74,13 @@
#include <linux/usb/serial.h>
-#ifndef CONFIG_USB_SAFE_PADDED
-#define CONFIG_USB_SAFE_PADDED 0
+#ifndef CONFIG_USB_SERIAL_SAFE_PADDED
+#define CONFIG_USB_SERIAL_SAFE_PADDED 0
#endif
static int debug;
static int safe = 1;
-static int padded = CONFIG_USB_SAFE_PADDED;
+static int padded = CONFIG_USB_SERIAL_SAFE_PADDED;
#define DRIVER_VERSION "v0.0b"
#define DRIVER_AUTHOR "sl@lineo.com, tbr@lineo.com"
diff --git a/drivers/usb/serial/visor.c b/drivers/usb/serial/visor.c
index 7d84a76..30e08c0 100644
--- a/drivers/usb/serial/visor.c
+++ b/drivers/usb/serial/visor.c
@@ -104,6 +104,8 @@
.driver_info = (kernel_ulong_t)&palm_os_4_probe },
{ USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_TJ25_ID),
.driver_info = (kernel_ulong_t)&palm_os_4_probe },
+ { USB_DEVICE(ACER_VENDOR_ID, ACER_S10_ID),
+ .driver_info = (kernel_ulong_t)&palm_os_4_probe },
{ USB_DEVICE(SAMSUNG_VENDOR_ID, SAMSUNG_SCH_I330_ID),
.driver_info = (kernel_ulong_t)&palm_os_4_probe },
{ USB_DEVICE(SAMSUNG_VENDOR_ID, SAMSUNG_SPH_I500_ID),
diff --git a/drivers/usb/serial/visor.h b/drivers/usb/serial/visor.h
index 4ce6f62..57229cf 100644
--- a/drivers/usb/serial/visor.h
+++ b/drivers/usb/serial/visor.h
@@ -48,6 +48,9 @@
#define SONY_CLIE_UX50_ID 0x0144
#define SONY_CLIE_TJ25_ID 0x0169
+#define ACER_VENDOR_ID 0x0502
+#define ACER_S10_ID 0x0001
+
#define SAMSUNG_VENDOR_ID 0x04E8
#define SAMSUNG_SCH_I330_ID 0x8001
#define SAMSUNG_SPH_I500_ID 0x6601
diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h
index d8d008d..2d92ce3 100644
--- a/drivers/usb/storage/unusual_devs.h
+++ b/drivers/usb/storage/unusual_devs.h
@@ -342,7 +342,7 @@
US_FL_FIX_CAPACITY),
/* Reported by Emil Larsson <emil@swip.net> */
-UNUSUAL_DEV( 0x04b0, 0x0411, 0x0100, 0x0100,
+UNUSUAL_DEV( 0x04b0, 0x0411, 0x0100, 0x0101,
"NIKON",
"NIKON DSC D80",
US_SC_DEVICE, US_PR_DEVICE, NULL,
diff --git a/drivers/usb/storage/usb.c b/drivers/usb/storage/usb.c
index 28842d2..25e557d 100644
--- a/drivers/usb/storage/usb.c
+++ b/drivers/usb/storage/usb.c
@@ -112,13 +112,6 @@
MODULE_PARM_DESC(delay_use, "seconds to delay before using a new device");
-/* These are used to make sure the module doesn't unload before all the
- * threads have exited.
- */
-static atomic_t total_threads = ATOMIC_INIT(0);
-static DECLARE_COMPLETION(threads_gone);
-
-
/*
* The entries in this table correspond, line for line,
* with the entries of us_unusual_dev_list[].
@@ -879,9 +872,6 @@
usb_stor_stop_transport(us);
wake_up(&us->delay_wait);
- /* It doesn't matter if the SCSI-scanning thread is still running.
- * The thread will exit when it sees the DISCONNECTING flag. */
-
/* queuecommand won't accept any new commands and the control
* thread won't execute a previously-queued command. If there
* is such a command pending, complete it with an error. */
@@ -891,12 +881,16 @@
scsi_lock(host);
us->srb->scsi_done(us->srb);
us->srb = NULL;
+ complete(&us->notify); /* in case of an abort */
scsi_unlock(host);
}
mutex_unlock(&us->dev_mutex);
/* Now we own no commands so it's safe to remove the SCSI host */
scsi_remove_host(host);
+
+ /* Wait for the SCSI-scanning thread to stop */
+ wait_for_completion(&us->scanning_done);
}
/* Second stage of disconnect processing: deallocate all resources */
@@ -947,9 +941,8 @@
/* Should we unbind if no devices were detected? */
}
- scsi_host_put(us_to_host(us));
usb_autopm_put_interface(us->pusb_intf);
- complete_and_exit(&threads_gone, 0);
+ complete_and_exit(&us->scanning_done, 0);
}
@@ -984,6 +977,7 @@
init_MUTEX_LOCKED(&(us->sema));
init_completion(&(us->notify));
init_waitqueue_head(&us->delay_wait);
+ init_completion(&us->scanning_done);
/* Associate the us_data structure with the USB device */
result = associate_dev(us, intf);
@@ -1033,11 +1027,6 @@
goto BadDevice;
}
- /* Take a reference to the host for the scanning thread and
- * count it among all the threads we have launched. Then
- * start it up. */
- scsi_host_get(us_to_host(us));
- atomic_inc(&total_threads);
usb_autopm_get_interface(intf); /* dropped in the scanning thread */
wake_up_process(th);
@@ -1104,16 +1093,6 @@
US_DEBUGP("-- calling usb_deregister()\n");
usb_deregister(&usb_storage_driver) ;
- /* Don't return until all of our control and scanning threads
- * have exited. Since each thread signals threads_gone as its
- * last act, we have to call wait_for_completion the right number
- * of times.
- */
- while (atomic_read(&total_threads) > 0) {
- wait_for_completion(&threads_gone);
- atomic_dec(&total_threads);
- }
-
usb_usual_clear_present(USB_US_TYPE_STOR);
}
diff --git a/drivers/usb/storage/usb.h b/drivers/usb/storage/usb.h
index 6445665..8d87503 100644
--- a/drivers/usb/storage/usb.h
+++ b/drivers/usb/storage/usb.h
@@ -150,6 +150,7 @@
struct semaphore sema; /* to sleep thread on */
struct completion notify; /* thread begin/end */
wait_queue_head_t delay_wait; /* wait during scan, reset */
+ struct completion scanning_done; /* wait for scan thread */
/* subdriver information */
void *extra; /* Any extra data */
diff --git a/drivers/video/au1100fb.c b/drivers/video/au1100fb.c
index 80a81ec..832e461 100644
--- a/drivers/video/au1100fb.c
+++ b/drivers/video/au1100fb.c
@@ -115,6 +115,52 @@
module_param(nocursor, int, 0644);
MODULE_PARM_DESC(nocursor, "cursor enable/disable");
+/* fb_blank
+ * Blank the screen. Depending on the mode, the screen will be
+ * activated with the backlight color, or desactivated
+ */
+static int au1100fb_fb_blank(int blank_mode, struct fb_info *fbi)
+{
+ struct au1100fb_device *fbdev = to_au1100fb_device(fbi);
+
+ print_dbg("fb_blank %d %p", blank_mode, fbi);
+
+ switch (blank_mode) {
+
+ case VESA_NO_BLANKING:
+ /* Turn on panel */
+ fbdev->regs->lcd_control |= LCD_CONTROL_GO;
+#ifdef CONFIG_MIPS_PB1100
+ if (drv_info.panel_idx == 1) {
+ au_writew(au_readw(PB1100_G_CONTROL)
+ | (PB1100_G_CONTROL_BL | PB1100_G_CONTROL_VDD),
+ PB1100_G_CONTROL);
+ }
+#endif
+ au_sync();
+ break;
+
+ case VESA_VSYNC_SUSPEND:
+ case VESA_HSYNC_SUSPEND:
+ case VESA_POWERDOWN:
+ /* Turn off panel */
+ fbdev->regs->lcd_control &= ~LCD_CONTROL_GO;
+#ifdef CONFIG_MIPS_PB1100
+ if (drv_info.panel_idx == 1) {
+ au_writew(au_readw(PB1100_G_CONTROL)
+ & ~(PB1100_G_CONTROL_BL | PB1100_G_CONTROL_VDD),
+ PB1100_G_CONTROL);
+ }
+#endif
+ au_sync();
+ break;
+ default:
+ break;
+
+ }
+ return 0;
+}
+
/*
* Set hardware with var settings. This will enable the controller with a specific
* mode, normally validated with the fb_check_var method
@@ -272,52 +318,6 @@
return 0;
}
-/* fb_blank
- * Blank the screen. Depending on the mode, the screen will be
- * activated with the backlight color, or desactivated
- */
-int au1100fb_fb_blank(int blank_mode, struct fb_info *fbi)
-{
- struct au1100fb_device *fbdev = to_au1100fb_device(fbi);
-
- print_dbg("fb_blank %d %p", blank_mode, fbi);
-
- switch (blank_mode) {
-
- case VESA_NO_BLANKING:
- /* Turn on panel */
- fbdev->regs->lcd_control |= LCD_CONTROL_GO;
-#ifdef CONFIG_MIPS_PB1100
- if (drv_info.panel_idx == 1) {
- au_writew(au_readw(PB1100_G_CONTROL)
- | (PB1100_G_CONTROL_BL | PB1100_G_CONTROL_VDD),
- PB1100_G_CONTROL);
- }
-#endif
- au_sync();
- break;
-
- case VESA_VSYNC_SUSPEND:
- case VESA_HSYNC_SUSPEND:
- case VESA_POWERDOWN:
- /* Turn off panel */
- fbdev->regs->lcd_control &= ~LCD_CONTROL_GO;
-#ifdef CONFIG_MIPS_PB1100
- if (drv_info.panel_idx == 1) {
- au_writew(au_readw(PB1100_G_CONTROL)
- & ~(PB1100_G_CONTROL_BL | PB1100_G_CONTROL_VDD),
- PB1100_G_CONTROL);
- }
-#endif
- au_sync();
- break;
- default:
- break;
-
- }
- return 0;
-}
-
/* fb_pan_display
* Pan display in x and/or y as specified
*/
diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c
index decfdc8..e58c87b 100644
--- a/drivers/video/console/fbcon.c
+++ b/drivers/video/console/fbcon.c
@@ -127,8 +127,20 @@
static int fbcon_is_default = 1;
static int fbcon_has_exited;
static int primary_device = -1;
+
+#ifdef CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY
static int map_override;
+static inline void fbcon_map_override(void)
+{
+ map_override = 1;
+}
+#else
+static inline void fbcon_map_override(void)
+{
+}
+#endif /* CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY */
+
/* font data */
static char fontname[40];
@@ -506,7 +518,7 @@
(options[j++]-'0') % FB_MAX;
}
- map_override = 1;
+ fbcon_map_override();
}
return 1;
diff --git a/drivers/video/console/newport_con.c b/drivers/video/console/newport_con.c
index 7fa1afe..dda0586 100644
--- a/drivers/video/console/newport_con.c
+++ b/drivers/video/console/newport_con.c
@@ -738,9 +738,8 @@
#ifdef MODULE
static int __init newport_console_init(void)
{
-
if (!sgi_gfxaddr)
- return NULL;
+ return 0;
if (!npregs)
npregs = (struct newport_regs *)/* ioremap cannot fail */
diff --git a/drivers/video/imsttfb.c b/drivers/video/imsttfb.c
index 5715b8a..94f4511 100644
--- a/drivers/video/imsttfb.c
+++ b/drivers/video/imsttfb.c
@@ -1391,7 +1391,7 @@
}
}
-#if USE_NV_MODES && defined(CONFIG_PPC)
+#if USE_NV_MODES && defined(CONFIG_PPC32)
{
int vmode = init_vmode, cmode = init_cmode;
diff --git a/drivers/video/matrox/g450_pll.c b/drivers/video/matrox/g450_pll.c
index 7c76e07..d42346e 100644
--- a/drivers/video/matrox/g450_pll.c
+++ b/drivers/video/matrox/g450_pll.c
@@ -331,16 +331,19 @@
tmp |= M1064_XPIXCLKCTRL_PLL_UP;
}
matroxfb_DAC_out(PMINFO M1064_XPIXCLKCTRL, tmp);
-#ifdef __powerpc__
- /* This is necessary to avoid jitter on PowerPC
- * (OpenFirmware) systems, but apparently
- * introduces jitter, at least on a x86-64
- * using DVI.
- * A simple workaround is disable for non-PPC.
- */
- matroxfb_DAC_out(PMINFO M1064_XDVICLKCTRL, 0);
-#endif /* __powerpc__ */
- matroxfb_DAC_out(PMINFO M1064_XPWRCTRL, xpwrctrl);
+ /* DVI PLL preferred for frequencies up to
+ panel link max, standard PLL otherwise */
+ if (fout >= MINFO->max_pixel_clock_panellink)
+ tmp = 0;
+ else tmp =
+ M1064_XDVICLKCTRL_DVIDATAPATHSEL |
+ M1064_XDVICLKCTRL_C1DVICLKSEL |
+ M1064_XDVICLKCTRL_C1DVICLKEN |
+ M1064_XDVICLKCTRL_DVILOOPCTL |
+ M1064_XDVICLKCTRL_P1LOOPBWDTCTL;
+ matroxfb_DAC_out(PMINFO M1064_XDVICLKCTRL,tmp);
+ matroxfb_DAC_out(PMINFO M1064_XPWRCTRL,
+ xpwrctrl);
matroxfb_DAC_unlock_irqrestore(flags);
}
diff --git a/drivers/video/matrox/matroxfb_DAC1064.h b/drivers/video/matrox/matroxfb_DAC1064.h
index df39c31..7a98ce8 100644
--- a/drivers/video/matrox/matroxfb_DAC1064.h
+++ b/drivers/video/matrox/matroxfb_DAC1064.h
@@ -33,6 +33,21 @@
#define M1064_XCURCTRL_3COLOR 0x01 /* transparent, 0, 1, 2 */
#define M1064_XCURCTRL_XGA 0x02 /* 0, 1, transparent, complement */
#define M1064_XCURCTRL_XWIN 0x03 /* transparent, transparent, 0, 1 */
+ /* drive DVI by standard(0)/DVI(1) PLL */
+ /* if set(1), C?DVICLKEN and C?DVICLKSEL must be set(1) */
+#define M1064_XDVICLKCTRL_DVIDATAPATHSEL 0x01
+ /* drive CRTC1 by standard(0)/DVI(1) PLL */
+#define M1064_XDVICLKCTRL_C1DVICLKSEL 0x02
+ /* drive CRTC2 by standard(0)/DVI(1) PLL */
+#define M1064_XDVICLKCTRL_C2DVICLKSEL 0x04
+ /* pixel clock allowed to(0)/blocked from(1) driving CRTC1 */
+#define M1064_XDVICLKCTRL_C1DVICLKEN 0x08
+ /* DVI PLL loop filter bandwidth selection bits */
+#define M1064_XDVICLKCTRL_DVILOOPCTL 0x30
+ /* CRTC2 pixel clock allowed to(0)/blocked from(1) driving CRTC2 */
+#define M1064_XDVICLKCTRL_C2DVICLKEN 0x40
+ /* P1PLL loop filter bandwith selection */
+#define M1064_XDVICLKCTRL_P1LOOPBWDTCTL 0x80
#define M1064_XCURCOL0RED 0x08
#define M1064_XCURCOL0GREEN 0x09
#define M1064_XCURCOL0BLUE 0x0A
diff --git a/drivers/video/matrox/matroxfb_base.h b/drivers/video/matrox/matroxfb_base.h
index d59577c..f3107ad 100644
--- a/drivers/video/matrox/matroxfb_base.h
+++ b/drivers/video/matrox/matroxfb_base.h
@@ -424,6 +424,7 @@
} mmio;
unsigned int max_pixel_clock;
+ unsigned int max_pixel_clock_panellink;
struct matrox_switch* hw_switch;
diff --git a/drivers/video/matrox/matroxfb_misc.c b/drivers/video/matrox/matroxfb_misc.c
index 5948e54..ab7fb50 100644
--- a/drivers/video/matrox/matroxfb_misc.c
+++ b/drivers/video/matrox/matroxfb_misc.c
@@ -658,6 +658,7 @@
MINFO->values.reg.mctlwtst_core = (MINFO->values.reg.mctlwtst & ~7) |
wtst_xlat[MINFO->values.reg.mctlwtst & 7];
}
+ MINFO->max_pixel_clock_panellink = bd->pins[47] * 4000;
return 0;
}
diff --git a/drivers/video/pvr2fb.c b/drivers/video/pvr2fb.c
index f930026..7d6c298 100644
--- a/drivers/video/pvr2fb.c
+++ b/drivers/video/pvr2fb.c
@@ -94,6 +94,7 @@
#define DISP_DIWCONF (DISP_BASE + 0xe8)
#define DISP_DIWHSTRT (DISP_BASE + 0xec)
#define DISP_DIWVSTRT (DISP_BASE + 0xf0)
+#define DISP_PIXDEPTH (DISP_BASE + 0x108)
/* Pixel clocks, one for TV output, doubled for VGA output */
#define TV_CLK 74239
@@ -143,6 +144,7 @@
unsigned char is_lowres; /* Is horizontal pixel-doubling enabled? */
unsigned long mmio_base; /* MMIO base */
+ u32 palette[16];
} *currentpar;
static struct fb_info *fb_info;
@@ -599,6 +601,7 @@
/* bits per pixel */
fb_writel(fb_readl(DISP_DIWMODE) | (--bytesperpixel << 2), DISP_DIWMODE);
+ fb_writel(bytesperpixel << 2, DISP_PIXDEPTH);
/* video enable, color sync, interlace,
* hsync and vsync polarity (currently unused) */
@@ -790,7 +793,7 @@
fb_info->fbops = &pvr2fb_ops;
fb_info->fix = pvr2_fix;
fb_info->par = currentpar;
- fb_info->pseudo_palette = (void *)(fb_info->par + 1);
+ fb_info->pseudo_palette = currentpar->palette;
fb_info->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_YPAN;
if (video_output == VO_VGA)
@@ -807,6 +810,8 @@
if (register_framebuffer(fb_info) < 0)
goto out_err;
+ /*Must write PIXDEPTH to register before anything is displayed - so force init */
+ pvr2_init_display(fb_info);
modememused = get_line_length(fb_info->var.xres_virtual,
fb_info->var.bits_per_pixel);
@@ -1082,14 +1087,15 @@
#endif
size = sizeof(struct fb_info) + sizeof(struct pvr2fb_par) + 16 * sizeof(u32);
- fb_info = kzalloc(size, GFP_KERNEL);
+ fb_info = framebuffer_alloc(sizeof(struct pvr2fb_par), NULL);
+
if (!fb_info) {
printk(KERN_ERR "Failed to allocate memory for fb_info\n");
return -ENOMEM;
}
- currentpar = (struct pvr2fb_par *)(fb_info + 1);
+ currentpar = fb_info->par;
for (i = 0; i < ARRAY_SIZE(board_driver); i++) {
struct pvr2_board *pvr_board = board_driver + i;
@@ -1102,7 +1108,7 @@
if (ret != 0) {
printk(KERN_ERR "pvr2fb: Failed init of %s device\n",
pvr_board->name);
- kfree(fb_info);
+ framebuffer_release(fb_info);
break;
}
}
@@ -1126,7 +1132,7 @@
#endif
unregister_framebuffer(fb_info);
- kfree(fb_info);
+ framebuffer_release(fb_info);
}
module_init(pvr2fb_init);
diff --git a/drivers/video/pxafb.c b/drivers/video/pxafb.c
index 81e571d..a280a52 100644
--- a/drivers/video/pxafb.c
+++ b/drivers/video/pxafb.c
@@ -66,7 +66,7 @@
#ifdef CONFIG_FB_PXA_PARAMETERS
#define PXAFB_OPTIONS_SIZE 256
-static char g_options[PXAFB_OPTIONS_SIZE] __initdata = "";
+static char g_options[PXAFB_OPTIONS_SIZE] __devinitdata = "";
#endif
static inline void pxafb_schedule_work(struct pxafb_info *fbi, u_int state)
diff --git a/drivers/video/stifb.c b/drivers/video/stifb.c
index c97709e..e7c8db2 100644
--- a/drivers/video/stifb.c
+++ b/drivers/video/stifb.c
@@ -1100,13 +1100,18 @@
/* only supported cards are allowed */
switch (fb->id) {
case CRT_ID_VISUALIZE_EG:
- /* look for a double buffering device like e.g. the
- "INTERNAL_EG_DX1024" in the RDI precisionbook laptop
- which won't work. The same device in non-double
- buffering mode returns "INTERNAL_EG_X1024". */
- if (strstr(sti->outptr.dev_name, "EG_DX")) {
- printk(KERN_WARNING
- "stifb: ignoring '%s'. Disable double buffering in IPL menu.\n",
+ /* Visualize cards can run either in "double buffer" or
+ "standard" mode. Depending on the mode, the card reports
+ a different device name, e.g. "INTERNAL_EG_DX1024" in double
+ buffer mode and "INTERNAL_EG_X1024" in standard mode.
+ Since this driver only supports standard mode, we check
+ if the device name contains the string "DX" and tell the
+ user how to reconfigure the card. */
+ if (strstr(sti->outptr.dev_name, "DX")) {
+ printk(KERN_WARNING "WARNING: stifb framebuffer driver does not "
+ "support '%s' in double-buffer mode.\n"
+ KERN_WARNING "WARNING: Please disable the double-buffer mode "
+ "in IPL menu (the PARISC-BIOS).\n",
sti->outptr.dev_name);
goto out_err0;
}
diff --git a/drivers/w1/w1_int.c b/drivers/w1/w1_int.c
index 2fbd8dd..6840dfe 100644
--- a/drivers/w1/w1_int.c
+++ b/drivers/w1/w1_int.c
@@ -170,22 +170,24 @@
void w1_remove_master_device(struct w1_bus_master *bm)
{
- struct w1_master *dev = NULL;
+ struct w1_master *dev, *found = NULL;
list_for_each_entry(dev, &w1_masters, w1_master_entry) {
if (!dev->initialized)
continue;
- if (dev->bus_master->data == bm->data)
+ if (dev->bus_master->data == bm->data) {
+ found = dev;
break;
+ }
}
- if (!dev) {
+ if (!found) {
printk(KERN_ERR "Device doesn't exist.\n");
return;
}
- __w1_remove_master_device(dev);
+ __w1_remove_master_device(found);
}
EXPORT_SYMBOL(w1_add_master_device);
diff --git a/drivers/zorro/zorro-sysfs.c b/drivers/zorro/zorro-sysfs.c
index 9130f1c..808b4f8 100644
--- a/drivers/zorro/zorro-sysfs.c
+++ b/drivers/zorro/zorro-sysfs.c
@@ -78,7 +78,7 @@
static struct bin_attribute zorro_config_attr = {
.attr = {
.name = "config",
- .mode = S_IRUGO | S_IWUSR,
+ .mode = S_IRUGO,
},
.size = sizeof(struct ConfigDev),
.read = zorro_read_config,
diff --git a/fs/9p/fid.c b/fs/9p/fid.c
index 08fa320..15e05a1 100644
--- a/fs/9p/fid.c
+++ b/fs/9p/fid.c
@@ -92,23 +92,6 @@
return fid;
}
-struct p9_fid *v9fs_fid_lookup_remove(struct dentry *dentry)
-{
- struct p9_fid *fid;
- struct v9fs_dentry *dent;
-
- dent = dentry->d_fsdata;
- fid = v9fs_fid_lookup(dentry);
- if (!IS_ERR(fid)) {
- spin_lock(&dent->lock);
- list_del(&fid->dlist);
- spin_unlock(&dent->lock);
- }
-
- return fid;
-}
-
-
/**
* v9fs_fid_clone - lookup the fid for a dentry, clone a private copy and
* release it
diff --git a/fs/9p/fid.h b/fs/9p/fid.h
index 47a0ba7..26e07df 100644
--- a/fs/9p/fid.h
+++ b/fs/9p/fid.h
@@ -28,6 +28,5 @@
};
struct p9_fid *v9fs_fid_lookup(struct dentry *dentry);
-struct p9_fid *v9fs_fid_lookup_remove(struct dentry *dentry);
struct p9_fid *v9fs_fid_clone(struct dentry *dentry);
int v9fs_fid_add(struct dentry *dentry, struct p9_fid *fid);
diff --git a/fs/autofs4/root.c b/fs/autofs4/root.c
index 2d4c8a3..45ff3d6 100644
--- a/fs/autofs4/root.c
+++ b/fs/autofs4/root.c
@@ -587,19 +587,20 @@
unhashed = autofs4_lookup_unhashed(sbi, dentry->d_parent, &dentry->d_name);
if (!unhashed) {
/*
- * Mark the dentry incomplete, but add it. This is needed so
- * that the VFS layer knows about the dentry, and we can count
- * on catching any lookups through the revalidate.
- *
- * Let all the hard work be done by the revalidate function that
- * needs to be able to do this anyway..
- *
- * We need to do this before we release the directory semaphore.
+ * Mark the dentry incomplete but don't hash it. We do this
+ * to serialize our inode creation operations (symlink and
+ * mkdir) which prevents deadlock during the callback to
+ * the daemon. Subsequent user space lookups for the same
+ * dentry are placed on the wait queue while the daemon
+ * itself is allowed passage unresticted so the create
+ * operation itself can then hash the dentry. Finally,
+ * we check for the hashed dentry and return the newly
+ * hashed dentry.
*/
dentry->d_op = &autofs4_root_dentry_operations;
dentry->d_fsdata = NULL;
- d_add(dentry, NULL);
+ d_instantiate(dentry, NULL);
} else {
struct autofs_info *ino = autofs4_dentry_ino(unhashed);
DPRINTK("rehash %p with %p", dentry, unhashed);
@@ -607,15 +608,17 @@
* If we are racing with expire the request might not
* be quite complete but the directory has been removed
* so it must have been successful, so just wait for it.
+ * We need to ensure the AUTOFS_INF_EXPIRING flag is clear
+ * before continuing as revalidate may fail when calling
+ * try_to_fill_dentry (returning EAGAIN) if we don't.
*/
- if (ino && (ino->flags & AUTOFS_INF_EXPIRING)) {
+ while (ino && (ino->flags & AUTOFS_INF_EXPIRING)) {
DPRINTK("wait for incomplete expire %p name=%.*s",
unhashed, unhashed->d_name.len,
unhashed->d_name.name);
autofs4_wait(sbi, unhashed, NFY_NONE);
DPRINTK("request completed");
}
- d_rehash(unhashed);
dentry = unhashed;
}
@@ -658,7 +661,7 @@
* for all system calls, but it should be OK for the operations
* we permit from an autofs.
*/
- if (dentry->d_inode && d_unhashed(dentry)) {
+ if (!oz_mode && d_unhashed(dentry)) {
/*
* A user space application can (and has done in the past)
* remove and re-create this directory during the callback.
@@ -716,7 +719,7 @@
strcpy(cp, symname);
inode = autofs4_get_inode(dir->i_sb, ino);
- d_instantiate(dentry, inode);
+ d_add(dentry, inode);
if (dir == dir->i_sb->s_root->d_inode)
dentry->d_op = &autofs4_root_dentry_operations;
@@ -844,7 +847,7 @@
return -ENOSPC;
inode = autofs4_get_inode(dir->i_sb, ino);
- d_instantiate(dentry, inode);
+ d_add(dentry, inode);
if (dir == dir->i_sb->s_root->d_inode)
dentry->d_op = &autofs4_root_dentry_operations;
diff --git a/fs/cifs/CHANGES b/fs/cifs/CHANGES
index 6d84ca2..bed6215 100644
--- a/fs/cifs/CHANGES
+++ b/fs/cifs/CHANGES
@@ -3,7 +3,10 @@
Fix NTLMv2 signing. NFS server mounted over cifs works (if cifs mount is
done with "serverino" mount option). Add support for POSIX Unlink
(helps with certain sharing violation cases when server such as
-Samba supports newer POSIX CIFS Protocol Extensions).
+Samba supports newer POSIX CIFS Protocol Extensions). Add "nounix"
+mount option to allow disabling the CIFS Unix Extensions for just
+that mount. Fix hang on spinlock in find_writable_file (race when
+reopening file after session crash).
Version 1.49
------------
diff --git a/fs/cifs/README b/fs/cifs/README
index 85f1eb1..b806b11 100644
--- a/fs/cifs/README
+++ b/fs/cifs/README
@@ -444,6 +444,13 @@
noposixpaths If CIFS Unix extensions are supported, do not request
posix path name support (this may cause servers to
reject creatingfile with certain reserved characters).
+ nounix Disable the CIFS Unix Extensions for this mount (tree
+ connection). This is rarely needed, but it may be useful
+ in order to turn off multiple settings all at once (ie
+ posix acls, posix locks, posix paths, symlink support
+ and retrieving uids/gids/mode from the server) or to
+ work around a bug in server which implement the Unix
+ Extensions.
nobrl Do not send byte range lock requests to the server.
This is necessary for certain applications that break
with cifs style mandatory byte range locks (and most
@@ -451,6 +458,12 @@
byte range locks).
remount remount the share (often used to change from ro to rw mounts
or vice versa)
+ servern Specify the server 's netbios name (RFC1001 name) to use
+ when attempting to setup a session to the server. This is
+ This is needed for mounting to some older servers (such
+ as OS/2 or Windows 98 and Windows ME) since they do not
+ support a default server name. A server name can be up
+ to 15 characters long and is usually uppercased.
sfu When the CIFS Unix Extensions are not negotiated, attempt to
create device files and fifos in a format compatible with
Services for Unix (SFU). In addition retrieve bits 10-12
diff --git a/fs/cifs/TODO b/fs/cifs/TODO
index d7bd515..29d4b27 100644
--- a/fs/cifs/TODO
+++ b/fs/cifs/TODO
@@ -82,8 +82,7 @@
v) mount check for unmatched uids
-w) Add mount option for Linux extension disable per mount, and partial
-disable per mount (uid off, symlink/fifo/mknod on but what about posix acls?)
+w) Add support for new vfs entry points for setlease and fallocate
x) Fix Samba 3 server to handle Linux kernel aio so dbench with lots of
processes can proceed better in parallel (on the server)
diff --git a/fs/cifs/file.c b/fs/cifs/file.c
index e13592a..894b1f7 100644
--- a/fs/cifs/file.c
+++ b/fs/cifs/file.c
@@ -1904,6 +1904,25 @@
return rc;
}
+static int is_inode_writable(struct cifsInodeInfo *cifs_inode)
+{
+ struct cifsFileInfo *open_file;
+
+ read_lock(&GlobalSMBSeslock);
+ list_for_each_entry(open_file, &cifs_inode->openFileList, flist) {
+ if (open_file->closePend)
+ continue;
+ if (open_file->pfile &&
+ ((open_file->pfile->f_flags & O_RDWR) ||
+ (open_file->pfile->f_flags & O_WRONLY))) {
+ read_unlock(&GlobalSMBSeslock);
+ return 1;
+ }
+ }
+ read_unlock(&GlobalSMBSeslock);
+ return 0;
+}
+
/* We do not want to update the file size from server for inodes
open for write - to avoid races with writepage extending
the file - in the future we could consider allowing
@@ -1912,19 +1931,13 @@
page caching in the current Linux kernel design */
int is_size_safe_to_change(struct cifsInodeInfo *cifsInode, __u64 end_of_file)
{
- struct cifsFileInfo *open_file = NULL;
+ if (!cifsInode)
+ return 1;
- if (cifsInode)
- open_file = find_writable_file(cifsInode);
-
- if (open_file) {
+ if (is_inode_writable(cifsInode)) {
+ /* This inode is open for write at least once */
struct cifs_sb_info *cifs_sb;
- /* there is not actually a write pending so let
- this handle go free and allow it to
- be closable if needed */
- atomic_dec(&open_file->wrtPending);
-
cifs_sb = CIFS_SB(cifsInode->vfs_inode.i_sb);
if ( cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO ) {
/* since no page cache to corrupt on directio
diff --git a/fs/cifs/sess.c b/fs/cifs/sess.c
index 2ea027d..892be9b 100644
--- a/fs/cifs/sess.c
+++ b/fs/cifs/sess.c
@@ -372,6 +372,10 @@
/* 2000 big enough to fit max user, domain, NOS name etc. */
str_area = kmalloc(2000, GFP_KERNEL);
+ if (str_area == NULL) {
+ cifs_small_buf_release(smb_buf);
+ return -ENOMEM;
+ }
bcc_ptr = str_area;
ses->flags &= ~CIFS_SES_LANMAN;
diff --git a/fs/compat_ioctl.c b/fs/compat_ioctl.c
index 2bc1428..a6c9078 100644
--- a/fs/compat_ioctl.c
+++ b/fs/compat_ioctl.c
@@ -3161,12 +3161,9 @@
COMPATIBLE_IOCTL(SIOCGIWSENS)
COMPATIBLE_IOCTL(SIOCSIWRANGE)
COMPATIBLE_IOCTL(SIOCSIWPRIV)
-COMPATIBLE_IOCTL(SIOCGIWPRIV)
COMPATIBLE_IOCTL(SIOCSIWSTATS)
-COMPATIBLE_IOCTL(SIOCGIWSTATS)
COMPATIBLE_IOCTL(SIOCSIWAP)
COMPATIBLE_IOCTL(SIOCGIWAP)
-COMPATIBLE_IOCTL(SIOCSIWSCAN)
COMPATIBLE_IOCTL(SIOCSIWRATE)
COMPATIBLE_IOCTL(SIOCGIWRATE)
COMPATIBLE_IOCTL(SIOCSIWRTS)
diff --git a/fs/direct-io.c b/fs/direct-io.c
index 52bb263..901dc55 100644
--- a/fs/direct-io.c
+++ b/fs/direct-io.c
@@ -958,35 +958,22 @@
ssize_t ret2;
size_t bytes;
- dio->bio = NULL;
dio->inode = inode;
dio->rw = rw;
dio->blkbits = blkbits;
dio->blkfactor = inode->i_blkbits - blkbits;
- dio->start_zero_done = 0;
- dio->size = 0;
dio->block_in_file = offset >> blkbits;
- dio->blocks_available = 0;
- dio->cur_page = NULL;
- dio->boundary = 0;
- dio->reap_counter = 0;
dio->get_block = get_block;
dio->end_io = end_io;
- dio->map_bh.b_private = NULL;
dio->final_block_in_bio = -1;
dio->next_block_for_io = -1;
- dio->page_errors = 0;
- dio->io_error = 0;
- dio->result = 0;
dio->iocb = iocb;
dio->i_size = i_size_read(inode);
spin_lock_init(&dio->bio_lock);
dio->refcount = 1;
- dio->bio_list = NULL;
- dio->waiter = NULL;
/*
* In case of non-aligned buffers, we may need 2 more
@@ -994,8 +981,6 @@
*/
if (unlikely(dio->blkfactor))
dio->pages_in_io = 2;
- else
- dio->pages_in_io = 0;
for (seg = 0; seg < nr_segs; seg++) {
user_addr = (unsigned long)iov[seg].iov_base;
@@ -1183,7 +1168,7 @@
}
}
- dio = kmalloc(sizeof(*dio), GFP_KERNEL);
+ dio = kzalloc(sizeof(*dio), GFP_KERNEL);
retval = -ENOMEM;
if (!dio)
goto out;
diff --git a/fs/dlm/lock.c b/fs/dlm/lock.c
index b455919..2082daf 100644
--- a/fs/dlm/lock.c
+++ b/fs/dlm/lock.c
@@ -1670,9 +1670,10 @@
with a deadlk here, we'd have to generate something like grant_lock with
the deadlk error.) */
-/* returns the highest requested mode of all blocked conversions */
+/* Returns the highest requested mode of all blocked conversions; sets
+ cw if there's a blocked conversion to DLM_LOCK_CW. */
-static int grant_pending_convert(struct dlm_rsb *r, int high)
+static int grant_pending_convert(struct dlm_rsb *r, int high, int *cw)
{
struct dlm_lkb *lkb, *s;
int hi, demoted, quit, grant_restart, demote_restart;
@@ -1709,6 +1710,9 @@
}
hi = max_t(int, lkb->lkb_rqmode, hi);
+
+ if (cw && lkb->lkb_rqmode == DLM_LOCK_CW)
+ *cw = 1;
}
if (grant_restart)
@@ -1721,29 +1725,52 @@
return max_t(int, high, hi);
}
-static int grant_pending_wait(struct dlm_rsb *r, int high)
+static int grant_pending_wait(struct dlm_rsb *r, int high, int *cw)
{
struct dlm_lkb *lkb, *s;
list_for_each_entry_safe(lkb, s, &r->res_waitqueue, lkb_statequeue) {
if (can_be_granted(r, lkb, 0, NULL))
grant_lock_pending(r, lkb);
- else
+ else {
high = max_t(int, lkb->lkb_rqmode, high);
+ if (lkb->lkb_rqmode == DLM_LOCK_CW)
+ *cw = 1;
+ }
}
return high;
}
+/* cw of 1 means there's a lock with a rqmode of DLM_LOCK_CW that's blocked
+ on either the convert or waiting queue.
+ high is the largest rqmode of all locks blocked on the convert or
+ waiting queue. */
+
+static int lock_requires_bast(struct dlm_lkb *gr, int high, int cw)
+{
+ if (gr->lkb_grmode == DLM_LOCK_PR && cw) {
+ if (gr->lkb_highbast < DLM_LOCK_EX)
+ return 1;
+ return 0;
+ }
+
+ if (gr->lkb_highbast < high &&
+ !__dlm_compat_matrix[gr->lkb_grmode+1][high+1])
+ return 1;
+ return 0;
+}
+
static void grant_pending_locks(struct dlm_rsb *r)
{
struct dlm_lkb *lkb, *s;
int high = DLM_LOCK_IV;
+ int cw = 0;
DLM_ASSERT(is_master(r), dlm_dump_rsb(r););
- high = grant_pending_convert(r, high);
- high = grant_pending_wait(r, high);
+ high = grant_pending_convert(r, high, &cw);
+ high = grant_pending_wait(r, high, &cw);
if (high == DLM_LOCK_IV)
return;
@@ -1751,27 +1778,41 @@
/*
* If there are locks left on the wait/convert queue then send blocking
* ASTs to granted locks based on the largest requested mode (high)
- * found above. FIXME: highbast < high comparison not valid for PR/CW.
+ * found above.
*/
list_for_each_entry_safe(lkb, s, &r->res_grantqueue, lkb_statequeue) {
- if (lkb->lkb_bastaddr && (lkb->lkb_highbast < high) &&
- !__dlm_compat_matrix[lkb->lkb_grmode+1][high+1]) {
- queue_bast(r, lkb, high);
+ if (lkb->lkb_bastaddr && lock_requires_bast(lkb, high, cw)) {
+ if (cw && high == DLM_LOCK_PR)
+ queue_bast(r, lkb, DLM_LOCK_CW);
+ else
+ queue_bast(r, lkb, high);
lkb->lkb_highbast = high;
}
}
}
+static int modes_require_bast(struct dlm_lkb *gr, struct dlm_lkb *rq)
+{
+ if ((gr->lkb_grmode == DLM_LOCK_PR && rq->lkb_rqmode == DLM_LOCK_CW) ||
+ (gr->lkb_grmode == DLM_LOCK_CW && rq->lkb_rqmode == DLM_LOCK_PR)) {
+ if (gr->lkb_highbast < DLM_LOCK_EX)
+ return 1;
+ return 0;
+ }
+
+ if (gr->lkb_highbast < rq->lkb_rqmode && !modes_compat(gr, rq))
+ return 1;
+ return 0;
+}
+
static void send_bast_queue(struct dlm_rsb *r, struct list_head *head,
struct dlm_lkb *lkb)
{
struct dlm_lkb *gr;
list_for_each_entry(gr, head, lkb_statequeue) {
- if (gr->lkb_bastaddr &&
- gr->lkb_highbast < lkb->lkb_rqmode &&
- !modes_compat(gr, lkb)) {
+ if (gr->lkb_bastaddr && modes_require_bast(gr, lkb)) {
queue_bast(r, gr, lkb->lkb_rqmode);
gr->lkb_highbast = lkb->lkb_rqmode;
}
@@ -2235,7 +2276,7 @@
before we try again to grant this one. */
if (is_demoted(lkb)) {
- grant_pending_convert(r, DLM_LOCK_IV);
+ grant_pending_convert(r, DLM_LOCK_IV, NULL);
if (_can_be_granted(r, lkb, 1)) {
grant_lock(r, lkb);
queue_cast(r, lkb, 0);
diff --git a/fs/dlm/lowcomms.c b/fs/dlm/lowcomms.c
index dd36273..9e9d2e8 100644
--- a/fs/dlm/lowcomms.c
+++ b/fs/dlm/lowcomms.c
@@ -313,6 +313,7 @@
in6_addr->sin6_port = cpu_to_be16(port);
*addr_len = sizeof(struct sockaddr_in6);
}
+ memset((char *)saddr + *addr_len, 0, sizeof(struct sockaddr_storage) - *addr_len);
}
/* Close a remote connection and tidy up */
@@ -332,8 +333,19 @@
__free_page(con->rx_page);
con->rx_page = NULL;
}
- con->retries = 0;
- mutex_unlock(&con->sock_mutex);
+
+ /* If we are an 'othercon' then NULL the pointer to us
+ from the parent and tidy ourself up */
+ if (test_bit(CF_IS_OTHERCON, &con->flags)) {
+ struct connection *parent = __nodeid2con(con->nodeid, 0);
+ parent->othercon = NULL;
+ kmem_cache_free(con_cache, con);
+ }
+ else {
+ /* Parent connections get reused */
+ con->retries = 0;
+ mutex_unlock(&con->sock_mutex);
+ }
}
/* We only send shutdown messages to nodes that are not part of the cluster */
@@ -631,7 +643,7 @@
out_close:
mutex_unlock(&con->sock_mutex);
- if (ret != -EAGAIN && !test_bit(CF_IS_OTHERCON, &con->flags)) {
+ if (ret != -EAGAIN) {
close_connection(con, false);
/* Reconnect when there is something to send */
}
@@ -1122,8 +1134,6 @@
log_print("Using TCP for communications");
- set_bit(CF_IS_OTHERCON, &con->flags);
-
sock = tcp_create_listen_sock(con, dlm_local_addr[0]);
if (sock) {
add_sock(sock, con);
@@ -1407,7 +1417,7 @@
for (i = 0; i <= max_nodeid; i++) {
con = __nodeid2con(i, 0);
if (con) {
- con->flags |= 0xFF;
+ con->flags |= 0x0F;
if (con->sock)
con->sock->sk->sk_user_data = NULL;
}
@@ -1423,8 +1433,6 @@
con = __nodeid2con(i, 0);
if (con) {
close_connection(con, true);
- if (con->othercon)
- kmem_cache_free(con_cache, con->othercon);
kmem_cache_free(con_cache, con);
}
}
diff --git a/fs/dlm/member.c b/fs/dlm/member.c
index 073599d..d099775 100644
--- a/fs/dlm/member.c
+++ b/fs/dlm/member.c
@@ -56,8 +56,10 @@
return -ENOMEM;
w = dlm_node_weight(ls->ls_name, nodeid);
- if (w < 0)
+ if (w < 0) {
+ kfree(memb);
return w;
+ }
memb->nodeid = nodeid;
memb->weight = w;
diff --git a/fs/dlm/rcom.c b/fs/dlm/rcom.c
index e3a1527..188b91c 100644
--- a/fs/dlm/rcom.c
+++ b/fs/dlm/rcom.c
@@ -386,8 +386,7 @@
dlm_recover_process_copy(ls, rc_in);
}
-static int send_ls_not_ready(struct dlm_ls *ls, int nodeid,
- struct dlm_rcom *rc_in)
+static int send_ls_not_ready(int nodeid, struct dlm_rcom *rc_in)
{
struct dlm_rcom *rc;
struct rcom_config *rf;
@@ -395,7 +394,7 @@
char *mb;
int mb_len = sizeof(struct dlm_rcom) + sizeof(struct rcom_config);
- mh = dlm_lowcomms_get_buffer(nodeid, mb_len, ls->ls_allocation, &mb);
+ mh = dlm_lowcomms_get_buffer(nodeid, mb_len, GFP_NOFS, &mb);
if (!mh)
return -ENOBUFS;
memset(mb, 0, mb_len);
@@ -465,7 +464,7 @@
log_print("lockspace %x from %d type %x not found",
hd->h_lockspace, nodeid, rc->rc_type);
if (rc->rc_type == DLM_RCOM_STATUS)
- send_ls_not_ready(ls, nodeid, rc);
+ send_ls_not_ready(nodeid, rc);
return;
}
diff --git a/fs/ecryptfs/inode.c b/fs/ecryptfs/inode.c
index 0a50942..5d40ad1 100644
--- a/fs/ecryptfs/inode.c
+++ b/fs/ecryptfs/inode.c
@@ -353,6 +353,14 @@
ecryptfs_printk(KERN_DEBUG, "Is a symlink; returning\n");
goto out;
}
+ if (special_file(lower_inode->i_mode)) {
+ ecryptfs_printk(KERN_DEBUG, "Is a special file; returning\n");
+ goto out;
+ }
+ if (special_file(lower_inode->i_mode)) {
+ ecryptfs_printk(KERN_DEBUG, "Is a special file; returning\n");
+ goto out;
+ }
if (!nd) {
ecryptfs_printk(KERN_DEBUG, "We have a NULL nd, just leave"
"as we *think* we are about to unlink\n");
diff --git a/fs/ecryptfs/main.c b/fs/ecryptfs/main.c
index e557a67..a984972 100644
--- a/fs/ecryptfs/main.c
+++ b/fs/ecryptfs/main.c
@@ -813,6 +813,15 @@
return rc;
}
+static void do_sysfs_unregistration(void)
+{
+ sysfs_remove_file(&ecryptfs_subsys.kobj,
+ &sysfs_attr_version.attr);
+ sysfs_remove_file(&ecryptfs_subsys.kobj,
+ &sysfs_attr_version_str.attr);
+ subsystem_unregister(&ecryptfs_subsys);
+}
+
static int __init ecryptfs_init(void)
{
int rc;
@@ -851,6 +860,9 @@
if (rc) {
ecryptfs_printk(KERN_ERR, "Failure occured while attempting to "
"initialize the eCryptfs netlink socket\n");
+ do_sysfs_unregistration();
+ unregister_filesystem(&ecryptfs_fs_type);
+ ecryptfs_free_kmem_caches();
}
out:
return rc;
@@ -858,11 +870,7 @@
static void __exit ecryptfs_exit(void)
{
- sysfs_remove_file(&ecryptfs_subsys.kobj,
- &sysfs_attr_version.attr);
- sysfs_remove_file(&ecryptfs_subsys.kobj,
- &sysfs_attr_version_str.attr);
- subsystem_unregister(&ecryptfs_subsys);
+ do_sysfs_unregistration();
ecryptfs_release_messaging(ecryptfs_transport);
unregister_filesystem(&ecryptfs_fs_type);
ecryptfs_free_kmem_caches();
diff --git a/fs/exec.c b/fs/exec.c
index 7bdea79..c21a8cc 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -780,18 +780,11 @@
int count;
/*
- * Tell all the sighand listeners that this sighand has
- * been detached. The signalfd_detach() function grabs the
- * sighand lock, if signal listeners are present on the sighand.
- */
- signalfd_detach(tsk);
-
- /*
* If we don't share sighandlers, then we aren't sharing anything
* and we can just re-use it all.
*/
if (atomic_read(&oldsighand->count) <= 1) {
- BUG_ON(atomic_read(&sig->count) != 1);
+ signalfd_detach(tsk);
exit_itimers(sig);
return 0;
}
@@ -930,12 +923,11 @@
sig->flags = 0;
no_thread_group:
+ signalfd_detach(tsk);
exit_itimers(sig);
if (leader)
release_task(leader);
- BUG_ON(atomic_read(&sig->count) != 1);
-
if (atomic_read(&oldsighand->count) == 1) {
/*
* Now that we nuked the rest of the thread group,
@@ -1084,9 +1076,12 @@
*/
current->mm->task_size = TASK_SIZE;
- if (bprm->e_uid != current->euid || bprm->e_gid != current->egid ||
- file_permission(bprm->file, MAY_READ) ||
- (bprm->interp_flags & BINPRM_FLAGS_ENFORCE_NONDUMP)) {
+ if (bprm->e_uid != current->euid || bprm->e_gid != current->egid) {
+ suid_keys(current);
+ set_dumpable(current->mm, suid_dumpable);
+ current->pdeath_signal = 0;
+ } else if (file_permission(bprm->file, MAY_READ) ||
+ (bprm->interp_flags & BINPRM_FLAGS_ENFORCE_NONDUMP)) {
suid_keys(current);
set_dumpable(current->mm, suid_dumpable);
}
@@ -1177,8 +1172,10 @@
{
int unsafe;
- if (bprm->e_uid != current->uid)
+ if (bprm->e_uid != current->uid) {
suid_keys(current);
+ current->pdeath_signal = 0;
+ }
exec_keys(current);
task_lock(current);
diff --git a/fs/gfs2/lops.c b/fs/gfs2/lops.c
index aff70f0..3b395c4 100644
--- a/fs/gfs2/lops.c
+++ b/fs/gfs2/lops.c
@@ -486,8 +486,8 @@
gfs2_pin(sdp, bd->bd_bh);
tr->tr_num_databuf_new++;
}
- sdp->sd_log_num_databuf++;
gfs2_log_lock(sdp);
+ sdp->sd_log_num_databuf++;
list_add(&le->le_list, &sdp->sd_log_le_databuf);
gfs2_log_unlock(sdp);
}
@@ -523,7 +523,7 @@
struct buffer_head *bh = NULL,*bh1 = NULL;
struct gfs2_log_descriptor *ld;
unsigned int limit;
- unsigned int total_dbuf = sdp->sd_log_num_databuf;
+ unsigned int total_dbuf;
unsigned int total_jdata = sdp->sd_log_num_jdata;
unsigned int num, n;
__be64 *ptr = NULL;
@@ -535,6 +535,7 @@
* into the log along with a header
*/
gfs2_log_lock(sdp);
+ total_dbuf = sdp->sd_log_num_databuf;
bd2 = bd1 = list_prepare_entry(bd1, &sdp->sd_log_le_databuf,
bd_le.le_list);
while(total_dbuf) {
@@ -653,6 +654,7 @@
break;
}
bh = NULL;
+ BUG_ON(total_dbuf < num);
total_dbuf -= num;
total_jdata -= num;
}
diff --git a/fs/gfs2/mount.c b/fs/gfs2/mount.c
index 6f006a8..4864659 100644
--- a/fs/gfs2/mount.c
+++ b/fs/gfs2/mount.c
@@ -82,19 +82,20 @@
char *options, *o, *v;
int error = 0;
- /* If someone preloaded options, use those instead */
- spin_lock(&gfs2_sys_margs_lock);
- if (!remount && gfs2_sys_margs) {
- data = gfs2_sys_margs;
- gfs2_sys_margs = NULL;
- }
- spin_unlock(&gfs2_sys_margs_lock);
+ if (!remount) {
+ /* If someone preloaded options, use those instead */
+ spin_lock(&gfs2_sys_margs_lock);
+ if (gfs2_sys_margs) {
+ data = gfs2_sys_margs;
+ gfs2_sys_margs = NULL;
+ }
+ spin_unlock(&gfs2_sys_margs_lock);
- /* Set some defaults */
- memset(args, 0, sizeof(struct gfs2_args));
- args->ar_num_glockd = GFS2_GLOCKD_DEFAULT;
- args->ar_quota = GFS2_QUOTA_DEFAULT;
- args->ar_data = GFS2_DATA_DEFAULT;
+ /* Set some defaults */
+ args->ar_num_glockd = GFS2_GLOCKD_DEFAULT;
+ args->ar_quota = GFS2_QUOTA_DEFAULT;
+ args->ar_data = GFS2_DATA_DEFAULT;
+ }
/* Split the options into tokens with the "," character and
process them */
diff --git a/fs/gfs2/ops_address.c b/fs/gfs2/ops_address.c
index ce90032..42a5f58 100644
--- a/fs/gfs2/ops_address.c
+++ b/fs/gfs2/ops_address.c
@@ -416,7 +416,7 @@
error = gfs2_trans_begin(sdp, rblocks, 0);
if (error)
- goto out;
+ goto out_trans_fail;
if (gfs2_is_stuffed(ip)) {
if (end > sdp->sd_sb.sb_bsize - sizeof(struct gfs2_dinode)) {
@@ -434,6 +434,7 @@
out:
if (error) {
gfs2_trans_end(sdp);
+out_trans_fail:
if (alloc_required) {
gfs2_inplace_release(ip);
out_qunlock:
diff --git a/fs/gfs2/ops_file.c b/fs/gfs2/ops_file.c
index 7734211..94d76ac 100644
--- a/fs/gfs2/ops_file.c
+++ b/fs/gfs2/ops_file.c
@@ -177,8 +177,8 @@
[5] = GFS2_DIF_APPENDONLY,
[7] = GFS2_DIF_NOATIME,
[12] = GFS2_DIF_EXHASH,
- [14] = GFS2_DIF_JDATA,
- [20] = GFS2_DIF_DIRECTIO,
+ [14] = GFS2_DIF_INHERIT_JDATA,
+ [20] = GFS2_DIF_INHERIT_DIRECTIO,
};
static const u32 gfs2_to_fsflags[32] = {
@@ -187,8 +187,6 @@
[gfs2fl_AppendOnly] = FS_APPEND_FL,
[gfs2fl_NoAtime] = FS_NOATIME_FL,
[gfs2fl_ExHash] = FS_INDEX_FL,
- [gfs2fl_Jdata] = FS_JOURNAL_DATA_FL,
- [gfs2fl_Directio] = FS_DIRECTIO_FL,
[gfs2fl_InheritDirectio] = FS_DIRECTIO_FL,
[gfs2fl_InheritJdata] = FS_JOURNAL_DATA_FL,
};
@@ -207,6 +205,12 @@
return error;
fsflags = fsflags_cvt(gfs2_to_fsflags, ip->i_di.di_flags);
+ if (!S_ISDIR(inode->i_mode)) {
+ if (ip->i_di.di_flags & GFS2_DIF_JDATA)
+ fsflags |= FS_JOURNAL_DATA_FL;
+ if (ip->i_di.di_flags & GFS2_DIF_DIRECTIO)
+ fsflags |= FS_DIRECTIO_FL;
+ }
if (put_user(fsflags, ptr))
error = -EFAULT;
@@ -270,13 +274,6 @@
if ((new_flags ^ flags) == 0)
goto out;
- if (S_ISDIR(inode->i_mode)) {
- if ((new_flags ^ flags) & GFS2_DIF_JDATA)
- new_flags ^= (GFS2_DIF_JDATA|GFS2_DIF_INHERIT_JDATA);
- if ((new_flags ^ flags) & GFS2_DIF_DIRECTIO)
- new_flags ^= (GFS2_DIF_DIRECTIO|GFS2_DIF_INHERIT_DIRECTIO);
- }
-
error = -EINVAL;
if ((new_flags ^ flags) & ~GFS2_FLAGS_USER_SET)
goto out;
@@ -315,11 +312,19 @@
static int gfs2_set_flags(struct file *filp, u32 __user *ptr)
{
+ struct inode *inode = filp->f_path.dentry->d_inode;
u32 fsflags, gfsflags;
if (get_user(fsflags, ptr))
return -EFAULT;
gfsflags = fsflags_cvt(fsflags_to_gfs2, fsflags);
- return do_gfs2_set_flags(filp, gfsflags, ~0);
+ if (!S_ISDIR(inode->i_mode)) {
+ if (gfsflags & GFS2_DIF_INHERIT_JDATA)
+ gfsflags ^= (GFS2_DIF_JDATA | GFS2_DIF_INHERIT_JDATA);
+ if (gfsflags & GFS2_DIF_INHERIT_DIRECTIO)
+ gfsflags ^= (GFS2_DIF_DIRECTIO | GFS2_DIF_INHERIT_DIRECTIO);
+ return do_gfs2_set_flags(filp, gfsflags, ~0);
+ }
+ return do_gfs2_set_flags(filp, gfsflags, ~GFS2_DIF_JDATA);
}
static long gfs2_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
diff --git a/fs/gfs2/rgrp.c b/fs/gfs2/rgrp.c
index e4e0406..ce48c45 100644
--- a/fs/gfs2/rgrp.c
+++ b/fs/gfs2/rgrp.c
@@ -863,16 +863,19 @@
u64 no_addr;
for(;;) {
+ if (goal >= rgd->rd_data)
+ break;
goal = rgblk_search(rgd, goal, GFS2_BLKST_UNLINKED,
GFS2_BLKST_UNLINKED);
- if (goal == 0)
- return 0;
+ if (goal == BFITNOENT)
+ break;
no_addr = goal + rgd->rd_data0;
- if (no_addr <= *last_unlinked)
+ goal++;
+ if (no_addr < *last_unlinked)
continue;
*last_unlinked = no_addr;
inode = gfs2_inode_lookup(rgd->rd_sbd->sd_vfs, DT_UNKNOWN,
- no_addr, -1);
+ no_addr, -1);
if (!IS_ERR(inode))
return inode;
}
@@ -1313,7 +1316,7 @@
bi->bi_len, blk, new_state);
}
- return (blk == BFITNOENT) ? 0 : (bi->bi_start * GFS2_NBBY) + blk;
+ return (blk == BFITNOENT) ? blk : (bi->bi_start * GFS2_NBBY) + blk;
}
/**
@@ -1393,6 +1396,7 @@
goal = rgd->rd_last_alloc_data;
blk = rgblk_search(rgd, goal, GFS2_BLKST_FREE, GFS2_BLKST_USED);
+ BUG_ON(blk == BFITNOENT);
rgd->rd_last_alloc_data = blk;
block = rgd->rd_data0 + blk;
@@ -1437,6 +1441,7 @@
goal = rgd->rd_last_alloc_meta;
blk = rgblk_search(rgd, goal, GFS2_BLKST_FREE, GFS2_BLKST_USED);
+ BUG_ON(blk == BFITNOENT);
rgd->rd_last_alloc_meta = blk;
block = rgd->rd_data0 + blk;
@@ -1478,6 +1483,7 @@
blk = rgblk_search(rgd, rgd->rd_last_alloc_meta,
GFS2_BLKST_FREE, GFS2_BLKST_DINODE);
+ BUG_ON(blk == BFITNOENT);
rgd->rd_last_alloc_meta = blk;
diff --git a/fs/jffs2/write.c b/fs/jffs2/write.c
index bc61859..664c164 100644
--- a/fs/jffs2/write.c
+++ b/fs/jffs2/write.c
@@ -566,6 +566,9 @@
struct jffs2_full_dirent **prev = &dir_f->dents;
uint32_t nhash = full_name_hash(name, namelen);
+ /* We don't actually want to reserve any space, but we do
+ want to be holding the alloc_sem when we write to flash */
+ down(&c->alloc_sem);
down(&dir_f->sem);
while ((*prev) && (*prev)->nhash <= nhash) {
diff --git a/fs/nfs/delegation.c b/fs/nfs/delegation.c
index 20ac403..c55a761 100644
--- a/fs/nfs/delegation.c
+++ b/fs/nfs/delegation.c
@@ -20,10 +20,8 @@
#include "delegation.h"
#include "internal.h"
-static void nfs_free_delegation(struct nfs_delegation *delegation)
+static void nfs_do_free_delegation(struct nfs_delegation *delegation)
{
- if (delegation->cred)
- put_rpccred(delegation->cred);
kfree(delegation);
}
@@ -31,7 +29,18 @@
{
struct nfs_delegation *delegation = container_of(head, struct nfs_delegation, rcu);
- nfs_free_delegation(delegation);
+ nfs_do_free_delegation(delegation);
+}
+
+static void nfs_free_delegation(struct nfs_delegation *delegation)
+{
+ struct rpc_cred *cred;
+
+ cred = rcu_dereference(delegation->cred);
+ rcu_assign_pointer(delegation->cred, NULL);
+ call_rcu(&delegation->rcu, nfs_free_delegation_callback);
+ if (cred)
+ put_rpccred(cred);
}
static int nfs_delegation_claim_locks(struct nfs_open_context *ctx, struct nfs4_state *state)
@@ -166,7 +175,7 @@
int res = 0;
res = nfs4_proc_delegreturn(inode, delegation->cred, &delegation->stateid);
- call_rcu(&delegation->rcu, nfs_free_delegation_callback);
+ nfs_free_delegation(delegation);
return res;
}
@@ -448,7 +457,7 @@
spin_unlock(&clp->cl_lock);
rcu_read_unlock();
if (delegation != NULL)
- call_rcu(&delegation->rcu, nfs_free_delegation_callback);
+ nfs_free_delegation(delegation);
goto restart;
}
rcu_read_unlock();
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c
index bca6cdc..71a49c3 100644
--- a/fs/nfs/inode.c
+++ b/fs/nfs/inode.c
@@ -468,7 +468,7 @@
ctx->lockowner = current->files;
ctx->error = 0;
ctx->dir_cookie = 0;
- kref_init(&ctx->kref);
+ atomic_set(&ctx->count, 1);
}
return ctx;
}
@@ -476,21 +476,18 @@
struct nfs_open_context *get_nfs_open_context(struct nfs_open_context *ctx)
{
if (ctx != NULL)
- kref_get(&ctx->kref);
+ atomic_inc(&ctx->count);
return ctx;
}
-static void nfs_free_open_context(struct kref *kref)
+void put_nfs_open_context(struct nfs_open_context *ctx)
{
- struct nfs_open_context *ctx = container_of(kref,
- struct nfs_open_context, kref);
+ struct inode *inode = ctx->path.dentry->d_inode;
- if (!list_empty(&ctx->list)) {
- struct inode *inode = ctx->path.dentry->d_inode;
- spin_lock(&inode->i_lock);
- list_del(&ctx->list);
- spin_unlock(&inode->i_lock);
- }
+ if (!atomic_dec_and_lock(&ctx->count, &inode->i_lock))
+ return;
+ list_del(&ctx->list);
+ spin_unlock(&inode->i_lock);
if (ctx->state != NULL)
nfs4_close_state(&ctx->path, ctx->state, ctx->mode);
if (ctx->cred != NULL)
@@ -500,11 +497,6 @@
kfree(ctx);
}
-void put_nfs_open_context(struct nfs_open_context *ctx)
-{
- kref_put(&ctx->kref, nfs_free_open_context);
-}
-
/*
* Ensure that mmap has a recent RPC credential for use when writing out
* shared pages
diff --git a/fs/nfs/namespace.c b/fs/nfs/namespace.c
index 7f86e65..aea76d0 100644
--- a/fs/nfs/namespace.c
+++ b/fs/nfs/namespace.c
@@ -175,10 +175,8 @@
void nfs_release_automount_timer(void)
{
- if (list_empty(&nfs_automount_list)) {
- cancel_delayed_work(&nfs_automount_task);
- flush_scheduled_work();
- }
+ if (list_empty(&nfs_automount_list))
+ cancel_delayed_work_sync(&nfs_automount_task);
}
/*
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 6ca2795..62b3ae2 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -332,11 +332,9 @@
switch (mode & (FMODE_READ|FMODE_WRITE|O_EXCL)) {
case FMODE_READ:
ret |= test_bit(NFS_O_RDONLY_STATE, &state->flags) != 0;
- ret |= test_bit(NFS_O_RDWR_STATE, &state->flags) != 0;
break;
case FMODE_WRITE:
ret |= test_bit(NFS_O_WRONLY_STATE, &state->flags) != 0;
- ret |= test_bit(NFS_O_RDWR_STATE, &state->flags) != 0;
break;
case FMODE_READ|FMODE_WRITE:
ret |= test_bit(NFS_O_RDWR_STATE, &state->flags) != 0;
@@ -1260,7 +1258,7 @@
nfs_increment_open_seqid(task->tk_status, calldata->arg.seqid);
switch (task->tk_status) {
case 0:
- nfs_set_open_stateid(state, &calldata->res.stateid, calldata->arg.open_flags);
+ nfs_set_open_stateid(state, &calldata->res.stateid, 0);
renew_lease(server, calldata->timestamp);
break;
case -NFS4ERR_STALE_STATEID:
@@ -1286,23 +1284,19 @@
.rpc_cred = state->owner->so_cred,
};
int clear_rd, clear_wr, clear_rdwr;
- int mode;
if (nfs_wait_on_sequence(calldata->arg.seqid, task) != 0)
return;
- mode = FMODE_READ|FMODE_WRITE;
clear_rd = clear_wr = clear_rdwr = 0;
spin_lock(&state->owner->so_lock);
/* Calculate the change in open mode */
if (state->n_rdwr == 0) {
if (state->n_rdonly == 0) {
- mode &= ~FMODE_READ;
clear_rd |= test_and_clear_bit(NFS_O_RDONLY_STATE, &state->flags);
clear_rdwr |= test_and_clear_bit(NFS_O_RDWR_STATE, &state->flags);
}
if (state->n_wronly == 0) {
- mode &= ~FMODE_WRITE;
clear_wr |= test_and_clear_bit(NFS_O_WRONLY_STATE, &state->flags);
clear_rdwr |= test_and_clear_bit(NFS_O_RDWR_STATE, &state->flags);
}
@@ -1314,9 +1308,13 @@
return;
}
nfs_fattr_init(calldata->res.fattr);
- if (mode != 0)
+ if (test_bit(NFS_O_RDONLY_STATE, &state->flags) != 0) {
msg.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_OPEN_DOWNGRADE];
- calldata->arg.open_flags = mode;
+ calldata->arg.open_flags = FMODE_READ;
+ } else if (test_bit(NFS_O_WRONLY_STATE, &state->flags) != 0) {
+ msg.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_OPEN_DOWNGRADE];
+ calldata->arg.open_flags = FMODE_WRITE;
+ }
calldata->timestamp = jiffies;
rpc_call_setup(task, &msg, 0);
}
diff --git a/fs/nfs/nfs4renewd.c b/fs/nfs/nfs4renewd.c
index 0505ca1..3ea352d 100644
--- a/fs/nfs/nfs4renewd.c
+++ b/fs/nfs/nfs4renewd.c
@@ -127,16 +127,15 @@
void
nfs4_renewd_prepare_shutdown(struct nfs_server *server)
{
- flush_scheduled_work();
+ cancel_delayed_work(&server->nfs_client->cl_renewd);
}
void
nfs4_kill_renewd(struct nfs_client *clp)
{
down_read(&clp->cl_sem);
- cancel_delayed_work(&clp->cl_renewd);
+ cancel_delayed_work_sync(&clp->cl_renewd);
up_read(&clp->cl_sem);
- flush_scheduled_work();
}
/*
diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c
index e9662ba..3e4adf8 100644
--- a/fs/nfs/nfs4state.c
+++ b/fs/nfs/nfs4state.c
@@ -341,8 +341,6 @@
else
list_move_tail(&state->open_states, &state->owner->so_states);
}
- if (mode == 0)
- list_del_init(&state->inode_states);
state->state = mode;
}
@@ -415,8 +413,7 @@
if (!atomic_dec_and_lock(&state->count, &owner->so_lock))
return;
spin_lock(&inode->i_lock);
- if (!list_empty(&state->inode_states))
- list_del(&state->inode_states);
+ list_del(&state->inode_states);
list_del(&state->open_states);
spin_unlock(&inode->i_lock);
spin_unlock(&owner->so_lock);
diff --git a/fs/ocfs2/alloc.c b/fs/ocfs2/alloc.c
index f5e11f4..4f51766 100644
--- a/fs/ocfs2/alloc.c
+++ b/fs/ocfs2/alloc.c
@@ -3731,7 +3731,6 @@
{
int status;
struct buffer_head *last_eb_bh = NULL;
- struct buffer_head *bh = NULL;
struct ocfs2_insert_type insert = {0, };
struct ocfs2_extent_rec rec;
@@ -3783,9 +3782,6 @@
ocfs2_extent_map_insert_rec(inode, &rec);
bail:
- if (bh)
- brelse(bh);
-
if (last_eb_bh)
brelse(last_eb_bh);
diff --git a/fs/ocfs2/cluster/tcp.c b/fs/ocfs2/cluster/tcp.c
index f0bdfd9..685c180 100644
--- a/fs/ocfs2/cluster/tcp.c
+++ b/fs/ocfs2/cluster/tcp.c
@@ -854,17 +854,25 @@
struct o2net_node *nn = o2net_nn_from_num(sc->sc_node->nd_num);
ssize_t ret;
-
- mutex_lock(&sc->sc_send_lock);
- ret = sc->sc_sock->ops->sendpage(sc->sc_sock,
- virt_to_page(kmalloced_virt),
- (long)kmalloced_virt & ~PAGE_MASK,
- size, MSG_DONTWAIT);
- mutex_unlock(&sc->sc_send_lock);
- if (ret != size) {
+ while (1) {
+ mutex_lock(&sc->sc_send_lock);
+ ret = sc->sc_sock->ops->sendpage(sc->sc_sock,
+ virt_to_page(kmalloced_virt),
+ (long)kmalloced_virt & ~PAGE_MASK,
+ size, MSG_DONTWAIT);
+ mutex_unlock(&sc->sc_send_lock);
+ if (ret == size)
+ break;
+ if (ret == (ssize_t)-EAGAIN) {
+ mlog(0, "sendpage of size %zu to " SC_NODEF_FMT
+ " returned EAGAIN\n", size, SC_NODEF_ARGS(sc));
+ cond_resched();
+ continue;
+ }
mlog(ML_ERROR, "sendpage of size %zu to " SC_NODEF_FMT
" failed with %zd\n", size, SC_NODEF_ARGS(sc), ret);
o2net_ensure_shutdown(nn, sc, 0);
+ break;
}
}
diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c
index c4034f6..4ffa715be 100644
--- a/fs/ocfs2/file.c
+++ b/fs/ocfs2/file.c
@@ -187,6 +187,7 @@
int ret;
struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
handle_t *handle;
+ struct ocfs2_dinode *di = (struct ocfs2_dinode *) bh->b_data;
mlog_entry_void();
@@ -197,11 +198,27 @@
goto out;
}
+ ret = ocfs2_journal_access(handle, inode, bh,
+ OCFS2_JOURNAL_ACCESS_WRITE);
+ if (ret) {
+ mlog_errno(ret);
+ goto out_commit;
+ }
+
+ /*
+ * Don't use ocfs2_mark_inode_dirty() here as we don't always
+ * have i_mutex to guard against concurrent changes to other
+ * inode fields.
+ */
inode->i_atime = CURRENT_TIME;
- ret = ocfs2_mark_inode_dirty(handle, inode, bh);
+ di->i_atime = cpu_to_le64(inode->i_atime.tv_sec);
+ di->i_atime_nsec = cpu_to_le32(inode->i_atime.tv_nsec);
+
+ ret = ocfs2_journal_dirty(handle, bh);
if (ret < 0)
mlog_errno(ret);
+out_commit:
ocfs2_commit_trans(OCFS2_SB(inode->i_sb), handle);
out:
mlog_exit(ret);
@@ -1011,6 +1028,11 @@
}
if (size_change && attr->ia_size != i_size_read(inode)) {
+ if (attr->ia_size > sb->s_maxbytes) {
+ status = -EFBIG;
+ goto bail_unlock;
+ }
+
if (i_size_read(inode) > attr->ia_size)
status = ocfs2_truncate_file(inode, bh, attr->ia_size);
else
@@ -1516,7 +1538,7 @@
struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
struct buffer_head *di_bh = NULL;
handle_t *handle;
- unsigned long long max_off = ocfs2_max_file_offset(inode->i_sb->s_blocksize_bits);
+ unsigned long long max_off = inode->i_sb->s_maxbytes;
if (ocfs2_is_hard_readonly(osb) || ocfs2_is_soft_readonly(osb))
return -EROFS;
@@ -1942,7 +1964,7 @@
}
dst = kmap_atomic(page, KM_USER0);
- memcpy(dst + (pos & (PAGE_CACHE_SIZE - 1)), buf, bytes);
+ memcpy(dst + (pos & (loff_t)(PAGE_CACHE_SIZE - 1)), buf, bytes);
kunmap_atomic(dst, KM_USER0);
flush_dcache_page(page);
ocfs2_put_write_source(user_page);
diff --git a/fs/ocfs2/namei.c b/fs/ocfs2/namei.c
index d430fda..701e6d0 100644
--- a/fs/ocfs2/namei.c
+++ b/fs/ocfs2/namei.c
@@ -1080,6 +1080,7 @@
struct buffer_head *old_inode_de_bh = NULL; // if old_dentry is a dir,
// this is the 1st dirent bh
nlink_t old_dir_nlink = old_dir->i_nlink;
+ struct ocfs2_dinode *old_di;
/* At some point it might be nice to break this function up a
* bit. */
@@ -1354,7 +1355,20 @@
old_inode->i_ctime = CURRENT_TIME;
mark_inode_dirty(old_inode);
- ocfs2_mark_inode_dirty(handle, old_inode, old_inode_bh);
+
+ status = ocfs2_journal_access(handle, old_inode, old_inode_bh,
+ OCFS2_JOURNAL_ACCESS_WRITE);
+ if (status >= 0) {
+ old_di = (struct ocfs2_dinode *) old_inode_bh->b_data;
+
+ old_di->i_ctime = cpu_to_le64(old_inode->i_ctime.tv_sec);
+ old_di->i_ctime_nsec = cpu_to_le32(old_inode->i_ctime.tv_nsec);
+
+ status = ocfs2_journal_dirty(handle, old_inode_bh);
+ if (status < 0)
+ mlog_errno(status);
+ } else
+ mlog_errno(status);
/* now that the name has been added to new_dir, remove the old name */
status = ocfs2_delete_entry(handle, old_dir, old_de, old_de_bh);
diff --git a/fs/ocfs2/ocfs2.h b/fs/ocfs2/ocfs2.h
index 5cc90a4..5830785 100644
--- a/fs/ocfs2/ocfs2.h
+++ b/fs/ocfs2/ocfs2.h
@@ -494,16 +494,16 @@
/*
* Find the 1st page index which covers the given clusters.
*/
-static inline unsigned long ocfs2_align_clusters_to_page_index(struct super_block *sb,
+static inline pgoff_t ocfs2_align_clusters_to_page_index(struct super_block *sb,
u32 clusters)
{
unsigned int cbits = OCFS2_SB(sb)->s_clustersize_bits;
- unsigned long index = clusters;
+ pgoff_t index = clusters;
if (PAGE_CACHE_SHIFT > cbits) {
- index = clusters >> (PAGE_CACHE_SHIFT - cbits);
+ index = (pgoff_t)clusters >> (PAGE_CACHE_SHIFT - cbits);
} else if (PAGE_CACHE_SHIFT < cbits) {
- index = clusters << (cbits - PAGE_CACHE_SHIFT);
+ index = (pgoff_t)clusters << (cbits - PAGE_CACHE_SHIFT);
}
return index;
diff --git a/fs/ocfs2/super.c b/fs/ocfs2/super.c
index 200c7d4..f2fc9a7 100644
--- a/fs/ocfs2/super.c
+++ b/fs/ocfs2/super.c
@@ -316,39 +316,51 @@
kmem_cache_free(ocfs2_inode_cachep, OCFS2_I(inode));
}
-/* From xfs_super.c:xfs_max_file_offset
- * Copyright (c) 2000-2004 Silicon Graphics, Inc.
- */
-unsigned long long ocfs2_max_file_offset(unsigned int blockshift)
+static unsigned long long ocfs2_max_file_offset(unsigned int bbits,
+ unsigned int cbits)
{
- unsigned int pagefactor = 1;
- unsigned int bitshift = BITS_PER_LONG - 1;
+ unsigned int bytes = 1 << cbits;
+ unsigned int trim = bytes;
+ unsigned int bitshift = 32;
- /* Figure out maximum filesize, on Linux this can depend on
- * the filesystem blocksize (on 32 bit platforms).
- * __block_prepare_write does this in an [unsigned] long...
- * page->index << (PAGE_CACHE_SHIFT - bbits)
- * So, for page sized blocks (4K on 32 bit platforms),
- * this wraps at around 8Tb (hence MAX_LFS_FILESIZE which is
- * (((u64)PAGE_CACHE_SIZE << (BITS_PER_LONG-1))-1)
- * but for smaller blocksizes it is less (bbits = log2 bsize).
- * Note1: get_block_t takes a long (implicit cast from above)
- * Note2: The Large Block Device (LBD and HAVE_SECTOR_T) patch
- * can optionally convert the [unsigned] long from above into
- * an [unsigned] long long.
+ /*
+ * i_size and all block offsets in ocfs2 are always 64 bits
+ * wide. i_clusters is 32 bits, in cluster-sized units. So on
+ * 64 bit platforms, cluster size will be the limiting factor.
*/
#if BITS_PER_LONG == 32
# if defined(CONFIG_LBD)
BUILD_BUG_ON(sizeof(sector_t) != 8);
- pagefactor = PAGE_CACHE_SIZE;
- bitshift = BITS_PER_LONG;
+ /*
+ * We might be limited by page cache size.
+ */
+ if (bytes > PAGE_CACHE_SIZE) {
+ bytes = PAGE_CACHE_SIZE;
+ trim = 1;
+ /*
+ * Shift by 31 here so that we don't get larger than
+ * MAX_LFS_FILESIZE
+ */
+ bitshift = 31;
+ }
# else
- pagefactor = PAGE_CACHE_SIZE >> (PAGE_CACHE_SHIFT - blockshift);
+ /*
+ * We are limited by the size of sector_t. Use block size, as
+ * that's what we expose to the VFS.
+ */
+ bytes = 1 << bbits;
+ trim = 1;
+ bitshift = 31;
# endif
#endif
- return (((unsigned long long)pagefactor) << bitshift) - 1;
+ /*
+ * Trim by a whole cluster when we can actually approach the
+ * on-disk limits. Otherwise we can overflow i_clusters when
+ * an extent start is at the max offset.
+ */
+ return (((unsigned long long)bytes) << bitshift) - trim;
}
static int ocfs2_remount(struct super_block *sb, int *flags, char *data)
@@ -1259,8 +1271,8 @@
int sector_size)
{
int status = 0;
- int i;
- struct ocfs2_dinode *di = NULL;
+ int i, cbits, bbits;
+ struct ocfs2_dinode *di = (struct ocfs2_dinode *)bh->b_data;
struct inode *inode = NULL;
struct buffer_head *bitmap_bh = NULL;
struct ocfs2_journal *journal;
@@ -1279,9 +1291,12 @@
sb->s_fs_info = osb;
sb->s_op = &ocfs2_sops;
sb->s_export_op = &ocfs2_export_ops;
+ sb->s_time_gran = 1;
sb->s_flags |= MS_NOATIME;
/* this is needed to support O_LARGEFILE */
- sb->s_maxbytes = ocfs2_max_file_offset(sb->s_blocksize_bits);
+ cbits = le32_to_cpu(di->id2.i_super.s_clustersize_bits);
+ bbits = le32_to_cpu(di->id2.i_super.s_blocksize_bits);
+ sb->s_maxbytes = ocfs2_max_file_offset(bbits, cbits);
osb->sb = sb;
/* Save off for ocfs2_rw_direct */
@@ -1341,8 +1356,6 @@
goto bail;
}
- di = (struct ocfs2_dinode *)bh->b_data;
-
osb->max_slots = le16_to_cpu(di->id2.i_super.s_max_slots);
if (osb->max_slots > OCFS2_MAX_SLOTS || osb->max_slots == 0) {
mlog(ML_ERROR, "Invalid number of node slots (%u)\n",
diff --git a/fs/ocfs2/super.h b/fs/ocfs2/super.h
index 3b9cb3d..783f527 100644
--- a/fs/ocfs2/super.h
+++ b/fs/ocfs2/super.h
@@ -45,6 +45,4 @@
#define ocfs2_abort(sb, fmt, args...) __ocfs2_abort(sb, __PRETTY_FUNCTION__, fmt, ##args)
-unsigned long long ocfs2_max_file_offset(unsigned int blockshift);
-
#endif /* OCFS2_SUPER_H */
diff --git a/fs/proc/array.c b/fs/proc/array.c
index 965625a..ee4814d 100644
--- a/fs/proc/array.c
+++ b/fs/proc/array.c
@@ -320,7 +320,21 @@
return buffer - orig;
}
-static clock_t task_utime(struct task_struct *p)
+/*
+ * Use precise platform statistics if available:
+ */
+#ifdef CONFIG_VIRT_CPU_ACCOUNTING
+static cputime_t task_utime(struct task_struct *p)
+{
+ return p->utime;
+}
+
+static cputime_t task_stime(struct task_struct *p)
+{
+ return p->stime;
+}
+#else
+static cputime_t task_utime(struct task_struct *p)
{
clock_t utime = cputime_to_clock_t(p->utime),
total = utime + cputime_to_clock_t(p->stime);
@@ -337,10 +351,10 @@
}
utime = (clock_t)temp;
- return utime;
+ return clock_t_to_cputime(utime);
}
-static clock_t task_stime(struct task_struct *p)
+static cputime_t task_stime(struct task_struct *p)
{
clock_t stime;
@@ -349,10 +363,12 @@
* the total, to make sure the total observed by userspace
* grows monotonically - apps rely on that):
*/
- stime = nsec_to_clock_t(p->se.sum_exec_runtime) - task_utime(p);
+ stime = nsec_to_clock_t(p->se.sum_exec_runtime) -
+ cputime_to_clock_t(task_utime(p));
- return stime;
+ return clock_t_to_cputime(stime);
}
+#endif
static int do_task_stat(struct task_struct *task, char *buffer, int whole)
{
@@ -368,8 +384,7 @@
unsigned long long start_time;
unsigned long cmin_flt = 0, cmaj_flt = 0;
unsigned long min_flt = 0, maj_flt = 0;
- cputime_t cutime, cstime;
- clock_t utime, stime;
+ cputime_t cutime, cstime, utime, stime;
unsigned long rsslim = 0;
char tcomm[sizeof(task->comm)];
unsigned long flags;
@@ -387,8 +402,7 @@
sigemptyset(&sigign);
sigemptyset(&sigcatch);
- cutime = cstime = cputime_zero;
- utime = stime = 0;
+ cutime = cstime = utime = stime = cputime_zero;
rcu_read_lock();
if (lock_task_sighand(task, &flags)) {
@@ -414,15 +428,15 @@
do {
min_flt += t->min_flt;
maj_flt += t->maj_flt;
- utime += task_utime(t);
- stime += task_stime(t);
+ utime = cputime_add(utime, task_utime(t));
+ stime = cputime_add(stime, task_stime(t));
t = next_thread(t);
} while (t != task);
min_flt += sig->min_flt;
maj_flt += sig->maj_flt;
- utime += cputime_to_clock_t(sig->utime);
- stime += cputime_to_clock_t(sig->stime);
+ utime = cputime_add(utime, sig->utime);
+ stime = cputime_add(stime, sig->stime);
}
sid = signal_session(sig);
@@ -471,8 +485,8 @@
cmin_flt,
maj_flt,
cmaj_flt,
- utime,
- stime,
+ cputime_to_clock_t(utime),
+ cputime_to_clock_t(stime),
cputime_to_clock_t(cutime),
cputime_to_clock_t(cstime),
priority,
diff --git a/fs/signalfd.c b/fs/signalfd.c
index 7b941ab..a8e293d 100644
--- a/fs/signalfd.c
+++ b/fs/signalfd.c
@@ -56,12 +56,18 @@
sighand = lock_task_sighand(lk->tsk, &lk->flags);
rcu_read_unlock();
- if (sighand && !ctx->tsk) {
+ if (!sighand)
+ return 0;
+
+ if (!ctx->tsk) {
unlock_task_sighand(lk->tsk, &lk->flags);
- sighand = NULL;
+ return 0;
}
- return sighand != NULL;
+ if (lk->tsk->tgid == current->tgid)
+ lk->tsk = current;
+
+ return 1;
}
static void signalfd_unlock(struct signalfd_lockctx *lk)
@@ -331,7 +337,7 @@
init_waitqueue_head(&ctx->wqh);
ctx->sigmask = sigmask;
- ctx->tsk = current;
+ ctx->tsk = current->group_leader;
sighand = current->sighand;
/*
diff --git a/fs/sysfs/bin.c b/fs/sysfs/bin.c
index 135353f..5afe2a2 100644
--- a/fs/sysfs/bin.c
+++ b/fs/sysfs/bin.c
@@ -248,12 +248,7 @@
void sysfs_remove_bin_file(struct kobject * kobj, struct bin_attribute * attr)
{
- if (sysfs_hash_and_remove(kobj->sd, attr->attr.name) < 0) {
- printk(KERN_ERR "%s: "
- "bad dentry or inode or no such file: \"%s\"\n",
- __FUNCTION__, attr->attr.name);
- dump_stack();
- }
+ sysfs_hash_and_remove(kobj->sd, attr->attr.name);
}
EXPORT_SYMBOL_GPL(sysfs_create_bin_file);
diff --git a/fs/sysfs/dir.c b/fs/sysfs/dir.c
index 048e605..83e76b3 100644
--- a/fs/sysfs/dir.c
+++ b/fs/sysfs/dir.c
@@ -762,12 +762,15 @@
static struct dentry * sysfs_lookup(struct inode *dir, struct dentry *dentry,
struct nameidata *nd)
{
+ struct dentry *ret = NULL;
struct sysfs_dirent * parent_sd = dentry->d_parent->d_fsdata;
struct sysfs_dirent * sd;
struct bin_attribute *bin_attr;
struct inode *inode;
int found = 0;
+ mutex_lock(&sysfs_mutex);
+
for (sd = parent_sd->s_children; sd; sd = sd->s_sibling) {
if (sysfs_type(sd) &&
!strcmp(sd->s_name, dentry->d_name.name)) {
@@ -778,14 +781,14 @@
/* no such entry */
if (!found)
- return NULL;
+ goto out_unlock;
/* attach dentry and inode */
inode = sysfs_get_inode(sd);
- if (!inode)
- return ERR_PTR(-ENOMEM);
-
- mutex_lock(&sysfs_mutex);
+ if (!inode) {
+ ret = ERR_PTR(-ENOMEM);
+ goto out_unlock;
+ }
if (inode->i_state & I_NEW) {
/* initialize inode according to type */
@@ -815,9 +818,9 @@
sysfs_instantiate(dentry, inode);
sysfs_attach_dentry(sd, dentry);
+ out_unlock:
mutex_unlock(&sysfs_mutex);
-
- return NULL;
+ return ret;
}
const struct inode_operations sysfs_dir_inode_operations = {
@@ -942,6 +945,8 @@
if (error)
goto out_drop;
+ mutex_lock(&sysfs_mutex);
+
dup_name = sd->s_name;
sd->s_name = new_name;
@@ -949,8 +954,6 @@
d_add(new_dentry, NULL);
d_move(sd->s_dentry, new_dentry);
- mutex_lock(&sysfs_mutex);
-
sysfs_unlink_sibling(sd);
sysfs_get(new_parent_sd);
sysfs_put(sd->s_parent);
diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h
index 3d0fea2..86aea44 100644
--- a/include/acpi/acpi_bus.h
+++ b/include/acpi/acpi_bus.h
@@ -321,8 +321,7 @@
};
extern struct kset acpi_subsys;
-extern int acpi_bus_generate_genetlink_event(struct acpi_device *device,
- u8 type, int data);
+extern int acpi_bus_generate_netlink_event(const char*, const char*, u8, int);
/*
* External Functions
*/
@@ -332,8 +331,13 @@
int acpi_bus_get_status(struct acpi_device *device);
int acpi_bus_get_power(acpi_handle handle, int *state);
int acpi_bus_set_power(acpi_handle handle, int state);
-int acpi_bus_generate_event(struct acpi_device *device, u8 type, int data);
+#ifdef CONFIG_ACPI_PROC_EVENT
+int acpi_bus_generate_proc_event(struct acpi_device *device, u8 type, int data);
int acpi_bus_receive_event(struct acpi_bus_event *event);
+#else
+static inline int acpi_bus_generate_proc_event(struct acpi_device *device, u8 type, int data)
+ { return 0; }
+#endif
int acpi_bus_register_driver(struct acpi_driver *driver);
void acpi_bus_unregister_driver(struct acpi_driver *driver);
int acpi_bus_add(struct acpi_device **child, struct acpi_device *parent,
diff --git a/include/acpi/acpixf.h b/include/acpi/acpixf.h
index b5cca5d..3d7ab9e 100644
--- a/include/acpi/acpixf.h
+++ b/include/acpi/acpixf.h
@@ -130,7 +130,7 @@
void *context, void **return_value);
acpi_status
-acpi_get_devices(char *HID,
+acpi_get_devices(const char *HID,
acpi_walk_callback user_function,
void *context, void **return_value);
diff --git a/include/acpi/acstruct.h b/include/acpi/acstruct.h
index aeb4498..8848265 100644
--- a/include/acpi/acstruct.h
+++ b/include/acpi/acstruct.h
@@ -146,7 +146,7 @@
struct acpi_get_devices_info {
acpi_walk_callback user_function;
void *context;
- char *hid;
+ const char *hid;
};
union acpi_aml_operands {
diff --git a/include/acpi/processor.h b/include/acpi/processor.h
index f9f987f..ec3ffda 100644
--- a/include/acpi/processor.h
+++ b/include/acpi/processor.h
@@ -232,7 +232,7 @@
extern int acpi_processor_preregister_performance(struct
acpi_processor_performance
- **performance);
+ *performance);
extern int acpi_processor_register_performance(struct acpi_processor_performance
*performance, unsigned int cpu);
diff --git a/include/asm-alpha/fcntl.h b/include/asm-alpha/fcntl.h
index 87f2cf4..25da001 100644
--- a/include/asm-alpha/fcntl.h
+++ b/include/asm-alpha/fcntl.h
@@ -16,6 +16,7 @@
#define O_LARGEFILE 0400000 /* will be set by the kernel on every open */
#define O_DIRECT 02000000 /* direct disk access - should check with OSF/1 */
#define O_NOATIME 04000000
+#define O_CLOEXEC 010000000 /* set close_on_exec */
#define F_GETLK 7
#define F_SETLK 8
diff --git a/include/asm-arm/pgtable-nommu.h b/include/asm-arm/pgtable-nommu.h
index b186bc8..33c83dd 100644
--- a/include/asm-arm/pgtable-nommu.h
+++ b/include/asm-arm/pgtable-nommu.h
@@ -74,7 +74,6 @@
* These would be in other places but having them here reduces the diffs.
*/
extern unsigned int kobjsize(const void *objp);
-extern int is_in_rom(unsigned long);
/*
* No page table caches to initialise.
diff --git a/include/asm-avr32/io.h b/include/asm-avr32/io.h
index e30d4b3..64bb92b 100644
--- a/include/asm-avr32/io.h
+++ b/include/asm-avr32/io.h
@@ -255,6 +255,8 @@
memset((void __force *)addr, val, count);
}
+#define mmiowb()
+
#define IO_SPACE_LIMIT 0xffffffff
extern void __iomem *__ioremap(unsigned long offset, size_t size,
diff --git a/include/asm-avr32/pgalloc.h b/include/asm-avr32/pgalloc.h
index bb82e70..0e680f4 100644
--- a/include/asm-avr32/pgalloc.h
+++ b/include/asm-avr32/pgalloc.h
@@ -27,13 +27,7 @@
*/
static __inline__ pgd_t *pgd_alloc(struct mm_struct *mm)
{
- unsigned int pgd_size = (USER_PTRS_PER_PGD * sizeof(pgd_t));
- pgd_t *pgd = kmalloc(pgd_size, GFP_KERNEL);
-
- if (pgd)
- memset(pgd, 0, pgd_size);
-
- return pgd;
+ return kcalloc(USER_PTRS_PER_PGD, sizeof(pgd_t), GFP_KERNEL);
}
static inline void pgd_free(pgd_t *pgd)
@@ -44,18 +38,9 @@
static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm,
unsigned long address)
{
- int count = 0;
pte_t *pte;
- do {
- pte = (pte_t *) __get_free_page(GFP_KERNEL | __GFP_REPEAT);
- if (pte)
- clear_page(pte);
- else {
- current->state = TASK_UNINTERRUPTIBLE;
- schedule_timeout(HZ);
- }
- } while (!pte && (count++ < 10));
+ pte = (pte_t *)get_zeroed_page(GFP_KERNEL | __GFP_REPEAT);
return pte;
}
@@ -63,18 +48,9 @@
static inline struct page *pte_alloc_one(struct mm_struct *mm,
unsigned long address)
{
- int count = 0;
struct page *pte;
- do {
- pte = alloc_pages(GFP_KERNEL, 0);
- if (pte)
- clear_page(page_address(pte));
- else {
- current->state = TASK_UNINTERRUPTIBLE;
- schedule_timeout(HZ);
- }
- } while (!pte && (count++ < 10));
+ pte = alloc_page(GFP_KERNEL | __GFP_REPEAT | __GFP_ZERO);
return pte;
}
diff --git a/include/asm-avr32/pgtable.h b/include/asm-avr32/pgtable.h
index c07bdd1..018f6e2 100644
--- a/include/asm-avr32/pgtable.h
+++ b/include/asm-avr32/pgtable.h
@@ -32,8 +32,6 @@
#define USER_PTRS_PER_PGD (TASK_SIZE / PGDIR_SIZE)
#define FIRST_USER_ADDRESS 0
-#define PTE_PHYS_MASK 0x1ffff000
-
#ifndef __ASSEMBLY__
extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
extern void paging_init(void);
@@ -265,7 +263,7 @@
* trivial.
*/
#define pages_to_mb(x) ((x) >> (20-PAGE_SHIFT))
-#define pte_page(x) phys_to_page(pte_val(x) & PTE_PHYS_MASK)
+#define pte_page(x) (pfn_to_page(pte_pfn(x)))
/*
* Mark the prot value as uncacheable and unbufferable
diff --git a/include/asm-frv/unistd.h b/include/asm-frv/unistd.h
index 7306c71..cd84f17 100644
--- a/include/asm-frv/unistd.h
+++ b/include/asm-frv/unistd.h
@@ -330,10 +330,11 @@
#define __NR_signalfd 321
#define __NR_timerfd 322
#define __NR_eventfd 323
+#define __NR_fallocate 324
#ifdef __KERNEL__
-#define NR_syscalls 324
+#define NR_syscalls 325
#define __ARCH_WANT_IPC_PARSE_VERSION
/* #define __ARCH_WANT_OLD_READDIR */
diff --git a/include/asm-generic/pgtable.h b/include/asm-generic/pgtable.h
index f605e8d..5f0d797 100644
--- a/include/asm-generic/pgtable.h
+++ b/include/asm-generic/pgtable.h
@@ -2,6 +2,7 @@
#define _ASM_GENERIC_PGTABLE_H
#ifndef __ASSEMBLY__
+#ifdef CONFIG_MMU
#ifndef __HAVE_ARCH_PTEP_SET_ACCESS_FLAGS
/*
@@ -133,41 +134,6 @@
#endif
/*
- * A facility to provide lazy MMU batching. This allows PTE updates and
- * page invalidations to be delayed until a call to leave lazy MMU mode
- * is issued. Some architectures may benefit from doing this, and it is
- * beneficial for both shadow and direct mode hypervisors, which may batch
- * the PTE updates which happen during this window. Note that using this
- * interface requires that read hazards be removed from the code. A read
- * hazard could result in the direct mode hypervisor case, since the actual
- * write to the page tables may not yet have taken place, so reads though
- * a raw PTE pointer after it has been modified are not guaranteed to be
- * up to date. This mode can only be entered and left under the protection of
- * the page table locks for all page tables which may be modified. In the UP
- * case, this is required so that preemption is disabled, and in the SMP case,
- * it must synchronize the delayed page table writes properly on other CPUs.
- */
-#ifndef __HAVE_ARCH_ENTER_LAZY_MMU_MODE
-#define arch_enter_lazy_mmu_mode() do {} while (0)
-#define arch_leave_lazy_mmu_mode() do {} while (0)
-#define arch_flush_lazy_mmu_mode() do {} while (0)
-#endif
-
-/*
- * A facility to provide batching of the reload of page tables with the
- * actual context switch code for paravirtualized guests. By convention,
- * only one of the lazy modes (CPU, MMU) should be active at any given
- * time, entry should never be nested, and entry and exits should always
- * be paired. This is for sanity of maintaining and reasoning about the
- * kernel code.
- */
-#ifndef __HAVE_ARCH_ENTER_LAZY_CPU_MODE
-#define arch_enter_lazy_cpu_mode() do {} while (0)
-#define arch_leave_lazy_cpu_mode() do {} while (0)
-#define arch_flush_lazy_cpu_mode() do {} while (0)
-#endif
-
-/*
* When walking page tables, get the address of the next boundary,
* or the end address of the range if that comes earlier. Although no
* vma end wraps to 0, rounded up __boundary may wrap to 0 throughout.
@@ -233,6 +199,43 @@
}
return 0;
}
+#endif /* CONFIG_MMU */
+
+/*
+ * A facility to provide lazy MMU batching. This allows PTE updates and
+ * page invalidations to be delayed until a call to leave lazy MMU mode
+ * is issued. Some architectures may benefit from doing this, and it is
+ * beneficial for both shadow and direct mode hypervisors, which may batch
+ * the PTE updates which happen during this window. Note that using this
+ * interface requires that read hazards be removed from the code. A read
+ * hazard could result in the direct mode hypervisor case, since the actual
+ * write to the page tables may not yet have taken place, so reads though
+ * a raw PTE pointer after it has been modified are not guaranteed to be
+ * up to date. This mode can only be entered and left under the protection of
+ * the page table locks for all page tables which may be modified. In the UP
+ * case, this is required so that preemption is disabled, and in the SMP case,
+ * it must synchronize the delayed page table writes properly on other CPUs.
+ */
+#ifndef __HAVE_ARCH_ENTER_LAZY_MMU_MODE
+#define arch_enter_lazy_mmu_mode() do {} while (0)
+#define arch_leave_lazy_mmu_mode() do {} while (0)
+#define arch_flush_lazy_mmu_mode() do {} while (0)
+#endif
+
+/*
+ * A facility to provide batching of the reload of page tables with the
+ * actual context switch code for paravirtualized guests. By convention,
+ * only one of the lazy modes (CPU, MMU) should be active at any given
+ * time, entry should never be nested, and entry and exits should always
+ * be paired. This is for sanity of maintaining and reasoning about the
+ * kernel code.
+ */
+#ifndef __HAVE_ARCH_ENTER_LAZY_CPU_MODE
+#define arch_enter_lazy_cpu_mode() do {} while (0)
+#define arch_leave_lazy_cpu_mode() do {} while (0)
+#define arch_flush_lazy_cpu_mode() do {} while (0)
+#endif
+
#endif /* !__ASSEMBLY__ */
#endif /* _ASM_GENERIC_PGTABLE_H */
diff --git a/include/asm-i386/apic.h b/include/asm-i386/apic.h
index 1e8f6f2..4091b33 100644
--- a/include/asm-i386/apic.h
+++ b/include/asm-i386/apic.h
@@ -116,6 +116,8 @@
extern int timer_over_8254;
extern int local_apic_timer_c2_ok;
+extern int local_apic_timer_disabled;
+
#else /* !CONFIG_X86_LOCAL_APIC */
static inline void lapic_shutdown(void) { }
diff --git a/include/asm-i386/cpufeature.h b/include/asm-i386/cpufeature.h
index c961c03..7b3aa28 100644
--- a/include/asm-i386/cpufeature.h
+++ b/include/asm-i386/cpufeature.h
@@ -79,7 +79,7 @@
#define X86_FEATURE_ARCH_PERFMON (3*32+11) /* Intel Architectural PerfMon */
#define X86_FEATURE_PEBS (3*32+12) /* Precise-Event Based Sampling */
#define X86_FEATURE_BTS (3*32+13) /* Branch Trace Store */
-#define X86_FEATURE_LAPIC_TIMER_BROKEN (3*32+ 14) /* lapic timer broken in C1 */
+/* 14 free */
#define X86_FEATURE_SYNC_RDTSC (3*32+15) /* RDTSC synchronizes the CPU */
#define X86_FEATURE_REP_GOOD (3*32+16) /* rep microcode works well on this CPU */
diff --git a/include/asm-i386/io.h b/include/asm-i386/io.h
index 7b65b5b..e8e0bd6 100644
--- a/include/asm-i386/io.h
+++ b/include/asm-i386/io.h
@@ -112,6 +112,9 @@
* writew/writel functions and the other mmio helpers. The returned
* address is not guaranteed to be usable directly as a virtual
* address.
+ *
+ * If the area you are trying to map is a PCI BAR you should have a
+ * look at pci_iomap().
*/
static inline void __iomem * ioremap(unsigned long offset, unsigned long size)
diff --git a/include/asm-i386/io_apic.h b/include/asm-i386/io_apic.h
index 3407640..dbe734d 100644
--- a/include/asm-i386/io_apic.h
+++ b/include/asm-i386/io_apic.h
@@ -150,7 +150,6 @@
#else /* !CONFIG_X86_IO_APIC */
#define io_apic_assign_pci_irqs 0
-static inline void disable_ioapic_setup(void) { }
#endif
#endif
diff --git a/include/asm-i386/mach-default/mach_wakecpu.h b/include/asm-i386/mach-default/mach_wakecpu.h
index 673b85c..3ebb178 100644
--- a/include/asm-i386/mach-default/mach_wakecpu.h
+++ b/include/asm-i386/mach-default/mach_wakecpu.h
@@ -15,7 +15,8 @@
static inline void wait_for_init_deassert(atomic_t *deassert)
{
- while (!atomic_read(deassert));
+ while (!atomic_read(deassert))
+ cpu_relax();
return;
}
diff --git a/include/asm-i386/mach-es7000/mach_wakecpu.h b/include/asm-i386/mach-es7000/mach_wakecpu.h
index efc903b..84ff583 100644
--- a/include/asm-i386/mach-es7000/mach_wakecpu.h
+++ b/include/asm-i386/mach-es7000/mach_wakecpu.h
@@ -31,7 +31,8 @@
static inline void wait_for_init_deassert(atomic_t *deassert)
{
#ifdef WAKE_SECONDARY_VIA_INIT
- while (!atomic_read(deassert));
+ while (!atomic_read(deassert))
+ cpu_relax();
#endif
return;
}
diff --git a/include/asm-i386/nmi.h b/include/asm-i386/nmi.h
index ff30c98..70a958a 100644
--- a/include/asm-i386/nmi.h
+++ b/include/asm-i386/nmi.h
@@ -33,11 +33,12 @@
extern atomic_t nmi_active;
extern unsigned int nmi_watchdog;
-#define NMI_DEFAULT -1
+#define NMI_DISABLED -1
#define NMI_NONE 0
#define NMI_IO_APIC 1
#define NMI_LOCAL_APIC 2
#define NMI_INVALID 3
+#define NMI_DEFAULT NMI_DISABLED
struct ctl_table;
struct file;
diff --git a/include/asm-i386/paravirt.h b/include/asm-i386/paravirt.h
index 7df88be..9fa3fa9 100644
--- a/include/asm-i386/paravirt.h
+++ b/include/asm-i386/paravirt.h
@@ -47,7 +47,8 @@
* The patch function should return the number of bytes of code
* generated, as we nop pad the rest in generic code.
*/
- unsigned (*patch)(u8 type, u16 clobber, void *firstinsn, unsigned len);
+ unsigned (*patch)(u8 type, u16 clobber, void *insnbuf,
+ unsigned long addr, unsigned len);
/* Basic arch-specific setup */
void (*arch_setup)(void);
@@ -253,13 +254,16 @@
unsigned paravirt_patch_nop(void);
unsigned paravirt_patch_ignore(unsigned len);
-unsigned paravirt_patch_call(void *target, u16 tgt_clobbers,
- void *site, u16 site_clobbers,
+unsigned paravirt_patch_call(void *insnbuf,
+ const void *target, u16 tgt_clobbers,
+ unsigned long addr, u16 site_clobbers,
unsigned len);
-unsigned paravirt_patch_jmp(void *target, void *site, unsigned len);
-unsigned paravirt_patch_default(u8 type, u16 clobbers, void *site, unsigned len);
+unsigned paravirt_patch_jmp(const void *target, void *insnbuf,
+ unsigned long addr, unsigned len);
+unsigned paravirt_patch_default(u8 type, u16 clobbers, void *insnbuf,
+ unsigned long addr, unsigned len);
-unsigned paravirt_patch_insns(void *site, unsigned len,
+unsigned paravirt_patch_insns(void *insnbuf, unsigned len,
const char *start, const char *end);
int paravirt_disable_iospace(void);
diff --git a/include/asm-i386/pci.h b/include/asm-i386/pci.h
index d790343..4fcacc7 100644
--- a/include/asm-i386/pci.h
+++ b/include/asm-i386/pci.h
@@ -8,6 +8,9 @@
int node; /* NUMA node */
};
+/* scan a bus after allocating a pci_sysdata for it */
+extern struct pci_bus *pci_scan_bus_with_sysdata(int busno);
+
#include <linux/mm.h> /* for struct page */
/* Can be used to override the logic in pci_scan_bus for skipping
diff --git a/include/asm-ia64/atomic.h b/include/asm-ia64/atomic.h
index 1fc3b83..50c2b83 100644
--- a/include/asm-ia64/atomic.h
+++ b/include/asm-ia64/atomic.h
@@ -55,7 +55,7 @@
do {
CMPXCHG_BUGCHECK(v);
- old = atomic_read(v);
+ old = atomic64_read(v);
new = old + i;
} while (ia64_cmpxchg(acq, v, old, new, sizeof(atomic64_t)) != old);
return new;
@@ -83,7 +83,7 @@
do {
CMPXCHG_BUGCHECK(v);
- old = atomic_read(v);
+ old = atomic64_read(v);
new = old - i;
} while (ia64_cmpxchg(acq, v, old, new, sizeof(atomic64_t)) != old);
return new;
diff --git a/include/asm-ia64/hw_irq.h b/include/asm-ia64/hw_irq.h
index efa1b8f..bba5baa 100644
--- a/include/asm-ia64/hw_irq.h
+++ b/include/asm-ia64/hw_irq.h
@@ -124,6 +124,11 @@
extern irq_desc_t irq_desc[NR_IRQS];
#ifndef CONFIG_IA64_GENERIC
+static inline ia64_vector __ia64_irq_to_vector(int irq)
+{
+ return irq_cfg[irq].vector;
+}
+
static inline unsigned int
__ia64_local_vector_to_irq (ia64_vector vec)
{
@@ -145,7 +150,7 @@
static inline ia64_vector
irq_to_vector (int irq)
{
- return irq_cfg[irq].vector;
+ return platform_irq_to_vector(irq);
}
/*
diff --git a/include/asm-ia64/machvec.h b/include/asm-ia64/machvec.h
index 5cf8bf1..c201a20 100644
--- a/include/asm-ia64/machvec.h
+++ b/include/asm-ia64/machvec.h
@@ -30,6 +30,7 @@
typedef void ia64_mv_timer_interrupt_t (int, void *);
typedef void ia64_mv_global_tlb_purge_t (struct mm_struct *, unsigned long, unsigned long, unsigned long);
typedef void ia64_mv_tlb_migrate_finish_t (struct mm_struct *);
+typedef u8 ia64_mv_irq_to_vector (int);
typedef unsigned int ia64_mv_local_vector_to_irq (u8);
typedef char *ia64_mv_pci_get_legacy_mem_t (struct pci_bus *);
typedef int ia64_mv_pci_legacy_read_t (struct pci_bus *, u16 port, u32 *val,
@@ -145,6 +146,7 @@
# define platform_dma_sync_sg_for_device ia64_mv.dma_sync_sg_for_device
# define platform_dma_mapping_error ia64_mv.dma_mapping_error
# define platform_dma_supported ia64_mv.dma_supported
+# define platform_irq_to_vector ia64_mv.irq_to_vector
# define platform_local_vector_to_irq ia64_mv.local_vector_to_irq
# define platform_pci_get_legacy_mem ia64_mv.pci_get_legacy_mem
# define platform_pci_legacy_read ia64_mv.pci_legacy_read
@@ -198,6 +200,7 @@
ia64_mv_dma_sync_sg_for_device *dma_sync_sg_for_device;
ia64_mv_dma_mapping_error *dma_mapping_error;
ia64_mv_dma_supported *dma_supported;
+ ia64_mv_irq_to_vector *irq_to_vector;
ia64_mv_local_vector_to_irq *local_vector_to_irq;
ia64_mv_pci_get_legacy_mem_t *pci_get_legacy_mem;
ia64_mv_pci_legacy_read_t *pci_legacy_read;
@@ -247,6 +250,7 @@
platform_dma_sync_sg_for_device, \
platform_dma_mapping_error, \
platform_dma_supported, \
+ platform_irq_to_vector, \
platform_local_vector_to_irq, \
platform_pci_get_legacy_mem, \
platform_pci_legacy_read, \
@@ -366,6 +370,9 @@
#ifndef platform_dma_supported
# define platform_dma_supported swiotlb_dma_supported
#endif
+#ifndef platform_irq_to_vector
+# define platform_irq_to_vector __ia64_irq_to_vector
+#endif
#ifndef platform_local_vector_to_irq
# define platform_local_vector_to_irq __ia64_local_vector_to_irq
#endif
diff --git a/include/asm-ia64/machvec_init.h b/include/asm-ia64/machvec_init.h
index 2d36f68..7f21249 100644
--- a/include/asm-ia64/machvec_init.h
+++ b/include/asm-ia64/machvec_init.h
@@ -2,6 +2,7 @@
extern ia64_mv_send_ipi_t ia64_send_ipi;
extern ia64_mv_global_tlb_purge_t ia64_global_tlb_purge;
+extern ia64_mv_irq_to_vector __ia64_irq_to_vector;
extern ia64_mv_local_vector_to_irq __ia64_local_vector_to_irq;
extern ia64_mv_pci_get_legacy_mem_t ia64_pci_get_legacy_mem;
extern ia64_mv_pci_legacy_read_t ia64_pci_legacy_read;
diff --git a/include/asm-ia64/machvec_sn2.h b/include/asm-ia64/machvec_sn2.h
index eaa2fce..61439a7 100644
--- a/include/asm-ia64/machvec_sn2.h
+++ b/include/asm-ia64/machvec_sn2.h
@@ -35,6 +35,7 @@
extern ia64_mv_timer_interrupt_t sn_timer_interrupt;
extern ia64_mv_global_tlb_purge_t sn2_global_tlb_purge;
extern ia64_mv_tlb_migrate_finish_t sn_tlb_migrate_finish;
+extern ia64_mv_irq_to_vector sn_irq_to_vector;
extern ia64_mv_local_vector_to_irq sn_local_vector_to_irq;
extern ia64_mv_pci_get_legacy_mem_t sn_pci_get_legacy_mem;
extern ia64_mv_pci_legacy_read_t sn_pci_legacy_read;
@@ -104,6 +105,7 @@
#define platform_readw_relaxed __sn_readw_relaxed
#define platform_readl_relaxed __sn_readl_relaxed
#define platform_readq_relaxed __sn_readq_relaxed
+#define platform_irq_to_vector sn_irq_to_vector
#define platform_local_vector_to_irq sn_local_vector_to_irq
#define platform_pci_get_legacy_mem sn_pci_get_legacy_mem
#define platform_pci_legacy_read sn_pci_legacy_read
diff --git a/include/asm-m68k/ioctls.h b/include/asm-m68k/ioctls.h
index 0c48929..b8d2f4b 100644
--- a/include/asm-m68k/ioctls.h
+++ b/include/asm-m68k/ioctls.h
@@ -46,6 +46,10 @@
#define TIOCSBRK 0x5427 /* BSD compatibility */
#define TIOCCBRK 0x5428 /* BSD compatibility */
#define TIOCGSID 0x5429 /* Return the session ID of FD */
+#define TCGETS2 _IOR('T',0x2A, struct termios2)
+#define TCSETS2 _IOW('T',0x2B, struct termios2)
+#define TCSETSW2 _IOW('T',0x2C, struct termios2)
+#define TCSETSF2 _IOW('T',0x2D, struct termios2)
#define TIOCGPTN _IOR('T',0x30, unsigned int) /* Get Pty Number (of pty-mux device) */
#define TIOCSPTLCK _IOW('T',0x31, int) /* Lock/unlock Pty */
diff --git a/include/asm-m68k/page.h b/include/asm-m68k/page.h
index 9e6d0d6..1431ea0 100644
--- a/include/asm-m68k/page.h
+++ b/include/asm-m68k/page.h
@@ -4,17 +4,15 @@
#ifdef __KERNEL__
+#include <linux/const.h>
+
/* PAGE_SHIFT determines the page size */
#ifndef CONFIG_SUN3
#define PAGE_SHIFT (12)
#else
#define PAGE_SHIFT (13)
#endif
-#ifdef __ASSEMBLY__
-#define PAGE_SIZE (1 << PAGE_SHIFT)
-#else
-#define PAGE_SIZE (1UL << PAGE_SHIFT)
-#endif
+#define PAGE_SIZE (_AC(1, UL) << PAGE_SHIFT)
#define PAGE_MASK (~(PAGE_SIZE-1))
#include <asm/setup.h>
@@ -27,6 +25,8 @@
#ifndef __ASSEMBLY__
+#include <linux/compiler.h>
+
#include <asm/module.h>
#define get_user_page(vaddr) __get_free_page(GFP_KERNEL)
diff --git a/include/asm-m68k/processor.h b/include/asm-m68k/processor.h
index 8455f77..4453ec3 100644
--- a/include/asm-m68k/processor.h
+++ b/include/asm-m68k/processor.h
@@ -38,12 +38,8 @@
#ifndef CONFIG_SUN3
#define TASK_SIZE (0xF0000000UL)
#else
-#ifdef __ASSEMBLY__
-#define TASK_SIZE (0x0E000000)
-#else
#define TASK_SIZE (0x0E000000UL)
#endif
-#endif
/* This decides where the kernel will search for a free chunk of vm
* space during mmap's.
diff --git a/include/asm-m68k/termbits.h b/include/asm-m68k/termbits.h
index 0e520f3..8c14170 100644
--- a/include/asm-m68k/termbits.h
+++ b/include/asm-m68k/termbits.h
@@ -141,6 +141,7 @@
#define HUPCL 0002000
#define CLOCAL 0004000
#define CBAUDEX 0010000
+#define BOTHER 0010000
#define B57600 0010001
#define B115200 0010002
#define B230400 0010003
@@ -156,10 +157,12 @@
#define B3000000 0010015
#define B3500000 0010016
#define B4000000 0010017
-#define CIBAUD 002003600000 /* input baud rate (not used) */
+#define CIBAUD 002003600000 /* input baud rate */
#define CMSPAR 010000000000 /* mark or space (stick) parity */
#define CRTSCTS 020000000000 /* flow control */
+#define IBSHIFT 16 /* Shift from CBAUD to CIBAUD */
+
/* c_lflag bits */
#define ISIG 0000001
#define ICANON 0000002
diff --git a/include/asm-m68k/termios.h b/include/asm-m68k/termios.h
index 00edabd..0823032 100644
--- a/include/asm-m68k/termios.h
+++ b/include/asm-m68k/termios.h
@@ -82,8 +82,10 @@
copy_to_user((termio)->c_cc, (termios)->c_cc, NCC); \
})
-#define user_termios_to_kernel_termios(k, u) copy_from_user(k, u, sizeof(struct termios))
-#define kernel_termios_to_user_termios(u, k) copy_to_user(u, k, sizeof(struct termios))
+#define user_termios_to_kernel_termios(k, u) copy_from_user(k, u, sizeof(struct termios2))
+#define kernel_termios_to_user_termios(u, k) copy_to_user(u, k, sizeof(struct termios2))
+#define user_termios_to_kernel_termios_1(k, u) copy_from_user(k, u, sizeof(struct termios))
+#define kernel_termios_to_user_termios_1(u, k) copy_to_user(u, k, sizeof(struct termios))
#endif /* __KERNEL__ */
diff --git a/include/asm-m68knommu/pgtable.h b/include/asm-m68knommu/pgtable.h
index e1e6a1d..4625101 100644
--- a/include/asm-m68knommu/pgtable.h
+++ b/include/asm-m68knommu/pgtable.h
@@ -65,4 +65,6 @@
#define VMALLOC_START 0
#define VMALLOC_END 0xffffffff
+#include <asm-generic/pgtable.h>
+
#endif /* _M68KNOMMU_PGTABLE_H */
diff --git a/include/asm-powerpc/dma-mapping.h b/include/asm-powerpc/dma-mapping.h
index f6bd804..744d6bb 100644
--- a/include/asm-powerpc/dma-mapping.h
+++ b/include/asm-powerpc/dma-mapping.h
@@ -95,7 +95,7 @@
return -EIO;
if (dma_ops->set_dma_mask != NULL)
return dma_ops->set_dma_mask(dev, dma_mask);
- if (!dev->dma_mask || !dma_supported(dev, *dev->dma_mask))
+ if (!dev->dma_mask || !dma_supported(dev, dma_mask))
return -EIO;
*dev->dma_mask = dma_mask;
return 0;
diff --git a/include/asm-powerpc/reg_booke.h b/include/asm-powerpc/reg_booke.h
index 064405c..8fdc2b4 100644
--- a/include/asm-powerpc/reg_booke.h
+++ b/include/asm-powerpc/reg_booke.h
@@ -223,7 +223,6 @@
#define MCSR_ICPERR 0x40000000UL /* I-Cache Parity Error */
#define MCSR_DCP_PERR 0x20000000UL /* D-Cache Push Parity Error */
#define MCSR_DCPERR 0x10000000UL /* D-Cache Parity Error */
-#define MCSR_GL_CI 0x00010000UL /* Guarded Load or Cache-Inhibited stwcx. */
#define MCSR_BUS_IAERR 0x00000080UL /* Instruction Address Error */
#define MCSR_BUS_RAERR 0x00000040UL /* Read Address Error */
#define MCSR_BUS_WAERR 0x00000020UL /* Write Address Error */
@@ -232,6 +231,12 @@
#define MCSR_BUS_WBERR 0x00000004UL /* Write Data Bus Error */
#define MCSR_BUS_IPERR 0x00000002UL /* Instruction parity Error */
#define MCSR_BUS_RPERR 0x00000001UL /* Read parity Error */
+
+/* e500 parts may set unused bits in MCSR; mask these off */
+#define MCSR_MASK (MCSR_MCP | MCSR_ICPERR | MCSR_DCP_PERR | \
+ MCSR_DCPERR | MCSR_BUS_IAERR | MCSR_BUS_RAERR | \
+ MCSR_BUS_WAERR | MCSR_BUS_IBERR | MCSR_BUS_RBERR | \
+ MCSR_BUS_WBERR | MCSR_BUS_IPERR | MCSR_BUS_RPERR)
#endif
#ifdef CONFIG_E200
#define MCSR_MCP 0x80000000UL /* Machine Check Input Pin */
@@ -243,6 +248,11 @@
#define MCSR_BUS_DRERR 0x00000008UL /* Read Bus Error on data load */
#define MCSR_BUS_WRERR 0x00000004UL /* Write Bus Error on buffered
store or cache line push */
+
+/* e200 parts may set unused bits in MCSR; mask these off */
+#define MCSR_MASK (MCSR_MCP | MCSR_CP_PERR | MCSR_CPERR | \
+ MCSR_EXCP_ERR | MCSR_BUS_IRERR | MCSR_BUS_DRERR | \
+ MCSR_BUS_WRERR)
#endif
/* Bit definitions for the DBSR. */
diff --git a/include/asm-powerpc/spu_priv1.h b/include/asm-powerpc/spu_priv1.h
index 7e78f6a..0f37c7c 100644
--- a/include/asm-powerpc/spu_priv1.h
+++ b/include/asm-powerpc/spu_priv1.h
@@ -178,6 +178,7 @@
int (*enumerate_spus)(int (*fn)(void *data));
int (*create_spu)(struct spu *spu, void *data);
int (*destroy_spu)(struct spu *spu);
+ int (*init_affinity)(void);
};
extern const struct spu_management_ops* spu_management_ops;
@@ -200,6 +201,12 @@
return spu_management_ops->destroy_spu(spu);
}
+static inline int
+spu_init_affinity (void)
+{
+ return spu_management_ops->init_affinity();
+}
+
/*
* The declarations folowing are put here for convenience
* and only intended to be used by the platform setup code.
diff --git a/include/asm-s390/atomic.h b/include/asm-s390/atomic.h
index ea48695..2d18465 100644
--- a/include/asm-s390/atomic.h
+++ b/include/asm-s390/atomic.h
@@ -67,8 +67,17 @@
#endif /* __GNUC__ */
-#define atomic_read(v) ((v)->counter)
-#define atomic_set(v,i) (((v)->counter) = (i))
+static inline int atomic_read(const atomic_t *v)
+{
+ barrier();
+ return v->counter;
+}
+
+static inline void atomic_set(atomic_t *v, int i)
+{
+ v->counter = i;
+ barrier();
+}
static __inline__ int atomic_add_return(int i, atomic_t * v)
{
@@ -182,8 +191,17 @@
#endif /* __GNUC__ */
-#define atomic64_read(v) ((v)->counter)
-#define atomic64_set(v,i) (((v)->counter) = (i))
+static inline long long atomic64_read(const atomic64_t *v)
+{
+ barrier();
+ return v->counter;
+}
+
+static inline void atomic64_set(atomic64_t *v, long long i)
+{
+ v->counter = i;
+ barrier();
+}
static __inline__ long long atomic64_add_return(long long i, atomic64_t * v)
{
diff --git a/include/asm-s390/cio.h b/include/asm-s390/cio.h
index f738d28..1982fb3 100644
--- a/include/asm-s390/cio.h
+++ b/include/asm-s390/cio.h
@@ -258,19 +258,6 @@
/* Sick revalidation of device. */
#define CIO_REVALIDATE 0x0008
-struct diag210 {
- __u16 vrdcdvno : 16; /* device number (input) */
- __u16 vrdclen : 16; /* data block length (input) */
- __u32 vrdcvcla : 8; /* virtual device class (output) */
- __u32 vrdcvtyp : 8; /* virtual device type (output) */
- __u32 vrdcvsta : 8; /* virtual device status (output) */
- __u32 vrdcvfla : 8; /* virtual device flags (output) */
- __u32 vrdcrccl : 8; /* real device class (output) */
- __u32 vrdccrty : 8; /* real device type (output) */
- __u32 vrdccrmd : 8; /* real device model (output) */
- __u32 vrdccrft : 8; /* real device feature (output) */
-} __attribute__ ((packed,aligned(4)));
-
struct ccw_dev_id {
u8 ssid;
u16 devno;
@@ -285,8 +272,6 @@
return 0;
}
-extern int diag210(struct diag210 *addr);
-
extern void wait_cons_dev(void);
extern void css_schedule_reprobe(void);
diff --git a/include/asm-s390/diag.h b/include/asm-s390/diag.h
new file mode 100644
index 0000000..72b2e2f
--- /dev/null
+++ b/include/asm-s390/diag.h
@@ -0,0 +1,39 @@
+/*
+ * s390 diagnose functions
+ *
+ * Copyright IBM Corp. 2007
+ * Author(s): Michael Holzheu <holzheu@de.ibm.com>
+ */
+
+#ifndef _ASM_S390_DIAG_H
+#define _ASM_S390_DIAG_H
+
+/*
+ * Diagnose 10: Release pages
+ */
+extern void diag10(unsigned long addr);
+
+/*
+ * Diagnose 14: Input spool file manipulation
+ */
+extern int diag14(unsigned long rx, unsigned long ry1, unsigned long subcode);
+
+/*
+ * Diagnose 210: Get information about a virtual device
+ */
+struct diag210 {
+ u16 vrdcdvno; /* device number (input) */
+ u16 vrdclen; /* data block length (input) */
+ u8 vrdcvcla; /* virtual device class (output) */
+ u8 vrdcvtyp; /* virtual device type (output) */
+ u8 vrdcvsta; /* virtual device status (output) */
+ u8 vrdcvfla; /* virtual device flags (output) */
+ u8 vrdcrccl; /* real device class (output) */
+ u8 vrdccrty; /* real device type (output) */
+ u8 vrdccrmd; /* real device model (output) */
+ u8 vrdccrft; /* real device feature (output) */
+} __attribute__((packed, aligned(4)));
+
+extern int diag210(struct diag210 *addr);
+
+#endif /* _ASM_S390_DIAG_H */
diff --git a/include/asm-s390/pgalloc.h b/include/asm-s390/pgalloc.h
index 56c8a6c..e45d3c9 100644
--- a/include/asm-s390/pgalloc.h
+++ b/include/asm-s390/pgalloc.h
@@ -19,8 +19,6 @@
#define check_pgt_cache() do {} while (0)
-extern void diag10(unsigned long addr);
-
/*
* Page allocation orders.
*/
diff --git a/include/asm-sh/dma-mapping.h b/include/asm-sh/dma-mapping.h
index 6f492ac..84fefda 100644
--- a/include/asm-sh/dma-mapping.h
+++ b/include/asm-sh/dma-mapping.h
@@ -160,6 +160,25 @@
dma_sync_single(dev, dma_handle, size, dir);
}
+static inline void dma_sync_single_range_for_cpu(struct device *dev,
+ dma_addr_t dma_handle,
+ unsigned long offset,
+ size_t size,
+ enum dma_data_direction direction)
+{
+ dma_sync_single_for_cpu(dev, dma_handle+offset, size, direction);
+}
+
+static inline void dma_sync_single_range_for_device(struct device *dev,
+ dma_addr_t dma_handle,
+ unsigned long offset,
+ size_t size,
+ enum dma_data_direction direction)
+{
+ dma_sync_single_for_device(dev, dma_handle+offset, size, direction);
+}
+
+
static inline void dma_sync_sg_for_cpu(struct device *dev,
struct scatterlist *sg, int nelems,
enum dma_data_direction dir)
diff --git a/include/asm-sh64/dma-mapping.h b/include/asm-sh64/dma-mapping.h
index d505f35..de43099 100644
--- a/include/asm-sh64/dma-mapping.h
+++ b/include/asm-sh64/dma-mapping.h
@@ -141,6 +141,24 @@
dma_sync_single(dev, dma_handle, size, dir);
}
+static inline void dma_sync_single_range_for_cpu(struct device *dev,
+ dma_addr_t dma_handle,
+ unsigned long offset,
+ size_t size,
+ enum dma_data_direction direction)
+{
+ dma_sync_single_for_cpu(dev, dma_handle+offset, size, direction);
+}
+
+static inline void dma_sync_single_range_for_device(struct device *dev,
+ dma_addr_t dma_handle,
+ unsigned long offset,
+ size_t size,
+ enum dma_data_direction direction)
+{
+ dma_sync_single_for_device(dev, dma_handle+offset, size, direction);
+}
+
static inline void dma_sync_sg_for_cpu(struct device *dev,
struct scatterlist *sg, int nelems,
enum dma_data_direction dir)
diff --git a/include/asm-sparc/fcntl.h b/include/asm-sparc/fcntl.h
index 7bbdfc7..5ec5463 100644
--- a/include/asm-sparc/fcntl.h
+++ b/include/asm-sparc/fcntl.h
@@ -32,5 +32,6 @@
#define __ARCH_FLOCK_PAD short __unused;
#define __ARCH_FLOCK64_PAD short __unused;
+#include <asm-generic/fcntl.h>
#endif
diff --git a/include/asm-sparc/prom.h b/include/asm-sparc/prom.h
index 350676c..71f2a19 100644
--- a/include/asm-sparc/prom.h
+++ b/include/asm-sparc/prom.h
@@ -67,6 +67,7 @@
extern int of_getintprop_default(struct device_node *np,
const char *name,
int def);
+extern int of_find_in_proplist(const char *list, const char *match, int len);
extern void prom_build_devicetree(void);
diff --git a/include/asm-sparc/sbus.h b/include/asm-sparc/sbus.h
index d036e44..27d076c 100644
--- a/include/asm-sparc/sbus.h
+++ b/include/asm-sparc/sbus.h
@@ -68,7 +68,6 @@
/* This struct describes the SBus(s) found on this machine. */
struct sbus_bus {
struct of_device ofdev;
- void *iommu; /* Opaque IOMMU cookie */
struct sbus_dev *devices; /* Link to devices on this SBus */
struct sbus_bus *next; /* next SBus, if more than one SBus */
int prom_node; /* PROM device tree node for this SBus */
diff --git a/include/asm-sparc/sfp-machine.h b/include/asm-sparc/sfp-machine.h
index ecfc86a..266a42b 100644
--- a/include/asm-sparc/sfp-machine.h
+++ b/include/asm-sparc/sfp-machine.h
@@ -203,4 +203,10 @@
#define FP_INHIBIT_RESULTS ((last_task_used_math->thread.fsr >> 23) & _fex)
#endif
+#ifdef CONFIG_SMP
+#define FP_TRAPPING_EXCEPTIONS ((current->thread.fsr >> 23) & 0x1f)
+#else
+#define FP_TRAPPING_EXCEPTIONS ((last_task_used_math->thread.fsr >> 23) & 0x1f)
+#endif
+
#endif
diff --git a/include/asm-sparc64/elf.h b/include/asm-sparc64/elf.h
index 303d85e..8653e86 100644
--- a/include/asm-sparc64/elf.h
+++ b/include/asm-sparc64/elf.h
@@ -70,6 +70,7 @@
#define HWCAP_SPARC_V9 16
#define HWCAP_SPARC_ULTRA3 32
#define HWCAP_SPARC_BLKINIT 64
+#define HWCAP_SPARC_N2 128
/*
* These are used to set parameters in the core dumps.
@@ -155,8 +156,13 @@
if (tlb_type == cheetah || tlb_type == cheetah_plus)
cap |= HWCAP_SPARC_ULTRA3;
- else if (tlb_type == hypervisor)
- cap |= HWCAP_SPARC_BLKINIT;
+ else if (tlb_type == hypervisor) {
+ if (sun4v_chip_type == SUN4V_CHIP_NIAGARA1 ||
+ sun4v_chip_type == SUN4V_CHIP_NIAGARA2)
+ cap |= HWCAP_SPARC_BLKINIT;
+ if (sun4v_chip_type == SUN4V_CHIP_NIAGARA2)
+ cap |= HWCAP_SPARC_N2;
+ }
return cap;
}
diff --git a/include/asm-sparc64/oplib.h b/include/asm-sparc64/oplib.h
index 3f23c5d..86dc5c0 100644
--- a/include/asm-sparc64/oplib.h
+++ b/include/asm-sparc64/oplib.h
@@ -1,8 +1,7 @@
-/* $Id: oplib.h,v 1.14 2001/12/19 00:29:51 davem Exp $
- * oplib.h: Describes the interface and available routines in the
+/* oplib.h: Describes the interface and available routines in the
* Linux Prom library.
*
- * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
+ * Copyright (C) 1995, 2007 David S. Miller (davem@davemloft.net)
* Copyright (C) 1996 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
*/
@@ -31,8 +30,10 @@
extern const char prom_peer_name[];
extern const char prom_compatible_name[];
extern const char prom_root_compatible[];
+extern const char prom_cpu_compatible[];
extern const char prom_finddev_name[];
extern const char prom_chosen_path[];
+extern const char prom_cpu_path[];
extern const char prom_getprop_name[];
extern const char prom_mmu_name[];
extern const char prom_callmethod_name[];
diff --git a/include/asm-sparc64/percpu.h b/include/asm-sparc64/percpu.h
index caf8750..a1f53a4 100644
--- a/include/asm-sparc64/percpu.h
+++ b/include/asm-sparc64/percpu.h
@@ -3,6 +3,8 @@
#include <linux/compiler.h>
+register unsigned long __local_per_cpu_offset asm("g5");
+
#ifdef CONFIG_SMP
#define setup_per_cpu_areas() do { } while (0)
@@ -23,8 +25,6 @@
__typeof__(type) per_cpu__##name \
____cacheline_aligned_in_smp
-register unsigned long __local_per_cpu_offset asm("g5");
-
/* var is in discarded region: offset to particular copy we want */
#define per_cpu(var, cpu) (*RELOC_HIDE(&per_cpu__##var, __per_cpu_offset(cpu)))
#define __get_cpu_var(var) (*RELOC_HIDE(&per_cpu__##var, __local_per_cpu_offset))
diff --git a/include/asm-sparc64/prom.h b/include/asm-sparc64/prom.h
index 31dcb92..07843f9 100644
--- a/include/asm-sparc64/prom.h
+++ b/include/asm-sparc64/prom.h
@@ -76,6 +76,7 @@
extern int of_getintprop_default(struct device_node *np,
const char *name,
int def);
+extern int of_find_in_proplist(const char *list, const char *match, int len);
extern void prom_build_devicetree(void);
diff --git a/include/asm-sparc64/sfp-machine.h b/include/asm-sparc64/sfp-machine.h
index 89d4243..c9331b0 100644
--- a/include/asm-sparc64/sfp-machine.h
+++ b/include/asm-sparc64/sfp-machine.h
@@ -88,4 +88,6 @@
#define FP_INHIBIT_RESULTS ((current_thread_info()->xfsr[0] >> 23) & _fex)
+#define FP_TRAPPING_EXCEPTIONS ((current_thread_info()->xfsr[0] >> 23) & 0x1f)
+
#endif
diff --git a/include/asm-sparc64/spitfire.h b/include/asm-sparc64/spitfire.h
index 23ad8a7..cf78078 100644
--- a/include/asm-sparc64/spitfire.h
+++ b/include/asm-sparc64/spitfire.h
@@ -38,6 +38,11 @@
#define L1DCACHE_SIZE 0x4000
+#define SUN4V_CHIP_INVALID 0x00
+#define SUN4V_CHIP_NIAGARA1 0x01
+#define SUN4V_CHIP_NIAGARA2 0x02
+#define SUN4V_CHIP_UNKNOWN 0xff
+
#ifndef __ASSEMBLY__
enum ultra_tlb_layout {
@@ -49,6 +54,8 @@
extern enum ultra_tlb_layout tlb_type;
+extern int sun4v_chip_type;
+
extern int cheetah_pcache_forced_on;
extern void cheetah_enable_pcache(void);
diff --git a/include/asm-sparc64/system.h b/include/asm-sparc64/system.h
index 64891cb..3f175fa 100644
--- a/include/asm-sparc64/system.h
+++ b/include/asm-sparc64/system.h
@@ -141,7 +141,6 @@
* not preserve it's value. Hairy, but it lets us remove 2 loads
* and 2 stores in this critical code path. -DaveM
*/
-#define EXTRA_CLOBBER ,"%l1"
#define switch_to(prev, next, last) \
do { if (test_thread_flag(TIF_PERFCTR)) { \
unsigned long __tmp; \
@@ -164,33 +163,34 @@
"stx %%i6, [%%sp + 2047 + 0x70]\n\t" \
"stx %%i7, [%%sp + 2047 + 0x78]\n\t" \
"rdpr %%wstate, %%o5\n\t" \
- "stx %%o6, [%%g6 + %3]\n\t" \
- "stb %%o5, [%%g6 + %2]\n\t" \
- "rdpr %%cwp, %%o5\n\t" \
+ "stx %%o6, [%%g6 + %6]\n\t" \
"stb %%o5, [%%g6 + %5]\n\t" \
- "mov %1, %%g6\n\t" \
- "ldub [%1 + %5], %%g1\n\t" \
+ "rdpr %%cwp, %%o5\n\t" \
+ "stb %%o5, [%%g6 + %8]\n\t" \
+ "mov %4, %%g6\n\t" \
+ "ldub [%4 + %8], %%g1\n\t" \
"wrpr %%g1, %%cwp\n\t" \
- "ldx [%%g6 + %3], %%o6\n\t" \
- "ldub [%%g6 + %2], %%o5\n\t" \
- "ldub [%%g6 + %4], %%o7\n\t" \
+ "ldx [%%g6 + %6], %%o6\n\t" \
+ "ldub [%%g6 + %5], %%o5\n\t" \
+ "ldub [%%g6 + %7], %%o7\n\t" \
"wrpr %%o5, 0x0, %%wstate\n\t" \
"ldx [%%sp + 2047 + 0x70], %%i6\n\t" \
"ldx [%%sp + 2047 + 0x78], %%i7\n\t" \
- "ldx [%%g6 + %6], %%g4\n\t" \
+ "ldx [%%g6 + %9], %%g4\n\t" \
"brz,pt %%o7, 1f\n\t" \
" mov %%g7, %0\n\t" \
"b,a ret_from_syscall\n\t" \
"1:\n\t" \
- : "=&r" (last) \
+ : "=&r" (last), "=r" (current), "=r" (current_thread_info_reg), \
+ "=r" (__local_per_cpu_offset) \
: "0" (task_thread_info(next)), \
"i" (TI_WSTATE), "i" (TI_KSP), "i" (TI_NEW_CHILD), \
"i" (TI_CWP), "i" (TI_TASK) \
: "cc", \
"g1", "g2", "g3", "g7", \
- "l2", "l3", "l4", "l5", "l6", "l7", \
+ "l1", "l2", "l3", "l4", "l5", "l6", "l7", \
"i0", "i1", "i2", "i3", "i4", "i5", \
- "o0", "o1", "o2", "o3", "o4", "o5", "o7" EXTRA_CLOBBER);\
+ "o0", "o1", "o2", "o3", "o4", "o5", "o7"); \
/* If you fuck with this, update ret_from_syscall code too. */ \
if (test_thread_flag(TIF_PERFCTR)) { \
write_pcr(current_thread_info()->pcr_reg); \
diff --git a/include/asm-sparc64/xor.h b/include/asm-sparc64/xor.h
index 8ce3f18..a023388 100644
--- a/include/asm-sparc64/xor.h
+++ b/include/asm-sparc64/xor.h
@@ -63,4 +63,8 @@
/* For VIS for everything except Niagara. */
#define XOR_SELECT_TEMPLATE(FASTEST) \
- (tlb_type == hypervisor ? &xor_block_niagara : &xor_block_VIS)
+ ((tlb_type == hypervisor && \
+ (sun4v_chip_type == SUN4V_CHIP_NIAGARA1 || \
+ sun4v_chip_type == SUN4V_CHIP_NIAGARA2)) ? \
+ &xor_block_niagara : \
+ &xor_block_VIS)
diff --git a/include/asm-x86_64/io_apic.h b/include/asm-x86_64/io_apic.h
index 969d225..d9f2e54 100644
--- a/include/asm-x86_64/io_apic.h
+++ b/include/asm-x86_64/io_apic.h
@@ -109,6 +109,12 @@
/* 1 if "noapic" boot option passed */
extern int skip_ioapic_setup;
+static inline void disable_ioapic_setup(void)
+{
+ skip_ioapic_setup = 1;
+}
+
+
/*
* If we use the IO-APIC for IRQ routing, disable automatic
* assignment of PCI IRQ's.
diff --git a/include/asm-x86_64/nmi.h b/include/asm-x86_64/nmi.h
index 5fb3c0d..65b6acf 100644
--- a/include/asm-x86_64/nmi.h
+++ b/include/asm-x86_64/nmi.h
@@ -64,11 +64,12 @@
extern atomic_t nmi_active;
extern unsigned int nmi_watchdog;
-#define NMI_DEFAULT -1
+#define NMI_DISABLED -1
#define NMI_NONE 0
#define NMI_IO_APIC 1
#define NMI_LOCAL_APIC 2
#define NMI_INVALID 3
+#define NMI_DEFAULT NMI_DISABLED
struct ctl_table;
struct file;
diff --git a/include/asm-x86_64/pci.h b/include/asm-x86_64/pci.h
index 88926eb..5da8cb0 100644
--- a/include/asm-x86_64/pci.h
+++ b/include/asm-x86_64/pci.h
@@ -10,6 +10,8 @@
void* iommu; /* IOMMU private data */
};
+extern struct pci_bus *pci_scan_bus_with_sysdata(int busno);
+
#ifdef CONFIG_CALGARY_IOMMU
static inline void* pci_iommu(struct pci_bus *bus)
{
diff --git a/include/linux/audit.h b/include/linux/audit.h
index 4bbd860..d6579df 100644
--- a/include/linux/audit.h
+++ b/include/linux/audit.h
@@ -63,8 +63,8 @@
#define AUDIT_ADD_RULE 1011 /* Add syscall filtering rule */
#define AUDIT_DEL_RULE 1012 /* Delete syscall filtering rule */
#define AUDIT_LIST_RULES 1013 /* List syscall filtering rules */
-#define AUDIT_TTY_GET 1014 /* Get TTY auditing status */
-#define AUDIT_TTY_SET 1015 /* Set TTY auditing status */
+#define AUDIT_TTY_GET 1016 /* Get TTY auditing status */
+#define AUDIT_TTY_SET 1017 /* Set TTY auditing status */
#define AUDIT_FIRST_USER_MSG 1100 /* Userspace messages mostly uninteresting to kernel */
#define AUDIT_USER_AVC 1107 /* We filter this differently */
diff --git a/include/linux/bio.h b/include/linux/bio.h
index 4d85262..1ddef34 100644
--- a/include/linux/bio.h
+++ b/include/linux/bio.h
@@ -24,6 +24,8 @@
#include <linux/mempool.h>
#include <linux/ioprio.h>
+#ifdef CONFIG_BLOCK
+
/* Platforms may set this to teach the BIO layer about IOMMU hardware. */
#include <asm/io.h>
@@ -361,4 +363,5 @@
__bio_kmap_irq((bio), (bio)->bi_idx, (flags))
#define bio_kunmap_irq(buf,flags) __bio_kunmap_irq(buf, flags)
+#endif /* CONFIG_BLOCK */
#endif /* __LINUX_BIO_H */
diff --git a/include/linux/blktrace_api.h b/include/linux/blktrace_api.h
index 90874a5..7b5d56b 100644
--- a/include/linux/blktrace_api.h
+++ b/include/linux/blktrace_api.h
@@ -105,7 +105,7 @@
*/
struct blk_io_trace_remap {
__be32 device;
- u32 __pad;
+ __be32 device_from;
__be64 sector;
};
@@ -272,6 +272,7 @@
return;
r.device = cpu_to_be32(dev);
+ r.device_from = cpu_to_be32(bio->bi_bdev->bd_dev);
r.sector = cpu_to_be64(to);
__blk_add_trace(bt, from, bio->bi_size, bio->bi_rw, BLK_TA_REMAP, !bio_flagged(bio, BIO_UPTODATE), sizeof(r), &r);
diff --git a/include/linux/bsg.h b/include/linux/bsg.h
index 102dc09..60e377b 100644
--- a/include/linux/bsg.h
+++ b/include/linux/bsg.h
@@ -15,14 +15,18 @@
__u32 request_len; /* [i] in bytes */
__u64 request; /* [i], [*i] {SCSI: cdb} */
+ __u64 request_tag; /* [i] {SCSI: task tag (only if flagged)} */
__u32 request_attr; /* [i] {SCSI: task attribute} */
- __u32 request_tag; /* [i] {SCSI: task tag (only if flagged)} */
__u32 request_priority; /* [i] {SCSI: task priority} */
+ __u32 request_extra; /* [i] {spare, for padding} */
__u32 max_response_len; /* [i] in bytes */
__u64 response; /* [i], [*o] {SCSI: (auto)sense data} */
- /* "din_" for data in (from device); "dout_" for data out (to device) */
+ /* "dout_": data out (to device); "din_": data in (from device) */
+ __u32 dout_iovec_count; /* [i] 0 -> "flat" dout transfer else
+ dout_xfer points to array of iovec */
__u32 dout_xfer_len; /* [i] bytes to be transferred to device */
+ __u32 din_iovec_count; /* [i] 0 -> "flat" din transfer */
__u32 din_xfer_len; /* [i] bytes to be transferred from device */
__u64 dout_xferp; /* [i], [*i] */
__u64 din_xferp; /* [i], [*o] */
@@ -39,8 +43,9 @@
__u32 info; /* [o] additional information */
__u32 duration; /* [o] time to complete, in milliseconds */
__u32 response_len; /* [o] bytes of response actually written */
- __s32 din_resid; /* [o] actual_din_xfer_len - din_xfer_len */
- __u32 generated_tag; /* [o] {SCSI: task tag that transport chose} */
+ __s32 din_resid; /* [o] din_xfer_len - actual_din_xfer_len */
+ __s32 dout_resid; /* [o] dout_xfer_len - actual_dout_xfer_len */
+ __u64 generated_tag; /* [o] {SCSI: transport generated task tag} */
__u32 spare_out; /* [o] */
__u32 padding;
diff --git a/include/linux/clockchips.h b/include/linux/clockchips.h
index e0bd46e..def5a65 100644
--- a/include/linux/clockchips.h
+++ b/include/linux/clockchips.h
@@ -123,7 +123,6 @@
extern void clockevents_set_mode(struct clock_event_device *dev,
enum clock_event_mode mode);
extern int clockevents_register_notifier(struct notifier_block *nb);
-extern void clockevents_unregister_notifier(struct notifier_block *nb);
extern int clockevents_program_event(struct clock_event_device *dev,
ktime_t expires, ktime_t now);
diff --git a/include/linux/cpu.h b/include/linux/cpu.h
index c2236bb..1d5ded0 100644
--- a/include/linux/cpu.h
+++ b/include/linux/cpu.h
@@ -41,8 +41,6 @@
extern int cpu_add_sysdev_attr_group(struct attribute_group *attrs);
extern void cpu_remove_sysdev_attr_group(struct attribute_group *attrs);
-extern struct sysdev_attribute attr_sched_mc_power_savings;
-extern struct sysdev_attribute attr_sched_smt_power_savings;
extern int sched_create_sysfs_power_savings_entries(struct sysdev_class *cls);
#ifdef CONFIG_HOTPLUG_CPU
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 6bf1395..16421f6 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -1659,7 +1659,6 @@
extern int generic_file_mmap(struct file *, struct vm_area_struct *);
extern int generic_file_readonly_mmap(struct file *, struct vm_area_struct *);
extern int file_read_actor(read_descriptor_t * desc, struct page *page, unsigned long offset, unsigned long size);
-extern int file_send_actor(read_descriptor_t * desc, struct page *page, unsigned long offset, unsigned long size);
int generic_write_checks(struct file *file, loff_t *pos, size_t *count, int isblk);
extern ssize_t generic_file_aio_read(struct kiocb *, const struct iovec *, unsigned long, loff_t);
extern ssize_t generic_file_aio_write(struct kiocb *, const struct iovec *, unsigned long, loff_t);
diff --git a/include/linux/ide.h b/include/linux/ide.h
index d71d012..c792b4f 100644
--- a/include/linux/ide.h
+++ b/include/linux/ide.h
@@ -1285,13 +1285,14 @@
#define BAD_DMA_DRIVE 0
#define GOOD_DMA_DRIVE 1
-#ifdef CONFIG_BLK_DEV_IDEDMA
struct drive_list_entry {
const char *id_model;
const char *id_firmware;
};
int ide_in_drive_list(struct hd_driveid *, const struct drive_list_entry *);
+
+#ifdef CONFIG_BLK_DEV_IDEDMA
int __ide_dma_bad_drive(ide_drive_t *);
int __ide_dma_good_drive(ide_drive_t *);
u8 ide_max_dma_mode(ide_drive_t *);
@@ -1312,7 +1313,6 @@
void ide_dma_off_quietly(ide_drive_t *);
void ide_dma_host_on(ide_drive_t *);
extern int __ide_dma_on(ide_drive_t *);
-extern int __ide_dma_check(ide_drive_t *);
extern int ide_dma_setup(ide_drive_t *);
extern void ide_dma_start(ide_drive_t *);
extern int __ide_dma_end(ide_drive_t *);
diff --git a/include/linux/init.h b/include/linux/init.h
index 1a4a283..74b1f43 100644
--- a/include/linux/init.h
+++ b/include/linux/init.h
@@ -43,7 +43,7 @@
#define __init __attribute__ ((__section__ (".init.text"))) __cold
#define __initdata __attribute__ ((__section__ (".init.data")))
#define __exitdata __attribute__ ((__section__(".exit.data")))
-#define __exit_call __attribute_used__ __attribute__ ((__section__ (".exitcall.exit"))) __cold
+#define __exit_call __attribute_used__ __attribute__ ((__section__ (".exitcall.exit")))
/* modpost check for section mismatches during the kernel build.
* A section mismatch happens when there are references from a
diff --git a/include/linux/input.h b/include/linux/input.h
index e02c6a6..cf2b561 100644
--- a/include/linux/input.h
+++ b/include/linux/input.h
@@ -363,6 +363,12 @@
#define KEY_UNKNOWN 240
+#define KEY_VIDEO_NEXT 241 /* drive next video source */
+#define KEY_VIDEO_PREV 242 /* drive previous video source */
+#define KEY_BRIGHTNESS_CYCLE 243 /* brightness up, after max is min */
+#define KEY_BRIGHTNESS_ZERO 244 /* brightness off, use ambient */
+#define KEY_DISPLAY_OFF 245 /* display device to off state */
+
#define BTN_MISC 0x100
#define BTN_0 0x100
#define BTN_1 0x101
diff --git a/include/linux/kbd_kern.h b/include/linux/kbd_kern.h
index 506ad20..8bdb16b 100644
--- a/include/linux/kbd_kern.h
+++ b/include/linux/kbd_kern.h
@@ -161,4 +161,7 @@
schedule_delayed_work(&t->buf.work, 0);
}
+/* mac_hid.c */
+extern int mac_hid_mouse_emulate_buttons(int, unsigned int, int);
+
#endif
diff --git a/include/linux/kernel.h b/include/linux/kernel.h
index 4300bb4..f592df7 100644
--- a/include/linux/kernel.h
+++ b/include/linux/kernel.h
@@ -224,9 +224,9 @@
char *linebuf, size_t linebuflen, bool ascii);
extern void print_hex_dump(const char *level, const char *prefix_str,
int prefix_type, int rowsize, int groupsize,
- void *buf, size_t len, bool ascii);
+ const void *buf, size_t len, bool ascii);
extern void print_hex_dump_bytes(const char *prefix_str, int prefix_type,
- void *buf, size_t len);
+ const void *buf, size_t len);
#define hex_asc(x) "0123456789abcdef"[x]
#ifdef DEBUG
diff --git a/include/linux/mempolicy.h b/include/linux/mempolicy.h
index e147cf5..5bdd656 100644
--- a/include/linux/mempolicy.h
+++ b/include/linux/mempolicy.h
@@ -166,7 +166,7 @@
static inline void check_highest_zone(enum zone_type k)
{
- if (k > policy_zone)
+ if (k > policy_zone && k != ZONE_MOVABLE)
policy_zone = k;
}
diff --git a/include/linux/mm.h b/include/linux/mm.h
index 655094d..1692dd6 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -1042,7 +1042,7 @@
}
/* mmap.c */
-extern int __vm_enough_memory(long pages, int cap_sys_admin);
+extern int __vm_enough_memory(struct mm_struct *mm, long pages, int cap_sys_admin);
extern void vma_adjust(struct vm_area_struct *vma, unsigned long start,
unsigned long end, pgoff_t pgoff, struct vm_area_struct *insert);
extern struct vm_area_struct *vma_merge(struct mm_struct *,
diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h
index 3ea68cd..4e56273 100644
--- a/include/linux/mmzone.h
+++ b/include/linux/mmzone.h
@@ -410,6 +410,24 @@
#endif
};
+#ifdef CONFIG_NUMA
+/*
+ * Only custom zonelists like MPOL_BIND need to be filtered as part of
+ * policies. As described in the comment for struct zonelist_cache, these
+ * zonelists will not have a zlcache so zlcache_ptr will not be set. Use
+ * that to determine if the zonelists needs to be filtered or not.
+ */
+static inline int alloc_should_filter_zonelist(struct zonelist *zonelist)
+{
+ return !zonelist->zlcache_ptr;
+}
+#else
+static inline int alloc_should_filter_zonelist(struct zonelist *zonelist)
+{
+ return 0;
+}
+#endif /* CONFIG_NUMA */
+
#ifdef CONFIG_ARCH_POPULATES_NODE_MAP
struct node_active_region {
unsigned long start_pfn;
diff --git a/include/linux/mod_devicetable.h b/include/linux/mod_devicetable.h
index 2ada8ee..4dc5fa8 100644
--- a/include/linux/mod_devicetable.h
+++ b/include/linux/mod_devicetable.h
@@ -159,7 +159,8 @@
#define AP_DEVICE_ID_MATCH_DEVICE_TYPE 0x01
-#define ACPI_ID_LEN 9
+#define ACPI_ID_LEN 16 /* only 9 bytes needed here, 16 bytes are used */
+ /* to workaround crosscompile issues */
struct acpi_device_id {
__u8 id[ACPI_ID_LEN];
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index 4a616d7..e679b27 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -1131,6 +1131,8 @@
extern void linkwatch_run_queue(void);
+extern int netdev_compute_features(unsigned long all, unsigned long one);
+
static inline int net_gso_ok(int features, int gso_type)
{
int feature = gso_type << NETIF_F_GSO_SHIFT;
diff --git a/include/linux/netfilter/Kbuild b/include/linux/netfilter/Kbuild
index 43397a4..ab57cb7 100644
--- a/include/linux/netfilter/Kbuild
+++ b/include/linux/netfilter/Kbuild
@@ -28,6 +28,7 @@
header-y += xt_realm.h
header-y += xt_sctp.h
header-y += xt_state.h
+header-y += xt_statistic.h
header-y += xt_string.h
header-y += xt_tcpmss.h
header-y += xt_tcpudp.h
diff --git a/include/linux/nfs_fs.h b/include/linux/nfs_fs.h
index 9ba4aec..157dcb0 100644
--- a/include/linux/nfs_fs.h
+++ b/include/linux/nfs_fs.h
@@ -71,7 +71,7 @@
struct nfs4_state;
struct nfs_open_context {
- struct kref kref;
+ atomic_t count;
struct path path;
struct rpc_cred *cred;
struct nfs4_state *state;
diff --git a/include/linux/pci.h b/include/linux/pci.h
index e7d8d4e..038a0dc 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -557,6 +557,7 @@
int pcix_get_max_mmrbc(struct pci_dev *dev);
int pcix_get_mmrbc(struct pci_dev *dev);
int pcix_set_mmrbc(struct pci_dev *dev, int mmrbc);
+int pcie_get_readrq(struct pci_dev *dev);
int pcie_set_readrq(struct pci_dev *dev, int rq);
void pci_update_resource(struct pci_dev *dev, struct resource *res, int resno);
int __must_check pci_assign_resource(struct pci_dev *dev, int i);
@@ -578,6 +579,9 @@
pci_power_t pci_choose_state(struct pci_dev *dev, pm_message_t state);
int pci_enable_wake(struct pci_dev *dev, pci_power_t state, int enable);
+/* Functions for PCI Hotplug drivers to use */
+int pci_bus_find_capability (struct pci_bus *bus, unsigned int devfn, int cap);
+
/* Helper functions for low-level code (drivers/pci/setup-[bus,res].c) */
void pci_bus_assign_resources(struct pci_bus *bus);
void pci_bus_size_bridges(struct pci_bus *bus);
diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h
index 0d58a39..06d23e1 100644
--- a/include/linux/pci_ids.h
+++ b/include/linux/pci_ids.h
@@ -360,6 +360,9 @@
#define PCI_DEVICE_ID_ATI_RS400_166 0x5a32
#define PCI_DEVICE_ID_ATI_RS400_200 0x5a33
#define PCI_DEVICE_ID_ATI_RS480 0x5950
+#define PCI_DEVICE_ID_ATI_RD580 0x5952
+#define PCI_DEVICE_ID_ATI_RX790 0x5957
+#define PCI_DEVICE_ID_ATI_RS690 0x7910
/* ATI IXP Chipset */
#define PCI_DEVICE_ID_ATI_IXP200_IDE 0x4349
#define PCI_DEVICE_ID_ATI_IXP200_SMBUS 0x4353
@@ -2093,8 +2096,10 @@
#define PCI_DEVICE_ID_MPC8568 0x0021
#define PCI_DEVICE_ID_MPC8567E 0x0022
#define PCI_DEVICE_ID_MPC8567 0x0023
-#define PCI_DEVICE_ID_MPC8544E 0x0030
-#define PCI_DEVICE_ID_MPC8544 0x0031
+#define PCI_DEVICE_ID_MPC8533E 0x0030
+#define PCI_DEVICE_ID_MPC8533 0x0031
+#define PCI_DEVICE_ID_MPC8544E 0x0032
+#define PCI_DEVICE_ID_MPC8544 0x0033
#define PCI_DEVICE_ID_MPC8641 0x7010
#define PCI_DEVICE_ID_MPC8641D 0x7011
diff --git a/include/linux/proc_fs.h b/include/linux/proc_fs.h
index 28e3664..cd13a78 100644
--- a/include/linux/proc_fs.h
+++ b/include/linux/proc_fs.h
@@ -75,7 +75,6 @@
write_proc_t *write_proc;
atomic_t count; /* use count */
int deleted; /* delete flag */
- void *set;
int pde_users; /* number of callers into module in progress */
spinlock_t pde_unload_lock; /* proc_fops checks and pde_users bumps */
struct completion *pde_unload_completion;
diff --git a/include/linux/rcupdate.h b/include/linux/rcupdate.h
index c6b7485..fe17d7d 100644
--- a/include/linux/rcupdate.h
+++ b/include/linux/rcupdate.h
@@ -281,7 +281,6 @@
extern void FASTCALL(call_rcu_bh(struct rcu_head *head,
void (*func)(struct rcu_head *head)));
extern void synchronize_rcu(void);
-void synchronize_idle(void);
extern void rcu_barrier(void);
#endif /* __KERNEL__ */
diff --git a/include/linux/sched.h b/include/linux/sched.h
index 17249fa..ba78807 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -139,7 +139,7 @@
extern void proc_sched_show_task(struct task_struct *p, struct seq_file *m);
extern void proc_sched_set_task(struct task_struct *p);
extern void
-print_cfs_rq(struct seq_file *m, int cpu, struct cfs_rq *cfs_rq, u64 now);
+print_cfs_rq(struct seq_file *m, int cpu, struct cfs_rq *cfs_rq);
#else
static inline void
proc_sched_show_task(struct task_struct *p, struct seq_file *m)
@@ -149,7 +149,7 @@
{
}
static inline void
-print_cfs_rq(struct seq_file *m, int cpu, struct cfs_rq *cfs_rq, u64 now)
+print_cfs_rq(struct seq_file *m, int cpu, struct cfs_rq *cfs_rq)
{
}
#endif
@@ -681,7 +681,7 @@
#define SCHED_LOAD_SHIFT 10
#define SCHED_LOAD_SCALE (1L << SCHED_LOAD_SHIFT)
-#define SCHED_LOAD_SCALE_FUZZ (SCHED_LOAD_SCALE >> 1)
+#define SCHED_LOAD_SCALE_FUZZ SCHED_LOAD_SCALE
#ifdef CONFIG_SMP
#define SD_LOAD_BALANCE 1 /* Do load balancing on this domain. */
@@ -855,26 +855,24 @@
struct sched_class {
struct sched_class *next;
- void (*enqueue_task) (struct rq *rq, struct task_struct *p,
- int wakeup, u64 now);
- void (*dequeue_task) (struct rq *rq, struct task_struct *p,
- int sleep, u64 now);
+ void (*enqueue_task) (struct rq *rq, struct task_struct *p, int wakeup);
+ void (*dequeue_task) (struct rq *rq, struct task_struct *p, int sleep);
void (*yield_task) (struct rq *rq, struct task_struct *p);
void (*check_preempt_curr) (struct rq *rq, struct task_struct *p);
- struct task_struct * (*pick_next_task) (struct rq *rq, u64 now);
- void (*put_prev_task) (struct rq *rq, struct task_struct *p, u64 now);
+ struct task_struct * (*pick_next_task) (struct rq *rq);
+ void (*put_prev_task) (struct rq *rq, struct task_struct *p);
- int (*load_balance) (struct rq *this_rq, int this_cpu,
+ unsigned long (*load_balance) (struct rq *this_rq, int this_cpu,
struct rq *busiest,
unsigned long max_nr_move, unsigned long max_load_move,
struct sched_domain *sd, enum cpu_idle_type idle,
- int *all_pinned, unsigned long *total_load_moved);
+ int *all_pinned, int *this_best_prio);
void (*set_curr_task) (struct rq *rq);
void (*task_tick) (struct rq *rq, struct task_struct *p);
- void (*task_new) (struct rq *rq, struct task_struct *p, u64 now);
+ void (*task_new) (struct rq *rq, struct task_struct *p);
};
struct load_weight {
@@ -1390,7 +1388,8 @@
#define sched_exec() {}
#endif
-extern void sched_clock_unstable_event(void);
+extern void sched_clock_idle_sleep_event(void);
+extern void sched_clock_idle_wakeup_event(u64 delta_ns);
#ifdef CONFIG_HOTPLUG_CPU
extern void idle_task_exit(void);
diff --git a/include/linux/security.h b/include/linux/security.h
index c11dc8a..1a15526 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -54,7 +54,7 @@
extern int cap_task_post_setuid (uid_t old_ruid, uid_t old_euid, uid_t old_suid, int flags);
extern void cap_task_reparent_to_init (struct task_struct *p);
extern int cap_syslog (int type);
-extern int cap_vm_enough_memory (long pages);
+extern int cap_vm_enough_memory (struct mm_struct *mm, long pages);
struct msghdr;
struct sk_buff;
@@ -1125,6 +1125,7 @@
* Return 0 if permission is granted.
* @vm_enough_memory:
* Check permissions for allocating a new virtual mapping.
+ * @mm contains the mm struct it is being added to.
* @pages contains the number of pages.
* Return 0 if permission is granted.
*
@@ -1169,7 +1170,7 @@
int (*quota_on) (struct dentry * dentry);
int (*syslog) (int type);
int (*settime) (struct timespec *ts, struct timezone *tz);
- int (*vm_enough_memory) (long pages);
+ int (*vm_enough_memory) (struct mm_struct *mm, long pages);
int (*bprm_alloc_security) (struct linux_binprm * bprm);
void (*bprm_free_security) (struct linux_binprm * bprm);
@@ -1469,10 +1470,14 @@
return security_ops->settime(ts, tz);
}
-
static inline int security_vm_enough_memory(long pages)
{
- return security_ops->vm_enough_memory(pages);
+ return security_ops->vm_enough_memory(current->mm, pages);
+}
+
+static inline int security_vm_enough_memory_mm(struct mm_struct *mm, long pages)
+{
+ return security_ops->vm_enough_memory(mm, pages);
}
static inline int security_bprm_alloc (struct linux_binprm *bprm)
@@ -2219,7 +2224,12 @@
static inline int security_vm_enough_memory(long pages)
{
- return cap_vm_enough_memory(pages);
+ return cap_vm_enough_memory(current->mm, pages);
+}
+
+static inline int security_vm_enough_memory_mm(struct mm_struct *mm, long pages)
+{
+ return cap_vm_enough_memory(mm, pages);
}
static inline int security_bprm_alloc (struct linux_binprm *bprm)
diff --git a/include/linux/selection.h b/include/linux/selection.h
index ed3408b..f945786 100644
--- a/include/linux/selection.h
+++ b/include/linux/selection.h
@@ -10,6 +10,8 @@
#include <linux/tiocl.h>
#include <linux/vt_buffer.h>
+struct tty_struct;
+
extern struct vc_data *sel_cons;
extern void clear_selection(void);
diff --git a/include/linux/serial_reg.h b/include/linux/serial_reg.h
index 1c5ed7d..96c0d93 100644
--- a/include/linux/serial_reg.h
+++ b/include/linux/serial_reg.h
@@ -118,6 +118,7 @@
#define UART_LSR_PE 0x04 /* Parity error indicator */
#define UART_LSR_OE 0x02 /* Overrun error indicator */
#define UART_LSR_DR 0x01 /* Receiver data ready */
+#define UART_LSR_BRK_ERROR_BITS 0x1E /* BI, FE, PE, OE bits */
#define UART_MSR 6 /* In: Modem Status Register */
#define UART_MSR_DCD 0x80 /* Data Carrier Detect */
diff --git a/include/linux/tty.h b/include/linux/tty.h
index 691a174..6570719 100644
--- a/include/linux/tty.h
+++ b/include/linux/tty.h
@@ -274,6 +274,8 @@
#define TTY_PTY_LOCK 16 /* pty private */
#define TTY_NO_WRITE_SPLIT 17 /* Preserve write boundaries to driver */
#define TTY_HUPPED 18 /* Post driver->hangup() */
+#define TTY_FLUSHING 19 /* Flushing to ldisc in progress */
+#define TTY_FLUSHPENDING 20 /* Queued buffer flush pending */
#define TTY_WRITE_FLUSH(tty) tty_write_flush((tty))
diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h
index c66c8a3..ae9b24c 100644
--- a/include/linux/videodev2.h
+++ b/include/linux/videodev2.h
@@ -617,7 +617,6 @@
#define V4L2_FBUF_CAP_LOCAL_ALPHA 0x0010
#define V4L2_FBUF_CAP_GLOBAL_ALPHA 0x0020
#define V4L2_FBUF_CAP_LOCAL_INV_ALPHA 0x0040
-#define V4L2_FBUF_CAP_GLOBAL_INV_ALPHA 0x0080
/* Flags for the 'flags' field. */
#define V4L2_FBUF_FLAG_PRIMARY 0x0001
#define V4L2_FBUF_FLAG_OVERLAY 0x0002
@@ -625,7 +624,6 @@
#define V4L2_FBUF_FLAG_LOCAL_ALPHA 0x0008
#define V4L2_FBUF_FLAG_GLOBAL_ALPHA 0x0010
#define V4L2_FBUF_FLAG_LOCAL_INV_ALPHA 0x0020
-#define V4L2_FBUF_FLAG_GLOBAL_INV_ALPHA 0x0040
struct v4l2_clip
{
diff --git a/include/math-emu/op-common.h b/include/math-emu/op-common.h
index 93780ab..bb46e76 100644
--- a/include/math-emu/op-common.h
+++ b/include/math-emu/op-common.h
@@ -145,13 +145,16 @@
{ \
X##_e = 1; \
_FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc); \
+ FP_SET_EXCEPTION(FP_EX_INEXACT); \
} \
else \
{ \
X##_e = 0; \
_FP_FRAC_SRL_##wc(X, _FP_WORKBITS); \
- FP_SET_EXCEPTION(FP_EX_UNDERFLOW); \
} \
+ if ((FP_CUR_EXCEPTIONS & FP_EX_INEXACT) || \
+ (FP_TRAPPING_EXCEPTIONS & FP_EX_UNDERFLOW)) \
+ FP_SET_EXCEPTION(FP_EX_UNDERFLOW); \
} \
else \
{ \
diff --git a/include/math-emu/soft-fp.h b/include/math-emu/soft-fp.h
index d02eb64..a6f873b 100644
--- a/include/math-emu/soft-fp.h
+++ b/include/math-emu/soft-fp.h
@@ -97,12 +97,19 @@
#define FP_INHIBIT_RESULTS 0
#endif
+#ifndef FP_TRAPPING_EXCEPTIONS
+#define FP_TRAPPING_EXCEPTIONS 0
+#endif
+
#define FP_SET_EXCEPTION(ex) \
_fex |= (ex)
#define FP_UNSET_EXCEPTION(ex) \
_fex &= ~(ex)
+#define FP_CUR_EXCEPTIONS \
+ (_fex)
+
#define FP_CLEAR_EXCEPTIONS \
_fex = 0
diff --git a/include/net/netfilter/ipv4/nf_conntrack_ipv4.h b/include/net/netfilter/ipv4/nf_conntrack_ipv4.h
index 7a67160..9bf0598 100644
--- a/include/net/netfilter/ipv4/nf_conntrack_ipv4.h
+++ b/include/net/netfilter/ipv4/nf_conntrack_ipv4.h
@@ -21,4 +21,6 @@
extern int nf_conntrack_ipv4_compat_init(void);
extern void nf_conntrack_ipv4_compat_fini(void);
+extern void need_ipv4_conntrack(void);
+
#endif /*_NF_CONNTRACK_IPV4_H*/
diff --git a/include/rdma/ib_mad.h b/include/rdma/ib_mad.h
index 30712dd..8ec3799 100644
--- a/include/rdma/ib_mad.h
+++ b/include/rdma/ib_mad.h
@@ -39,6 +39,8 @@
#if !defined( IB_MAD_H )
#define IB_MAD_H
+#include <linux/list.h>
+
#include <rdma/ib_verbs.h>
/* Management base version */
diff --git a/include/rdma/ib_verbs.h b/include/rdma/ib_verbs.h
index 0627a6a..4bea182 100644
--- a/include/rdma/ib_verbs.h
+++ b/include/rdma/ib_verbs.h
@@ -46,6 +46,8 @@
#include <linux/mm.h>
#include <linux/dma-mapping.h>
#include <linux/kref.h>
+#include <linux/list.h>
+#include <linux/rwsem.h>
#include <asm/atomic.h>
#include <asm/scatterlist.h>
@@ -731,11 +733,6 @@
size_t outlen;
};
-#define IB_UMEM_MAX_PAGE_CHUNK \
- ((PAGE_SIZE - offsetof(struct ib_umem_chunk, page_list)) / \
- ((void *) &((struct ib_umem_chunk *) 0)->page_list[1] - \
- (void *) &((struct ib_umem_chunk *) 0)->page_list[0]))
-
struct ib_pd {
struct ib_device *device;
struct ib_uobject *uobject;
diff --git a/include/scsi/scsi_driver.h b/include/scsi/scsi_driver.h
index 02e26c1..3465f31 100644
--- a/include/scsi/scsi_driver.h
+++ b/include/scsi/scsi_driver.h
@@ -13,8 +13,6 @@
int (*init_command)(struct scsi_cmnd *);
void (*rescan)(struct device *);
- int (*issue_flush)(struct device *, sector_t *);
- int (*prepare_flush)(struct request_queue *, struct request *);
};
#define to_scsi_driver(drv) \
container_of((drv), struct scsi_driver, gendrv)
diff --git a/include/scsi/sd.h b/include/scsi/sd.h
index 78583fe..ce02ad1 100644
--- a/include/scsi/sd.h
+++ b/include/scsi/sd.h
@@ -56,8 +56,6 @@
static int sd_resume(struct device *dev);
static void sd_rescan(struct device *);
static int sd_init_command(struct scsi_cmnd *);
-static int sd_issue_flush(struct device *, sector_t *);
-static void sd_prepare_flush(struct request_queue *, struct request *);
static void sd_read_capacity(struct scsi_disk *sdkp, unsigned char *buffer);
static void scsi_disk_release(struct class_device *cdev);
static void sd_print_sense_hdr(struct scsi_disk *, struct scsi_sense_hdr *);
diff --git a/init/main.c b/init/main.c
index d3bcb3b..cc0653e 100644
--- a/init/main.c
+++ b/init/main.c
@@ -146,9 +146,14 @@
* greater than 0, limits the maximum number of CPUs activated in
* SMP mode to <NUM>.
*/
+#ifndef CONFIG_X86_IO_APIC
+static inline void disable_ioapic_setup(void) {};
+#endif
+
static int __init nosmp(char *str)
{
max_cpus = 0;
+ disable_ioapic_setup();
return 0;
}
@@ -157,10 +162,13 @@
static int __init maxcpus(char *str)
{
get_option(&str, &max_cpus);
- return 1;
+ if (max_cpus == 0)
+ disable_ioapic_setup();
+
+ return 0;
}
-__setup("maxcpus=", maxcpus);
+early_param("maxcpus=", maxcpus);
#else
#define max_cpus NR_CPUS
#endif
diff --git a/kernel/auditsc.c b/kernel/auditsc.c
index a777d37..04f3ffb 100644
--- a/kernel/auditsc.c
+++ b/kernel/auditsc.c
@@ -1992,19 +1992,19 @@
extern uid_t audit_sig_uid;
extern u32 audit_sig_sid;
- if (audit_pid && t->tgid == audit_pid &&
- (sig == SIGTERM || sig == SIGHUP || sig == SIGUSR1)) {
- audit_sig_pid = tsk->pid;
- if (ctx)
- audit_sig_uid = ctx->loginuid;
- else
- audit_sig_uid = tsk->uid;
- selinux_get_task_sid(tsk, &audit_sig_sid);
+ if (audit_pid && t->tgid == audit_pid) {
+ if (sig == SIGTERM || sig == SIGHUP || sig == SIGUSR1) {
+ audit_sig_pid = tsk->pid;
+ if (ctx)
+ audit_sig_uid = ctx->loginuid;
+ else
+ audit_sig_uid = tsk->uid;
+ selinux_get_task_sid(tsk, &audit_sig_sid);
+ }
+ if (!audit_signals || audit_dummy_context())
+ return 0;
}
- if (!audit_signals) /* audit_context checked in wrapper */
- return 0;
-
/* optimize the common case by putting first signal recipient directly
* in audit_context */
if (!ctx->target_pid) {
@@ -2023,7 +2023,7 @@
axp->d.next = ctx->aux_pids;
ctx->aux_pids = (void *)axp;
}
- BUG_ON(axp->pid_count > AUDIT_AUX_PIDS);
+ BUG_ON(axp->pid_count >= AUDIT_AUX_PIDS);
axp->target_pid[axp->pid_count] = t->tgid;
selinux_get_task_sid(t, &axp->target_sid[axp->pid_count]);
diff --git a/kernel/futex.c b/kernel/futex.c
index 3415e9a..e8935b1 100644
--- a/kernel/futex.c
+++ b/kernel/futex.c
@@ -1670,6 +1670,7 @@
attempt);
if (ret)
goto out;
+ uval = 0;
goto retry_unlocked;
}
diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c
index 615ce97..f1a73f0 100644
--- a/kernel/irq/chip.c
+++ b/kernel/irq/chip.c
@@ -352,13 +352,10 @@
* keep it masked and get out of here
*/
action = desc->action;
- if (unlikely(!action || (desc->status & IRQ_DISABLED))) {
- desc->status |= IRQ_PENDING;
+ if (unlikely(!action || (desc->status & IRQ_DISABLED)))
goto out_unlock;
- }
desc->status |= IRQ_INPROGRESS;
- desc->status &= ~IRQ_PENDING;
spin_unlock(&desc->lock);
action_ret = handle_IRQ_event(irq, action);
diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c
index 203a518..853aefb 100644
--- a/kernel/irq/manage.c
+++ b/kernel/irq/manage.c
@@ -462,7 +462,9 @@
* We do this after actually deregistering it, to make sure that
* a 'real' IRQ doesn't run in parallel with our fake
*/
+ local_irq_save(flags);
handler(irq, dev_id);
+ local_irq_restore(flags);
}
#endif
}
diff --git a/kernel/irq/resend.c b/kernel/irq/resend.c
index c382727..a804679 100644
--- a/kernel/irq/resend.c
+++ b/kernel/irq/resend.c
@@ -63,15 +63,11 @@
desc->chip->enable(irq);
/*
- * Temporary hack to figure out more about the problem, which
- * is causing the ancient network cards to die.
+ * We do not resend level type interrupts. Level type
+ * interrupts are resent by hardware when they are still
+ * active.
*/
- if (desc->handle_irq != handle_edge_irq) {
- WARN_ON_ONCE(1);
- return;
- }
-
- if ((status & (IRQ_PENDING | IRQ_REPLAY)) == IRQ_PENDING) {
+ if ((status & (IRQ_LEVEL | IRQ_PENDING | IRQ_REPLAY)) == IRQ_PENDING) {
desc->status = (status & ~IRQ_PENDING) | IRQ_REPLAY;
if (!desc->chip || !desc->chip->retrigger ||
diff --git a/kernel/kprobes.c b/kernel/kprobes.c
index 3e9f513..4b8a449 100644
--- a/kernel/kprobes.c
+++ b/kernel/kprobes.c
@@ -1063,6 +1063,11 @@
EXPORT_SYMBOL_GPL(unregister_kprobe);
EXPORT_SYMBOL_GPL(register_jprobe);
EXPORT_SYMBOL_GPL(unregister_jprobe);
+#ifdef CONFIG_KPROBES
EXPORT_SYMBOL_GPL(jprobe_return);
+#endif
+
+#ifdef CONFIG_KPROBES
EXPORT_SYMBOL_GPL(register_kretprobe);
EXPORT_SYMBOL_GPL(unregister_kretprobe);
+#endif
diff --git a/kernel/module.c b/kernel/module.c
index 33c04ad..db0ead0 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -784,8 +784,7 @@
static ssize_t show_refcnt(struct module_attribute *mattr,
struct module *mod, char *buffer)
{
- /* sysfs holds a reference */
- return sprintf(buffer, "%u\n", module_refcount(mod)-1);
+ return sprintf(buffer, "%u\n", module_refcount(mod));
}
static struct module_attribute refcnt = {
diff --git a/kernel/posix-timers.c b/kernel/posix-timers.c
index 55b3761..7a15afb 100644
--- a/kernel/posix-timers.c
+++ b/kernel/posix-timers.c
@@ -547,9 +547,9 @@
new_timer->it_process = process;
list_add(&new_timer->list,
&process->signal->posix_timers);
- spin_unlock_irqrestore(&process->sighand->siglock, flags);
if (new_timer->it_sigev_notify == (SIGEV_SIGNAL|SIGEV_THREAD_ID))
get_task_struct(process);
+ spin_unlock_irqrestore(&process->sighand->siglock, flags);
} else {
spin_unlock_irqrestore(&process->sighand->siglock, flags);
process = NULL;
@@ -605,13 +605,14 @@
timr = (struct k_itimer *) idr_find(&posix_timers_id, (int) timer_id);
if (timr) {
spin_lock(&timr->it_lock);
- spin_unlock(&idr_lock);
if ((timr->it_id != timer_id) || !(timr->it_process) ||
timr->it_process->tgid != current->tgid) {
- unlock_timer(timr, *flags);
+ spin_unlock(&timr->it_lock);
+ spin_unlock_irqrestore(&idr_lock, *flags);
timr = NULL;
- }
+ } else
+ spin_unlock(&idr_lock);
} else
spin_unlock_irqrestore(&idr_lock, *flags);
diff --git a/kernel/power/snapshot.c b/kernel/power/snapshot.c
index a3b7854..a686590 100644
--- a/kernel/power/snapshot.c
+++ b/kernel/power/snapshot.c
@@ -709,7 +709,8 @@
region->end_pfn << PAGE_SHIFT);
for (pfn = region->start_pfn; pfn < region->end_pfn; pfn++)
- memory_bm_set_bit(bm, pfn);
+ if (pfn_valid(pfn))
+ memory_bm_set_bit(bm, pfn);
}
}
diff --git a/kernel/printk.c b/kernel/printk.c
index bd2cd06..8451dfc 100644
--- a/kernel/printk.c
+++ b/kernel/printk.c
@@ -1083,6 +1083,19 @@
}
EXPORT_SYMBOL(unregister_console);
+static int __init disable_boot_consoles(void)
+{
+ if (console_drivers != NULL) {
+ if (console_drivers->flags & CON_BOOT) {
+ printk(KERN_INFO "turn off boot console %s%d\n",
+ console_drivers->name, console_drivers->index);
+ return unregister_console(console_drivers);
+ }
+ }
+ return 0;
+}
+late_initcall(disable_boot_consoles);
+
/**
* tty_write_message - write a message to a certain tty, not just the console.
* @tty: the destination tty_struct
diff --git a/kernel/profile.c b/kernel/profile.c
index 5b20fe9..cb1e37d 100644
--- a/kernel/profile.c
+++ b/kernel/profile.c
@@ -199,11 +199,11 @@
EXPORT_SYMBOL_GPL(unregister_timer_hook);
EXPORT_SYMBOL_GPL(task_handoff_register);
EXPORT_SYMBOL_GPL(task_handoff_unregister);
+EXPORT_SYMBOL_GPL(profile_event_register);
+EXPORT_SYMBOL_GPL(profile_event_unregister);
#endif /* CONFIG_PROFILING */
-EXPORT_SYMBOL_GPL(profile_event_register);
-EXPORT_SYMBOL_GPL(profile_event_unregister);
#ifdef CONFIG_SMP
/*
diff --git a/kernel/sched.c b/kernel/sched.c
index 72bb948..6798328 100644
--- a/kernel/sched.c
+++ b/kernel/sched.c
@@ -262,7 +262,9 @@
s64 clock_max_delta;
unsigned int clock_warps, clock_overflows;
- unsigned int clock_unstable_events;
+ u64 idle_clock;
+ unsigned int clock_deep_idle_events;
+ u64 tick_timestamp;
atomic_t nr_iowait;
@@ -318,15 +320,19 @@
}
/*
- * Per-runqueue clock, as finegrained as the platform can give us:
+ * Update the per-runqueue clock, as finegrained as the platform can give
+ * us, but without assuming monotonicity, etc.:
*/
-static unsigned long long __rq_clock(struct rq *rq)
+static void __update_rq_clock(struct rq *rq)
{
u64 prev_raw = rq->prev_clock_raw;
u64 now = sched_clock();
s64 delta = now - prev_raw;
u64 clock = rq->clock;
+#ifdef CONFIG_SCHED_DEBUG
+ WARN_ON_ONCE(cpu_of(rq) != smp_processor_id());
+#endif
/*
* Protect against sched_clock() occasionally going backwards:
*/
@@ -337,8 +343,11 @@
/*
* Catch too large forward jumps too:
*/
- if (unlikely(delta > 2*TICK_NSEC)) {
- clock++;
+ if (unlikely(clock + delta > rq->tick_timestamp + TICK_NSEC)) {
+ if (clock < rq->tick_timestamp + TICK_NSEC)
+ clock = rq->tick_timestamp + TICK_NSEC;
+ else
+ clock++;
rq->clock_overflows++;
} else {
if (unlikely(delta > rq->clock_max_delta))
@@ -349,18 +358,12 @@
rq->prev_clock_raw = now;
rq->clock = clock;
-
- return clock;
}
-static inline unsigned long long rq_clock(struct rq *rq)
+static void update_rq_clock(struct rq *rq)
{
- int this_cpu = smp_processor_id();
-
- if (this_cpu == cpu_of(rq))
- return __rq_clock(rq);
-
- return rq->clock;
+ if (likely(smp_processor_id() == cpu_of(rq)))
+ __update_rq_clock(rq);
}
/*
@@ -386,9 +389,12 @@
{
unsigned long long now;
unsigned long flags;
+ struct rq *rq;
local_irq_save(flags);
- now = rq_clock(cpu_rq(cpu));
+ rq = cpu_rq(cpu);
+ update_rq_clock(rq);
+ now = rq->clock;
local_irq_restore(flags);
return now;
@@ -551,18 +557,40 @@
}
/*
- * CPU frequency is/was unstable - start new by setting prev_clock_raw:
+ * We are going deep-idle (irqs are disabled):
*/
-void sched_clock_unstable_event(void)
+void sched_clock_idle_sleep_event(void)
{
- unsigned long flags;
- struct rq *rq;
+ struct rq *rq = cpu_rq(smp_processor_id());
- rq = task_rq_lock(current, &flags);
- rq->prev_clock_raw = sched_clock();
- rq->clock_unstable_events++;
- task_rq_unlock(rq, &flags);
+ spin_lock(&rq->lock);
+ __update_rq_clock(rq);
+ spin_unlock(&rq->lock);
+ rq->clock_deep_idle_events++;
}
+EXPORT_SYMBOL_GPL(sched_clock_idle_sleep_event);
+
+/*
+ * We just idled delta nanoseconds (called with irqs disabled):
+ */
+void sched_clock_idle_wakeup_event(u64 delta_ns)
+{
+ struct rq *rq = cpu_rq(smp_processor_id());
+ u64 now = sched_clock();
+
+ rq->idle_clock += delta_ns;
+ /*
+ * Override the previous timestamp and ignore all
+ * sched_clock() deltas that occured while we idled,
+ * and use the PM-provided delta_ns to advance the
+ * rq clock:
+ */
+ spin_lock(&rq->lock);
+ rq->prev_clock_raw = now;
+ rq->clock += delta_ns;
+ spin_unlock(&rq->lock);
+}
+EXPORT_SYMBOL_GPL(sched_clock_idle_wakeup_event);
/*
* resched_task - mark a task 'to be rescheduled now'.
@@ -637,6 +665,11 @@
#define WMULT_SHIFT 32
+/*
+ * Shift right and round:
+ */
+#define RSR(x, y) (((x) + (1UL << ((y) - 1))) >> (y))
+
static unsigned long
calc_delta_mine(unsigned long delta_exec, unsigned long weight,
struct load_weight *lw)
@@ -644,18 +677,17 @@
u64 tmp;
if (unlikely(!lw->inv_weight))
- lw->inv_weight = WMULT_CONST / lw->weight;
+ lw->inv_weight = (WMULT_CONST - lw->weight/2) / lw->weight + 1;
tmp = (u64)delta_exec * weight;
/*
* Check whether we'd overflow the 64-bit multiplication:
*/
- if (unlikely(tmp > WMULT_CONST)) {
- tmp = ((tmp >> WMULT_SHIFT/2) * lw->inv_weight)
- >> (WMULT_SHIFT/2);
- } else {
- tmp = (tmp * lw->inv_weight) >> WMULT_SHIFT;
- }
+ if (unlikely(tmp > WMULT_CONST))
+ tmp = RSR(RSR(tmp, WMULT_SHIFT/2) * lw->inv_weight,
+ WMULT_SHIFT/2);
+ else
+ tmp = RSR(tmp * lw->inv_weight, WMULT_SHIFT);
return (unsigned long)min(tmp, (u64)(unsigned long)LONG_MAX);
}
@@ -703,11 +735,14 @@
* the relative distance between them is ~25%.)
*/
static const int prio_to_weight[40] = {
-/* -20 */ 88818, 71054, 56843, 45475, 36380, 29104, 23283, 18626, 14901, 11921,
-/* -10 */ 9537, 7629, 6103, 4883, 3906, 3125, 2500, 2000, 1600, 1280,
-/* 0 */ NICE_0_LOAD /* 1024 */,
-/* 1 */ 819, 655, 524, 419, 336, 268, 215, 172, 137,
-/* 10 */ 110, 87, 70, 56, 45, 36, 29, 23, 18, 15,
+ /* -20 */ 88761, 71755, 56483, 46273, 36291,
+ /* -15 */ 29154, 23254, 18705, 14949, 11916,
+ /* -10 */ 9548, 7620, 6100, 4904, 3906,
+ /* -5 */ 3121, 2501, 1991, 1586, 1277,
+ /* 0 */ 1024, 820, 655, 526, 423,
+ /* 5 */ 335, 272, 215, 172, 137,
+ /* 10 */ 110, 87, 70, 56, 45,
+ /* 15 */ 36, 29, 23, 18, 15,
};
/*
@@ -718,14 +753,14 @@
* into multiplications:
*/
static const u32 prio_to_wmult[40] = {
-/* -20 */ 48356, 60446, 75558, 94446, 118058,
-/* -15 */ 147573, 184467, 230589, 288233, 360285,
-/* -10 */ 450347, 562979, 703746, 879575, 1099582,
-/* -5 */ 1374389, 1717986, 2147483, 2684354, 3355443,
-/* 0 */ 4194304, 5244160, 6557201, 8196502, 10250518,
-/* 5 */ 12782640, 16025997, 19976592, 24970740, 31350126,
-/* 10 */ 39045157, 49367440, 61356675, 76695844, 95443717,
-/* 15 */ 119304647, 148102320, 186737708, 238609294, 286331153,
+ /* -20 */ 48388, 59856, 76040, 92818, 118348,
+ /* -15 */ 147320, 184698, 229616, 287308, 360437,
+ /* -10 */ 449829, 563644, 704093, 875809, 1099582,
+ /* -5 */ 1376151, 1717300, 2157191, 2708050, 3363326,
+ /* 0 */ 4194304, 5237765, 6557202, 8165337, 10153587,
+ /* 5 */ 12820798, 15790321, 19976592, 24970740, 31350126,
+ /* 10 */ 39045157, 49367440, 61356676, 76695844, 95443717,
+ /* 15 */ 119304647, 148102320, 186737708, 238609294, 286331153,
};
static void activate_task(struct rq *rq, struct task_struct *p, int wakeup);
@@ -745,8 +780,7 @@
unsigned long max_nr_move, unsigned long max_load_move,
struct sched_domain *sd, enum cpu_idle_type idle,
int *all_pinned, unsigned long *load_moved,
- int this_best_prio, int best_prio, int best_prio_seen,
- struct rq_iterator *iterator);
+ int *this_best_prio, struct rq_iterator *iterator);
#include "sched_stats.h"
#include "sched_rt.c"
@@ -782,14 +816,14 @@
* This function is called /before/ updating rq->ls.load
* and when switching tasks.
*/
-static void update_curr_load(struct rq *rq, u64 now)
+static void update_curr_load(struct rq *rq)
{
struct load_stat *ls = &rq->ls;
u64 start;
start = ls->load_update_start;
- ls->load_update_start = now;
- ls->delta_stat += now - start;
+ ls->load_update_start = rq->clock;
+ ls->delta_stat += rq->clock - start;
/*
* Stagger updates to ls->delta_fair. Very frequent updates
* can be expensive.
@@ -798,30 +832,28 @@
__update_curr_load(rq, ls);
}
-static inline void
-inc_load(struct rq *rq, const struct task_struct *p, u64 now)
+static inline void inc_load(struct rq *rq, const struct task_struct *p)
{
- update_curr_load(rq, now);
+ update_curr_load(rq);
update_load_add(&rq->ls.load, p->se.load.weight);
}
-static inline void
-dec_load(struct rq *rq, const struct task_struct *p, u64 now)
+static inline void dec_load(struct rq *rq, const struct task_struct *p)
{
- update_curr_load(rq, now);
+ update_curr_load(rq);
update_load_sub(&rq->ls.load, p->se.load.weight);
}
-static void inc_nr_running(struct task_struct *p, struct rq *rq, u64 now)
+static void inc_nr_running(struct task_struct *p, struct rq *rq)
{
rq->nr_running++;
- inc_load(rq, p, now);
+ inc_load(rq, p);
}
-static void dec_nr_running(struct task_struct *p, struct rq *rq, u64 now)
+static void dec_nr_running(struct task_struct *p, struct rq *rq)
{
rq->nr_running--;
- dec_load(rq, p, now);
+ dec_load(rq, p);
}
static void set_load_weight(struct task_struct *p)
@@ -848,18 +880,16 @@
p->se.load.inv_weight = prio_to_wmult[p->static_prio - MAX_RT_PRIO];
}
-static void
-enqueue_task(struct rq *rq, struct task_struct *p, int wakeup, u64 now)
+static void enqueue_task(struct rq *rq, struct task_struct *p, int wakeup)
{
sched_info_queued(p);
- p->sched_class->enqueue_task(rq, p, wakeup, now);
+ p->sched_class->enqueue_task(rq, p, wakeup);
p->se.on_rq = 1;
}
-static void
-dequeue_task(struct rq *rq, struct task_struct *p, int sleep, u64 now)
+static void dequeue_task(struct rq *rq, struct task_struct *p, int sleep)
{
- p->sched_class->dequeue_task(rq, p, sleep, now);
+ p->sched_class->dequeue_task(rq, p, sleep);
p->se.on_rq = 0;
}
@@ -914,13 +944,11 @@
*/
static void activate_task(struct rq *rq, struct task_struct *p, int wakeup)
{
- u64 now = rq_clock(rq);
-
if (p->state == TASK_UNINTERRUPTIBLE)
rq->nr_uninterruptible--;
- enqueue_task(rq, p, wakeup, now);
- inc_nr_running(p, rq, now);
+ enqueue_task(rq, p, wakeup);
+ inc_nr_running(p, rq);
}
/*
@@ -928,13 +956,13 @@
*/
static inline void activate_idle_task(struct task_struct *p, struct rq *rq)
{
- u64 now = rq_clock(rq);
+ update_rq_clock(rq);
if (p->state == TASK_UNINTERRUPTIBLE)
rq->nr_uninterruptible--;
- enqueue_task(rq, p, 0, now);
- inc_nr_running(p, rq, now);
+ enqueue_task(rq, p, 0);
+ inc_nr_running(p, rq);
}
/*
@@ -942,13 +970,11 @@
*/
static void deactivate_task(struct rq *rq, struct task_struct *p, int sleep)
{
- u64 now = rq_clock(rq);
-
if (p->state == TASK_UNINTERRUPTIBLE)
rq->nr_uninterruptible++;
- dequeue_task(rq, p, sleep, now);
- dec_nr_running(p, rq, now);
+ dequeue_task(rq, p, sleep);
+ dec_nr_running(p, rq);
}
/**
@@ -1516,6 +1542,7 @@
out_activate:
#endif /* CONFIG_SMP */
+ update_rq_clock(rq);
activate_task(rq, p, 1);
/*
* Sync wakeups (i.e. those types of wakeups where the waker
@@ -1647,12 +1674,11 @@
unsigned long flags;
struct rq *rq;
int this_cpu;
- u64 now;
rq = task_rq_lock(p, &flags);
BUG_ON(p->state != TASK_RUNNING);
this_cpu = smp_processor_id(); /* parent's CPU */
- now = rq_clock(rq);
+ update_rq_clock(rq);
p->prio = effective_prio(p);
@@ -1666,8 +1692,8 @@
* Let the scheduling class do new task startup
* management (if any):
*/
- p->sched_class->task_new(rq, p, now);
- inc_nr_running(p, rq, now);
+ p->sched_class->task_new(rq, p);
+ inc_nr_running(p, rq);
}
check_preempt_curr(rq, p);
task_rq_unlock(rq, &flags);
@@ -1954,7 +1980,6 @@
unsigned long total_load = this_rq->ls.load.weight;
unsigned long this_load = total_load;
struct load_stat *ls = &this_rq->ls;
- u64 now = __rq_clock(this_rq);
int i, scale;
this_rq->nr_load_updates++;
@@ -1962,7 +1987,7 @@
goto do_avg;
/* Update delta_fair/delta_exec fields first */
- update_curr_load(this_rq, now);
+ update_curr_load(this_rq);
fair_delta64 = ls->delta_fair + 1;
ls->delta_fair = 0;
@@ -1970,8 +1995,8 @@
exec_delta64 = ls->delta_exec + 1;
ls->delta_exec = 0;
- sample_interval64 = now - ls->load_update_last;
- ls->load_update_last = now;
+ sample_interval64 = this_rq->clock - ls->load_update_last;
+ ls->load_update_last = this_rq->clock;
if ((s64)sample_interval64 < (s64)TICK_NSEC)
sample_interval64 = TICK_NSEC;
@@ -2026,6 +2051,8 @@
spin_lock(&rq1->lock);
}
}
+ update_rq_clock(rq1);
+ update_rq_clock(rq2);
}
/*
@@ -2153,12 +2180,6 @@
if (task_running(rq, p))
return 0;
- /*
- * Aggressive migration if too many balance attempts have failed:
- */
- if (sd->nr_balance_failed > sd->cache_nice_tries)
- return 1;
-
return 1;
}
@@ -2166,8 +2187,7 @@
unsigned long max_nr_move, unsigned long max_load_move,
struct sched_domain *sd, enum cpu_idle_type idle,
int *all_pinned, unsigned long *load_moved,
- int this_best_prio, int best_prio, int best_prio_seen,
- struct rq_iterator *iterator)
+ int *this_best_prio, struct rq_iterator *iterator)
{
int pulled = 0, pinned = 0, skip_for_load;
struct task_struct *p;
@@ -2192,12 +2212,8 @@
*/
skip_for_load = (p->se.load.weight >> 1) > rem_load_move +
SCHED_LOAD_SCALE_FUZZ;
- if (skip_for_load && p->prio < this_best_prio)
- skip_for_load = !best_prio_seen && p->prio == best_prio;
- if (skip_for_load ||
+ if ((skip_for_load && p->prio >= *this_best_prio) ||
!can_migrate_task(p, busiest, this_cpu, sd, idle, &pinned)) {
-
- best_prio_seen |= p->prio == best_prio;
p = iterator->next(iterator->arg);
goto next;
}
@@ -2211,8 +2227,8 @@
* and the prescribed amount of weighted load.
*/
if (pulled < max_nr_move && rem_load_move > 0) {
- if (p->prio < this_best_prio)
- this_best_prio = p->prio;
+ if (p->prio < *this_best_prio)
+ *this_best_prio = p->prio;
p = iterator->next(iterator->arg);
goto next;
}
@@ -2231,32 +2247,52 @@
}
/*
- * move_tasks tries to move up to max_nr_move tasks and max_load_move weighted
- * load from busiest to this_rq, as part of a balancing operation within
- * "domain". Returns the number of tasks moved.
+ * move_tasks tries to move up to max_load_move weighted load from busiest to
+ * this_rq, as part of a balancing operation within domain "sd".
+ * Returns 1 if successful and 0 otherwise.
*
* Called with both runqueues locked.
*/
static int move_tasks(struct rq *this_rq, int this_cpu, struct rq *busiest,
- unsigned long max_nr_move, unsigned long max_load_move,
+ unsigned long max_load_move,
struct sched_domain *sd, enum cpu_idle_type idle,
int *all_pinned)
{
struct sched_class *class = sched_class_highest;
- unsigned long load_moved, total_nr_moved = 0, nr_moved;
- long rem_load_move = max_load_move;
+ unsigned long total_load_moved = 0;
+ int this_best_prio = this_rq->curr->prio;
do {
- nr_moved = class->load_balance(this_rq, this_cpu, busiest,
- max_nr_move, (unsigned long)rem_load_move,
- sd, idle, all_pinned, &load_moved);
- total_nr_moved += nr_moved;
- max_nr_move -= nr_moved;
- rem_load_move -= load_moved;
+ total_load_moved +=
+ class->load_balance(this_rq, this_cpu, busiest,
+ ULONG_MAX, max_load_move - total_load_moved,
+ sd, idle, all_pinned, &this_best_prio);
class = class->next;
- } while (class && max_nr_move && rem_load_move > 0);
+ } while (class && max_load_move > total_load_moved);
- return total_nr_moved;
+ return total_load_moved > 0;
+}
+
+/*
+ * move_one_task tries to move exactly one task from busiest to this_rq, as
+ * part of active balancing operations within "domain".
+ * Returns 1 if successful and 0 otherwise.
+ *
+ * Called with both runqueues locked.
+ */
+static int move_one_task(struct rq *this_rq, int this_cpu, struct rq *busiest,
+ struct sched_domain *sd, enum cpu_idle_type idle)
+{
+ struct sched_class *class;
+ int this_best_prio = MAX_PRIO;
+
+ for (class = sched_class_highest; class; class = class->next)
+ if (class->load_balance(this_rq, this_cpu, busiest,
+ 1, ULONG_MAX, sd, idle, NULL,
+ &this_best_prio))
+ return 1;
+
+ return 0;
}
/*
@@ -2475,7 +2511,7 @@
* a think about bumping its value to force at least one task to be
* moved
*/
- if (*imbalance + SCHED_LOAD_SCALE_FUZZ < busiest_load_per_task/2) {
+ if (*imbalance + SCHED_LOAD_SCALE_FUZZ < busiest_load_per_task) {
unsigned long tmp, pwr_now, pwr_move;
unsigned int imbn;
@@ -2588,11 +2624,6 @@
*/
#define MAX_PINNED_INTERVAL 512
-static inline unsigned long minus_1_or_zero(unsigned long n)
-{
- return n > 0 ? n - 1 : 0;
-}
-
/*
* Check this_cpu to ensure it is balanced within domain. Attempt to move
* tasks if there is an imbalance.
@@ -2601,7 +2632,7 @@
struct sched_domain *sd, enum cpu_idle_type idle,
int *balance)
{
- int nr_moved, all_pinned = 0, active_balance = 0, sd_idle = 0;
+ int ld_moved, all_pinned = 0, active_balance = 0, sd_idle = 0;
struct sched_group *group;
unsigned long imbalance;
struct rq *busiest;
@@ -2642,18 +2673,17 @@
schedstat_add(sd, lb_imbalance[idle], imbalance);
- nr_moved = 0;
+ ld_moved = 0;
if (busiest->nr_running > 1) {
/*
* Attempt to move tasks. If find_busiest_group has found
* an imbalance but busiest->nr_running <= 1, the group is
- * still unbalanced. nr_moved simply stays zero, so it is
+ * still unbalanced. ld_moved simply stays zero, so it is
* correctly treated as an imbalance.
*/
local_irq_save(flags);
double_rq_lock(this_rq, busiest);
- nr_moved = move_tasks(this_rq, this_cpu, busiest,
- minus_1_or_zero(busiest->nr_running),
+ ld_moved = move_tasks(this_rq, this_cpu, busiest,
imbalance, sd, idle, &all_pinned);
double_rq_unlock(this_rq, busiest);
local_irq_restore(flags);
@@ -2661,7 +2691,7 @@
/*
* some other cpu did the load balance for us.
*/
- if (nr_moved && this_cpu != smp_processor_id())
+ if (ld_moved && this_cpu != smp_processor_id())
resched_cpu(this_cpu);
/* All tasks on this runqueue were pinned by CPU affinity */
@@ -2673,7 +2703,7 @@
}
}
- if (!nr_moved) {
+ if (!ld_moved) {
schedstat_inc(sd, lb_failed[idle]);
sd->nr_balance_failed++;
@@ -2722,10 +2752,10 @@
sd->balance_interval *= 2;
}
- if (!nr_moved && !sd_idle && sd->flags & SD_SHARE_CPUPOWER &&
+ if (!ld_moved && !sd_idle && sd->flags & SD_SHARE_CPUPOWER &&
!test_sd_parent(sd, SD_POWERSAVINGS_BALANCE))
return -1;
- return nr_moved;
+ return ld_moved;
out_balanced:
schedstat_inc(sd, lb_balanced[idle]);
@@ -2757,7 +2787,7 @@
struct sched_group *group;
struct rq *busiest = NULL;
unsigned long imbalance;
- int nr_moved = 0;
+ int ld_moved = 0;
int sd_idle = 0;
int all_pinned = 0;
cpumask_t cpus = CPU_MASK_ALL;
@@ -2792,12 +2822,13 @@
schedstat_add(sd, lb_imbalance[CPU_NEWLY_IDLE], imbalance);
- nr_moved = 0;
+ ld_moved = 0;
if (busiest->nr_running > 1) {
/* Attempt to move tasks */
double_lock_balance(this_rq, busiest);
- nr_moved = move_tasks(this_rq, this_cpu, busiest,
- minus_1_or_zero(busiest->nr_running),
+ /* this_rq->clock is already updated */
+ update_rq_clock(busiest);
+ ld_moved = move_tasks(this_rq, this_cpu, busiest,
imbalance, sd, CPU_NEWLY_IDLE,
&all_pinned);
spin_unlock(&busiest->lock);
@@ -2809,7 +2840,7 @@
}
}
- if (!nr_moved) {
+ if (!ld_moved) {
schedstat_inc(sd, lb_failed[CPU_NEWLY_IDLE]);
if (!sd_idle && sd->flags & SD_SHARE_CPUPOWER &&
!test_sd_parent(sd, SD_POWERSAVINGS_BALANCE))
@@ -2817,7 +2848,7 @@
} else
sd->nr_balance_failed = 0;
- return nr_moved;
+ return ld_moved;
out_balanced:
schedstat_inc(sd, lb_balanced[CPU_NEWLY_IDLE]);
@@ -2894,6 +2925,8 @@
/* move a task from busiest_rq to target_rq */
double_lock_balance(busiest_rq, target_rq);
+ update_rq_clock(busiest_rq);
+ update_rq_clock(target_rq);
/* Search for an sd spanning us and the target CPU. */
for_each_domain(target_cpu, sd) {
@@ -2905,8 +2938,8 @@
if (likely(sd)) {
schedstat_inc(sd, alb_cnt);
- if (move_tasks(target_rq, target_cpu, busiest_rq, 1,
- ULONG_MAX, sd, CPU_IDLE, NULL))
+ if (move_one_task(target_rq, target_cpu, busiest_rq,
+ sd, CPU_IDLE))
schedstat_inc(sd, alb_pushed);
else
schedstat_inc(sd, alb_failed);
@@ -3004,6 +3037,7 @@
struct sched_domain *sd;
/* Earliest time when we have to do rebalance again */
unsigned long next_balance = jiffies + 60*HZ;
+ int update_next_balance = 0;
for_each_domain(cpu, sd) {
if (!(sd->flags & SD_LOAD_BALANCE))
@@ -3040,8 +3074,10 @@
if (sd->flags & SD_SERIALIZE)
spin_unlock(&balancing);
out:
- if (time_after(next_balance, sd->last_balance + interval))
+ if (time_after(next_balance, sd->last_balance + interval)) {
next_balance = sd->last_balance + interval;
+ update_next_balance = 1;
+ }
/*
* Stop the load balance at this level. There is another
@@ -3051,7 +3087,14 @@
if (!balance)
break;
}
- rq->next_balance = next_balance;
+
+ /*
+ * next_balance will be updated only when there is a need.
+ * When the cpu is attached to null domain for ex, it will not be
+ * updated.
+ */
+ if (likely(update_next_balance))
+ rq->next_balance = next_balance;
}
/*
@@ -3090,7 +3133,7 @@
if (need_resched())
break;
- rebalance_domains(balance_cpu, SCHED_IDLE);
+ rebalance_domains(balance_cpu, CPU_IDLE);
rq = cpu_rq(balance_cpu);
if (time_after(this_rq->next_balance, rq->next_balance))
@@ -3175,8 +3218,7 @@
unsigned long max_nr_move, unsigned long max_load_move,
struct sched_domain *sd, enum cpu_idle_type idle,
int *all_pinned, unsigned long *load_moved,
- int this_best_prio, int best_prio, int best_prio_seen,
- struct rq_iterator *iterator)
+ int *this_best_prio, struct rq_iterator *iterator)
{
*load_moved = 0;
@@ -3202,7 +3244,8 @@
rq = task_rq_lock(p, &flags);
ns = p->se.sum_exec_runtime;
if (rq->curr == p) {
- delta_exec = rq_clock(rq) - p->se.exec_start;
+ update_rq_clock(rq);
+ delta_exec = rq->clock - p->se.exec_start;
if ((s64)delta_exec > 0)
ns += delta_exec;
}
@@ -3296,11 +3339,19 @@
int cpu = smp_processor_id();
struct rq *rq = cpu_rq(cpu);
struct task_struct *curr = rq->curr;
+ u64 next_tick = rq->tick_timestamp + TICK_NSEC;
spin_lock(&rq->lock);
+ __update_rq_clock(rq);
+ /*
+ * Let rq->clock advance by at least TICK_NSEC:
+ */
+ if (unlikely(rq->clock < next_tick))
+ rq->clock = next_tick;
+ rq->tick_timestamp = rq->clock;
+ update_cpu_load(rq);
if (curr != rq->idle) /* FIXME: needed? */
curr->sched_class->task_tick(rq, curr);
- update_cpu_load(rq);
spin_unlock(&rq->lock);
#ifdef CONFIG_SMP
@@ -3382,7 +3433,7 @@
* Pick up the highest-prio task:
*/
static inline struct task_struct *
-pick_next_task(struct rq *rq, struct task_struct *prev, u64 now)
+pick_next_task(struct rq *rq, struct task_struct *prev)
{
struct sched_class *class;
struct task_struct *p;
@@ -3392,14 +3443,14 @@
* the fair class we can call that function directly:
*/
if (likely(rq->nr_running == rq->cfs.nr_running)) {
- p = fair_sched_class.pick_next_task(rq, now);
+ p = fair_sched_class.pick_next_task(rq);
if (likely(p))
return p;
}
class = sched_class_highest;
for ( ; ; ) {
- p = class->pick_next_task(rq, now);
+ p = class->pick_next_task(rq);
if (p)
return p;
/*
@@ -3418,7 +3469,6 @@
struct task_struct *prev, *next;
long *switch_count;
struct rq *rq;
- u64 now;
int cpu;
need_resched:
@@ -3436,6 +3486,7 @@
spin_lock_irq(&rq->lock);
clear_tsk_need_resched(prev);
+ __update_rq_clock(rq);
if (prev->state && !(preempt_count() & PREEMPT_ACTIVE)) {
if (unlikely((prev->state & TASK_INTERRUPTIBLE) &&
@@ -3450,9 +3501,8 @@
if (unlikely(!rq->nr_running))
idle_balance(cpu, rq);
- now = __rq_clock(rq);
- prev->sched_class->put_prev_task(rq, prev, now);
- next = pick_next_task(rq, prev, now);
+ prev->sched_class->put_prev_task(rq, prev);
+ next = pick_next_task(rq, prev);
sched_info_switch(prev, next);
@@ -3895,17 +3945,16 @@
unsigned long flags;
int oldprio, on_rq;
struct rq *rq;
- u64 now;
BUG_ON(prio < 0 || prio > MAX_PRIO);
rq = task_rq_lock(p, &flags);
- now = rq_clock(rq);
+ update_rq_clock(rq);
oldprio = p->prio;
on_rq = p->se.on_rq;
if (on_rq)
- dequeue_task(rq, p, 0, now);
+ dequeue_task(rq, p, 0);
if (rt_prio(prio))
p->sched_class = &rt_sched_class;
@@ -3915,7 +3964,7 @@
p->prio = prio;
if (on_rq) {
- enqueue_task(rq, p, 0, now);
+ enqueue_task(rq, p, 0);
/*
* Reschedule if we are currently running on this runqueue and
* our priority decreased, or if we are not currently running on
@@ -3938,7 +3987,6 @@
int old_prio, delta, on_rq;
unsigned long flags;
struct rq *rq;
- u64 now;
if (TASK_NICE(p) == nice || nice < -20 || nice > 19)
return;
@@ -3947,7 +3995,7 @@
* the task might be in the middle of scheduling on another CPU.
*/
rq = task_rq_lock(p, &flags);
- now = rq_clock(rq);
+ update_rq_clock(rq);
/*
* The RT priorities are set via sched_setscheduler(), but we still
* allow the 'normal' nice value to be set - but as expected
@@ -3960,8 +4008,8 @@
}
on_rq = p->se.on_rq;
if (on_rq) {
- dequeue_task(rq, p, 0, now);
- dec_load(rq, p, now);
+ dequeue_task(rq, p, 0);
+ dec_load(rq, p);
}
p->static_prio = NICE_TO_PRIO(nice);
@@ -3971,8 +4019,8 @@
delta = p->prio - old_prio;
if (on_rq) {
- enqueue_task(rq, p, 0, now);
- inc_load(rq, p, now);
+ enqueue_task(rq, p, 0);
+ inc_load(rq, p);
/*
* If the task increased its priority or is running and
* lowered its priority, then reschedule its CPU:
@@ -4208,6 +4256,7 @@
spin_unlock_irqrestore(&p->pi_lock, flags);
goto recheck;
}
+ update_rq_clock(rq);
on_rq = p->se.on_rq;
if (on_rq)
deactivate_task(rq, p, 0);
@@ -4463,10 +4512,8 @@
out_unlock:
read_unlock(&tasklist_lock);
mutex_unlock(&sched_hotcpu_mutex);
- if (retval)
- return retval;
- return 0;
+ return retval;
}
/**
@@ -4870,7 +4917,7 @@
if (sysctl_sched_granularity > gran_limit)
sysctl_sched_granularity = gran_limit;
- sysctl_sched_runtime_limit = sysctl_sched_granularity * 4;
+ sysctl_sched_runtime_limit = sysctl_sched_granularity * 5;
sysctl_sched_wakeup_granularity = sysctl_sched_granularity / 2;
}
@@ -4966,6 +5013,7 @@
on_rq = p->se.on_rq;
if (on_rq)
deactivate_task(rq_src, p, 0);
+
set_task_cpu(p, dest_cpu);
if (on_rq) {
activate_task(rq_dest, p, 0);
@@ -5198,7 +5246,8 @@
for ( ; ; ) {
if (!rq->nr_running)
break;
- next = pick_next_task(rq, rq->curr, rq_clock(rq));
+ update_rq_clock(rq);
+ next = pick_next_task(rq, rq->curr);
if (!next)
break;
migrate_dead(dead_cpu, next);
@@ -5210,12 +5259,20 @@
#if defined(CONFIG_SCHED_DEBUG) && defined(CONFIG_SYSCTL)
static struct ctl_table sd_ctl_dir[] = {
- {CTL_UNNUMBERED, "sched_domain", NULL, 0, 0755, NULL, },
+ {
+ .procname = "sched_domain",
+ .mode = 0555,
+ },
{0,},
};
static struct ctl_table sd_ctl_root[] = {
- {CTL_UNNUMBERED, "kernel", NULL, 0, 0755, sd_ctl_dir, },
+ {
+ .ctl_name = CTL_KERN,
+ .procname = "kernel",
+ .mode = 0555,
+ .child = sd_ctl_dir,
+ },
{0,},
};
@@ -5231,11 +5288,10 @@
}
static void
-set_table_entry(struct ctl_table *entry, int ctl_name,
+set_table_entry(struct ctl_table *entry,
const char *procname, void *data, int maxlen,
mode_t mode, proc_handler *proc_handler)
{
- entry->ctl_name = ctl_name;
entry->procname = procname;
entry->data = data;
entry->maxlen = maxlen;
@@ -5248,28 +5304,28 @@
{
struct ctl_table *table = sd_alloc_ctl_entry(14);
- set_table_entry(&table[0], 1, "min_interval", &sd->min_interval,
+ set_table_entry(&table[0], "min_interval", &sd->min_interval,
sizeof(long), 0644, proc_doulongvec_minmax);
- set_table_entry(&table[1], 2, "max_interval", &sd->max_interval,
+ set_table_entry(&table[1], "max_interval", &sd->max_interval,
sizeof(long), 0644, proc_doulongvec_minmax);
- set_table_entry(&table[2], 3, "busy_idx", &sd->busy_idx,
+ set_table_entry(&table[2], "busy_idx", &sd->busy_idx,
sizeof(int), 0644, proc_dointvec_minmax);
- set_table_entry(&table[3], 4, "idle_idx", &sd->idle_idx,
+ set_table_entry(&table[3], "idle_idx", &sd->idle_idx,
sizeof(int), 0644, proc_dointvec_minmax);
- set_table_entry(&table[4], 5, "newidle_idx", &sd->newidle_idx,
+ set_table_entry(&table[4], "newidle_idx", &sd->newidle_idx,
sizeof(int), 0644, proc_dointvec_minmax);
- set_table_entry(&table[5], 6, "wake_idx", &sd->wake_idx,
+ set_table_entry(&table[5], "wake_idx", &sd->wake_idx,
sizeof(int), 0644, proc_dointvec_minmax);
- set_table_entry(&table[6], 7, "forkexec_idx", &sd->forkexec_idx,
+ set_table_entry(&table[6], "forkexec_idx", &sd->forkexec_idx,
sizeof(int), 0644, proc_dointvec_minmax);
- set_table_entry(&table[7], 8, "busy_factor", &sd->busy_factor,
+ set_table_entry(&table[7], "busy_factor", &sd->busy_factor,
sizeof(int), 0644, proc_dointvec_minmax);
- set_table_entry(&table[8], 9, "imbalance_pct", &sd->imbalance_pct,
+ set_table_entry(&table[8], "imbalance_pct", &sd->imbalance_pct,
sizeof(int), 0644, proc_dointvec_minmax);
- set_table_entry(&table[10], 11, "cache_nice_tries",
+ set_table_entry(&table[10], "cache_nice_tries",
&sd->cache_nice_tries,
sizeof(int), 0644, proc_dointvec_minmax);
- set_table_entry(&table[12], 13, "flags", &sd->flags,
+ set_table_entry(&table[12], "flags", &sd->flags,
sizeof(int), 0644, proc_dointvec_minmax);
return table;
@@ -5289,9 +5345,8 @@
i = 0;
for_each_domain(cpu, sd) {
snprintf(buf, 32, "domain%d", i);
- entry->ctl_name = i + 1;
entry->procname = kstrdup(buf, GFP_KERNEL);
- entry->mode = 0755;
+ entry->mode = 0555;
entry->child = sd_alloc_ctl_domain_table(sd);
entry++;
i++;
@@ -5310,9 +5365,8 @@
for (i = 0; i < cpu_num; i++, entry++) {
snprintf(buf, 32, "cpu%d", i);
- entry->ctl_name = i + 1;
entry->procname = kstrdup(buf, GFP_KERNEL);
- entry->mode = 0755;
+ entry->mode = 0555;
entry->child = sd_alloc_ctl_cpu_table(i);
}
sd_sysctl_header = register_sysctl_table(sd_ctl_root);
@@ -5379,6 +5433,7 @@
rq->migration_thread = NULL;
/* Idle task back to normal (off runqueue, low prio) */
rq = task_rq_lock(rq->idle, &flags);
+ update_rq_clock(rq);
deactivate_task(rq, rq->idle, 0);
rq->idle->static_prio = MAX_PRIO;
__setscheduler(rq, rq->idle, SCHED_NORMAL, 0);
@@ -6301,7 +6356,7 @@
}
#if defined(CONFIG_SCHED_MC) || defined(CONFIG_SCHED_SMT)
-int arch_reinit_sched_domains(void)
+static int arch_reinit_sched_domains(void)
{
int err;
@@ -6330,6 +6385,34 @@
return ret ? ret : count;
}
+#ifdef CONFIG_SCHED_MC
+static ssize_t sched_mc_power_savings_show(struct sys_device *dev, char *page)
+{
+ return sprintf(page, "%u\n", sched_mc_power_savings);
+}
+static ssize_t sched_mc_power_savings_store(struct sys_device *dev,
+ const char *buf, size_t count)
+{
+ return sched_power_savings_store(buf, count, 0);
+}
+static SYSDEV_ATTR(sched_mc_power_savings, 0644, sched_mc_power_savings_show,
+ sched_mc_power_savings_store);
+#endif
+
+#ifdef CONFIG_SCHED_SMT
+static ssize_t sched_smt_power_savings_show(struct sys_device *dev, char *page)
+{
+ return sprintf(page, "%u\n", sched_smt_power_savings);
+}
+static ssize_t sched_smt_power_savings_store(struct sys_device *dev,
+ const char *buf, size_t count)
+{
+ return sched_power_savings_store(buf, count, 1);
+}
+static SYSDEV_ATTR(sched_smt_power_savings, 0644, sched_smt_power_savings_show,
+ sched_smt_power_savings_store);
+#endif
+
int sched_create_sysfs_power_savings_entries(struct sysdev_class *cls)
{
int err = 0;
@@ -6348,34 +6431,6 @@
}
#endif
-#ifdef CONFIG_SCHED_MC
-static ssize_t sched_mc_power_savings_show(struct sys_device *dev, char *page)
-{
- return sprintf(page, "%u\n", sched_mc_power_savings);
-}
-static ssize_t sched_mc_power_savings_store(struct sys_device *dev,
- const char *buf, size_t count)
-{
- return sched_power_savings_store(buf, count, 0);
-}
-SYSDEV_ATTR(sched_mc_power_savings, 0644, sched_mc_power_savings_show,
- sched_mc_power_savings_store);
-#endif
-
-#ifdef CONFIG_SCHED_SMT
-static ssize_t sched_smt_power_savings_show(struct sys_device *dev, char *page)
-{
- return sprintf(page, "%u\n", sched_smt_power_savings);
-}
-static ssize_t sched_smt_power_savings_store(struct sys_device *dev,
- const char *buf, size_t count)
-{
- return sched_power_savings_store(buf, count, 1);
-}
-SYSDEV_ATTR(sched_smt_power_savings, 0644, sched_smt_power_savings_show,
- sched_smt_power_savings_store);
-#endif
-
/*
* Force a reinitialization of the sched domains hierarchy. The domains
* and groups cannot be updated in place without racing with the balancing
@@ -6616,12 +6671,13 @@
goto out_unlock;
#endif
+ update_rq_clock(rq);
on_rq = p->se.on_rq;
if (on_rq)
- deactivate_task(task_rq(p), p, 0);
+ deactivate_task(rq, p, 0);
__setscheduler(rq, p, SCHED_NORMAL, 0);
if (on_rq) {
- activate_task(task_rq(p), p, 0);
+ activate_task(rq, p, 0);
resched_task(rq->curr);
}
#ifdef CONFIG_SMP
diff --git a/kernel/sched_debug.c b/kernel/sched_debug.c
index 1c61e53..ab18f45 100644
--- a/kernel/sched_debug.c
+++ b/kernel/sched_debug.c
@@ -29,34 +29,34 @@
} while (0)
static void
-print_task(struct seq_file *m, struct rq *rq, struct task_struct *p, u64 now)
+print_task(struct seq_file *m, struct rq *rq, struct task_struct *p)
{
if (rq->curr == p)
SEQ_printf(m, "R");
else
SEQ_printf(m, " ");
- SEQ_printf(m, "%15s %5d %15Ld %13Ld %13Ld %9Ld %5d "
- "%15Ld %15Ld %15Ld %15Ld %15Ld\n",
+ SEQ_printf(m, "%15s %5d %15Ld %13Ld %13Ld %9Ld %5d ",
p->comm, p->pid,
(long long)p->se.fair_key,
(long long)(p->se.fair_key - rq->cfs.fair_clock),
(long long)p->se.wait_runtime,
(long long)(p->nvcsw + p->nivcsw),
- p->prio,
+ p->prio);
#ifdef CONFIG_SCHEDSTATS
+ SEQ_printf(m, "%15Ld %15Ld %15Ld %15Ld %15Ld\n",
(long long)p->se.sum_exec_runtime,
(long long)p->se.sum_wait_runtime,
(long long)p->se.sum_sleep_runtime,
(long long)p->se.wait_runtime_overruns,
- (long long)p->se.wait_runtime_underruns
+ (long long)p->se.wait_runtime_underruns);
#else
- 0LL, 0LL, 0LL, 0LL, 0LL
+ SEQ_printf(m, "%15Ld %15Ld %15Ld %15Ld %15Ld\n",
+ 0LL, 0LL, 0LL, 0LL, 0LL);
#endif
- );
}
-static void print_rq(struct seq_file *m, struct rq *rq, int rq_cpu, u64 now)
+static void print_rq(struct seq_file *m, struct rq *rq, int rq_cpu)
{
struct task_struct *g, *p;
@@ -77,7 +77,7 @@
if (!p->se.on_rq || task_cpu(p) != rq_cpu)
continue;
- print_task(m, rq, p, now);
+ print_task(m, rq, p);
} while_each_thread(g, p);
read_unlock_irq(&tasklist_lock);
@@ -106,9 +106,9 @@
(long long)wait_runtime_rq_sum);
}
-void print_cfs_rq(struct seq_file *m, int cpu, struct cfs_rq *cfs_rq, u64 now)
+void print_cfs_rq(struct seq_file *m, int cpu, struct cfs_rq *cfs_rq)
{
- SEQ_printf(m, "\ncfs_rq %p\n", cfs_rq);
+ SEQ_printf(m, "\ncfs_rq\n");
#define P(x) \
SEQ_printf(m, " .%-30s: %Ld\n", #x, (long long)(cfs_rq->x))
@@ -124,7 +124,7 @@
print_cfs_rq_runtime_sum(m, cpu, cfs_rq);
}
-static void print_cpu(struct seq_file *m, int cpu, u64 now)
+static void print_cpu(struct seq_file *m, int cpu)
{
struct rq *rq = &per_cpu(runqueues, cpu);
@@ -154,10 +154,11 @@
P(next_balance);
P(curr->pid);
P(clock);
+ P(idle_clock);
P(prev_clock_raw);
P(clock_warps);
P(clock_overflows);
- P(clock_unstable_events);
+ P(clock_deep_idle_events);
P(clock_max_delta);
P(cpu_load[0]);
P(cpu_load[1]);
@@ -166,9 +167,9 @@
P(cpu_load[4]);
#undef P
- print_cfs_stats(m, cpu, now);
+ print_cfs_stats(m, cpu);
- print_rq(m, rq, cpu, now);
+ print_rq(m, rq, cpu);
}
static int sched_debug_show(struct seq_file *m, void *v)
@@ -184,7 +185,7 @@
SEQ_printf(m, "now at %Lu nsecs\n", (unsigned long long)now);
for_each_online_cpu(cpu)
- print_cpu(m, cpu, now);
+ print_cpu(m, cpu);
SEQ_printf(m, "\n");
diff --git a/kernel/sched_fair.c b/kernel/sched_fair.c
index 6f579ff..4d6b7e2 100644
--- a/kernel/sched_fair.c
+++ b/kernel/sched_fair.c
@@ -19,7 +19,7 @@
/*
* Preemption granularity:
- * (default: 2 msec, units: nanoseconds)
+ * (default: 10 msec, units: nanoseconds)
*
* NOTE: this granularity value is not the same as the concept of
* 'timeslice length' - timeslices in CFS will typically be somewhat
@@ -31,18 +31,17 @@
* number of CPUs. (i.e. factor 2x on 2-way systems, 3x on 4-way
* systems, 4x on 8-way systems, 5x on 16-way systems, etc.)
*/
-unsigned int sysctl_sched_granularity __read_mostly = 2000000000ULL/HZ;
+unsigned int sysctl_sched_granularity __read_mostly = 10000000UL;
/*
* SCHED_BATCH wake-up granularity.
- * (default: 10 msec, units: nanoseconds)
+ * (default: 25 msec, units: nanoseconds)
*
* This option delays the preemption effects of decoupled workloads
* and reduces their over-scheduling. Synchronous workloads will still
* have immediate wakeup/sleep latencies.
*/
-unsigned int sysctl_sched_batch_wakeup_granularity __read_mostly =
- 10000000000ULL/HZ;
+unsigned int sysctl_sched_batch_wakeup_granularity __read_mostly = 25000000UL;
/*
* SCHED_OTHER wake-up granularity.
@@ -52,12 +51,12 @@
* and reduces their over-scheduling. Synchronous workloads will still
* have immediate wakeup/sleep latencies.
*/
-unsigned int sysctl_sched_wakeup_granularity __read_mostly = 1000000000ULL/HZ;
+unsigned int sysctl_sched_wakeup_granularity __read_mostly = 1000000UL;
unsigned int sysctl_sched_stat_granularity __read_mostly;
/*
- * Initialized in sched_init_granularity():
+ * Initialized in sched_init_granularity() [to 5 times the base granularity]:
*/
unsigned int sysctl_sched_runtime_limit __read_mostly;
@@ -75,7 +74,7 @@
unsigned int sysctl_sched_features __read_mostly =
SCHED_FEAT_FAIR_SLEEPERS *1 |
- SCHED_FEAT_SLEEPER_AVG *1 |
+ SCHED_FEAT_SLEEPER_AVG *0 |
SCHED_FEAT_SLEEPER_LOAD_AVG *1 |
SCHED_FEAT_PRECISE_CPU_LOAD *1 |
SCHED_FEAT_START_DEBIT *1 |
@@ -222,21 +221,25 @@
{
u64 tmp;
- /*
- * Negative nice levels get the same granularity as nice-0:
- */
- if (likely(curr->load.weight >= NICE_0_LOAD))
+ if (likely(curr->load.weight == NICE_0_LOAD))
return granularity;
/*
- * Positive nice level tasks get linearly finer
+ * Positive nice levels get the same granularity as nice-0:
+ */
+ if (likely(curr->load.weight < NICE_0_LOAD)) {
+ tmp = curr->load.weight * (u64)granularity;
+ return (long) (tmp >> NICE_0_SHIFT);
+ }
+ /*
+ * Negative nice level tasks get linearly finer
* granularity:
*/
- tmp = curr->load.weight * (u64)granularity;
+ tmp = curr->load.inv_weight * (u64)granularity;
/*
* It will always fit into 'long':
*/
- return (long) (tmp >> NICE_0_SHIFT);
+ return (long) (tmp >> WMULT_SHIFT);
}
static inline void
@@ -281,31 +284,28 @@
* are not in our scheduling class.
*/
static inline void
-__update_curr(struct cfs_rq *cfs_rq, struct sched_entity *curr, u64 now)
+__update_curr(struct cfs_rq *cfs_rq, struct sched_entity *curr)
{
- unsigned long delta, delta_exec, delta_fair;
- long delta_mine;
+ unsigned long delta, delta_exec, delta_fair, delta_mine;
struct load_weight *lw = &cfs_rq->load;
unsigned long load = lw->weight;
- if (unlikely(!load))
- return;
-
delta_exec = curr->delta_exec;
schedstat_set(curr->exec_max, max((u64)delta_exec, curr->exec_max));
curr->sum_exec_runtime += delta_exec;
cfs_rq->exec_clock += delta_exec;
+ if (unlikely(!load))
+ return;
+
delta_fair = calc_delta_fair(delta_exec, lw);
delta_mine = calc_delta_mine(delta_exec, curr->load.weight, lw);
- if (cfs_rq->sleeper_bonus > sysctl_sched_stat_granularity) {
- delta = calc_delta_mine(cfs_rq->sleeper_bonus,
- curr->load.weight, lw);
- if (unlikely(delta > cfs_rq->sleeper_bonus))
- delta = cfs_rq->sleeper_bonus;
-
+ if (cfs_rq->sleeper_bonus > sysctl_sched_granularity) {
+ delta = min((u64)delta_mine, cfs_rq->sleeper_bonus);
+ delta = min(delta, (unsigned long)(
+ (long)sysctl_sched_runtime_limit - curr->wait_runtime));
cfs_rq->sleeper_bonus -= delta;
delta_mine -= delta;
}
@@ -321,7 +321,7 @@
add_wait_runtime(cfs_rq, curr, delta_mine - delta_exec);
}
-static void update_curr(struct cfs_rq *cfs_rq, u64 now)
+static void update_curr(struct cfs_rq *cfs_rq)
{
struct sched_entity *curr = cfs_rq_curr(cfs_rq);
unsigned long delta_exec;
@@ -334,22 +334,22 @@
* since the last time we changed load (this cannot
* overflow on 32 bits):
*/
- delta_exec = (unsigned long)(now - curr->exec_start);
+ delta_exec = (unsigned long)(rq_of(cfs_rq)->clock - curr->exec_start);
curr->delta_exec += delta_exec;
if (unlikely(curr->delta_exec > sysctl_sched_stat_granularity)) {
- __update_curr(cfs_rq, curr, now);
+ __update_curr(cfs_rq, curr);
curr->delta_exec = 0;
}
- curr->exec_start = now;
+ curr->exec_start = rq_of(cfs_rq)->clock;
}
static inline void
-update_stats_wait_start(struct cfs_rq *cfs_rq, struct sched_entity *se, u64 now)
+update_stats_wait_start(struct cfs_rq *cfs_rq, struct sched_entity *se)
{
se->wait_start_fair = cfs_rq->fair_clock;
- schedstat_set(se->wait_start, now);
+ schedstat_set(se->wait_start, rq_of(cfs_rq)->clock);
}
/*
@@ -377,8 +377,7 @@
/*
* Task is being enqueued - update stats:
*/
-static void
-update_stats_enqueue(struct cfs_rq *cfs_rq, struct sched_entity *se, u64 now)
+static void update_stats_enqueue(struct cfs_rq *cfs_rq, struct sched_entity *se)
{
s64 key;
@@ -387,7 +386,7 @@
* a dequeue/enqueue event is a NOP)
*/
if (se != cfs_rq_curr(cfs_rq))
- update_stats_wait_start(cfs_rq, se, now);
+ update_stats_wait_start(cfs_rq, se);
/*
* Update the key:
*/
@@ -407,7 +406,8 @@
(WMULT_SHIFT - NICE_0_SHIFT);
} else {
tmp = se->wait_runtime;
- key -= (tmp * se->load.weight) >> NICE_0_SHIFT;
+ key -= (tmp * se->load.inv_weight) >>
+ (WMULT_SHIFT - NICE_0_SHIFT);
}
}
@@ -418,11 +418,12 @@
* Note: must be called with a freshly updated rq->fair_clock.
*/
static inline void
-__update_stats_wait_end(struct cfs_rq *cfs_rq, struct sched_entity *se, u64 now)
+__update_stats_wait_end(struct cfs_rq *cfs_rq, struct sched_entity *se)
{
unsigned long delta_fair = se->delta_fair_run;
- schedstat_set(se->wait_max, max(se->wait_max, now - se->wait_start));
+ schedstat_set(se->wait_max, max(se->wait_max,
+ rq_of(cfs_rq)->clock - se->wait_start));
if (unlikely(se->load.weight != NICE_0_LOAD))
delta_fair = calc_weighted(delta_fair, se->load.weight,
@@ -432,7 +433,7 @@
}
static void
-update_stats_wait_end(struct cfs_rq *cfs_rq, struct sched_entity *se, u64 now)
+update_stats_wait_end(struct cfs_rq *cfs_rq, struct sched_entity *se)
{
unsigned long delta_fair;
@@ -442,7 +443,7 @@
se->delta_fair_run += delta_fair;
if (unlikely(abs(se->delta_fair_run) >=
sysctl_sched_stat_granularity)) {
- __update_stats_wait_end(cfs_rq, se, now);
+ __update_stats_wait_end(cfs_rq, se);
se->delta_fair_run = 0;
}
@@ -451,34 +452,34 @@
}
static inline void
-update_stats_dequeue(struct cfs_rq *cfs_rq, struct sched_entity *se, u64 now)
+update_stats_dequeue(struct cfs_rq *cfs_rq, struct sched_entity *se)
{
- update_curr(cfs_rq, now);
+ update_curr(cfs_rq);
/*
* Mark the end of the wait period if dequeueing a
* waiting task:
*/
if (se != cfs_rq_curr(cfs_rq))
- update_stats_wait_end(cfs_rq, se, now);
+ update_stats_wait_end(cfs_rq, se);
}
/*
* We are picking a new current task - update its stats:
*/
static inline void
-update_stats_curr_start(struct cfs_rq *cfs_rq, struct sched_entity *se, u64 now)
+update_stats_curr_start(struct cfs_rq *cfs_rq, struct sched_entity *se)
{
/*
* We are starting a new run period:
*/
- se->exec_start = now;
+ se->exec_start = rq_of(cfs_rq)->clock;
}
/*
* We are descheduling a task - update its stats:
*/
static inline void
-update_stats_curr_end(struct cfs_rq *cfs_rq, struct sched_entity *se, u64 now)
+update_stats_curr_end(struct cfs_rq *cfs_rq, struct sched_entity *se)
{
se->exec_start = 0;
}
@@ -487,12 +488,18 @@
* Scheduling class queueing methods:
*/
-static void
-__enqueue_sleeper(struct cfs_rq *cfs_rq, struct sched_entity *se, u64 now)
+static void __enqueue_sleeper(struct cfs_rq *cfs_rq, struct sched_entity *se)
{
unsigned long load = cfs_rq->load.weight, delta_fair;
long prev_runtime;
+ /*
+ * Do not boost sleepers if there's too much bonus 'in flight'
+ * already:
+ */
+ if (unlikely(cfs_rq->sleeper_bonus > sysctl_sched_runtime_limit))
+ return;
+
if (sysctl_sched_features & SCHED_FEAT_SLEEPER_LOAD_AVG)
load = rq_of(cfs_rq)->cpu_load[2];
@@ -512,18 +519,16 @@
prev_runtime = se->wait_runtime;
__add_wait_runtime(cfs_rq, se, delta_fair);
+ schedstat_add(cfs_rq, wait_runtime, se->wait_runtime);
delta_fair = se->wait_runtime - prev_runtime;
/*
* Track the amount of bonus we've given to sleepers:
*/
cfs_rq->sleeper_bonus += delta_fair;
-
- schedstat_add(cfs_rq, wait_runtime, se->wait_runtime);
}
-static void
-enqueue_sleeper(struct cfs_rq *cfs_rq, struct sched_entity *se, u64 now)
+static void enqueue_sleeper(struct cfs_rq *cfs_rq, struct sched_entity *se)
{
struct task_struct *tsk = task_of(se);
unsigned long delta_fair;
@@ -538,7 +543,7 @@
se->delta_fair_sleep += delta_fair;
if (unlikely(abs(se->delta_fair_sleep) >=
sysctl_sched_stat_granularity)) {
- __enqueue_sleeper(cfs_rq, se, now);
+ __enqueue_sleeper(cfs_rq, se);
se->delta_fair_sleep = 0;
}
@@ -546,7 +551,7 @@
#ifdef CONFIG_SCHEDSTATS
if (se->sleep_start) {
- u64 delta = now - se->sleep_start;
+ u64 delta = rq_of(cfs_rq)->clock - se->sleep_start;
if ((s64)delta < 0)
delta = 0;
@@ -558,7 +563,7 @@
se->sum_sleep_runtime += delta;
}
if (se->block_start) {
- u64 delta = now - se->block_start;
+ u64 delta = rq_of(cfs_rq)->clock - se->block_start;
if ((s64)delta < 0)
delta = 0;
@@ -573,26 +578,24 @@
}
static void
-enqueue_entity(struct cfs_rq *cfs_rq, struct sched_entity *se,
- int wakeup, u64 now)
+enqueue_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, int wakeup)
{
/*
* Update the fair clock.
*/
- update_curr(cfs_rq, now);
+ update_curr(cfs_rq);
if (wakeup)
- enqueue_sleeper(cfs_rq, se, now);
+ enqueue_sleeper(cfs_rq, se);
- update_stats_enqueue(cfs_rq, se, now);
+ update_stats_enqueue(cfs_rq, se);
__enqueue_entity(cfs_rq, se);
}
static void
-dequeue_entity(struct cfs_rq *cfs_rq, struct sched_entity *se,
- int sleep, u64 now)
+dequeue_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, int sleep)
{
- update_stats_dequeue(cfs_rq, se, now);
+ update_stats_dequeue(cfs_rq, se);
if (sleep) {
se->sleep_start_fair = cfs_rq->fair_clock;
#ifdef CONFIG_SCHEDSTATS
@@ -600,9 +603,9 @@
struct task_struct *tsk = task_of(se);
if (tsk->state & TASK_INTERRUPTIBLE)
- se->sleep_start = now;
+ se->sleep_start = rq_of(cfs_rq)->clock;
if (tsk->state & TASK_UNINTERRUPTIBLE)
- se->block_start = now;
+ se->block_start = rq_of(cfs_rq)->clock;
}
cfs_rq->wait_runtime -= se->wait_runtime;
#endif
@@ -629,7 +632,7 @@
}
static inline void
-set_next_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, u64 now)
+set_next_entity(struct cfs_rq *cfs_rq, struct sched_entity *se)
{
/*
* Any task has to be enqueued before it get to execute on
@@ -638,49 +641,46 @@
* done a put_prev_task_fair() shortly before this, which
* updated rq->fair_clock - used by update_stats_wait_end())
*/
- update_stats_wait_end(cfs_rq, se, now);
- update_stats_curr_start(cfs_rq, se, now);
+ update_stats_wait_end(cfs_rq, se);
+ update_stats_curr_start(cfs_rq, se);
set_cfs_rq_curr(cfs_rq, se);
}
-static struct sched_entity *pick_next_entity(struct cfs_rq *cfs_rq, u64 now)
+static struct sched_entity *pick_next_entity(struct cfs_rq *cfs_rq)
{
struct sched_entity *se = __pick_next_entity(cfs_rq);
- set_next_entity(cfs_rq, se, now);
+ set_next_entity(cfs_rq, se);
return se;
}
-static void
-put_prev_entity(struct cfs_rq *cfs_rq, struct sched_entity *prev, u64 now)
+static void put_prev_entity(struct cfs_rq *cfs_rq, struct sched_entity *prev)
{
/*
* If still on the runqueue then deactivate_task()
* was not called and update_curr() has to be done:
*/
if (prev->on_rq)
- update_curr(cfs_rq, now);
+ update_curr(cfs_rq);
- update_stats_curr_end(cfs_rq, prev, now);
+ update_stats_curr_end(cfs_rq, prev);
if (prev->on_rq)
- update_stats_wait_start(cfs_rq, prev, now);
+ update_stats_wait_start(cfs_rq, prev);
set_cfs_rq_curr(cfs_rq, NULL);
}
static void entity_tick(struct cfs_rq *cfs_rq, struct sched_entity *curr)
{
- struct rq *rq = rq_of(cfs_rq);
struct sched_entity *next;
- u64 now = __rq_clock(rq);
/*
* Dequeue and enqueue the task to update its
* position within the tree:
*/
- dequeue_entity(cfs_rq, curr, 0, now);
- enqueue_entity(cfs_rq, curr, 0, now);
+ dequeue_entity(cfs_rq, curr, 0);
+ enqueue_entity(cfs_rq, curr, 0);
/*
* Reschedule if another task tops the current one.
@@ -785,8 +785,7 @@
* increased. Here we update the fair scheduling stats and
* then put the task into the rbtree:
*/
-static void
-enqueue_task_fair(struct rq *rq, struct task_struct *p, int wakeup, u64 now)
+static void enqueue_task_fair(struct rq *rq, struct task_struct *p, int wakeup)
{
struct cfs_rq *cfs_rq;
struct sched_entity *se = &p->se;
@@ -795,7 +794,7 @@
if (se->on_rq)
break;
cfs_rq = cfs_rq_of(se);
- enqueue_entity(cfs_rq, se, wakeup, now);
+ enqueue_entity(cfs_rq, se, wakeup);
}
}
@@ -804,15 +803,14 @@
* decreased. We remove the task from the rbtree and
* update the fair scheduling stats:
*/
-static void
-dequeue_task_fair(struct rq *rq, struct task_struct *p, int sleep, u64 now)
+static void dequeue_task_fair(struct rq *rq, struct task_struct *p, int sleep)
{
struct cfs_rq *cfs_rq;
struct sched_entity *se = &p->se;
for_each_sched_entity(se) {
cfs_rq = cfs_rq_of(se);
- dequeue_entity(cfs_rq, se, sleep, now);
+ dequeue_entity(cfs_rq, se, sleep);
/* Don't dequeue parent if it has other entities besides us */
if (cfs_rq->load.weight)
break;
@@ -825,14 +823,14 @@
static void yield_task_fair(struct rq *rq, struct task_struct *p)
{
struct cfs_rq *cfs_rq = task_cfs_rq(p);
- u64 now = __rq_clock(rq);
+ __update_rq_clock(rq);
/*
* Dequeue and enqueue the task to update its
* position within the tree:
*/
- dequeue_entity(cfs_rq, &p->se, 0, now);
- enqueue_entity(cfs_rq, &p->se, 0, now);
+ dequeue_entity(cfs_rq, &p->se, 0);
+ enqueue_entity(cfs_rq, &p->se, 0);
}
/*
@@ -845,7 +843,8 @@
unsigned long gran;
if (unlikely(rt_prio(p->prio))) {
- update_curr(cfs_rq, rq_clock(rq));
+ update_rq_clock(rq);
+ update_curr(cfs_rq);
resched_task(curr);
return;
}
@@ -861,7 +860,7 @@
__check_preempt_curr_fair(cfs_rq, &p->se, &curr->se, gran);
}
-static struct task_struct *pick_next_task_fair(struct rq *rq, u64 now)
+static struct task_struct *pick_next_task_fair(struct rq *rq)
{
struct cfs_rq *cfs_rq = &rq->cfs;
struct sched_entity *se;
@@ -870,7 +869,7 @@
return NULL;
do {
- se = pick_next_entity(cfs_rq, now);
+ se = pick_next_entity(cfs_rq);
cfs_rq = group_cfs_rq(se);
} while (cfs_rq);
@@ -880,14 +879,14 @@
/*
* Account for a descheduled task:
*/
-static void put_prev_task_fair(struct rq *rq, struct task_struct *prev, u64 now)
+static void put_prev_task_fair(struct rq *rq, struct task_struct *prev)
{
struct sched_entity *se = &prev->se;
struct cfs_rq *cfs_rq;
for_each_sched_entity(se) {
cfs_rq = cfs_rq_of(se);
- put_prev_entity(cfs_rq, se, now);
+ put_prev_entity(cfs_rq, se);
}
}
@@ -930,6 +929,7 @@
return __load_balance_iterator(cfs_rq, cfs_rq->rb_load_balance_curr);
}
+#ifdef CONFIG_FAIR_GROUP_SCHED
static int cfs_rq_best_prio(struct cfs_rq *cfs_rq)
{
struct sched_entity *curr;
@@ -943,12 +943,13 @@
return p->prio;
}
+#endif
-static int
+static unsigned long
load_balance_fair(struct rq *this_rq, int this_cpu, struct rq *busiest,
- unsigned long max_nr_move, unsigned long max_load_move,
- struct sched_domain *sd, enum cpu_idle_type idle,
- int *all_pinned, unsigned long *total_load_moved)
+ unsigned long max_nr_move, unsigned long max_load_move,
+ struct sched_domain *sd, enum cpu_idle_type idle,
+ int *all_pinned, int *this_best_prio)
{
struct cfs_rq *busy_cfs_rq;
unsigned long load_moved, total_nr_moved = 0, nr_moved;
@@ -959,15 +960,14 @@
cfs_rq_iterator.next = load_balance_next_fair;
for_each_leaf_cfs_rq(busiest, busy_cfs_rq) {
+#ifdef CONFIG_FAIR_GROUP_SCHED
struct cfs_rq *this_cfs_rq;
long imbalance;
unsigned long maxload;
- int this_best_prio, best_prio, best_prio_seen = 0;
this_cfs_rq = cpu_cfs_rq(busy_cfs_rq, this_cpu);
- imbalance = busy_cfs_rq->load.weight -
- this_cfs_rq->load.weight;
+ imbalance = busy_cfs_rq->load.weight - this_cfs_rq->load.weight;
/* Don't pull if this_cfs_rq has more load than busy_cfs_rq */
if (imbalance <= 0)
continue;
@@ -976,27 +976,17 @@
imbalance /= 2;
maxload = min(rem_load_move, imbalance);
- this_best_prio = cfs_rq_best_prio(this_cfs_rq);
- best_prio = cfs_rq_best_prio(busy_cfs_rq);
-
- /*
- * Enable handling of the case where there is more than one task
- * with the best priority. If the current running task is one
- * of those with prio==best_prio we know it won't be moved
- * and therefore it's safe to override the skip (based on load)
- * of any task we find with that prio.
- */
- if (cfs_rq_curr(busy_cfs_rq) == &busiest->curr->se)
- best_prio_seen = 1;
-
+ *this_best_prio = cfs_rq_best_prio(this_cfs_rq);
+#else
+# define maxload rem_load_move
+#endif
/* pass busy_cfs_rq argument into
* load_balance_[start|next]_fair iterators
*/
cfs_rq_iterator.arg = busy_cfs_rq;
nr_moved = balance_tasks(this_rq, this_cpu, busiest,
max_nr_move, maxload, sd, idle, all_pinned,
- &load_moved, this_best_prio, best_prio,
- best_prio_seen, &cfs_rq_iterator);
+ &load_moved, this_best_prio, &cfs_rq_iterator);
total_nr_moved += nr_moved;
max_nr_move -= nr_moved;
@@ -1006,9 +996,7 @@
break;
}
- *total_load_moved = max_load_move - rem_load_move;
-
- return total_nr_moved;
+ return max_load_move - rem_load_move;
}
/*
@@ -1032,14 +1020,14 @@
* monopolize the CPU. Note: the parent runqueue is locked,
* the child is not running yet.
*/
-static void task_new_fair(struct rq *rq, struct task_struct *p, u64 now)
+static void task_new_fair(struct rq *rq, struct task_struct *p)
{
struct cfs_rq *cfs_rq = task_cfs_rq(p);
struct sched_entity *se = &p->se;
sched_info_queued(p);
- update_stats_enqueue(cfs_rq, se, now);
+ update_stats_enqueue(cfs_rq, se);
/*
* Child runs first: we let it run before the parent
* until it reschedules once. We set up the key so that
@@ -1059,7 +1047,7 @@
* -granularity/2, so initialize the task with that:
*/
if (sysctl_sched_features & SCHED_FEAT_START_DEBIT)
- p->se.wait_runtime = -(sysctl_sched_granularity / 2);
+ p->se.wait_runtime = -((long)sysctl_sched_granularity / 2);
__enqueue_entity(cfs_rq, se);
}
@@ -1072,15 +1060,10 @@
*/
static void set_curr_task_fair(struct rq *rq)
{
- struct task_struct *curr = rq->curr;
- struct sched_entity *se = &curr->se;
- u64 now = rq_clock(rq);
- struct cfs_rq *cfs_rq;
+ struct sched_entity *se = &rq->curr->se;
- for_each_sched_entity(se) {
- cfs_rq = cfs_rq_of(se);
- set_next_entity(cfs_rq, se, now);
- }
+ for_each_sched_entity(se)
+ set_next_entity(cfs_rq_of(se), se);
}
#else
static void set_curr_task_fair(struct rq *rq)
@@ -1109,12 +1092,11 @@
};
#ifdef CONFIG_SCHED_DEBUG
-void print_cfs_stats(struct seq_file *m, int cpu, u64 now)
+static void print_cfs_stats(struct seq_file *m, int cpu)
{
- struct rq *rq = cpu_rq(cpu);
struct cfs_rq *cfs_rq;
- for_each_leaf_cfs_rq(rq, cfs_rq)
- print_cfs_rq(m, cpu, cfs_rq, now);
+ for_each_leaf_cfs_rq(cpu_rq(cpu), cfs_rq)
+ print_cfs_rq(m, cpu, cfs_rq);
}
#endif
diff --git a/kernel/sched_idletask.c b/kernel/sched_idletask.c
index 41841e7..3503fb2 100644
--- a/kernel/sched_idletask.c
+++ b/kernel/sched_idletask.c
@@ -13,7 +13,7 @@
resched_task(rq->idle);
}
-static struct task_struct *pick_next_task_idle(struct rq *rq, u64 now)
+static struct task_struct *pick_next_task_idle(struct rq *rq)
{
schedstat_inc(rq, sched_goidle);
@@ -25,7 +25,7 @@
* message if some code attempts to do it:
*/
static void
-dequeue_task_idle(struct rq *rq, struct task_struct *p, int sleep, u64 now)
+dequeue_task_idle(struct rq *rq, struct task_struct *p, int sleep)
{
spin_unlock_irq(&rq->lock);
printk(KERN_ERR "bad: scheduling from the idle thread!\n");
@@ -33,15 +33,15 @@
spin_lock_irq(&rq->lock);
}
-static void put_prev_task_idle(struct rq *rq, struct task_struct *prev, u64 now)
+static void put_prev_task_idle(struct rq *rq, struct task_struct *prev)
{
}
-static int
+static unsigned long
load_balance_idle(struct rq *this_rq, int this_cpu, struct rq *busiest,
unsigned long max_nr_move, unsigned long max_load_move,
struct sched_domain *sd, enum cpu_idle_type idle,
- int *all_pinned, unsigned long *total_load_moved)
+ int *all_pinned, int *this_best_prio)
{
return 0;
}
diff --git a/kernel/sched_rt.c b/kernel/sched_rt.c
index 002fcf8..4b87476 100644
--- a/kernel/sched_rt.c
+++ b/kernel/sched_rt.c
@@ -7,7 +7,7 @@
* Update the current task's runtime statistics. Skip current tasks that
* are not in our scheduling class.
*/
-static inline void update_curr_rt(struct rq *rq, u64 now)
+static inline void update_curr_rt(struct rq *rq)
{
struct task_struct *curr = rq->curr;
u64 delta_exec;
@@ -15,18 +15,17 @@
if (!task_has_rt_policy(curr))
return;
- delta_exec = now - curr->se.exec_start;
+ delta_exec = rq->clock - curr->se.exec_start;
if (unlikely((s64)delta_exec < 0))
delta_exec = 0;
schedstat_set(curr->se.exec_max, max(curr->se.exec_max, delta_exec));
curr->se.sum_exec_runtime += delta_exec;
- curr->se.exec_start = now;
+ curr->se.exec_start = rq->clock;
}
-static void
-enqueue_task_rt(struct rq *rq, struct task_struct *p, int wakeup, u64 now)
+static void enqueue_task_rt(struct rq *rq, struct task_struct *p, int wakeup)
{
struct rt_prio_array *array = &rq->rt.active;
@@ -37,12 +36,11 @@
/*
* Adding/removing a task to/from a priority array:
*/
-static void
-dequeue_task_rt(struct rq *rq, struct task_struct *p, int sleep, u64 now)
+static void dequeue_task_rt(struct rq *rq, struct task_struct *p, int sleep)
{
struct rt_prio_array *array = &rq->rt.active;
- update_curr_rt(rq, now);
+ update_curr_rt(rq);
list_del(&p->run_list);
if (list_empty(array->queue + p->prio))
@@ -75,7 +73,7 @@
resched_task(rq->curr);
}
-static struct task_struct *pick_next_task_rt(struct rq *rq, u64 now)
+static struct task_struct *pick_next_task_rt(struct rq *rq)
{
struct rt_prio_array *array = &rq->rt.active;
struct task_struct *next;
@@ -89,14 +87,14 @@
queue = array->queue + idx;
next = list_entry(queue->next, struct task_struct, run_list);
- next->se.exec_start = now;
+ next->se.exec_start = rq->clock;
return next;
}
-static void put_prev_task_rt(struct rq *rq, struct task_struct *p, u64 now)
+static void put_prev_task_rt(struct rq *rq, struct task_struct *p)
{
- update_curr_rt(rq, now);
+ update_curr_rt(rq);
p->se.exec_start = 0;
}
@@ -172,28 +170,15 @@
return p;
}
-static int
+static unsigned long
load_balance_rt(struct rq *this_rq, int this_cpu, struct rq *busiest,
unsigned long max_nr_move, unsigned long max_load_move,
struct sched_domain *sd, enum cpu_idle_type idle,
- int *all_pinned, unsigned long *load_moved)
+ int *all_pinned, int *this_best_prio)
{
- int this_best_prio, best_prio, best_prio_seen = 0;
int nr_moved;
struct rq_iterator rt_rq_iterator;
-
- best_prio = sched_find_first_bit(busiest->rt.active.bitmap);
- this_best_prio = sched_find_first_bit(this_rq->rt.active.bitmap);
-
- /*
- * Enable handling of the case where there is more than one task
- * with the best priority. If the current running task is one
- * of those with prio==best_prio we know it won't be moved
- * and therefore it's safe to override the skip (based on load)
- * of any task we find with that prio.
- */
- if (busiest->curr->prio == best_prio)
- best_prio_seen = 1;
+ unsigned long load_moved;
rt_rq_iterator.start = load_balance_start_rt;
rt_rq_iterator.next = load_balance_next_rt;
@@ -203,11 +188,10 @@
rt_rq_iterator.arg = busiest;
nr_moved = balance_tasks(this_rq, this_cpu, busiest, max_nr_move,
- max_load_move, sd, idle, all_pinned, load_moved,
- this_best_prio, best_prio, best_prio_seen,
- &rt_rq_iterator);
+ max_load_move, sd, idle, all_pinned, &load_moved,
+ this_best_prio, &rt_rq_iterator);
- return nr_moved;
+ return load_moved;
}
static void task_tick_rt(struct rq *rq, struct task_struct *p)
@@ -223,10 +207,15 @@
return;
p->time_slice = static_prio_timeslice(p->static_prio);
- set_tsk_need_resched(p);
- /* put it at the end of the queue: */
- requeue_task_rt(rq, p);
+ /*
+ * Requeue to the end of queue if we are not the only element
+ * on the queue:
+ */
+ if (p->run_list.prev != p->run_list.next) {
+ requeue_task_rt(rq, p);
+ set_tsk_need_resched(p);
+ }
}
static struct sched_class rt_sched_class __read_mostly = {
diff --git a/kernel/signal.c b/kernel/signal.c
index b27c01a..ad63109 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -378,7 +378,7 @@
/* We only dequeue private signals from ourselves, we don't let
* signalfd steal them
*/
- if (tsk == current)
+ if (likely(tsk == current))
signr = __dequeue_signal(&tsk->pending, mask, info);
if (!signr) {
signr = __dequeue_signal(&tsk->signal->shared_pending,
@@ -425,7 +425,7 @@
if (!(tsk->signal->flags & SIGNAL_GROUP_EXIT))
tsk->signal->flags |= SIGNAL_STOP_DEQUEUED;
}
- if ( signr &&
+ if (signr && likely(tsk == current) &&
((info->si_code & __SI_MASK) == __SI_TIMER) &&
info->si_sys_private){
/*
diff --git a/kernel/sysctl.c b/kernel/sysctl.c
index 79c891e..9029690 100644
--- a/kernel/sysctl.c
+++ b/kernel/sysctl.c
@@ -27,7 +27,6 @@
#include <linux/capability.h>
#include <linux/ctype.h>
#include <linux/utsname.h>
-#include <linux/capability.h>
#include <linux/smp_lock.h>
#include <linux/fs.h>
#include <linux/init.h>
@@ -1023,6 +1022,7 @@
.mode = 0644,
.proc_handler = &proc_doulongvec_minmax,
},
+#endif
#ifdef CONFIG_NUMA
{
.ctl_name = CTL_UNNUMBERED,
@@ -1034,7 +1034,6 @@
.strategy = &sysctl_string,
},
#endif
-#endif
#if defined(CONFIG_X86_32) || \
(defined(CONFIG_SUPERH) && defined(CONFIG_VSYSCALL))
{
diff --git a/kernel/time/clockevents.c b/kernel/time/clockevents.c
index 2ad1c37..41dd310 100644
--- a/kernel/time/clockevents.c
+++ b/kernel/time/clockevents.c
@@ -113,16 +113,6 @@
return ret;
}
-/**
- * clockevents_unregister_notifier - unregister a clock events change listener
- */
-void clockevents_unregister_notifier(struct notifier_block *nb)
-{
- spin_lock(&clockevents_lock);
- raw_notifier_chain_unregister(&clockevents_chain, nb);
- spin_unlock(&clockevents_lock);
-}
-
/*
* Notify about a clock event change. Called with clockevents_lock
* held.
diff --git a/lib/Kconfig b/lib/Kconfig
index e5c2c51..ba3d104 100644
--- a/lib/Kconfig
+++ b/lib/Kconfig
@@ -138,4 +138,7 @@
depends on !NO_DMA
default y
+config CHECK_SIGNATURE
+ bool
+
endmenu
diff --git a/lib/Makefile b/lib/Makefile
index d9e5f1c..6b0ba8c 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -21,7 +21,8 @@
endif
obj-$(CONFIG_GENERIC_IOMAP) += iomap.o
-obj-$(CONFIG_HAS_IOMEM) += iomap_copy.o devres.o check_signature.o
+obj-$(CONFIG_HAS_IOMEM) += iomap_copy.o devres.o
+obj-$(CONFIG_CHECK_SIGNATURE) += check_signature.o
obj-$(CONFIG_DEBUG_LOCKING_API_SELFTESTS) += locking-selftest.o
obj-$(CONFIG_DEBUG_SPINLOCK) += spinlock_debug.o
lib-$(CONFIG_RWSEM_GENERIC_SPINLOCK) += rwsem-spinlock.o
diff --git a/lib/hexdump.c b/lib/hexdump.c
index 473f5ae..bd5edae 100644
--- a/lib/hexdump.c
+++ b/lib/hexdump.c
@@ -145,9 +145,9 @@
*/
void print_hex_dump(const char *level, const char *prefix_str, int prefix_type,
int rowsize, int groupsize,
- void *buf, size_t len, bool ascii)
+ const void *buf, size_t len, bool ascii)
{
- u8 *ptr = buf;
+ const u8 *ptr = buf;
int i, linelen, remaining = len;
unsigned char linebuf[200];
@@ -189,7 +189,7 @@
* rowsize of 16, groupsize of 1, and ASCII output included.
*/
void print_hex_dump_bytes(const char *prefix_str, int prefix_type,
- void *buf, size_t len)
+ const void *buf, size_t len)
{
print_hex_dump(KERN_DEBUG, prefix_str, prefix_type, 16, 1,
buf, len, 1);
diff --git a/lib/iomap.c b/lib/iomap.c
index a57d262..864f2ec 100644
--- a/lib/iomap.c
+++ b/lib/iomap.c
@@ -240,7 +240,20 @@
EXPORT_SYMBOL(ioport_map);
EXPORT_SYMBOL(ioport_unmap);
-/* Create a virtual mapping cookie for a PCI BAR (memory or IO) */
+/**
+ * pci_iomap - create a virtual mapping cookie for a PCI BAR
+ * @dev: PCI device that owns the BAR
+ * @bar: BAR number
+ * @maxlen: length of the memory to map
+ *
+ * Using this function you will get a __iomem address to your device BAR.
+ * You can access it using ioread*() and iowrite*(). These functions hide
+ * the details if this is a MMIO or PIO address space and will just do what
+ * you expect from them in the correct way.
+ *
+ * @maxlen specifies the maximum length to map. If you want to get access to
+ * the complete BAR without checking for its length first, pass %0 here.
+ * */
void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long maxlen)
{
unsigned long start = pci_resource_start(dev, bar);
diff --git a/mm/filemap.c b/mm/filemap.c
index 6cf700d..90b657b 100644
--- a/mm/filemap.c
+++ b/mm/filemap.c
@@ -843,7 +843,7 @@
/**
* do_generic_mapping_read - generic file read routine
* @mapping: address_space to be read
- * @ra: file's readahead state
+ * @_ra: file's readahead state
* @filp: the file to read
* @ppos: current file position
* @desc: read_descriptor
@@ -1218,26 +1218,6 @@
}
EXPORT_SYMBOL(generic_file_aio_read);
-int file_send_actor(read_descriptor_t * desc, struct page *page, unsigned long offset, unsigned long size)
-{
- ssize_t written;
- unsigned long count = desc->count;
- struct file *file = desc->arg.data;
-
- if (size > count)
- size = count;
-
- written = file->f_op->sendpage(file, page, offset,
- size, &file->f_pos, size<count);
- if (written < 0) {
- desc->error = written;
- written = 0;
- }
- desc->count = count - written;
- desc->written += written;
- return written;
-}
-
static ssize_t
do_readahead(struct address_space *mapping, struct file *filp,
unsigned long index, unsigned long nr)
diff --git a/mm/hugetlb.c b/mm/hugetlb.c
index d7ca59d..de4cf45 100644
--- a/mm/hugetlb.c
+++ b/mm/hugetlb.c
@@ -643,7 +643,7 @@
spin_unlock(&mm->page_table_lock);
ret = hugetlb_fault(mm, vma, vaddr, 0);
spin_lock(&mm->page_table_lock);
- if (!(ret & VM_FAULT_MAJOR))
+ if (!(ret & VM_FAULT_ERROR))
continue;
remainder = 0;
diff --git a/mm/mempolicy.c b/mm/mempolicy.c
index 71b84b4..172abff 100644
--- a/mm/mempolicy.c
+++ b/mm/mempolicy.c
@@ -149,7 +149,7 @@
lower zones etc. Avoid empty zones because the memory allocator
doesn't like them. If you implement node hot removal you
have to fix that. */
- k = policy_zone;
+ k = MAX_NR_ZONES - 1;
while (1) {
for_each_node_mask(nd, *nodes) {
struct zone *z = &NODE_DATA(nd)->node_zones[k];
diff --git a/mm/mmap.c b/mm/mmap.c
index b653721..0d40e66 100644
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -93,7 +93,7 @@
* Note this is a helper function intended to be used by LSMs which
* wish to use this logic.
*/
-int __vm_enough_memory(long pages, int cap_sys_admin)
+int __vm_enough_memory(struct mm_struct *mm, long pages, int cap_sys_admin)
{
unsigned long free, allowed;
@@ -166,7 +166,7 @@
/* Don't let a single process grow too big:
leave 3% of the size of this process for other processes */
- allowed -= current->mm->total_vm / 32;
+ allowed -= mm->total_vm / 32;
/*
* cast `allowed' as a signed long because vm_committed_space
@@ -2077,7 +2077,7 @@
if (__vma && __vma->vm_start < vma->vm_end)
return -ENOMEM;
if ((vma->vm_flags & VM_ACCOUNT) &&
- security_vm_enough_memory(vma_pages(vma)))
+ security_vm_enough_memory_mm(mm, vma_pages(vma)))
return -ENOMEM;
vma_link(mm, vma, prev, rb_link, rb_parent);
return 0;
diff --git a/mm/nommu.c b/mm/nommu.c
index 9eef6a39..8ed0cb4 100644
--- a/mm/nommu.c
+++ b/mm/nommu.c
@@ -1270,7 +1270,7 @@
* Note this is a helper function intended to be used by LSMs which
* wish to use this logic.
*/
-int __vm_enough_memory(long pages, int cap_sys_admin)
+int __vm_enough_memory(struct mm_struct *mm, long pages, int cap_sys_admin)
{
unsigned long free, allowed;
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index 3da85b8..6427653 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -1157,6 +1157,7 @@
nodemask_t *allowednodes = NULL;/* zonelist_cache approximation */
int zlc_active = 0; /* set if using zonelist_cache */
int did_zlc_setup = 0; /* just call zlc_setup() one time */
+ enum zone_type highest_zoneidx = -1; /* Gets set for policy zonelists */
zonelist_scan:
/*
@@ -1166,6 +1167,18 @@
z = zonelist->zones;
do {
+ /*
+ * In NUMA, this could be a policy zonelist which contains
+ * zones that may not be allowed by the current gfp_mask.
+ * Check the zone is allowed by the current flags
+ */
+ if (unlikely(alloc_should_filter_zonelist(zonelist))) {
+ if (highest_zoneidx == -1)
+ highest_zoneidx = gfp_zone(gfp_mask);
+ if (zone_idx(*z) > highest_zoneidx)
+ continue;
+ }
+
if (NUMA_BUILD && zlc_active &&
!zlc_zone_worth_trying(zonelist, z, allowednodes))
continue;
diff --git a/mm/slab.c b/mm/slab.c
index a684778..6f6abef 100644
--- a/mm/slab.c
+++ b/mm/slab.c
@@ -883,6 +883,7 @@
*/
static int use_alien_caches __read_mostly = 1;
+static int numa_platform __read_mostly = 1;
static int __init noaliencache_setup(char *s)
{
use_alien_caches = 0;
@@ -1399,8 +1400,10 @@
int order;
int node;
- if (num_possible_nodes() == 1)
+ if (num_possible_nodes() == 1) {
use_alien_caches = 0;
+ numa_platform = 0;
+ }
for (i = 0; i < NUM_INIT_LISTS; i++) {
kmem_list3_init(&initkmem_list3[i]);
@@ -3558,7 +3561,14 @@
check_irq_off();
objp = cache_free_debugcheck(cachep, objp, __builtin_return_address(0));
- if (cache_free_alien(cachep, objp))
+ /*
+ * Skip calling cache_free_alien() when the platform is not numa.
+ * This will avoid cache misses that happen while accessing slabp (which
+ * is per page memory reference) to get nodeid. Instead use a global
+ * variable to skip the call, which is mostly likely to be present in
+ * the cache.
+ */
+ if (numa_platform && cache_free_alien(cachep, objp))
return;
if (likely(ac->avail < ac->limit)) {
diff --git a/mm/slub.c b/mm/slub.c
index 6c6d74f..04151da 100644
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -211,7 +211,8 @@
#define MAX_OBJECTS_PER_SLAB 65535
/* Internal SLUB flags */
-#define __OBJECT_POISON 0x80000000 /* Poison object */
+#define __OBJECT_POISON 0x80000000 /* Poison object */
+#define __SYSFS_ADD_DEFERRED 0x40000000 /* Not yet visible via sysfs */
/* Not all arches define cache_line_size */
#ifndef cache_line_size
@@ -1876,9 +1877,16 @@
BUG_ON(kmalloc_caches->size < sizeof(struct kmem_cache_node));
- page = new_slab(kmalloc_caches, gfpflags | GFP_THISNODE, node);
+ page = new_slab(kmalloc_caches, gfpflags, node);
BUG_ON(!page);
+ if (page_to_nid(page) != node) {
+ printk(KERN_ERR "SLUB: Unable to allocate memory from "
+ "node %d\n", node);
+ printk(KERN_ERR "SLUB: Allocating a useless per node structure "
+ "in order to be able to continue\n");
+ }
+
n = page->freelist;
BUG_ON(!n);
page->freelist = get_freepointer(kmalloc_caches, n);
@@ -2277,10 +2285,26 @@
}
#ifdef CONFIG_ZONE_DMA
+
+static void sysfs_add_func(struct work_struct *w)
+{
+ struct kmem_cache *s;
+
+ down_write(&slub_lock);
+ list_for_each_entry(s, &slab_caches, list) {
+ if (s->flags & __SYSFS_ADD_DEFERRED) {
+ s->flags &= ~__SYSFS_ADD_DEFERRED;
+ sysfs_slab_add(s);
+ }
+ }
+ up_write(&slub_lock);
+}
+
+static DECLARE_WORK(sysfs_add_work, sysfs_add_func);
+
static noinline struct kmem_cache *dma_kmalloc_cache(int index, gfp_t flags)
{
struct kmem_cache *s;
- struct kmem_cache *x;
char *text;
size_t realsize;
@@ -2289,22 +2313,36 @@
return s;
/* Dynamically create dma cache */
- x = kmalloc(kmem_size, flags & ~SLUB_DMA);
- if (!x)
- panic("Unable to allocate memory for dma cache\n");
+ if (flags & __GFP_WAIT)
+ down_write(&slub_lock);
+ else {
+ if (!down_write_trylock(&slub_lock))
+ goto out;
+ }
+
+ if (kmalloc_caches_dma[index])
+ goto unlock_out;
realsize = kmalloc_caches[index].objsize;
- text = kasprintf(flags & ~SLUB_DMA, "kmalloc_dma-%d",
- (unsigned int)realsize);
- s = create_kmalloc_cache(x, text, realsize, flags);
- down_write(&slub_lock);
- if (!kmalloc_caches_dma[index]) {
- kmalloc_caches_dma[index] = s;
- up_write(&slub_lock);
- return s;
+ text = kasprintf(flags & ~SLUB_DMA, "kmalloc_dma-%d", (unsigned int)realsize),
+ s = kmalloc(kmem_size, flags & ~SLUB_DMA);
+
+ if (!s || !text || !kmem_cache_open(s, flags, text,
+ realsize, ARCH_KMALLOC_MINALIGN,
+ SLAB_CACHE_DMA|__SYSFS_ADD_DEFERRED, NULL)) {
+ kfree(s);
+ kfree(text);
+ goto unlock_out;
}
+
+ list_add(&s->list, &slab_caches);
+ kmalloc_caches_dma[index] = s;
+
+ schedule_work(&sysfs_add_work);
+
+unlock_out:
up_write(&slub_lock);
- kmem_cache_destroy(s);
+out:
return kmalloc_caches_dma[index];
}
#endif
@@ -2500,15 +2538,11 @@
slab_unlock(page);
discard_slab(s, page);
} else {
- if (n->nr_partial > MAX_PARTIAL)
- list_move(&page->lru,
- slabs_by_inuse + page->inuse);
+ list_move(&page->lru,
+ slabs_by_inuse + page->inuse);
}
}
- if (n->nr_partial <= MAX_PARTIAL)
- goto out;
-
/*
* Rebuild the partial list with the slabs filled up most
* first and the least used slabs at the end.
@@ -2516,7 +2550,6 @@
for (i = s->objects - 1; i >= 0; i--)
list_splice(slabs_by_inuse + i, n->partial.prev);
- out:
spin_unlock_irqrestore(&n->list_lock, flags);
}
@@ -3086,7 +3119,7 @@
unsigned long flags;
struct page *page;
- if (!atomic_read(&n->nr_slabs))
+ if (!atomic_long_read(&n->nr_slabs))
continue;
spin_lock_irqsave(&n->list_lock, flags);
@@ -3221,7 +3254,7 @@
}
if (flags & SO_FULL) {
- int full_slabs = atomic_read(&n->nr_slabs)
+ int full_slabs = atomic_long_read(&n->nr_slabs)
- per_cpu[node]
- n->nr_partial;
@@ -3257,7 +3290,7 @@
for_each_node(node) {
struct kmem_cache_node *n = get_node(s, node);
- if (n->nr_partial || atomic_read(&n->nr_slabs))
+ if (n->nr_partial || atomic_long_read(&n->nr_slabs))
return 1;
}
return 0;
diff --git a/mm/sparse.c b/mm/sparse.c
index 3047bf0..239f5a7 100644
--- a/mm/sparse.c
+++ b/mm/sparse.c
@@ -41,6 +41,15 @@
return section_to_node_table[page_to_section(page)];
}
EXPORT_SYMBOL(page_to_nid);
+
+static void set_section_nid(unsigned long section_nr, int nid)
+{
+ section_to_node_table[section_nr] = nid;
+}
+#else /* !NODE_NOT_IN_PAGE_FLAGS */
+static inline void set_section_nid(unsigned long section_nr, int nid)
+{
+}
#endif
#ifdef CONFIG_SPARSEMEM_EXTREME
@@ -68,10 +77,6 @@
struct mem_section *section;
int ret = 0;
-#ifdef NODE_NOT_IN_PAGE_FLAGS
- section_to_node_table[section_nr] = nid;
-#endif
-
if (mem_section[root])
return -EEXIST;
@@ -148,6 +153,7 @@
struct mem_section *ms;
sparse_index_init(section, nid);
+ set_section_nid(section, nid);
ms = __nr_to_section(section);
if (!ms->section_mem_map)
diff --git a/mm/vmscan.c b/mm/vmscan.c
index d419e10..a6e65d0 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -271,6 +271,12 @@
unlock_page(page);
}
+/* Request for sync pageout. */
+enum pageout_io {
+ PAGEOUT_IO_ASYNC,
+ PAGEOUT_IO_SYNC,
+};
+
/* possible outcome of pageout() */
typedef enum {
/* failed to write page out, page is locked */
@@ -287,7 +293,8 @@
* pageout is called by shrink_page_list() for each dirty page.
* Calls ->writepage().
*/
-static pageout_t pageout(struct page *page, struct address_space *mapping)
+static pageout_t pageout(struct page *page, struct address_space *mapping,
+ enum pageout_io sync_writeback)
{
/*
* If the page is dirty, only perform writeback if that write
@@ -346,6 +353,15 @@
ClearPageReclaim(page);
return PAGE_ACTIVATE;
}
+
+ /*
+ * Wait on writeback if requested to. This happens when
+ * direct reclaiming a large contiguous area and the
+ * first attempt to free a range of pages fails.
+ */
+ if (PageWriteback(page) && sync_writeback == PAGEOUT_IO_SYNC)
+ wait_on_page_writeback(page);
+
if (!PageWriteback(page)) {
/* synchronous write or broken a_ops? */
ClearPageReclaim(page);
@@ -423,7 +439,8 @@
* shrink_page_list() returns the number of reclaimed pages
*/
static unsigned long shrink_page_list(struct list_head *page_list,
- struct scan_control *sc)
+ struct scan_control *sc,
+ enum pageout_io sync_writeback)
{
LIST_HEAD(ret_pages);
struct pagevec freed_pvec;
@@ -458,8 +475,23 @@
if (page_mapped(page) || PageSwapCache(page))
sc->nr_scanned++;
- if (PageWriteback(page))
- goto keep_locked;
+ may_enter_fs = (sc->gfp_mask & __GFP_FS) ||
+ (PageSwapCache(page) && (sc->gfp_mask & __GFP_IO));
+
+ if (PageWriteback(page)) {
+ /*
+ * Synchronous reclaim is performed in two passes,
+ * first an asynchronous pass over the list to
+ * start parallel writeback, and a second synchronous
+ * pass to wait for the IO to complete. Wait here
+ * for any page for which writeback has already
+ * started.
+ */
+ if (sync_writeback == PAGEOUT_IO_SYNC && may_enter_fs)
+ wait_on_page_writeback(page);
+ else
+ goto keep_locked;
+ }
referenced = page_referenced(page, 1);
/* In active use or really unfreeable? Activate it. */
@@ -478,8 +510,6 @@
#endif /* CONFIG_SWAP */
mapping = page_mapping(page);
- may_enter_fs = (sc->gfp_mask & __GFP_FS) ||
- (PageSwapCache(page) && (sc->gfp_mask & __GFP_IO));
/*
* The page is mapped into the page tables of one or more
@@ -505,7 +535,7 @@
goto keep_locked;
/* Page is dirty, try to write it out here */
- switch(pageout(page, mapping)) {
+ switch (pageout(page, mapping, sync_writeback)) {
case PAGE_KEEP:
goto keep_locked;
case PAGE_ACTIVATE:
@@ -777,6 +807,7 @@
(sc->order > PAGE_ALLOC_COSTLY_ORDER)?
ISOLATE_BOTH : ISOLATE_INACTIVE);
nr_active = clear_active_flags(&page_list);
+ __count_vm_events(PGDEACTIVATE, nr_active);
__mod_zone_page_state(zone, NR_ACTIVE, -nr_active);
__mod_zone_page_state(zone, NR_INACTIVE,
@@ -785,7 +816,29 @@
spin_unlock_irq(&zone->lru_lock);
nr_scanned += nr_scan;
- nr_freed = shrink_page_list(&page_list, sc);
+ nr_freed = shrink_page_list(&page_list, sc, PAGEOUT_IO_ASYNC);
+
+ /*
+ * If we are direct reclaiming for contiguous pages and we do
+ * not reclaim everything in the list, try again and wait
+ * for IO to complete. This will stall high-order allocations
+ * but that should be acceptable to the caller
+ */
+ if (nr_freed < nr_taken && !current_is_kswapd() &&
+ sc->order > PAGE_ALLOC_COSTLY_ORDER) {
+ congestion_wait(WRITE, HZ/10);
+
+ /*
+ * The attempt at page out may have made some
+ * of the pages active, mark them inactive again.
+ */
+ nr_active = clear_active_flags(&page_list);
+ count_vm_events(PGDEACTIVATE, nr_active);
+
+ nr_freed += shrink_page_list(&page_list, sc,
+ PAGEOUT_IO_SYNC);
+ }
+
nr_reclaimed += nr_freed;
local_irq_disable();
if (current_is_kswapd()) {
diff --git a/net/802/psnap.c b/net/802/psnap.c
index 04ee43e..31128cb 100644
--- a/net/802/psnap.c
+++ b/net/802/psnap.c
@@ -55,6 +55,9 @@
.type = __constant_htons(ETH_P_SNAP),
};
+ if (unlikely(!pskb_may_pull(skb, 5)))
+ goto drop;
+
rcu_read_lock();
proto = find_snap_client(skb_transport_header(skb));
if (proto) {
@@ -62,14 +65,18 @@
skb->transport_header += 5;
skb_pull_rcsum(skb, 5);
rc = proto->rcvfunc(skb, dev, &snap_packet_type, orig_dev);
- } else {
- skb->sk = NULL;
- kfree_skb(skb);
- rc = 1;
}
-
rcu_read_unlock();
+
+ if (unlikely(!proto))
+ goto drop;
+
+out:
return rc;
+
+drop:
+ kfree_skb(skb);
+ goto out;
}
/*
diff --git a/net/8021q/vlanproc.c b/net/8021q/vlanproc.c
index c0040c9..bd08aa0 100644
--- a/net/8021q/vlanproc.c
+++ b/net/8021q/vlanproc.c
@@ -319,7 +319,7 @@
static const char fmt[] = "%30s %12lu\n";
int i;
- if ((vlandev == NULL) || (!(vlandev->priv_flags & IFF_802_1Q_VLAN)))
+ if (!(vlandev->priv_flags & IFF_802_1Q_VLAN))
return 0;
seq_printf(seq, "%s VID: %d REORDER_HDR: %i dev->priv_flags: %hx\n",
diff --git a/net/9p/conv.c b/net/9p/conv.c
index f2a041c..d979d95 100644
--- a/net/9p/conv.c
+++ b/net/9p/conv.c
@@ -796,6 +796,7 @@
if (err) {
kfree(fc);
fc = ERR_PTR(err);
+ goto error;
}
if (buf_check_overflow(bufp)) {
diff --git a/net/9p/mux.c b/net/9p/mux.c
index acb0388..5d70558 100644
--- a/net/9p/mux.c
+++ b/net/9p/mux.c
@@ -288,9 +288,10 @@
m->extended = extended;
m->trans = trans;
m->tagpool = p9_idpool_create();
- if (!m->tagpool) {
+ if (IS_ERR(m->tagpool)) {
+ mtmp = ERR_PTR(-ENOMEM);
kfree(m);
- return ERR_PTR(PTR_ERR(m->tagpool));
+ return mtmp;
}
m->err = 0;
@@ -308,8 +309,10 @@
memset(&m->poll_waddr, 0, sizeof(m->poll_waddr));
m->poll_task = NULL;
n = p9_mux_poll_start(m);
- if (n)
+ if (n) {
+ kfree(m);
return ERR_PTR(n);
+ }
n = trans->poll(trans, &m->pt);
if (n & POLLIN) {
diff --git a/net/atm/lec.c b/net/atm/lec.c
index 2770fb4..59d5aa3 100644
--- a/net/atm/lec.c
+++ b/net/atm/lec.c
@@ -21,7 +21,6 @@
#include <net/dst.h>
#include <linux/proc_fs.h>
#include <linux/spinlock.h>
-#include <linux/proc_fs.h>
#include <linux/seq_file.h>
/* TokenRing if needed */
diff --git a/net/ax25/ax25_iface.c b/net/ax25/ax25_iface.c
index 16be0c1..8443af5 100644
--- a/net/ax25/ax25_iface.c
+++ b/net/ax25/ax25_iface.c
@@ -69,7 +69,6 @@
if (protocol->pid == pid) {
protocol_list = protocol->next;
write_unlock_bh(&protocol_list_lock);
- kfree(protocol);
return;
}
@@ -78,7 +77,6 @@
s = protocol->next;
protocol->next = protocol->next->next;
write_unlock_bh(&protocol_list_lock);
- kfree(s);
return;
}
diff --git a/net/bridge/br_device.c b/net/bridge/br_device.c
index 5e1892d..0eded17 100644
--- a/net/bridge/br_device.c
+++ b/net/bridge/br_device.c
@@ -179,5 +179,5 @@
dev->priv_flags = IFF_EBRIDGE;
dev->features = NETIF_F_SG | NETIF_F_FRAGLIST | NETIF_F_HIGHDMA |
- NETIF_F_TSO | NETIF_F_NO_CSUM | NETIF_F_GSO_ROBUST;
+ NETIF_F_GSO_MASK | NETIF_F_NO_CSUM | NETIF_F_LLTX;
}
diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c
index b40dada..749f0e8 100644
--- a/net/bridge/br_if.c
+++ b/net/bridge/br_if.c
@@ -349,43 +349,15 @@
void br_features_recompute(struct net_bridge *br)
{
struct net_bridge_port *p;
- unsigned long features, checksum;
+ unsigned long features;
- checksum = br->feature_mask & NETIF_F_ALL_CSUM ? NETIF_F_NO_CSUM : 0;
- features = br->feature_mask & ~NETIF_F_ALL_CSUM;
+ features = br->feature_mask;
list_for_each_entry(p, &br->port_list, list) {
- unsigned long feature = p->dev->features;
-
- /* if device needs checksumming, downgrade to hw checksumming */
- if (checksum & NETIF_F_NO_CSUM && !(feature & NETIF_F_NO_CSUM))
- checksum ^= NETIF_F_NO_CSUM | NETIF_F_HW_CSUM;
-
- /* if device can't do all checksum, downgrade to ipv4/ipv6 */
- if (checksum & NETIF_F_HW_CSUM && !(feature & NETIF_F_HW_CSUM))
- checksum ^= NETIF_F_HW_CSUM
- | NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM;
-
- if (checksum & NETIF_F_IPV6_CSUM && !(feature & NETIF_F_IPV6_CSUM))
- checksum &= ~NETIF_F_IPV6_CSUM;
-
- if (!(feature & NETIF_F_IP_CSUM))
- checksum = 0;
-
- if (feature & NETIF_F_GSO)
- feature |= NETIF_F_GSO_SOFTWARE;
- feature |= NETIF_F_GSO;
-
- features &= feature;
+ features = netdev_compute_features(features, p->dev->features);
}
- if (!(checksum & NETIF_F_ALL_CSUM))
- features &= ~NETIF_F_SG;
- if (!(features & NETIF_F_SG))
- features &= ~NETIF_F_GSO_MASK;
-
- br->dev->features = features | checksum | NETIF_F_LLTX |
- NETIF_F_GSO_ROBUST;
+ br->dev->features = features;
}
/* called with RTNL */
diff --git a/net/bridge/br_stp_if.c b/net/bridge/br_stp_if.c
index 1ea2f86..1a430ec 100644
--- a/net/bridge/br_stp_if.c
+++ b/net/bridge/br_stp_if.c
@@ -132,7 +132,7 @@
} else {
br->stp_enabled = BR_KERNEL_STP;
printk(KERN_INFO "%s: starting userspace STP failed, "
- "staring kernel STP\n", br->dev->name);
+ "starting kernel STP\n", br->dev->name);
/* To start timers on any ports left in blocking */
spin_lock_bh(&br->lock);
diff --git a/net/bridge/br_sysfs_br.c b/net/bridge/br_sysfs_br.c
index 4f42263..c65f54e 100644
--- a/net/bridge/br_sysfs_br.c
+++ b/net/bridge/br_sysfs_br.c
@@ -147,20 +147,27 @@
return sprintf(buf, "%d\n", br->stp_enabled);
}
-static void set_stp_state(struct net_bridge *br, unsigned long val)
-{
- rtnl_lock();
- spin_unlock_bh(&br->lock);
- br_stp_set_enabled(br, val);
- spin_lock_bh(&br->lock);
- rtnl_unlock();
-}
static ssize_t store_stp_state(struct device *d,
struct device_attribute *attr, const char *buf,
size_t len)
{
- return store_bridge_parm(d, buf, len, set_stp_state);
+ struct net_bridge *br = to_bridge(d);
+ char *endp;
+ unsigned long val;
+
+ if (!capable(CAP_NET_ADMIN))
+ return -EPERM;
+
+ val = simple_strtoul(buf, &endp, 0);
+ if (endp == buf)
+ return -EINVAL;
+
+ rtnl_lock();
+ br_stp_set_enabled(br, val);
+ rtnl_unlock();
+
+ return len;
}
static DEVICE_ATTR(stp_state, S_IRUGO | S_IWUSR, show_stp_state,
store_stp_state);
diff --git a/net/core/dev.c b/net/core/dev.c
index 6cc8a70..a76021c 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -3993,6 +3993,45 @@
static int __init netdev_dma_register(void) { return -ENODEV; }
#endif /* CONFIG_NET_DMA */
+/**
+ * netdev_compute_feature - compute conjunction of two feature sets
+ * @all: first feature set
+ * @one: second feature set
+ *
+ * Computes a new feature set after adding a device with feature set
+ * @one to the master device with current feature set @all. Returns
+ * the new feature set.
+ */
+int netdev_compute_features(unsigned long all, unsigned long one)
+{
+ /* if device needs checksumming, downgrade to hw checksumming */
+ if (all & NETIF_F_NO_CSUM && !(one & NETIF_F_NO_CSUM))
+ all ^= NETIF_F_NO_CSUM | NETIF_F_HW_CSUM;
+
+ /* if device can't do all checksum, downgrade to ipv4/ipv6 */
+ if (all & NETIF_F_HW_CSUM && !(one & NETIF_F_HW_CSUM))
+ all ^= NETIF_F_HW_CSUM
+ | NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM;
+
+ if (one & NETIF_F_GSO)
+ one |= NETIF_F_GSO_SOFTWARE;
+ one |= NETIF_F_GSO;
+
+ /* If even one device supports robust GSO, enable it for all. */
+ if (one & NETIF_F_GSO_ROBUST)
+ all |= NETIF_F_GSO_ROBUST;
+
+ all &= one | NETIF_F_LLTX;
+
+ if (!(all & NETIF_F_ALL_CSUM))
+ all &= ~NETIF_F_SG;
+ if (!(all & NETIF_F_SG))
+ all &= ~NETIF_F_GSO_MASK;
+
+ return all;
+}
+EXPORT_SYMBOL(netdev_compute_features);
+
/*
* Initialize the DEV module. At boot time this walks the device list and
* unhooks any devices that fail to initialise (normally hardware not
diff --git a/net/core/ethtool.c b/net/core/ethtool.c
index 2ab0a60..c5e0593 100644
--- a/net/core/ethtool.c
+++ b/net/core/ethtool.c
@@ -948,7 +948,6 @@
return rc;
}
-EXPORT_SYMBOL(dev_ethtool);
EXPORT_SYMBOL(ethtool_op_get_link);
EXPORT_SYMBOL(ethtool_op_get_sg);
EXPORT_SYMBOL(ethtool_op_get_tso);
diff --git a/net/core/utils.c b/net/core/utils.c
index 2030bb8..0bf17da 100644
--- a/net/core/utils.c
+++ b/net/core/utils.c
@@ -25,6 +25,7 @@
#include <linux/random.h>
#include <linux/percpu.h>
#include <linux/init.h>
+#include <net/sock.h>
#include <asm/byteorder.h>
#include <asm/system.h>
diff --git a/net/dccp/ccid.c b/net/dccp/ccid.c
index ccbf72c..c45088b 100644
--- a/net/dccp/ccid.c
+++ b/net/dccp/ccid.c
@@ -40,6 +40,7 @@
static inline void ccids_read_lock(void)
{
atomic_inc(&ccids_lockct);
+ smp_mb__after_atomic_inc();
spin_unlock_wait(&ccids_lock);
}
diff --git a/net/dccp/ccids/ccid2.c b/net/dccp/ccids/ccid2.c
index 248d20f..d29b88f 100644
--- a/net/dccp/ccids/ccid2.c
+++ b/net/dccp/ccids/ccid2.c
@@ -298,7 +298,7 @@
int rc;
ccid2_pr_debug("allocating more space in history\n");
- rc = ccid2_hc_tx_alloc_seq(hctx, CCID2_SEQBUF_LEN, GFP_KERNEL);
+ rc = ccid2_hc_tx_alloc_seq(hctx, CCID2_SEQBUF_LEN, gfp_any());
BUG_ON(rc); /* XXX what do we do? */
next = hctx->ccid2hctx_seqh->ccid2s_next;
diff --git a/net/dccp/feat.c b/net/dccp/feat.c
index cd845df..5ebdd86 100644
--- a/net/dccp/feat.c
+++ b/net/dccp/feat.c
@@ -327,10 +327,16 @@
}
switch (type) {
- case DCCPO_CHANGE_L: opt->dccpop_type = DCCPO_CONFIRM_R; break;
- case DCCPO_CHANGE_R: opt->dccpop_type = DCCPO_CONFIRM_L; break;
- default: DCCP_WARN("invalid type %d\n", type); return;
-
+ case DCCPO_CHANGE_L:
+ opt->dccpop_type = DCCPO_CONFIRM_R;
+ break;
+ case DCCPO_CHANGE_R:
+ opt->dccpop_type = DCCPO_CONFIRM_L;
+ break;
+ default:
+ DCCP_WARN("invalid type %d\n", type);
+ kfree(opt);
+ return;
}
opt->dccpop_feat = feature;
opt->dccpop_val = NULL;
diff --git a/net/econet/af_econet.c b/net/econet/af_econet.c
index b5524f3..35c96bc 100644
--- a/net/econet/af_econet.c
+++ b/net/econet/af_econet.c
@@ -1146,6 +1146,9 @@
sock_release(udpsock);
#endif
unregister_netdevice_notifier(&econet_netdev_notifier);
+#ifdef CONFIG_ECONET_NATIVE
+ dev_remove_pack(&econet_packet_type);
+#endif
sock_unregister(econet_family_ops.family);
proto_unregister(&econet_proto);
}
diff --git a/net/ieee80211/softmac/ieee80211softmac_wx.c b/net/ieee80211/softmac/ieee80211softmac_wx.c
index f13937b..d054e92 100644
--- a/net/ieee80211/softmac/ieee80211softmac_wx.c
+++ b/net/ieee80211/softmac/ieee80211softmac_wx.c
@@ -74,8 +74,8 @@
struct ieee80211softmac_auth_queue_item *authptr;
int length = 0;
+check_assoc_again:
mutex_lock(&sm->associnfo.mutex);
-
/* Check if we're already associating to this or another network
* If it's another network, cancel and start over with our new network
* If it's our network, ignore the change, we're already doing it!
@@ -98,13 +98,18 @@
cancel_delayed_work(&authptr->work);
sm->associnfo.bssvalid = 0;
sm->associnfo.bssfixed = 0;
- flush_scheduled_work();
sm->associnfo.associating = 0;
sm->associnfo.associated = 0;
+ /* We must unlock to avoid deadlocks with the assoc workqueue
+ * on the associnfo.mutex */
+ mutex_unlock(&sm->associnfo.mutex);
+ flush_scheduled_work();
+ /* Avoid race! Check assoc status again. Maybe someone started an
+ * association while we flushed. */
+ goto check_assoc_again;
}
}
-
sm->associnfo.static_essid = 0;
sm->associnfo.assoc_wait = 0;
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c
index c9e2b5e..0f1d7be 100644
--- a/net/ipv4/ip_output.c
+++ b/net/ipv4/ip_output.c
@@ -75,7 +75,6 @@
#include <net/icmp.h>
#include <net/checksum.h>
#include <net/inetpeer.h>
-#include <net/checksum.h>
#include <linux/igmp.h>
#include <linux/netfilter_ipv4.h>
#include <linux/netfilter_bridge.h>
diff --git a/net/ipv4/ipconfig.c b/net/ipv4/ipconfig.c
index 342ca8d..c5b2470 100644
--- a/net/ipv4/ipconfig.c
+++ b/net/ipv4/ipconfig.c
@@ -1281,9 +1281,9 @@
*/
if (ic_myaddr == NONE ||
#ifdef CONFIG_ROOT_NFS
- (MAJOR(ROOT_DEV) == UNNAMED_MAJOR
- && root_server_addr == NONE
- && ic_servaddr == NONE) ||
+ (root_server_addr == NONE
+ && ic_servaddr == NONE
+ && ROOT_DEV == Root_NFS) ||
#endif
ic_first_dev->next) {
#ifdef IPCONFIG_DYNAMIC
diff --git a/net/ipv4/ipvs/ip_vs_ctl.c b/net/ipv4/ipvs/ip_vs_ctl.c
index e1052bc..902fd57 100644
--- a/net/ipv4/ipvs/ip_vs_ctl.c
+++ b/net/ipv4/ipvs/ip_vs_ctl.c
@@ -29,7 +29,6 @@
#include <linux/proc_fs.h>
#include <linux/workqueue.h>
#include <linux/swap.h>
-#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <linux/netfilter.h>
@@ -909,7 +908,7 @@
write_lock_bh(&__ip_vs_svc_lock);
/* Wait until all other svc users go away */
- while (atomic_read(&svc->usecnt) > 1) {};
+ IP_VS_WAIT_WHILE(atomic_read(&svc->usecnt) > 1);
/* call the update_service, because server weight may be changed */
svc->scheduler->update_service(svc);
diff --git a/net/ipv4/netfilter/ipt_CLUSTERIP.c b/net/ipv4/netfilter/ipt_CLUSTERIP.c
index dcc12b1..69bd362 100644
--- a/net/ipv4/netfilter/ipt_CLUSTERIP.c
+++ b/net/ipv4/netfilter/ipt_CLUSTERIP.c
@@ -19,7 +19,6 @@
#include <linux/udp.h>
#include <linux/icmp.h>
#include <linux/if_arp.h>
-#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <linux/netfilter_arp.h>
#include <linux/netfilter/x_tables.h>
diff --git a/net/ipv4/netfilter/ipt_recent.c b/net/ipv4/netfilter/ipt_recent.c
index 3218043..6d0c0f7 100644
--- a/net/ipv4/netfilter/ipt_recent.c
+++ b/net/ipv4/netfilter/ipt_recent.c
@@ -387,12 +387,17 @@
st = kzalloc(sizeof(*st), GFP_KERNEL);
if (st == NULL)
return -ENOMEM;
+
ret = seq_open(file, &recent_seq_ops);
- if (ret)
+ if (ret) {
kfree(st);
+ goto out;
+ }
+
st->table = pde->data;
seq = file->private_data;
seq->private = st;
+out:
return ret;
}
diff --git a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
index 64552af..d9b5177 100644
--- a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
+++ b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
@@ -509,3 +509,9 @@
module_init(nf_conntrack_l3proto_ipv4_init);
module_exit(nf_conntrack_l3proto_ipv4_fini);
+
+void need_ipv4_conntrack(void)
+{
+ return;
+}
+EXPORT_SYMBOL_GPL(need_ipv4_conntrack);
diff --git a/net/ipv4/netfilter/nf_nat_sip.c b/net/ipv4/netfilter/nf_nat_sip.c
index a889ec3..e14d419 100644
--- a/net/ipv4/netfilter/nf_nat_sip.c
+++ b/net/ipv4/netfilter/nf_nat_sip.c
@@ -104,7 +104,7 @@
dataoff = ip_hdrlen(*pskb) + sizeof(struct udphdr);
datalen = (*pskb)->len - dataoff;
if (datalen < sizeof("SIP/2.0") - 1)
- return NF_DROP;
+ return NF_ACCEPT;
addr_map_init(ct, &map);
diff --git a/net/ipv4/netfilter/nf_nat_standalone.c b/net/ipv4/netfilter/nf_nat_standalone.c
index 332814d..46cc99d 100644
--- a/net/ipv4/netfilter/nf_nat_standalone.c
+++ b/net/ipv4/netfilter/nf_nat_standalone.c
@@ -328,7 +328,7 @@
{
int ret = 0;
- need_conntrack();
+ need_ipv4_conntrack();
#ifdef CONFIG_XFRM
BUG_ON(ip_nat_decode_session != NULL);
diff --git a/net/ipv4/tcp_htcp.c b/net/ipv4/tcp_htcp.c
index b66556c..5215691 100644
--- a/net/ipv4/tcp_htcp.c
+++ b/net/ipv4/tcp_htcp.c
@@ -79,7 +79,6 @@
static inline void measure_rtt(struct sock *sk, u32 srtt)
{
const struct inet_connection_sock *icsk = inet_csk(sk);
- const struct tcp_sock *tp = tcp_sk(sk);
struct htcp *ca = inet_csk_ca(sk);
/* keep track of minimum RTT seen so far, minRTT is zero at first */
@@ -87,8 +86,7 @@
ca->minRTT = srtt;
/* max RTT */
- if (icsk->icsk_ca_state == TCP_CA_Open
- && tp->snd_ssthresh < 0xFFFF && htcp_ccount(ca) > 3) {
+ if (icsk->icsk_ca_state == TCP_CA_Open) {
if (ca->maxRTT < ca->minRTT)
ca->maxRTT = ca->minRTT;
if (ca->maxRTT < srtt
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
index 50d86e9..5dead39 100644
--- a/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -794,7 +794,7 @@
/*
* Copy a block of the IP datagram.
*/
- if (skb_copy_bits(skb, ptr, skb_transport_header(skb), len))
+ if (skb_copy_bits(skb, ptr, skb_transport_header(frag), len))
BUG();
left -= len;
diff --git a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c
index d684639..761a910 100644
--- a/net/ipv6/ipv6_sockglue.c
+++ b/net/ipv6/ipv6_sockglue.c
@@ -820,7 +820,7 @@
return 0;
len = min_t(unsigned int, len, ipv6_optlen(hdr));
- if (copy_to_user(optval, hdr, len));
+ if (copy_to_user(optval, hdr, len))
return -EFAULT;
return ipv6_optlen(hdr);
}
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
index cbdb784..0f7defb 100644
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -56,7 +56,6 @@
#include <net/inet_ecn.h>
#include <net/protocol.h>
#include <net/xfrm.h>
-#include <net/addrconf.h>
#include <net/snmp.h>
#include <net/dsfield.h>
#include <net/timewait_sock.h>
diff --git a/net/irda/irmod.c b/net/irda/irmod.c
index 1900937..8ba703d 100644
--- a/net/irda/irmod.c
+++ b/net/irda/irmod.c
@@ -128,8 +128,8 @@
out_err_3:
#ifdef CONFIG_SYSCTL
irda_sysctl_unregister();
-#endif
out_err_2:
+#endif
#ifdef CONFIG_PROC_FS
irda_proc_unregister();
#endif
diff --git a/net/irda/irnetlink.c b/net/irda/irnetlink.c
index 694ea4d..1e429c9 100644
--- a/net/irda/irnetlink.c
+++ b/net/irda/irnetlink.c
@@ -106,7 +106,7 @@
}
if(nla_put_string(msg, IRDA_NL_ATTR_IFNAME,
- dev->name));
+ dev->name))
goto err_out;
if(nla_put_u32(msg, IRDA_NL_ATTR_MODE, irlap->mode))
diff --git a/net/mac80211/debugfs_netdev.c b/net/mac80211/debugfs_netdev.c
index 799a920..095be91 100644
--- a/net/mac80211/debugfs_netdev.c
+++ b/net/mac80211/debugfs_netdev.c
@@ -271,9 +271,11 @@
}
}
-#define DEBUGFS_DEL(name, type)\
- debugfs_remove(sdata->debugfs.type.name);\
- sdata->debugfs.type.name = NULL;
+#define DEBUGFS_DEL(name, type) \
+ do { \
+ debugfs_remove(sdata->debugfs.type.name); \
+ sdata->debugfs.type.name = NULL; \
+ } while (0)
static void del_sta_files(struct ieee80211_sub_if_data *sdata)
{
diff --git a/net/mac80211/debugfs_sta.c b/net/mac80211/debugfs_sta.c
index d41e696..da34ea7 100644
--- a/net/mac80211/debugfs_sta.c
+++ b/net/mac80211/debugfs_sta.c
@@ -157,7 +157,7 @@
struct sta_info *sta = file->private_data;
for (i = 0; i < NUM_RX_DATA_QUEUES; i++)
p += scnprintf(p, sizeof(buf)+buf-p, "%x ",
- sta->last_seq_ctrl[i]);
+ le16_to_cpu(sta->last_seq_ctrl[i]));
p += scnprintf(p, sizeof(buf)+buf-p, "\n");
return simple_read_from_buffer(userbuf, count, ppos, buf, p - buf);
}
diff --git a/net/mac80211/ieee80211.c b/net/mac80211/ieee80211.c
index c944b17..7286c38 100644
--- a/net/mac80211/ieee80211.c
+++ b/net/mac80211/ieee80211.c
@@ -1650,6 +1650,7 @@
if (skb_headroom(skb) < headroom) {
if (pskb_expand_head(skb, headroom, 0, GFP_ATOMIC)) {
dev_kfree_skb(skb);
+ dev_put(odev);
return 0;
}
}
@@ -4677,7 +4678,6 @@
memset(skb->cb, 0, sizeof(skb->cb));
netif_rx(skb);
skb = skb2;
- break;
}
}
out:
diff --git a/net/mac80211/ieee80211_ioctl.c b/net/mac80211/ieee80211_ioctl.c
index d0e1ab5..e7904db 100644
--- a/net/mac80211/ieee80211_ioctl.c
+++ b/net/mac80211/ieee80211_ioctl.c
@@ -697,17 +697,24 @@
if (!netif_running(dev))
return -ENETDOWN;
- if (local->scan_flags & IEEE80211_SCAN_MATCH_SSID) {
- if (sdata->type == IEEE80211_IF_TYPE_STA ||
- sdata->type == IEEE80211_IF_TYPE_IBSS) {
+ switch (sdata->type) {
+ case IEEE80211_IF_TYPE_STA:
+ case IEEE80211_IF_TYPE_IBSS:
+ if (local->scan_flags & IEEE80211_SCAN_MATCH_SSID) {
ssid = sdata->u.sta.ssid;
ssid_len = sdata->u.sta.ssid_len;
- } else if (sdata->type == IEEE80211_IF_TYPE_AP) {
+ }
+ break;
+ case IEEE80211_IF_TYPE_AP:
+ if (local->scan_flags & IEEE80211_SCAN_MATCH_SSID) {
ssid = sdata->u.ap.ssid;
ssid_len = sdata->u.ap.ssid_len;
- } else
- return -EINVAL;
+ }
+ break;
+ default:
+ return -EOPNOTSUPP;
}
+
return ieee80211_sta_req_scan(dev, ssid, ssid_len);
}
diff --git a/net/mac80211/ieee80211_sta.c b/net/mac80211/ieee80211_sta.c
index 7ba352e..0d99b68 100644
--- a/net/mac80211/ieee80211_sta.c
+++ b/net/mac80211/ieee80211_sta.c
@@ -2154,7 +2154,11 @@
return 0;
} else {
if (ifsta->state != IEEE80211_AUTHENTICATE) {
- ieee80211_sta_start_scan(dev, NULL, 0);
+ if (ifsta->auto_ssid_sel)
+ ieee80211_sta_start_scan(dev, NULL, 0);
+ else
+ ieee80211_sta_start_scan(dev, ifsta->ssid,
+ ifsta->ssid_len);
ifsta->state = IEEE80211_AUTHENTICATE;
set_bit(IEEE80211_STA_REQ_AUTH, &ifsta->request);
} else
diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c
index 6f89b10..2863e72 100644
--- a/net/netfilter/nf_conntrack_netlink.c
+++ b/net/netfilter/nf_conntrack_netlink.c
@@ -1052,17 +1052,18 @@
}
/* implicit 'else' */
- /* we only allow nat config for new conntracks */
- if (cda[CTA_NAT_SRC-1] || cda[CTA_NAT_DST-1]) {
- err = -EINVAL;
- goto out_unlock;
- }
-
/* We manipulate the conntrack inside the global conntrack table lock,
* so there's no need to increase the refcount */
err = -EEXIST;
- if (!(nlh->nlmsg_flags & NLM_F_EXCL))
- err = ctnetlink_change_conntrack(nf_ct_tuplehash_to_ctrack(h), cda);
+ if (!(nlh->nlmsg_flags & NLM_F_EXCL)) {
+ /* we only allow nat config for new conntracks */
+ if (cda[CTA_NAT_SRC-1] || cda[CTA_NAT_DST-1]) {
+ err = -EINVAL;
+ goto out_unlock;
+ }
+ err = ctnetlink_change_conntrack(nf_ct_tuplehash_to_ctrack(h),
+ cda);
+ }
out_unlock:
write_unlock_bh(&nf_conntrack_lock);
diff --git a/net/netfilter/nf_conntrack_sip.c b/net/netfilter/nf_conntrack_sip.c
index 1276a44..d449fa4 100644
--- a/net/netfilter/nf_conntrack_sip.c
+++ b/net/netfilter/nf_conntrack_sip.c
@@ -295,6 +295,7 @@
static int skp_epaddr_len(struct nf_conn *ct, const char *dptr,
const char *limit, int *shift)
{
+ const char *start = dptr;
int s = *shift;
/* Search for @, but stop at the end of the line.
@@ -309,8 +310,10 @@
if (dptr <= limit && *dptr == '@') {
dptr++;
(*shift)++;
- } else
+ } else {
+ dptr = start;
*shift = s;
+ }
return epaddr_len(ct, dptr, limit, shift);
}
@@ -330,7 +333,8 @@
while (dptr <= limit) {
if ((strncmp(dptr, hnfo->lname, hnfo->lnlen) != 0) &&
- (strncmp(dptr, hnfo->sname, hnfo->snlen) != 0)) {
+ (hnfo->sname == NULL ||
+ strncmp(dptr, hnfo->sname, hnfo->snlen) != 0)) {
dptr++;
continue;
}
diff --git a/net/netfilter/xt_u32.c b/net/netfilter/xt_u32.c
index 74f9b14..bec4279 100644
--- a/net/netfilter/xt_u32.c
+++ b/net/netfilter/xt_u32.c
@@ -36,7 +36,7 @@
at = 0;
pos = ct->location[0].number;
- if (skb->len < 4 || pos > skb->len - 4);
+ if (skb->len < 4 || pos > skb->len - 4)
return false;
ret = skb_copy_bits(skb, pos, &n, sizeof(n));
diff --git a/net/netlabel/netlabel_domainhash.c b/net/netlabel/netlabel_domainhash.c
index f46a0ae..b6c844b 100644
--- a/net/netlabel/netlabel_domainhash.c
+++ b/net/netlabel/netlabel_domainhash.c
@@ -126,7 +126,9 @@
if (domain != NULL) {
bkt = netlbl_domhsh_hash(domain);
- list_for_each_entry_rcu(iter, &netlbl_domhsh->tbl[bkt], list)
+ list_for_each_entry_rcu(iter,
+ &rcu_dereference(netlbl_domhsh)->tbl[bkt],
+ list)
if (iter->valid && strcmp(iter->domain, domain) == 0)
return iter;
}
@@ -227,7 +229,7 @@
spin_lock(&netlbl_domhsh_lock);
if (netlbl_domhsh_search(entry->domain, 0) == NULL)
list_add_tail_rcu(&entry->list,
- &netlbl_domhsh->tbl[bkt]);
+ &rcu_dereference(netlbl_domhsh)->tbl[bkt]);
else
ret_val = -EEXIST;
spin_unlock(&netlbl_domhsh_lock);
@@ -423,8 +425,8 @@
iter_bkt < rcu_dereference(netlbl_domhsh)->size;
iter_bkt++, chain_cnt = 0) {
list_for_each_entry_rcu(iter_entry,
- &netlbl_domhsh->tbl[iter_bkt],
- list)
+ &rcu_dereference(netlbl_domhsh)->tbl[iter_bkt],
+ list)
if (iter_entry->valid) {
if (chain_cnt++ < *skip_chain)
continue;
diff --git a/net/sched/act_police.c b/net/sched/act_police.c
index bf90e60f..6085be5 100644
--- a/net/sched/act_police.c
+++ b/net/sched/act_police.c
@@ -16,7 +16,6 @@
#include <linux/string.h>
#include <linux/errno.h>
#include <linux/skbuff.h>
-#include <linux/module.h>
#include <linux/rtnetlink.h>
#include <linux/init.h>
#include <net/act_api.h>
diff --git a/net/socket.c b/net/socket.c
index ec07703..7d44453 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -1168,7 +1168,7 @@
module_put(pf->owner);
err = security_socket_post_create(sock, family, type, protocol, kern);
if (err)
- goto out_release;
+ goto out_sock_release;
*res = sock;
return 0;
diff --git a/net/sunrpc/auth_gss/auth_gss.c b/net/sunrpc/auth_gss/auth_gss.c
index 4bbc59c..53995af 100644
--- a/net/sunrpc/auth_gss/auth_gss.c
+++ b/net/sunrpc/auth_gss/auth_gss.c
@@ -736,9 +736,6 @@
{
dprintk("RPC: gss_free_ctx\n");
- if (ctx->gc_gss_ctx)
- gss_delete_sec_context(&ctx->gc_gss_ctx);
-
kfree(ctx->gc_wire_ctx.data);
kfree(ctx);
}
@@ -753,7 +750,13 @@
static void
gss_free_ctx(struct gss_cl_ctx *ctx)
{
+ struct gss_ctx *gc_gss_ctx;
+
+ gc_gss_ctx = rcu_dereference(ctx->gc_gss_ctx);
+ rcu_assign_pointer(ctx->gc_gss_ctx, NULL);
call_rcu(&ctx->gc_rcu, gss_free_ctx_callback);
+ if (gc_gss_ctx)
+ gss_delete_sec_context(&gc_gss_ctx);
}
static void
diff --git a/net/sunrpc/auth_gss/svcauth_gss.c b/net/sunrpc/auth_gss/svcauth_gss.c
index dc2f41e..7da7050 100644
--- a/net/sunrpc/auth_gss/svcauth_gss.c
+++ b/net/sunrpc/auth_gss/svcauth_gss.c
@@ -42,7 +42,6 @@
#include <linux/pagemap.h>
#include <linux/sunrpc/auth_gss.h>
-#include <linux/sunrpc/svcauth.h>
#include <linux/sunrpc/gss_err.h>
#include <linux/sunrpc/svcauth.h>
#include <linux/sunrpc/svcauth_gss.h>
diff --git a/net/sunrpc/cache.c b/net/sunrpc/cache.c
index 01c3c41..ebe344f 100644
--- a/net/sunrpc/cache.c
+++ b/net/sunrpc/cache.c
@@ -371,8 +371,7 @@
}
if (list_empty(&cache_list)) {
/* module must be being unloaded so its safe to kill the worker */
- cancel_delayed_work(&cache_cleaner);
- flush_scheduled_work();
+ cancel_delayed_work_sync(&cache_cleaner);
}
return 0;
}
diff --git a/net/sunrpc/rpc_pipe.c b/net/sunrpc/rpc_pipe.c
index 650af06..669e12a 100644
--- a/net/sunrpc/rpc_pipe.c
+++ b/net/sunrpc/rpc_pipe.c
@@ -132,8 +132,7 @@
rpci->nwriters = 0;
if (ops->release_pipe)
ops->release_pipe(inode);
- cancel_delayed_work(&rpci->queue_timeout);
- flush_workqueue(rpciod_workqueue);
+ cancel_delayed_work_sync(&rpci->queue_timeout);
}
rpc_inode_setowner(inode, NULL);
mutex_unlock(&inode->i_mutex);
diff --git a/net/sunrpc/sched.c b/net/sunrpc/sched.c
index b5723c2..954d7ec 100644
--- a/net/sunrpc/sched.c
+++ b/net/sunrpc/sched.c
@@ -50,8 +50,6 @@
/*
* rpciod-related stuff
*/
-static DEFINE_MUTEX(rpciod_mutex);
-static atomic_t rpciod_users = ATOMIC_INIT(0);
struct workqueue_struct *rpciod_workqueue;
/*
@@ -961,60 +959,49 @@
spin_unlock(&clnt->cl_lock);
}
+int rpciod_up(void)
+{
+ return try_module_get(THIS_MODULE) ? 0 : -EINVAL;
+}
+
+void rpciod_down(void)
+{
+ module_put(THIS_MODULE);
+}
+
/*
- * Start up the rpciod process if it's not already running.
+ * Start up the rpciod workqueue.
*/
-int
-rpciod_up(void)
+static int rpciod_start(void)
{
struct workqueue_struct *wq;
- int error = 0;
- if (atomic_inc_not_zero(&rpciod_users))
- return 0;
-
- mutex_lock(&rpciod_mutex);
-
- /* Guard against races with rpciod_down() */
- if (rpciod_workqueue != NULL)
- goto out_ok;
/*
* Create the rpciod thread and wait for it to start.
*/
dprintk("RPC: creating workqueue rpciod\n");
- error = -ENOMEM;
wq = create_workqueue("rpciod");
- if (wq == NULL)
- goto out;
-
rpciod_workqueue = wq;
- error = 0;
-out_ok:
- atomic_inc(&rpciod_users);
-out:
- mutex_unlock(&rpciod_mutex);
- return error;
+ return rpciod_workqueue != NULL;
}
-void
-rpciod_down(void)
+static void rpciod_stop(void)
{
- if (!atomic_dec_and_test(&rpciod_users))
- return;
+ struct workqueue_struct *wq = NULL;
- mutex_lock(&rpciod_mutex);
+ if (rpciod_workqueue == NULL)
+ return;
dprintk("RPC: destroying workqueue rpciod\n");
- if (atomic_read(&rpciod_users) == 0 && rpciod_workqueue != NULL) {
- destroy_workqueue(rpciod_workqueue);
- rpciod_workqueue = NULL;
- }
- mutex_unlock(&rpciod_mutex);
+ wq = rpciod_workqueue;
+ rpciod_workqueue = NULL;
+ destroy_workqueue(wq);
}
void
rpc_destroy_mempool(void)
{
+ rpciod_stop();
if (rpc_buffer_mempool)
mempool_destroy(rpc_buffer_mempool);
if (rpc_task_mempool)
@@ -1048,6 +1035,8 @@
rpc_buffer_slabp);
if (!rpc_buffer_mempool)
goto err_nomem;
+ if (!rpciod_start())
+ goto err_nomem;
return 0;
err_nomem:
rpc_destroy_mempool();
diff --git a/net/tipc/port.c b/net/tipc/port.c
index 5d2b9ce..7608815 100644
--- a/net/tipc/port.c
+++ b/net/tipc/port.c
@@ -41,7 +41,6 @@
#include "addr.h"
#include "link.h"
#include "node.h"
-#include "port.h"
#include "name_table.h"
#include "user_reg.h"
#include "msg.h"
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
index e5a3be0..7012891 100644
--- a/net/xfrm/xfrm_policy.c
+++ b/net/xfrm/xfrm_policy.c
@@ -23,10 +23,9 @@
#include <linux/netfilter.h>
#include <linux/module.h>
#include <linux/cache.h>
+#include <linux/audit.h>
#include <net/xfrm.h>
#include <net/ip.h>
-#include <linux/audit.h>
-#include <linux/cache.h>
#include "xfrm_hash.h"
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
index 31be405..d4356e6 100644
--- a/net/xfrm/xfrm_state.c
+++ b/net/xfrm/xfrm_state.c
@@ -19,9 +19,8 @@
#include <linux/ipsec.h>
#include <linux/module.h>
#include <linux/cache.h>
-#include <asm/uaccess.h>
#include <linux/audit.h>
-#include <linux/cache.h>
+#include <asm/uaccess.h>
#include "xfrm_hash.h"
diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl
index 73751ab..dae7d30 100755
--- a/scripts/checkpatch.pl
+++ b/scripts/checkpatch.pl
@@ -9,7 +9,7 @@
my $P = $0;
$P =~ s@.*/@@g;
-my $V = '0.08';
+my $V = '0.09';
use Getopt::Long qw(:config no_auto_abbrev);
@@ -311,7 +311,7 @@
my $Ident = qr{[A-Za-z\d_]+};
my $Storage = qr{extern|static};
- my $Sparse = qr{__user|__kernel|__force|__iomem};
+ my $Sparse = qr{__user|__kernel|__force|__iomem|__must_check|__init_refok};
my $NonptrType = qr{
\b
(?:const\s+)?
@@ -325,6 +325,7 @@
unsigned|
float|
double|
+ bool|
long\s+int|
long\s+long|
long\s+long\s+int|
@@ -340,7 +341,8 @@
}x;
my $Type = qr{
\b$NonptrType\b
- (?:\s*\*+\s*const|\s*\*+)?
+ (?:\s*\*+\s*const|\s*\*+|(?:\s*\[\s*\])+)?
+ (?:\s+$Sparse)*
}x;
my $Declare = qr{(?:$Storage\s+)?$Type};
my $Attribute = qr{const|__read_mostly|__init|__initdata|__meminit};
@@ -494,16 +496,15 @@
ERROR("use tabs not spaces\n" . $herevet);
}
- #
- # The rest of our checks refer specifically to C style
- # only apply those _outside_ comments.
- #
- next if ($in_comment);
-
# Remove comments from the line before processing.
- $line =~ s@/\*.*\*/@@g;
- $line =~ s@/\*.*@@;
- $line =~ s@.*\*/@@;
+ my $comment_edge = ($line =~ s@/\*.*\*/@@g) +
+ ($line =~ s@/\*.*@@) +
+ ($line =~ s@^(.).*\*/@$1@);
+
+# The rest of our checks refer specifically to C style
+# only apply those _outside_ comments. Only skip
+# lines in the middle of comments.
+ next if (!$comment_edge && $in_comment);
# Standardise the strings and chars within the input to simplify matching.
$line = sanitise_line($line);
@@ -599,7 +600,7 @@
if (($prevline !~ /^}/) &&
($prevline !~ /^\+}/) &&
($prevline !~ /^ }/) &&
- ($prevline !~ /\s$name(?:\s+$Attribute)?\s*(?:;|=)/)) {
+ ($prevline !~ /\b\Q$name\E(?:\s+$Attribute)?\s*(?:;|=)/)) {
WARN("EXPORT_SYMBOL(foo); should immediately follow its function/variable\n" . $herecurr);
}
}
@@ -680,9 +681,9 @@
# check for spaces between functions and their parentheses.
if ($line =~ /($Ident)\s+\(/ &&
- $1 !~ /^(?:if|for|while|switch|return|volatile)$/ &&
+ $1 !~ /^(?:if|for|while|switch|return|volatile|__volatile__|__attribute__|format|__extension__|Copyright)$/ &&
$line !~ /$Type\s+\(/ && $line !~ /^.\#\s*define\b/) {
- ERROR("no space between function name and open parenthesis '('\n" . $herecurr);
+ WARN("no space between function name and open parenthesis '('\n" . $herecurr);
}
# Check operator spacing.
# Note we expand the line with the leading + as the real
@@ -712,6 +713,7 @@
$c = 'W' if ($elements[$n + 2] =~ /^\s/);
$c = 'B' if ($elements[$n + 2] =~ /^(\)|\]|;)/);
$c = 'O' if ($elements[$n + 2] eq '');
+ $c = 'E' if ($elements[$n + 2] =~ /\s*\\$/);
} else {
$c = 'E';
}
@@ -812,7 +814,11 @@
# All the others need spaces both sides.
} elsif ($ctx !~ /[EW]x[WE]/) {
- ERROR("need spaces around that '$op' $at\n" . $hereptr);
+ # Ignore email addresses <foo@bar>
+ if (!($op eq '<' && $cb =~ /$;\S+\@\S+>/) &&
+ !($op eq '>' && $cb =~ /<\S+\@\S+$;/)) {
+ ERROR("need spaces around that '$op' $at\n" . $hereptr);
+ }
}
$off += length($elements[$n + 1]);
}
@@ -823,15 +829,24 @@
WARN("multiple assignments should be avoided\n" . $herecurr);
}
-# check for multiple declarations, allowing for a function declaration
-# continuation.
- if ($line =~ /^.\s*$Type\s+$Ident(?:\s*=[^,{]*)?\s*,\s*$Ident.*/ &&
- $line !~ /^.\s*$Type\s+$Ident(?:\s*=[^,{]*)?\s*,\s*$Type\s*$Ident.*/) {
- WARN("declaring multiple variables together should be avoided\n" . $herecurr);
- }
+## # check for multiple declarations, allowing for a function declaration
+## # continuation.
+## if ($line =~ /^.\s*$Type\s+$Ident(?:\s*=[^,{]*)?\s*,\s*$Ident.*/ &&
+## $line !~ /^.\s*$Type\s+$Ident(?:\s*=[^,{]*)?\s*,\s*$Type\s*$Ident.*/) {
+##
+## # Remove any bracketed sections to ensure we do not
+## # falsly report the parameters of functions.
+## my $ln = $line;
+## while ($ln =~ s/\([^\(\)]*\)//g) {
+## }
+## if ($ln =~ /,/) {
+## WARN("declaring multiple variables together should be avoided\n" . $herecurr);
+## }
+## }
#need space before brace following if, while, etc
- if ($line =~ /\(.*\){/ || $line =~ /do{/) {
+ if (($line =~ /\(.*\){/ && $line !~ /\($Type\){/) ||
+ $line =~ /do{/) {
ERROR("need a space before the open brace '{'\n" . $herecurr);
}
@@ -841,6 +856,22 @@
ERROR("need a space after that close brace '}'\n" . $herecurr);
}
+# check spacing on square brackets
+ if ($line =~ /\[\s/ && $line !~ /\[\s*$/) {
+ ERROR("no space after that open square bracket '['\n" . $herecurr);
+ }
+ if ($line =~ /\s\]/) {
+ ERROR("no space before that close square bracket ']'\n" . $herecurr);
+ }
+
+# check spacing on paretheses
+ if ($line =~ /\(\s/ && $line !~ /\(\s*$/) {
+ ERROR("no space after that open parenthesis '('\n" . $herecurr);
+ }
+ if ($line =~ /\s\)/) {
+ ERROR("no space before that close parenthesis ')'\n" . $herecurr);
+ }
+
#goto labels aren't indented, allow a single space however
if ($line=~/^.\s+[A-Za-z\d_]+:(?![0-9]+)/ and
!($line=~/^. [A-Za-z\d_]+:/) and !($line=~/^.\s+default:/)) {
@@ -910,7 +941,7 @@
# grabbing the statement after the identifier
$prevline =~ m{^(.#\s*define\s*$Ident(?:\([^\)]*\))?\s*)(.*)\\\s*$};
##print "1<$1> 2<$2>\n";
- if ($2 ne '') {
+ if (defined $2 && $2 ne '') {
$off = length($1);
$ln--;
$cnt++;
@@ -950,8 +981,10 @@
my ($lvl, @block) = ctx_block_level($nr, $cnt);
my $stmt = join(' ', @block);
- $stmt =~ s/^[^{]*{//;
- $stmt =~ s/}[^}]*$//;
+ $stmt =~ s/(^[^{]*){//;
+ my $before = $1;
+ $stmt =~ s/}([^}]*$)//;
+ my $after = $1;
#print "block<" . join(' ', @block) . "><" . scalar(@block) . ">\n";
#print "stmt<$stmt>\n\n";
@@ -963,12 +996,14 @@
# Also nested if's often require braces to
# disambiguate the else binding so shhh there.
my @semi = ($stmt =~ /;/g);
+ push(@semi, "/**/") if ($stmt =~ m@/\*@);
##print "semi<" . scalar(@semi) . ">\n";
if ($lvl == 0 && scalar(@semi) < 2 &&
- $stmt !~ /{/ && $stmt !~ /\bif\b/) {
+ $stmt !~ /{/ && $stmt !~ /\bif\b/ &&
+ $before !~ /}/ && $after !~ /{/) {
my $herectx = "$here\n" . join("\n", @control, @block[1 .. $#block]) . "\n";
shift(@block);
- ERROR("braces {} are not necessary for single statement blocks\n" . $herectx);
+ WARN("braces {} are not necessary for single statement blocks\n" . $herectx);
}
}
}
@@ -1013,6 +1048,11 @@
# $clean = 0;
# }
+# warn about spacing in #ifdefs
+ if ($line =~ /^.#\s*(ifdef|ifndef|elif)\s\s+/) {
+ ERROR("exactly one space required after that #$1\n" . $herecurr);
+ }
+
# check for spinlock_t definitions without a comment.
if ($line =~ /^.\s*(struct\s+mutex|spinlock_t)\s+\S+;/) {
my $which = $1;
@@ -1027,14 +1067,14 @@
}
}
# check of hardware specific defines
- if ($line =~ m@^.#\s*if.*\b(__i386__|__powerpc64__|__sun__|__s390x__)\b@) {
+ if ($line =~ m@^.#\s*if.*\b(__i386__|__powerpc64__|__sun__|__s390x__)\b@ && $realfile !~ m@include/asm-@) {
CHK("architecture specific defines should be avoided\n" . $herecurr);
}
# check the location of the inline attribute, that it is between
# storage class and type.
- if ($line =~ /$Type\s+(?:inline|__always_inline)\b/ ||
- $line =~ /\b(?:inline|always_inline)\s+$Storage/) {
+ if ($line =~ /$Type\s+(?:inline|__always_inline|noinline)\b/ ||
+ $line =~ /\b(?:inline|__always_inline|noinline)\s+$Storage/) {
ERROR("inline keyword should sit between storage class and type\n" . $herecurr);
}
diff --git a/security/commoncap.c b/security/commoncap.c
index 338606e..7520361 100644
--- a/security/commoncap.c
+++ b/security/commoncap.c
@@ -315,13 +315,13 @@
return 0;
}
-int cap_vm_enough_memory(long pages)
+int cap_vm_enough_memory(struct mm_struct *mm, long pages)
{
int cap_sys_admin = 0;
if (cap_capable(current, CAP_SYS_ADMIN) == 0)
cap_sys_admin = 1;
- return __vm_enough_memory(pages, cap_sys_admin);
+ return __vm_enough_memory(mm, pages, cap_sys_admin);
}
EXPORT_SYMBOL(cap_capable);
diff --git a/security/dummy.c b/security/dummy.c
index 19d813d..853ec22 100644
--- a/security/dummy.c
+++ b/security/dummy.c
@@ -108,13 +108,13 @@
return 0;
}
-static int dummy_vm_enough_memory(long pages)
+static int dummy_vm_enough_memory(struct mm_struct *mm, long pages)
{
int cap_sys_admin = 0;
if (dummy_capable(current, CAP_SYS_ADMIN) == 0)
cap_sys_admin = 1;
- return __vm_enough_memory(pages, cap_sys_admin);
+ return __vm_enough_memory(mm, pages, cap_sys_admin);
}
static int dummy_bprm_alloc_security (struct linux_binprm *bprm)
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 6237933..d8bc417 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -1584,7 +1584,7 @@
* Do not audit the selinux permission check, as this is applied to all
* processes that allocate mappings.
*/
-static int selinux_vm_enough_memory(long pages)
+static int selinux_vm_enough_memory(struct mm_struct *mm, long pages)
{
int rc, cap_sys_admin = 0;
struct task_security_struct *tsec = current->security;
@@ -1600,7 +1600,7 @@
if (rc == 0)
cap_sys_admin = 1;
- return __vm_enough_memory(pages, cap_sys_admin);
+ return __vm_enough_memory(mm, pages, cap_sys_admin);
}
/* binprm security operations */
diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c
index f00161e..6100fc0 100644
--- a/security/selinux/ss/services.c
+++ b/security/selinux/ss/services.c
@@ -2127,7 +2127,7 @@
*rule = NULL;
if (!ss_initialized)
- return -ENOTSUPP;
+ return -EOPNOTSUPP;
switch (field) {
case AUDIT_SUBJ_USER: