diff options
116 files changed, 1548 insertions, 625 deletions
diff --git a/Documentation/DocBook/deviceiobook.tmpl b/Documentation/DocBook/deviceiobook.tmpl index 90ed23df1f68..c917de681ccd 100644 --- a/Documentation/DocBook/deviceiobook.tmpl +++ b/Documentation/DocBook/deviceiobook.tmpl @@ -316,7 +316,8 @@ CPU B: spin_unlock_irqrestore(&dev_lock, flags) <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/HOWTO b/Documentation/HOWTO index f8cc3f8ed152..c64e969dc33b 100644 --- a/Documentation/HOWTO +++ b/Documentation/HOWTO @@ -208,7 +208,7 @@ tools. One such tool that is particularly recommended is the Linux 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 @@ One of the best ways to put into practice your hacking skills is by fixing bugs reported by other people. Not only you will help to make the kernel more stable, you'll learn to fix real world problems and you will improve your skills, and other developers will be aware of your presence. Fixing -bugs is one of the best ways to 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 d6b45a9b29b4..397575880dc4 100644 --- a/Documentation/SubmittingPatches +++ b/Documentation/SubmittingPatches @@ -560,7 +560,7 @@ NO!!!! No more huge patch bombs to linux-kernel@vger.kernel.org people! <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/filesystems/9p.txt b/Documentation/filesystems/9p.txt index bbd8b28c13de..cda6905cbe49 100644 --- a/Documentation/filesystems/9p.txt +++ b/Documentation/filesystems/9p.txt @@ -6,12 +6,26 @@ ABOUT 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 @@ subset of the namespace by extending the path: '#U*'/tmp would just export 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/kernel-parameters.txt b/Documentation/kernel-parameters.txt index 975f029be25c..b41cde31d112 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt @@ -952,14 +952,10 @@ and is between 256 and 4096 characters. It is defined in the file 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. @@ -1184,7 +1180,8 @@ and is between 256 and 4096 characters. It is defined in the file 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. @@ -1826,6 +1823,10 @@ and is between 256 and 4096 characters. It is defined in the file -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. diff --git a/Documentation/ko_KR/HOWTO b/Documentation/ko_KR/HOWTO new file mode 100644 index 000000000000..b51d7ca842ba --- /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/MAINTAINERS b/MAINTAINERS index abe5fa7f9c33..10a6f57776b2 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -167,11 +167,11 @@ S: Maintained 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 diff --git a/arch/i386/kernel/io_apic.c b/arch/i386/kernel/io_apic.c index 4b8a8da4b2e0..e2f4a1c68547 100644 --- a/arch/i386/kernel/io_apic.c +++ b/arch/i386/kernel/io_apic.c @@ -754,14 +754,6 @@ static int pirq_entries [MAX_PIRQS]; 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; diff --git a/arch/i386/kernel/tsc.c b/arch/i386/kernel/tsc.c index debd7dbb4158..a39280b4dd3a 100644 --- a/arch/i386/kernel/tsc.c +++ b/arch/i386/kernel/tsc.c @@ -292,7 +292,6 @@ static struct clocksource clocksource_tsc = { void mark_tsc_unstable(char *reason) { - sched_clock_unstable_event(); if (!tsc_unstable) { tsc_unstable = 1; tsc_enabled = 0; diff --git a/arch/m68knommu/kernel/process.c b/arch/m68knommu/kernel/process.c index 846f97534685..47502d5ec19f 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 48e6b33e8b44..15d62c5279a9 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/sh/Makefile b/arch/sh/Makefile index 3d211aa33cd8..97ac58682d0f 100644 --- a/arch/sh/Makefile +++ b/arch/sh/Makefile @@ -34,6 +34,8 @@ isa-y := $(isa-y)-nofpu 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_SH4A) += $(call cc-option,-m4a,) \ 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 6e4e96541358..dab193293f20 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 @@ static int __init sh4202_devices_setup(void) 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/x86_64/kernel/io_apic.c b/arch/x86_64/kernel/io_apic.c index f57f8b901912..966fa1062491 100644 --- a/arch/x86_64/kernel/io_apic.c +++ b/arch/x86_64/kernel/io_apic.c @@ -397,14 +397,12 @@ static void clear_IO_APIC (void) 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) diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c index 91dc4b316a08..9b2c0f74f869 100644 --- a/drivers/acpi/battery.c +++ b/drivers/acpi/battery.c @@ -113,7 +113,7 @@ struct acpi_battery_info { acpi_string oem_info; }; -enum acpi_battery_files { +enum acpi_battery_files{ ACPI_BATTERY_INFO = 0, ACPI_BATTERY_STATE, ACPI_BATTERY_ALARM, @@ -129,14 +129,13 @@ struct acpi_battery_flags { }; struct acpi_battery { + struct mutex mutex; struct acpi_device *device; struct acpi_battery_flags flags; struct acpi_buffer bif_data; struct acpi_buffer bst_data; - struct mutex lock; unsigned long alarm; unsigned long update_time[ACPI_BATTERY_NUMFILES]; - }; inline int acpi_battery_present(struct acpi_battery *battery) @@ -236,10 +235,10 @@ static int acpi_battery_get_info(struct acpi_battery *battery) return 0; /* Evaluate _BIF */ - mutex_lock(&battery->lock); - status = acpi_evaluate_object(acpi_battery_handle(battery), "_BIF", - NULL, &buffer); - mutex_unlock(&battery->lock); + + status = + acpi_evaluate_object(acpi_battery_handle(battery), "_BIF", NULL, + &buffer); if (ACPI_FAILURE(status)) { ACPI_EXCEPTION((AE_INFO, status, "Evaluating _BIF")); return -ENODEV; @@ -286,10 +285,10 @@ static int acpi_battery_get_state(struct acpi_battery *battery) return 0; /* Evaluate _BST */ - mutex_lock(&battery->lock); - status = acpi_evaluate_object(acpi_battery_handle(battery), "_BST", - NULL, &buffer); - mutex_unlock(&battery->lock); + + status = + acpi_evaluate_object(acpi_battery_handle(battery), "_BST", NULL, + &buffer); if (ACPI_FAILURE(status)) { ACPI_EXCEPTION((AE_INFO, status, "Evaluating _BST")); return -ENODEV; @@ -337,10 +336,9 @@ static int acpi_battery_set_alarm(struct acpi_battery *battery, arg0.integer.value = alarm; - mutex_lock(&battery->lock); - status = acpi_evaluate_object(acpi_battery_handle(battery), "_BTP", + status = + acpi_evaluate_object(acpi_battery_handle(battery), "_BTP", &arg_list, NULL); - mutex_unlock(&battery->lock); if (ACPI_FAILURE(status)) return -ENODEV; @@ -660,6 +658,8 @@ acpi_battery_write_alarm(struct file *file, if (!battery || (count > sizeof(alarm_string) - 1)) return -EINVAL; + mutex_lock(&battery->mutex); + result = acpi_battery_update(battery, 1, &update_result); if (result) { result = -ENODEV; @@ -688,7 +688,9 @@ acpi_battery_write_alarm(struct file *file, acpi_battery_check_result(battery, result); if (!result) - return count; + result = count; + + mutex_unlock(&battery->mutex); return result; } @@ -712,6 +714,8 @@ static int acpi_battery_read(int fid, struct seq_file *seq) int update_result = ACPI_BATTERY_NONE_UPDATE; int update = 0; + mutex_lock(&battery->mutex); + update = (get_seconds() - battery->update_time[fid] >= update_time); update = (update | battery->flags.update[fid]); @@ -729,6 +733,7 @@ static int acpi_battery_read(int fid, struct seq_file *seq) result = acpi_read_funcs[fid].print(seq, result); acpi_battery_check_result(battery, result); battery->flags.update[fid] = result; + mutex_unlock(&battery->mutex); return result; } @@ -895,7 +900,10 @@ static int acpi_battery_add(struct acpi_device *device) if (!battery) return -ENOMEM; - mutex_init(&battery->lock); + mutex_init(&battery->mutex); + + mutex_lock(&battery->mutex); + battery->device = device; strcpy(acpi_device_name(device), ACPI_BATTERY_DEVICE_NAME); strcpy(acpi_device_class(device), ACPI_BATTERY_CLASS); @@ -931,6 +939,7 @@ static int acpi_battery_add(struct acpi_device *device) kfree(battery); } + mutex_unlock(&battery->mutex); return result; } @@ -945,6 +954,8 @@ static int acpi_battery_remove(struct acpi_device *device, int type) battery = acpi_driver_data(device); + mutex_lock(&battery->mutex); + status = acpi_remove_notify_handler(device->handle, ACPI_ALL_NOTIFY, acpi_battery_notify); @@ -955,7 +966,9 @@ static int acpi_battery_remove(struct acpi_device *device, int type) kfree(battery->bst_data.pointer); - mutex_destroy(&battery->lock); + mutex_unlock(&battery->mutex); + + mutex_destroy(&battery->mutex); kfree(battery); diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index 56bee9e065cf..43749c86861f 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c @@ -696,14 +696,6 @@ ec_parse_device(acpi_handle handle, u32 Level, void *context, void **retval) return AE_CTRL_TERMINATE; } -static void ec_remove_handlers(struct acpi_ec *ec) -{ - acpi_remove_address_space_handler(ec->handle, - ACPI_ADR_SPACE_EC, - &acpi_ec_space_handler); - acpi_remove_gpe_handler(NULL, ec->gpe, &acpi_ec_gpe_handler); -} - static int acpi_ec_add(struct acpi_device *device) { struct acpi_ec *ec = NULL; @@ -727,13 +719,16 @@ static int acpi_ec_add(struct acpi_device *device) /* Check if we found the boot EC */ if (boot_ec) { if (boot_ec->gpe == ec->gpe) { - ec_remove_handlers(boot_ec); - mutex_destroy(&boot_ec->lock); - kfree(boot_ec); - first_ec = boot_ec = NULL; + /* We might have incorrect info for GL at boot time */ + mutex_lock(&boot_ec->lock); + boot_ec->global_lock = ec->global_lock; + /* Copy handlers from new ec into boot ec */ + list_splice(&ec->list, &boot_ec->list); + mutex_unlock(&boot_ec->lock); + kfree(ec); + ec = boot_ec; } - } - if (!first_ec) + } else first_ec = ec; ec->handle = device->handle; acpi_driver_data(device) = ec; @@ -762,6 +757,9 @@ static int acpi_ec_remove(struct acpi_device *device, int type) if (ec == first_ec) first_ec = NULL; + /* Don't touch boot EC */ + if (boot_ec != ec) + kfree(ec); return 0; } @@ -825,7 +823,9 @@ static int acpi_ec_start(struct acpi_device *device) if (!ec) return -EINVAL; - ret = ec_install_handlers(ec); + /* Boot EC is already working */ + if (ec != boot_ec) + ret = ec_install_handlers(ec); /* EC is fully operational, allow queries */ atomic_set(&ec->query_pending, 0); @@ -835,6 +835,7 @@ static int acpi_ec_start(struct acpi_device *device) static int acpi_ec_stop(struct acpi_device *device, int type) { + acpi_status status; struct acpi_ec *ec; if (!device) @@ -843,7 +844,21 @@ static int acpi_ec_stop(struct acpi_device *device, int type) ec = acpi_driver_data(device); if (!ec) return -EINVAL; - ec_remove_handlers(ec); + + /* Don't touch boot EC */ + if (ec == boot_ec) + return 0; + + status = acpi_remove_address_space_handler(ec->handle, + ACPI_ADR_SPACE_EC, + &acpi_ec_space_handler); + if (ACPI_FAILURE(status)) + return -ENODEV; + + status = acpi_remove_gpe_handler(NULL, ec->gpe, &acpi_ec_gpe_handler); + if (ACPI_FAILURE(status)) + return -ENODEV; + return 0; } diff --git a/drivers/acpi/hardware/hwsleep.c b/drivers/acpi/hardware/hwsleep.c index 76c525dc590b..cf69c0040a39 100644 --- a/drivers/acpi/hardware/hwsleep.c +++ b/drivers/acpi/hardware/hwsleep.c @@ -576,13 +576,10 @@ acpi_status acpi_leave_sleep_state(u8 sleep_state) 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 @@ acpi_status acpi_leave_sleep_state(u8 sleep_state) 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 ab65b2c2560e..f39fbc6b9237 100644 --- a/drivers/acpi/namespace/nsxfeval.c +++ b/drivers/acpi/namespace/nsxfeval.c @@ -540,7 +540,7 @@ acpi_ns_get_device_callback(acpi_handle obj_handle, ******************************************************************************/ 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_idle.c b/drivers/acpi/processor_idle.c index a8634a0655fc..d9b8af763e1e 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 @@ static void acpi_processor_idle(void) * 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 @@ static void acpi_processor_idle(void) 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 @@ static void acpi_processor_idle(void) /* 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 @@ static void acpi_processor_idle(void) 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 @@ static void acpi_processor_idle(void) /* 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; diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index be74347d1354..64620d668742 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c @@ -35,8 +35,9 @@ struct acpi_device_bus_id{ * 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 e8cff5dd4cbc..c52ade816fb4 100644 --- a/drivers/acpi/sleep/main.c +++ b/drivers/acpi/sleep/main.c @@ -305,7 +305,7 @@ int acpi_pm_device_sleep_state(struct device *dev, int wake, int *d_min_p) 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 1da64b4518c0..8cc9492ffbf2 100644 --- a/drivers/acpi/tables/tbutils.c +++ b/drivers/acpi/tables/tbutils.c @@ -51,6 +51,65 @@ ACPI_MODULE_NAME("tbutils") 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 @@ acpi_tb_parse_root_table(acpi_physical_address rsdp_address, u8 flags) 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 @@ acpi_tb_parse_root_table(acpi_physical_address rsdp_address, u8 flags) */ 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_tb_parse_root_table(acpi_physical_address rsdp_address, u8 flags) */ 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/thermal.c b/drivers/acpi/thermal.c index 2c9cfe297f73..bc6d5866ef98 100644 --- a/drivers/acpi/thermal.c +++ b/drivers/acpi/thermal.c @@ -77,23 +77,27 @@ MODULE_LICENSE("GPL"); static int act; module_param(act, int, 0644); -MODULE_PARM_DESC(act, "Disable or override all lowest active trip points.\n"); +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, 0444); -MODULE_PARM_DESC(tzp, "Thermal zone polling frequency, in 1/10 seconds.\n"); +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 disable action on ACPI thermal zone critical and hot trips.\n"); +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.\n"); +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.\n"); +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); @@ -340,6 +344,20 @@ static int acpi_thermal_get_trip_points(struct acpi_thermal *tz) 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 = @@ -1075,9 +1093,9 @@ static int acpi_thermal_add_fs(struct acpi_device *device) 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; @@ -1351,6 +1369,13 @@ static int thermal_act(struct dmi_system_id *d) { } 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) { @@ -1399,6 +1424,14 @@ static struct dmi_system_id thermal_dmi_table[] __initdata = { 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 */ diff --git a/drivers/acpi/utilities/utglobal.c b/drivers/acpi/utilities/utglobal.c index 1621655d6e2b..93ea8290b4f7 100644 --- a/drivers/acpi/utilities/utglobal.c +++ b/drivers/acpi/utilities/utglobal.c @@ -126,6 +126,7 @@ const char *acpi_format_exception(acpi_status status) "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 9a5cfcfd8da5..6659bdd2a454 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 acpi_video_bus { 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 @@ static void acpi_video_bus_notify(acpi_handle handle, u32 event, void *data) { 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 @@ static void acpi_video_bus_notify(acpi_handle handle, u32 event, void *data) 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_proc_event(device, event, 0); + keycode = KEY_SWITCHVIDEOMODE; break; case ACPI_VIDEO_NOTIFY_PROBE: /* User plugged in or removed a video @@ -1784,21 +1791,37 @@ static void acpi_video_bus_notify(acpi_handle handle, u32 event, void *data) acpi_video_device_rebind(video); acpi_video_switch_output(video, event); 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_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,30 +1829,55 @@ static void acpi_video_device_notify(acpi_handle handle, u32 event, void *data) { 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) */ + 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_CYCLE_BRIGHTNESS: /* Cycle brightness */ 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_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; } @@ -1838,6 +1886,7 @@ 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) @@ -1881,6 +1930,39 @@ static int acpi_video_bus_add(struct acpi_device *device) 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 +1996,7 @@ static int acpi_video_bus_remove(struct acpi_device *device, int type) 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/libata-core.c b/drivers/ata/libata-core.c index 99d4fbffb0df..2ad4dda6d4a7 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -3700,11 +3700,16 @@ int ata_dev_revalidate(struct ata_device *dev, unsigned int readid_flags) 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_it821x.c b/drivers/ata/pata_it821x.c index 430673be1df7..7225124d96c2 100644 --- a/drivers/ata/pata_it821x.c +++ b/drivers/ata/pata_it821x.c @@ -587,7 +587,7 @@ static int it821x_port_start(struct ata_port *ap) 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 69a5aa4949f5..e3245b36269a 100644 --- a/drivers/ata/pata_pdc2027x.c +++ b/drivers/ata/pata_pdc2027x.c @@ -563,13 +563,13 @@ static long pdc_read_counter(struct ata_host *host) 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 @@ static long pdc_detect_pll_input_clock(struct ata_host *host) 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 @@ static long pdc_detect_pll_input_clock(struct ata_host *host) 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 66bd0e83ac07..2bd7645f1a88 100644 --- a/drivers/ata/pata_sis.c +++ b/drivers/ata/pata_sis.c @@ -54,6 +54,7 @@ struct sis_laptop { 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 f645fe22cd1e..ea18e33f50ef 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 @@ static int via_cable_override(struct pci_dev *pdev) /* 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/char/tty_io.c b/drivers/char/tty_io.c index 51ea93cab6c4..9c867cf6de64 100644 --- a/drivers/char/tty_io.c +++ b/drivers/char/tty_io.c @@ -2063,8 +2063,7 @@ static int init_dev(struct tty_driver *driver, int idx, } 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; @@ -2094,8 +2093,7 @@ static int init_dev(struct tty_driver *driver, int idx, } 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; diff --git a/drivers/lguest/Kconfig b/drivers/lguest/Kconfig index fd6925f41647..41e2250613a1 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--- diff --git a/drivers/media/dvb/b2c2/flexcop-i2c.c b/drivers/media/dvb/b2c2/flexcop-i2c.c index 02a0ea6e1c17..6bf858a436c9 100644 --- a/drivers/media/dvb/b2c2/flexcop-i2c.c +++ b/drivers/media/dvb/b2c2/flexcop-i2c.c @@ -135,6 +135,13 @@ static int flexcop_master_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg msgs 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 acf026342ec5..bdd797071cb0 100644 --- a/drivers/media/dvb/dvb-core/dvb_net.c +++ b/drivers/media/dvb/dvb-core/dvb_net.c @@ -800,7 +800,8 @@ static int dvb_net_ts_callback(const u8 *buffer1, size_t buffer1_len, } -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 @@ static int dvb_net_sec_callback(const u8 *buffer1, size_t buffer1_len, * 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/video/em28xx/em28xx-video.c b/drivers/media/video/em28xx/em28xx-video.c index 2c7b158ce7e1..40307f3f6fe3 100644 --- a/drivers/media/video/em28xx/em28xx-video.c +++ b/drivers/media/video/em28xx/em28xx-video.c @@ -1772,6 +1772,7 @@ static int em28xx_usb_probe(struct usb_interface *interface, 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/pwc/pwc-if.c b/drivers/media/video/pwc/pwc-if.c index 9c0e8d18c2f6..3d81966d8c42 100644 --- a/drivers/media/video/pwc/pwc-if.c +++ b/drivers/media/video/pwc/pwc-if.c @@ -1196,12 +1196,19 @@ static int pwc_video_open(struct inode *inode, struct file *file) 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 @@ static int pwc_video_close(struct inode *inode, struct file *file) 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 @@ static int pwc_video_close(struct inode *inode, struct file *file) 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 @@ static void usb_pwc_disconnect(struct usb_interface *intf) /* 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 910a04f53920..8e8e5b27e77e 100644 --- a/drivers/media/video/pwc/pwc.h +++ b/drivers/media/video/pwc/pwc.h @@ -193,6 +193,7 @@ struct pwc_device 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/misc/asus-laptop.c b/drivers/misc/asus-laptop.c index f8ae58f01637..7dce318df1bd 100644 --- a/drivers/misc/asus-laptop.c +++ b/drivers/misc/asus-laptop.c @@ -1072,7 +1072,8 @@ static void asus_backlight_exit(void) } #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 743bd49ae6f5..d38ddce592c0 100644 --- a/drivers/misc/sony-laptop.c +++ b/drivers/misc/sony-laptop.c @@ -856,6 +856,15 @@ static struct dmi_system_id sony_nc_ids[] = { }, }, { + .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, @@ -2308,8 +2317,6 @@ static int sony_pic_remove(struct acpi_device *device, int type) 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; @@ -2319,6 +2326,8 @@ static int sony_pic_remove(struct acpi_device *device, int type) release_region(spic_dev.cur_ioport->io.minimum, spic_dev.cur_ioport->io.address_length); + sonypi_compat_exit(); + sony_laptop_remove_input(); /* pf attrs */ @@ -2384,6 +2393,9 @@ static int sony_pic_add(struct acpi_device *device) 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, @@ -2398,7 +2410,7 @@ static int sony_pic_add(struct acpi_device *device) 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 */ @@ -2438,9 +2450,6 @@ static int sony_pic_add(struct acpi_device *device) if (result) goto err_remove_pf; - if (sonypi_compat_init()) - goto err_remove_pf; - return 0; err_remove_pf: @@ -2456,6 +2465,9 @@ err_release_region: 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/mmc/core/bus.c b/drivers/mmc/core/bus.c index fe0e785ed7d2..817a79462b3d 100644 --- a/drivers/mmc/core/bus.c +++ b/drivers/mmc/core/bus.c @@ -186,12 +186,10 @@ struct mmc_card *mmc_alloc_card(struct mmc_host *host) { 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 6a7e29849603..2c7ce8f43a9a 100644 --- a/drivers/mmc/core/host.c +++ b/drivers/mmc/core/host.c @@ -58,12 +58,10 @@ struct mmc_host *mmc_alloc_host(int extra, struct device *dev) { 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/sdhci.c b/drivers/mmc/host/sdhci.c index f2bc87ac24f7..20a7d89e01ba 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c @@ -385,6 +385,9 @@ static void sdhci_prepare_data(struct sdhci_host *host, struct mmc_data *data) 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 @@ static void sdhci_set_transfer_mode(struct sdhci_host *host, { 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 @@ static void sdhci_finish_data(struct sdhci_host *host) /* * 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 @@ static void sdhci_finish_command(struct sdhci_host *host) 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 @@ static void sdhci_cmd_irq(struct sdhci_host *host, u32 intmask) 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 @@ static void sdhci_data_irq(struct sdhci_host *host, u32 intmask) 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 @@ static void sdhci_data_irq(struct sdhci_host *host, u32 intmask) 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 @@ static int __devinit sdhci_probe_slot(struct pci_dev *pdev, int slot) */ 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 d157776c1149..e28987d6d2eb 100644 --- a/drivers/mmc/host/sdhci.h +++ b/drivers/mmc/host/sdhci.h @@ -182,6 +182,7 @@ struct sdhci_host { 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/pci/hotplug/acpiphp_ibm.c b/drivers/pci/hotplug/acpiphp_ibm.c index d2c410cd3c45..56829f82be4a 100644 --- a/drivers/pci/hotplug/acpiphp_ibm.c +++ b/drivers/pci/hotplug/acpiphp_ibm.c @@ -402,7 +402,7 @@ static acpi_status __init ibm_find_acpi_device(acpi_handle handle, 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 79ff6b4de3a6..37d72f123a80 100644 --- a/drivers/pci/hotplug/cpqphp_ctrl.c +++ b/drivers/pci/hotplug/cpqphp_ctrl.c @@ -1746,10 +1746,8 @@ static void pushbutton_helper_thread(unsigned long data) 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 c6e132d7c0f7..4c36e80f6d26 100644 --- a/drivers/pci/pci.h +++ b/drivers/pci/pci.h @@ -5,12 +5,7 @@ extern int pci_uevent(struct device *dev, char **envp, int num_envp, 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 @@ static inline int pci_proc_detach_bus(struct pci_bus *bus) { return 0; } /* 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 34b8dae0d90f..27e00b2d7b5b 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c @@ -653,20 +653,20 @@ int pci_scan_bridge(struct pci_bus *bus, struct pci_dev * dev, int max, int pass 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 c559085c89a5..2d40f437b9fc 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c @@ -947,7 +947,7 @@ static void k8t_sound_hostbridge(struct pci_dev *dev) 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 @@ static void __devinit quirk_e100_interrupt(struct pci_dev *dev) 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_GCN 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 b6a4f02b01d1..6c0440c20e31 100644 --- a/drivers/pnp/card.c +++ b/drivers/pnp/card.c @@ -25,13 +25,13 @@ static const struct pnp_card_device_id *match_card(struct pnp_card_driver *drv, 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 @@ static int pnp_interface_attach_card(struct pnp_card *card) return 0; - err_name: +err_name: device_remove_file(&card->dev, &dev_attr_name); return rc; } @@ -321,10 +321,10 @@ struct pnp_dev *pnp_request_card_device(struct pnp_card_link *clink, 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 @@ struct pnp_dev *pnp_request_card_device(struct pnp_card_link *clink, 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 61066fdb9e6d..d5964feb14de 100644 --- a/drivers/pnp/core.c +++ b/drivers/pnp/core.c @@ -52,9 +52,6 @@ int pnp_register_protocol(struct pnp_protocol *protocol) 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 @@ static void pnp_free_ids(struct pnp_dev *dev) 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) */ 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 30b8f6f3258a..2fa64a6b25c8 100644 --- a/drivers/pnp/driver.c +++ b/drivers/pnp/driver.c @@ -118,7 +118,7 @@ static int pnp_device_probe(struct device *dev) goto fail; return error; - fail: +fail: pnp_device_detach(pnp_dev); return error; } @@ -232,10 +232,6 @@ int pnp_add_id(struct pnp_id *id, struct pnp_dev *dev) { 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 fe6684e13e82..a0cfb75bbb8d 100644 --- a/drivers/pnp/interface.c +++ b/drivers/pnp/interface.c @@ -459,7 +459,8 @@ pnp_set_current_resources(struct device *dmdev, struct device_attribute *attr, up(&pnp_res_mutex); goto done; } - done: + +done: if (retval < 0) return retval; return count; @@ -499,10 +500,10 @@ int pnp_interface_attach_device(struct pnp_dev *dev) 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 b4e2aa995b53..b035d60a1dcc 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 @@ MODULE_LICENSE("GPL"); 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 @@ static int __init isapnp_isolate(void) } else if (iteration > 1) { break; } - __next: +__next: if (csn == 255) break; checksum = 0x6a; @@ -733,7 +729,7 @@ static int __init isapnp_create_device(struct pnp_card *card, "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 @@ static void __init isapnp_parse_resource_map(struct pnp_card *card) "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_protocol); 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 @@ static int isapnp_get_resources(struct pnp_dev *dev, 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_set_resources(struct pnp_dev *dev, 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 @@ static int __init isapnp_init(void) 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 @@ static int __init isapnp_init(void) } 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 @@ static int __init isapnp_init(void) 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 @@ static int __init isapnp_init(void) } } } - 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 3fbc0f9ffc26..560ccb640816 100644 --- a/drivers/pnp/isapnp/proc.c +++ b/drivers/pnp/isapnp/proc.c @@ -112,33 +112,6 @@ static int isapnp_proc_attach_device(struct pnp_dev *dev) 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 @@ int __init isapnp_proc_init(void) } 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 3bda513a6bd3..0826287eef53 100644 --- a/drivers/pnp/manager.c +++ b/drivers/pnp/manager.c @@ -21,9 +21,6 @@ static int pnp_assign_port(struct pnp_dev *dev, struct pnp_port *rule, int idx) 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 @@ static int pnp_assign_mem(struct pnp_dev *dev, struct pnp_mem *rule, int idx) 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 @@ static int pnp_assign_irq(struct pnp_dev *dev, struct pnp_irq *rule, int idx) 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 @@ static int pnp_assign_dma(struct pnp_dev *dev, struct pnp_dma *rule, int idx) 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 @@ static int pnp_assign_resources(struct pnp_dev *dev, int depnum) 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 pnp_manual_config_dev(struct pnp_dev *dev, struct pnp_resource_table *res, 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 @@ int pnp_manual_config_dev(struct pnp_dev *dev, struct pnp_resource_table *res, kfree(bak); return 0; - fail: +fail: dev->res = *bak; up(&pnp_res_mutex); kfree(bak); @@ -460,9 +446,6 @@ int pnp_auto_config_dev(struct pnp_dev *dev) 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 pnp_activate_dev(struct pnp_dev *dev) { int error; - if (!dev) - return -EINVAL; if (dev->active) return 0; /* the device is already active */ @@ -568,8 +549,6 @@ int pnp_disable_dev(struct pnp_dev *dev) { int error; - if (!dev) - return -EINVAL; if (!dev->active) return 0; /* the device is already disabled */ @@ -596,8 +575,6 @@ int pnp_disable_dev(struct pnp_dev *dev) 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 616fc72190bf..a5a372222d69 100644 --- a/drivers/pnp/pnpacpi/core.c +++ b/drivers/pnp/pnpacpi/core.c @@ -248,9 +248,9 @@ static int __init pnpacpi_add_device(struct acpi_device *device) 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 ce5027feb3da..0e3b8d0ff06b 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 void pnpacpi_parse_allocated_address_space(struct pnp_resource_table *res 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 @@ static acpi_status pnpacpi_option_resource(struct acpi_resource *res, 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 int pnpacpi_supported_resource(struct acpi_resource *res) 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_count_resources(struct acpi_resource *res, 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 pnpacpi_encode_resources(struct pnp_resource_table *res_table, 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 3692a099b45f..0691f473e9d4 100644 --- a/drivers/pnp/pnpbios/core.c +++ b/drivers/pnp/pnpbios/core.c @@ -419,7 +419,6 @@ static void __init build_devlist(void) 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 @@ static int __init pnpbios_setup(char *str) } __setup("pnpbios=", pnpbios_setup); -#endif /* PnP BIOS signature: "$PnP" */ #define PNP_SIGNATURE (('$' << 0) + ('P' << 8) + ('n' << 16) + ('P' << 24)) @@ -591,6 +589,7 @@ subsys_initcall(pnpbios_init); 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 @@ static int __init pnpbios_thread_init(void) 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 9c8c07701b65..9d9841f24a85 100644 --- a/drivers/pnp/pnpbios/proc.c +++ b/drivers/pnp/pnpbios/proc.c @@ -212,7 +212,7 @@ static int proc_write_node(struct file *file, const char __user * buf, 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 04ecd7b67230..3fabf11b0027 100644 --- a/drivers/pnp/pnpbios/rsparser.c +++ b/drivers/pnp/pnpbios/rsparser.c @@ -238,7 +238,7 @@ static unsigned char *pnpbios_parse_allocated_resource_data(unsigned char *p, 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 @@ static void pnpbios_parse_fixed_mem32_option(unsigned char *p, int size, struct pnp_option *option) { struct pnp_mem *mem; + mem = kzalloc(sizeof(struct pnp_mem), GFP_KERNEL); if (!mem) return; @@ -468,7 +469,7 @@ static unsigned char *pnpbios_parse_resource_option_data(unsigned char *p, 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 @@ static unsigned char *pnpbios_parse_compatible_ids(unsigned char *p, 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 @@ static unsigned char *pnpbios_encode_allocated_resource_data(unsigned char *p, 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 ea6ec14a0559..ef1286900db3 100644 --- a/drivers/pnp/resource.c +++ b/drivers/pnp/resource.c @@ -47,9 +47,6 @@ struct pnp_option *pnp_register_independent_option(struct pnp_dev *dev) { 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 *pnp_register_dependent_option(struct pnp_dev *dev, { struct pnp_option *option; - if (!dev) - return NULL; - option = pnp_build_option(priority); if (dev->dependent) { @@ -83,11 +77,6 @@ int pnp_register_irq_resource(struct pnp_option *option, struct pnp_irq *data) { 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 @@ int pnp_register_dma_resource(struct pnp_option *option, struct pnp_dma *data) { 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 @@ int pnp_register_port_resource(struct pnp_option *option, struct pnp_port *data) { 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 @@ int pnp_register_mem_resource(struct pnp_option *option, struct pnp_mem *data) { 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/usb/Kconfig b/drivers/usb/Kconfig index 63436892688c..7580aa5da0f8 100644 --- a/drivers/usb/Kconfig +++ b/drivers/usb/Kconfig @@ -21,6 +21,7 @@ config USB_ARCH_HAS_HCD 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 02c52f8d5dbf..a73e714288e5 100644 --- a/drivers/usb/atm/cxacru.c +++ b/drivers/usb/atm/cxacru.c @@ -456,7 +456,6 @@ static int cxacru_start_wait_urb(struct urb *urb, struct completion *done, 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 @@ static int cxacru_start_wait_urb(struct urb *urb, struct completion *done, 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 a1a1c9d467e0..29807d048b04 100644 --- a/drivers/usb/atm/ueagle-atm.c +++ b/drivers/usb/atm/ueagle-atm.c @@ -1721,9 +1721,12 @@ static int uea_bind(struct usbatm_data *usbatm, struct usb_interface *intf, 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 fe940e0536e0..f51e22490edf 100644 --- a/drivers/usb/class/cdc-acm.c +++ b/drivers/usb/class/cdc-acm.c @@ -921,6 +921,10 @@ skip_normal_probe: 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 @@ static void acm_disconnect(struct usb_interface *intf) 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 654857493a82..a1ad11d0c47c 100644 --- a/drivers/usb/core/driver.c +++ b/drivers/usb/core/driver.c @@ -1224,6 +1224,8 @@ static int usb_autopm_do_device(struct usb_device *udev, int inc_usage_cnt) 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 @@ static int usb_autopm_do_device(struct usb_device *udev, int inc_usage_cnt) 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 @@ static int usb_autopm_do_interface(struct usb_interface *intf, 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 e341a1da517f..f7b337feb3ea 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -1644,9 +1644,10 @@ static int finish_port_resume(struct usb_device *udev) * 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 b6bd05e3d439..d8f7b089a8f0 100644 --- a/drivers/usb/core/message.c +++ b/drivers/usb/core/message.c @@ -637,12 +637,12 @@ int usb_get_descriptor(struct usb_device *dev, unsigned char type, unsigned char 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 @@ static int usb_if_uevent(struct device *dev, char **envp, int num_envp, 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 b7917c5a3c6f..9e467118dc94 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 @@ static const struct usb_device_id usb_quirk_list[] = { { 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 @@ static const struct usb_device_id usb_quirk_list[] = { { 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 f2fbdc7fe376..d008d1360a7a 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 be7a1bd2823b..965ad7bec7b7 100644 --- a/drivers/usb/gadget/file_storage.c +++ b/drivers/usb/gadget/file_storage.c @@ -599,7 +599,6 @@ enum fsg_buffer_state { struct fsg_buffhd { void *buf; - dma_addr_t dma; enum fsg_buffer_state state; struct fsg_buffhd *next; @@ -1295,6 +1294,7 @@ static int class_setup_req(struct fsg_dev *fsg, 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 @@ static int class_setup_req(struct fsg_dev *fsg, 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 @@ static int class_setup_req(struct fsg_dev *fsg, 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 @@ static int class_setup_req(struct fsg_dev *fsg, 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 @@ static int send_status(struct fsg_dev *fsg) 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 @@ reset: 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 10b2b33b8698..d57bcfbc08a5 100644 --- a/drivers/usb/gadget/fsl_usb2_udc.c +++ b/drivers/usb/gadget/fsl_usb2_udc.c @@ -1277,31 +1277,32 @@ static void setup_received_irq(struct fsl_udc *udc, 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 @@ static void setup_received_irq(struct fsl_udc *udc, ? 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,39 +1331,42 @@ static void setup_received_irq(struct fsl_udc *udc, 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); } - break; + return; } - /* 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; - } + default: 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; + } } /* Process request for Data or Status phase of ep0 diff --git a/drivers/usb/gadget/pxa2xx_udc.c b/drivers/usb/gadget/pxa2xx_udc.c index 72b4ebbf132d..1407ad1c8128 100644 --- a/drivers/usb/gadget/pxa2xx_udc.c +++ b/drivers/usb/gadget/pxa2xx_udc.c @@ -967,7 +967,7 @@ static int pxa2xx_udc_pullup(struct usb_gadget *_gadget, int is_active) 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 @@ static int pxa2xx_udc_suspend(struct platform_device *dev, pm_message_t state) { 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 2f529828c74d..565d6ef4c4cf 100644 --- a/drivers/usb/host/Kconfig +++ b/drivers/usb/host/Kconfig @@ -237,7 +237,7 @@ config USB_SL811_CS 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 5d1b12aad776..b1d19268cb23 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 @@ static const struct hc_driver ehci_au1xxx_hc_driver = { /* * 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-ppc-soc.c b/drivers/usb/host/ehci-ppc-soc.c index c2cedb09ed8b..4f99b0eb27bc 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 @@ static const struct hc_driver ehci_ppc_soc_hc_driver = { /* * 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/ohci-dbg.c b/drivers/usb/host/ohci-dbg.c index 6f9e43e9a6ca..f61c6cdd06f2 100644 --- a/drivers/usb/host/ohci-dbg.c +++ b/drivers/usb/host/ohci-dbg.c @@ -74,7 +74,7 @@ urb_print (struct urb * urb, char * str, int small) #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 d60f1985320c..40a1de4c256e 100644 --- a/drivers/usb/host/r8a66597-hcd.c +++ b/drivers/usb/host/r8a66597-hcd.c @@ -2208,8 +2208,6 @@ static int __init r8a66597_probe(struct platform_device *pdev) 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 7f765ec038cd..b88eb3c62c02 100644 --- a/drivers/usb/host/u132-hcd.c +++ b/drivers/usb/host/u132-hcd.c @@ -1520,12 +1520,15 @@ static void u132_hcd_endp_work_scheduler(struct work_struct *work) } } } +#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 cff6fd190a28..77bb893bf2e9 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 e67ce25f7512..86724e885704 100644 --- a/drivers/usb/serial/belkin_sa.c +++ b/drivers/usb/serial/belkin_sa.c @@ -383,6 +383,10 @@ static void belkin_sa_set_termios (struct usb_serial_port *port, struct ktermios } 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 7b1673a44077..1370c423d7c2 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c @@ -538,6 +538,8 @@ static struct usb_device_id id_table_combined [] = { { 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 d9e49716db13..c70e1de6389e 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 04bd3b7a2985..f1c90cfe7251 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 @@ static int debug = 0; */ #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 @@ struct garmin_data { __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 @@ struct garmin_data { #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 @@ struct garmin_data { /* 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 struct usb_driver garmin_driver = { 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 @@ static int gsp_rec_packet(struct garmin_data * garmin_data_p, int count) 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 @@ static int nat_receive(struct garmin_data * garmin_data_p, 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 @@ static int garmin_clear(struct garmin_data * garmin_data_p) 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 @@ static int garmin_init_session(struct usb_serial_port *port) 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 @@ static int garmin_init_session(struct usb_serial_port *port) /* 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 @@ static int garmin_open (struct usb_serial_port *port, struct file *filp) 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 @@ static void garmin_write_bulk_callback (struct urb *urb) { 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; - /* free up the transfer buffer, as usb_free_urb() does not do this */ - kfree (urb->transfer_buffer); + if (port) { + struct garmin_data * garmin_data_p = usb_get_serial_port_data(port); - dbg("%s - port %d", __FUNCTION__, port->number); + 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); + 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); } - 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); } 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 @@ static int garmin_write_bulk (struct usb_serial_port *port, 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 @@ static int garmin_write_bulk (struct usb_serial_port *port, "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_bulk (struct usb_serial_port *port, 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 @@ static int garmin_write (struct usb_serial_port *port, 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 int garmin_chars_in_buffer (struct usb_serial_port *port) 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 @@ static void garmin_read_process(struct garmin_data * garmin_data_p, 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 0455c1552ae9..6a3a704b5849 100644 --- a/drivers/usb/serial/ipaq.c +++ b/drivers/usb/serial/ipaq.c @@ -545,6 +545,7 @@ static struct usb_device_id ipaq_id_table [] = { { 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 84c12b5f1271..4cb3c165742b 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c @@ -110,6 +110,7 @@ static int option_send_setup(struct usb_serial_port *port); #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 @@ static int option_send_setup(struct usb_serial_port *port); #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 @@ static struct usb_device_id option_ids[] = { { 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 d7db71eca520..833ada47fc54 100644 --- a/drivers/usb/serial/oti6858.c +++ b/drivers/usb/serial/oti6858.c @@ -818,19 +818,17 @@ static int oti6858_ioctl(struct usb_serial_port *port, struct file *file, 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 86899d55d8d8..51669b7622bb 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 7d84a7647e81..30e08c0bcdc2 100644 --- a/drivers/usb/serial/visor.c +++ b/drivers/usb/serial/visor.c @@ -104,6 +104,8 @@ static struct usb_device_id id_table [] = { .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 4ce6f62a6f39..57229cf66477 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 d8d008d42946..2d92ce31018f 100644 --- a/drivers/usb/storage/unusual_devs.h +++ b/drivers/usb/storage/unusual_devs.h @@ -342,7 +342,7 @@ UNUSUAL_DEV( 0x04b0, 0x040d, 0x0100, 0x0100, 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 28842d208bb0..25e557d4fe6b 100644 --- a/drivers/usb/storage/usb.c +++ b/drivers/usb/storage/usb.c @@ -112,13 +112,6 @@ module_param(delay_use, uint, S_IRUGO | S_IWUSR); 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 @@ static void quiesce_and_remove_host(struct us_data *us) 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 @@ static void quiesce_and_remove_host(struct us_data *us) 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 @@ retry: /* 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 @@ static int storage_probe(struct usb_interface *intf, 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 @@ static int storage_probe(struct usb_interface *intf, 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 @@ static void __exit usb_stor_exit(void) 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 6445665b1577..8d87503e2560 100644 --- a/drivers/usb/storage/usb.h +++ b/drivers/usb/storage/usb.h @@ -150,6 +150,7 @@ struct us_data { 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/fs/9p/fid.c b/fs/9p/fid.c index 08fa320b7e6d..15e05a15b575 100644 --- a/fs/9p/fid.c +++ b/fs/9p/fid.c @@ -92,23 +92,6 @@ struct p9_fid *v9fs_fid_lookup(struct dentry *dentry) 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 47a0ba742872..26e07df783b9 100644 --- a/fs/9p/fid.h +++ b/fs/9p/fid.h @@ -28,6 +28,5 @@ struct v9fs_dentry { }; 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/proc/array.c b/fs/proc/array.c index 965625a0977d..ee4814dd98f9 100644 --- a/fs/proc/array.c +++ b/fs/proc/array.c @@ -320,7 +320,21 @@ int proc_pid_status(struct task_struct *task, char *buffer) 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 @@ static clock_t task_utime(struct task_struct *p) } 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 @@ static clock_t task_stime(struct task_struct *p) * 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 @@ static int do_task_stat(struct task_struct *task, char *buffer, int whole) 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 @@ static int do_task_stat(struct task_struct *task, char *buffer, int whole) 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 @@ static int do_task_stat(struct task_struct *task, char *buffer, int whole) 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 @@ static int do_task_stat(struct task_struct *task, char *buffer, int whole) 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/sysfs/bin.c b/fs/sysfs/bin.c index 135353f8a296..5afe2a26f5d8 100644 --- a/fs/sysfs/bin.c +++ b/fs/sysfs/bin.c @@ -248,12 +248,7 @@ int sysfs_create_bin_file(struct kobject * kobj, struct bin_attribute * attr) 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 048e6054c2fd..83e76b3813c9 100644 --- a/fs/sysfs/dir.c +++ b/fs/sysfs/dir.c @@ -762,12 +762,15 @@ static int sysfs_count_nlink(struct sysfs_dirent *sd) 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 @@ static struct dentry * sysfs_lookup(struct inode *dir, struct dentry *dentry, /* 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 @@ static struct dentry * sysfs_lookup(struct inode *dir, struct dentry *dentry, 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 @@ int sysfs_rename_dir(struct kobject *kobj, struct sysfs_dirent *new_parent_sd, if (error) goto out_drop; + mutex_lock(&sysfs_mutex); + dup_name = sd->s_name; sd->s_name = new_name; @@ -949,8 +954,6 @@ int sysfs_rename_dir(struct kobject *kobj, struct sysfs_dirent *new_parent_sd, 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/acpixf.h b/include/acpi/acpixf.h index b5cca5daa348..3d7ab9e0c9fe 100644 --- a/include/acpi/acpixf.h +++ b/include/acpi/acpixf.h @@ -130,7 +130,7 @@ acpi_walk_namespace(acpi_object_type type, 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 aeb4498e5e06..88482655407f 100644 --- a/include/acpi/acstruct.h +++ b/include/acpi/acstruct.h @@ -146,7 +146,7 @@ struct acpi_init_walk_info { 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/asm-i386/io.h b/include/asm-i386/io.h index 7b65b5b00034..e8e0bd641120 100644 --- a/include/asm-i386/io.h +++ b/include/asm-i386/io.h @@ -112,6 +112,9 @@ extern void __iomem * __ioremap(unsigned long offset, unsigned long size, unsign * 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 340764076d5f..dbe734ddf2af 100644 --- a/include/asm-i386/io_apic.h +++ b/include/asm-i386/io_apic.h @@ -150,7 +150,6 @@ extern int (*ioapic_renumber_irq)(int ioapic, int irq); #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-m68knommu/pgtable.h b/include/asm-m68knommu/pgtable.h index e1e6a1d2333a..46251016e821 100644 --- a/include/asm-m68knommu/pgtable.h +++ b/include/asm-m68knommu/pgtable.h @@ -65,4 +65,6 @@ extern unsigned int kobjsize(const void *objp); #define VMALLOC_START 0 #define VMALLOC_END 0xffffffff +#include <asm-generic/pgtable.h> + #endif /* _M68KNOMMU_PGTABLE_H */ diff --git a/include/asm-x86_64/io_apic.h b/include/asm-x86_64/io_apic.h index 969d225a9350..d9f2e54324d5 100644 --- a/include/asm-x86_64/io_apic.h +++ b/include/asm-x86_64/io_apic.h @@ -109,6 +109,12 @@ extern int mpc_default_type; /* 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/linux/audit.h b/include/linux/audit.h index 4bbd8601b8f0..d6579df8dadf 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/input.h b/include/linux/input.h index e02c6a66b2ba..cf2b5619aa13 100644 --- a/include/linux/input.h +++ b/include/linux/input.h @@ -363,6 +363,12 @@ struct input_absinfo { #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/pci.h b/include/linux/pci.h index e7d8d4e19a53..038a0dc7273a 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -557,6 +557,7 @@ int pci_set_consistent_dma_mask(struct pci_dev *dev, u64 mask); 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 @@ int pci_set_power_state(struct pci_dev *dev, pci_power_t state); 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 8938d59013c6..f77944e432f2 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 diff --git a/include/linux/sched.h b/include/linux/sched.h index 682ef87da6eb..ba78807eab91 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -681,7 +681,7 @@ enum cpu_idle_type { #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. */ @@ -1388,7 +1388,8 @@ extern void sched_exec(void); #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/init/main.c b/init/main.c index d3bcb3b11620..cc0653ec081d 100644 --- a/init/main.c +++ b/init/main.c @@ -146,9 +146,14 @@ static unsigned int __initdata max_cpus = NR_CPUS; * 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 @@ early_param("nosmp", nosmp); 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/module.c b/kernel/module.c index 33c04ad51175..db0ead0363e2 100644 --- a/kernel/module.c +++ b/kernel/module.c @@ -784,8 +784,7 @@ EXPORT_SYMBOL_GPL(symbol_put_addr); 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/sched.c b/kernel/sched.c index 45e17b83b7f1..96e9b82246d2 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -262,7 +262,8 @@ struct rq { 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; @@ -556,18 +557,40 @@ static inline struct rq *this_rq_lock(void) } /* - * 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'. @@ -2494,7 +2517,7 @@ group_next: * 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; @@ -3020,6 +3043,7 @@ static inline void rebalance_domains(int cpu, enum cpu_idle_type idle) 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)) @@ -3056,8 +3080,10 @@ static inline void rebalance_domains(int cpu, enum cpu_idle_type idle) 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 @@ -3067,7 +3093,14 @@ out: 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; } /* @@ -4890,7 +4923,7 @@ static inline void sched_init_granularity(void) 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 * 8; sysctl_sched_wakeup_granularity = sysctl_sched_granularity / 2; } @@ -5234,15 +5267,16 @@ static void migrate_dead_tasks(unsigned int dead_cpu) static struct ctl_table sd_ctl_dir[] = { { .procname = "sched_domain", - .mode = 0755, + .mode = 0555, }, {0,}, }; static struct ctl_table sd_ctl_root[] = { { + .ctl_name = CTL_KERN, .procname = "kernel", - .mode = 0755, + .mode = 0555, .child = sd_ctl_dir, }, {0,}, @@ -5318,7 +5352,7 @@ static ctl_table *sd_alloc_ctl_cpu_table(int cpu) for_each_domain(cpu, sd) { snprintf(buf, 32, "domain%d", i); entry->procname = kstrdup(buf, GFP_KERNEL); - entry->mode = 0755; + entry->mode = 0555; entry->child = sd_alloc_ctl_domain_table(sd); entry++; i++; @@ -5338,7 +5372,7 @@ static void init_sched_domain_sysctl(void) for (i = 0; i < cpu_num; i++, entry++) { snprintf(buf, 32, "cpu%d", i); 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); diff --git a/kernel/sched_debug.c b/kernel/sched_debug.c index 87e524762b85..ab18f45f2ab2 100644 --- a/kernel/sched_debug.c +++ b/kernel/sched_debug.c @@ -154,10 +154,11 @@ static void print_cpu(struct seq_file *m, int cpu) 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]); diff --git a/lib/iomap.c b/lib/iomap.c index a57d262a5ed9..864f2ec1966e 100644 --- a/lib/iomap.c +++ b/lib/iomap.c @@ -240,7 +240,20 @@ void ioport_unmap(void __iomem *addr) 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/net/9p/conv.c b/net/9p/conv.c index f2a041cb508a..d979d958ea19 100644 --- a/net/9p/conv.c +++ b/net/9p/conv.c @@ -796,6 +796,7 @@ struct p9_fcall *p9_create_twrite_u(u32 fid, u64 offset, u32 count, 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 acb038810f39..5d70558c4c61 100644 --- a/net/9p/mux.c +++ b/net/9p/mux.c @@ -288,9 +288,10 @@ struct p9_conn *p9_conn_create(struct p9_transport *trans, int msize, 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 @@ struct p9_conn *p9_conn_create(struct p9_transport *trans, int msize, 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) { |