diff options
172 files changed, 2660 insertions, 1377 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) | |||
| 316 | 316 | ||
| 317 | <chapter id="pubfunctions"> | 317 | <chapter id="pubfunctions"> |
| 318 | <title>Public Functions Provided</title> | 318 | <title>Public Functions Provided</title> |
| 319 | !Einclude/asm-i386/io.h | 319 | !Iinclude/asm-i386/io.h |
| 320 | !Elib/iomap.c | ||
| 320 | </chapter> | 321 | </chapter> |
| 321 | 322 | ||
| 322 | </book> | 323 | </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 | |||
| 208 | Cross-Reference project, which is able to present source code in a | 208 | Cross-Reference project, which is able to present source code in a |
| 209 | self-referential, indexed webpage format. An excellent up-to-date | 209 | self-referential, indexed webpage format. An excellent up-to-date |
| 210 | repository of the kernel code may be found at: | 210 | repository of the kernel code may be found at: |
| 211 | http://sosdg.org/~coywolf/lxr/ | 211 | http://users.sosdg.org/~qiyong/lxr/ |
| 212 | 212 | ||
| 213 | 213 | ||
| 214 | The development process | 214 | The development process |
| @@ -384,7 +384,7 @@ One of the best ways to put into practice your hacking skills is by fixing | |||
| 384 | bugs reported by other people. Not only you will help to make the kernel | 384 | bugs reported by other people. Not only you will help to make the kernel |
| 385 | more stable, you'll learn to fix real world problems and you will improve | 385 | more stable, you'll learn to fix real world problems and you will improve |
| 386 | your skills, and other developers will be aware of your presence. Fixing | 386 | your skills, and other developers will be aware of your presence. Fixing |
| 387 | bugs is one of the best ways to earn merit amongst the developers, because | 387 | bugs is one of the best ways to get merits among other developers, because |
| 388 | not many people like wasting time fixing other people's bugs. | 388 | not many people like wasting time fixing other people's bugs. |
| 389 | 389 | ||
| 390 | To work in the already reported bug reports, go to http://bugzilla.kernel.org. | 390 | 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! | |||
| 560 | <http://marc.theaimsgroup.com/?l=linux-kernel&m=112112749912944&w=2> | 560 | <http://marc.theaimsgroup.com/?l=linux-kernel&m=112112749912944&w=2> |
| 561 | 561 | ||
| 562 | Kernel Documentation/CodingStyle: | 562 | Kernel Documentation/CodingStyle: |
| 563 | <http://sosdg.org/~coywolf/lxr/source/Documentation/CodingStyle> | 563 | <http://users.sosdg.org/~qiyong/lxr/source/Documentation/CodingStyle> |
| 564 | 564 | ||
| 565 | Linus Torvalds's mail on the canonical patch format: | 565 | Linus Torvalds's mail on the canonical patch format: |
| 566 | <http://lkml.org/lkml/2005/4/7/183> | 566 | <http://lkml.org/lkml/2005/4/7/183> |
diff --git a/Documentation/accounting/getdelays.c b/Documentation/accounting/getdelays.c index 24c5aade8998..cbee3a27f768 100644 --- a/Documentation/accounting/getdelays.c +++ b/Documentation/accounting/getdelays.c | |||
| @@ -196,7 +196,7 @@ void print_delayacct(struct taskstats *t) | |||
| 196 | "IO %15s%15s\n" | 196 | "IO %15s%15s\n" |
| 197 | " %15llu%15llu\n" | 197 | " %15llu%15llu\n" |
| 198 | "MEM %15s%15s\n" | 198 | "MEM %15s%15s\n" |
| 199 | " %15llu%15llu\n" | 199 | " %15llu%15llu\n", |
| 200 | "count", "real total", "virtual total", "delay total", | 200 | "count", "real total", "virtual total", "delay total", |
| 201 | t->cpu_count, t->cpu_run_real_total, t->cpu_run_virtual_total, | 201 | t->cpu_count, t->cpu_run_real_total, t->cpu_run_virtual_total, |
| 202 | t->cpu_delay_total, | 202 | t->cpu_delay_total, |
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 @@ | |||
| 1 | NOTE: | ||
| 2 | This is a version of Documentation/HOWTO translated into korean | ||
| 3 | This document is maintained by minchan Kim < minchan.kim@gmail.com> | ||
| 4 | If you find any difference between this document and the original file or | ||
| 5 | a problem with the translation, please contact the maintainer of this file. | ||
| 6 | |||
| 7 | Please also note that the purpose of this file is to be easier to | ||
| 8 | read for non English (read: korean) speakers and is not intended as | ||
| 9 | a fork. So if you have any comments or updates for this file please | ||
| 10 | try to update the original English file first. | ||
| 11 | |||
| 12 | ================================== | ||
| 13 | 이 문서는 | ||
| 14 | Documentation/HOWTO | ||
| 15 | 의 한글 번역입니다. | ||
| 16 | |||
| 17 | 역자: 김민찬 <minchan.kim@gmail.com > | ||
| 18 | 감수: 이제이미 <jamee.lee@samsung.com> | ||
| 19 | ================================== | ||
| 20 | |||
| 21 | 어떻게 리눅스 커널 개발을 하는가 | ||
| 22 | --------------------------------- | ||
| 23 | |||
| 24 | 이 문서는 커널 개발에 있어 가장 중요한 문서이다. 이 문서는 | ||
| 25 | 리눅스 커널 개발자가 되는 법과 리눅스 커널 개발 커뮤니티와 일하는 | ||
| 26 | 법을 담고있다. 커널 프로그래밍의기술적인 측면과 관련된 내용들은 | ||
| 27 | 포함하지 않으려고 하였지만 올바으로 여러분을 안내하는 데 도움이 | ||
| 28 | 될 것이다. | ||
| 29 | |||
| 30 | 이 문서에서 오래된 것을 발견하면 문서의 아래쪽에 나열된 메인트너에게 | ||
| 31 | 패치를 보내달라. | ||
| 32 | |||
| 33 | |||
| 34 | 소개 | ||
| 35 | ---- | ||
| 36 | |||
| 37 | 자, 여러분은 리눅스 커널 개발자가 되는 법을 배우고 싶은가? 아니면 | ||
| 38 | 상사로부터"이 장치를 위한 리눅스 드라이버를 작성하시오"라는 말을 | ||
| 39 | 들었는가? 이 문서는 여러분이 겪게 될 과정과 커뮤니티와 일하는 법을 | ||
| 40 | 조언하여 여러분의 목적을 달성하기 위해 필요한 것 모두를 알려주는 | ||
| 41 | 것이다. | ||
| 42 | |||
| 43 | 커널은 대부분은 C로 작성되었어고 몇몇 아키텍쳐의 의존적인 부분은 | ||
| 44 | 어셈블리로 작성되었다. 커널 개발을 위해 C를 잘 이해하고 있어야 한다. | ||
| 45 | 여러분이 특정 아키텍쳐의 low-level 개발을 할 것이 아니라면 | ||
| 46 | 어셈블리(특정 아키텍쳐)는 잘 알아야 할 필요는 없다. | ||
| 47 | 다음의 참고서적들은 기본에 충실한 C 교육이나 수년간의 경험에 견주지는 | ||
| 48 | 못하지만 적어도 참고 용도로는 좋을 것이다 | ||
| 49 | - "The C Programming Language" by Kernighan and Ritchie [Prentice Hall] | ||
| 50 | - "Practical C Programming" by Steve Oualline [O'Reilly] | ||
| 51 | - "C: A Reference Manual" by Harbison and Steele [Prentice Hall] | ||
| 52 | |||
| 53 | 커널은 GNU C와 GNU 툴체인을 사용하여 작성되었다. 이 툴들은 ISO C89 표준을 | ||
| 54 | 따르는 반면 표준에 있지 않은 많은 확장기능도 가지고 있다. 커널은 표준 C | ||
| 55 | 라이브러리와는 관계없이 freestanding C 환경이어서 C 표준의 일부는 | ||
| 56 | 지원되지 않는다. 임의의 long long 나누기나 floating point는 지원되지 않는다. | ||
| 57 | 때론 이런 이유로 커널이 그런 확장 기능을 가진 툴체인을 가지고 만들어졌다는 | ||
| 58 | 것이 이해하기 어려울 수도 있고 게다가 불행하게도 그런 것을 정확하게 설명하는 | ||
| 59 | 어떤 참고문서도 있지 않다. 정보를 얻기 위해서는 gcc info (`info gcc`)페이지를 | ||
| 60 | 살펴보라. | ||
| 61 | |||
| 62 | 여러분은 기존의 개발 커뮤니티와 일하는 법을 배우려고 하고 있다는 것을 | ||
| 63 | 기억하라. 코딩, 스타일, 절차에 관한 훌륭한 표준을 가진 사람들이 모인 | ||
| 64 | 다양한 그룹이 있다. 이 표준들은 오랜동안 크고 지역적으로 분산된 팀들에 | ||
| 65 | 의해 가장 좋은 방법으로 일하기위하여 찾은 것을 기초로 만들어져왔다. | ||
| 66 | 그 표준들은 문서화가 잘 되어 있기 때문에 가능한한 미리 많은 표준들에 | ||
| 67 | 관하여 배우려고 시도하라. 다른 사람들은 여러분이나 여러분의 회사가 | ||
| 68 | 일하는 방식에 적응하는 것을 원하지는 않는다. | ||
| 69 | |||
| 70 | |||
| 71 | 법적 문제 | ||
| 72 | --------- | ||
| 73 | |||
| 74 | 리눅스 커널 소스 코드는 GPL로 배포(release)되었다. 소스트리의 메인 | ||
| 75 | 디렉토리에 있는 라이센스에 관하여 상세하게 쓰여 있는 COPYING이라는 | ||
| 76 | 파일을 봐라.여러분이 라이센스에 관한 더 깊은 문제를 가지고 있다면 | ||
| 77 | 리눅스 커널 메일링 리스트에 묻지말고 변호사와 연락하라. 메일링 | ||
| 78 | 리스트들에 있는 사람들은 변호사가 아니기 때문에 법적 문제에 관하여 | ||
| 79 | 그들의 말에 의지해서는 안된다. | ||
| 80 | |||
| 81 | GPL에 관한 잦은 질문들과 답변들은 다음을 참조하라. | ||
| 82 | http://www.gnu.org/licenses/gpl-faq.html | ||
| 83 | |||
| 84 | |||
| 85 | 문서 | ||
| 86 | ---- | ||
| 87 | |||
| 88 | 리눅스 커널 소스 트리는 커널 커뮤니티와 일하는 법을 배우기 위한 많은 | ||
| 89 | 귀중한 문서들을 가지고 있다. 새로운 기능들이 커널에 들어가게 될 때, | ||
| 90 | 그 기능을 어떻게 사용하는지에 관한 설명을 위하여 새로운 문서 파일을 | ||
| 91 | 추가하는 것을 권장한다. 커널이 유저스페이스로 노출하는 인터페이스를 | ||
| 92 | 변경하게 되면 변경을 설명하는 메뉴얼 페이지들에 대한 패치나 정보를 | ||
| 93 | mtk-manpages@gmx.net의 메인트너에게 보낼 것을 권장한다. | ||
| 94 | |||
| 95 | 다음은 커널 소스 트리에 있는 읽어야 할 파일들의 리스트이다. | ||
| 96 | README | ||
| 97 | 이 파일은 리눅스 커널에 관하여 간단한 배경 설명과 커널을 설정하고 | ||
| 98 | 빌드하기 위해 필요한 것을 설명한다. 커널에 입문하는 사람들은 여기서 | ||
| 99 | 시작해야 한다. | ||
| 100 | |||
| 101 | Documentation/Changes | ||
| 102 | 이 파일은 커널을 성공적으로 빌드하고 실행시키기 위해 필요한 다양한 | ||
| 103 | 소프트웨어 패키지들의 최소 버젼을 나열한다. | ||
| 104 | |||
| 105 | Documentation/CodingStyle | ||
| 106 | 이 문서는 리눅스 커널 코딩 스타일과 그렇게 한 몇몇 이유를 설명한다. | ||
| 107 | 모든 새로운 코드는 이 문서에 가이드라인들을 따라야 한다. 대부분의 | ||
| 108 | 메인트너들은 이 규칙을 따르는 패치들만을 받아들일 것이고 많은 사람들이 | ||
| 109 | 그 패치가 올바른 스타일일 경우만 코드를 검토할 것이다. | ||
| 110 | |||
| 111 | Documentation/SubmittingPatches | ||
| 112 | Documentation/SubmittingDrivers | ||
| 113 | 이 파일들은 성공적으로 패치를 만들고 보내는 법을 다음의 내용들로 | ||
| 114 | 굉장히 상세히 설명하고 있다(그러나 다음으로 한정되진 않는다). | ||
| 115 | - Email 내용들 | ||
| 116 | - Email 양식 | ||
| 117 | - 그것을 누구에게 보낼지 | ||
| 118 | 이러한 규칙들을 따르는 것이 성공을 보장하진 않는다(왜냐하면 모든 | ||
| 119 | 패치들은 내용과 스타일에 관하여 면밀히 검토되기 때문이다). | ||
| 120 | 그러나 규칙을 따르지 않는다면 거의 성공하지도 못할 것이다. | ||
| 121 | |||
| 122 | 올바른 패치들을 만드는 법에 관한 훌륭한 다른 문서들이 있다. | ||
| 123 | "The Perfect Patch" | ||
| 124 | http://www.zip.com.au/~akpm/linux/patches/stuff/tpp.txt | ||
| 125 | "Linux kernel patch submission format" | ||
| 126 | http://linux.yyz.us/patch-format.html | ||
| 127 | |||
| 128 | Documentation/stable_api_nonsense.txt | ||
| 129 | 이 문서는 의도적으로 커널이 변하지 않는 API를 갖지 않도록 결정한 | ||
| 130 | 이유를 설명하며 다음과 같은 것들을 포함한다. | ||
| 131 | - 서브시스템 shim-layer(호환성을 위해?) | ||
| 132 | - 운영 체제들 간의 드라이버 이식성 | ||
| 133 | - 커널 소스 트리내에 빠른 변화를 늦추는 것(또는 빠른 변화를 막는 것) | ||
| 134 | 이 문서는 리눅스 개발 철학을 이해하는데 필수적이며 다른 운영체제에서 | ||
| 135 | 리눅스로 옮겨오는 사람들에게는 매우 중요하다. | ||
| 136 | |||
| 137 | |||
| 138 | Documentation/SecurityBugs | ||
| 139 | 여러분들이 리눅스 커널의 보안 문제를 발견했다고 생각한다면 이 문서에 | ||
| 140 | 나온 단계에 따라서 커널 개발자들에게 알리고 그 문제를 해결할 수 있도록 | ||
| 141 | 도와 달라. | ||
| 142 | |||
| 143 | Documentation/ManagementStyle | ||
| 144 | 이 문서는 리눅스 커널 메인트너들이 어떻게 그들의 방법론의 정신을 | ||
| 145 | 어떻게 공유하고 운영하는지를 설명한다. 이것은 커널 개발에 입문하는 | ||
| 146 | 모든 사람들(또는 커널 개발에 작은 호기심이라도 있는 사람들)이 | ||
| 147 | 읽어야 할 중요한 문서이다. 왜냐하면 이 문서는 커널 메인트너들의 | ||
| 148 | 독특한 행동에 관하여 흔히 있는 오해들과 혼란들을 해소하고 있기 | ||
| 149 | 때문이다. | ||
| 150 | |||
| 151 | Documentation/stable_kernel_rules.txt | ||
| 152 | 이 문서는 안정적인 커널 배포가 이루어지는 규칙을 설명하고 있으며 | ||
| 153 | 여러분들이 이러한 배포들 중 하나에 변경을 하길 원한다면 | ||
| 154 | 무엇을 해야 하는지를 설명한다. | ||
| 155 | |||
| 156 | Documentation/kernel-docs.txt | ||
| 157 | 커널 개발에 관계된 외부 문서의 리스트이다. 커널 내의 포함된 문서들 | ||
| 158 | 중에 여러분이 찾고 싶은 문서를 발견하지 못할 경우 이 리스트를 | ||
| 159 | 살펴보라. | ||
| 160 | |||
| 161 | Documentation/applying-patches.txt | ||
| 162 | 패치가 무엇이며 그것을 커널의 다른 개발 브랜치들에 어떻게 | ||
| 163 | 적용하는지에 관하여 자세히 설명 하고 있는 좋은 입문서이다. | ||
| 164 | |||
| 165 | 커널은 소스 코드 그 자체에서 자동적으로 만들어질 수 있는 많은 문서들을 | ||
| 166 | 가지고 있다. 이것은 커널 내의 API에 대한 모든 설명, 그리고 락킹을 | ||
| 167 | 올바르게 처리하는 법에 관한 규칙을 포함하고 있다. 이 문서는 | ||
| 168 | Documentation/DocBook/ 디렉토리 내에서 만들어지며 PDF, Postscript, HTML, | ||
| 169 | 그리고 man 페이지들로 다음과 같이 실행하여 만들어 진다. | ||
| 170 | make pdfdocs | ||
| 171 | make psdocs | ||
| 172 | make htmldocs | ||
| 173 | make mandocs | ||
| 174 | 각각의 명령을 메인 커널 소스 디렉토리로부터 실행한다. | ||
| 175 | |||
| 176 | |||
| 177 | 커널 개발자가 되는 것 | ||
| 178 | --------------------- | ||
| 179 | |||
| 180 | 여러분이 리눅스 커널 개발에 관하여 아무것도 모른다면 Linux KernelNewbies | ||
| 181 | 프로젝트를 봐야 한다. | ||
| 182 | http://kernelnewbies.org | ||
| 183 | 그곳은 거의 모든 종류의 기본적인 커널 개발 질문들(질문하기 전에 먼저 | ||
| 184 | 아카이브를 찾아봐라. 과거에 이미 답변되었을 수도 있다)을 할수있는 도움이 | ||
| 185 | 될만한 메일링 리스트가 있다. 또한 실시간으로 질문 할수 있는 IRC 채널도 | ||
| 186 | 가지고 있으며 리눅스 커널 개발을 배우는 데 유용한 문서들을 보유하고 있다. | ||
| 187 | |||
| 188 | 웹사이트는 코드구성, 서브시스템들, 그리고 현재 프로젝트들 | ||
| 189 | (트리 내, 외부에 존재하는)에 관한 기본적인 정보들을 가지고 있다. 또한 | ||
| 190 | 그곳은 커널 컴파일이나 패치를 하는 법과 같은 기본적인 것들을 설명한다. | ||
| 191 | |||
| 192 | 여러분이 어디서 시작해야 할진 모르지만 커널 개발 커뮤니티에 참여할 수 | ||
| 193 | 있는 일들을 찾길 원한다면 리눅스 커널 Janitor 프로젝트를 살펴봐라. | ||
| 194 | http://janitor.kernelnewbies.org/ | ||
| 195 | 그곳은 시작하기에 아주 딱 좋은 곳이다. 그곳은 리눅스 커널 소스 트리내에 | ||
| 196 | 간단히 정리되고 수정될 수 있는 문제들에 관하여 설명한다. 여러분은 이 | ||
| 197 | 프로젝트를 대표하는 개발자들과 일하면서 자신의 패치를 리눅스 커널 트리에 | ||
| 198 | 반영하기 위한 기본적인 것들을 배우게 될것이며 여러분이 아직 아이디어를 | ||
| 199 | 가지고 있지 않다면 다음에 무엇을 해야할지에 관한 방향을 배울 수 있을 | ||
| 200 | 것이다. | ||
| 201 | |||
| 202 | 여러분들이 이미 커널 트리에 반영하길 원하는 코드 묶음을 가지고 있지만 | ||
| 203 | 올바른 포맷으로 포장하는데 도움이 필요하다면 그러한 문제를 돕기 위해 | ||
| 204 | 만들어진 kernel-mentors 프로젝트가 있다. 그곳은 메일링 리스트이며 | ||
| 205 | 다음에서 참조할 수 있다. | ||
| 206 | http://selenic.com/mailman/listinfo/kernel-mentors | ||
| 207 | |||
| 208 | 리눅스 커널 코드에 실제 변경을 하기 전에 반드시 그 코드가 어떻게 | ||
| 209 | 동작하는지 이해하고 있어야 한다. 코드를 분석하기 위하여 특정한 툴의 | ||
| 210 | 도움을 빌려서라도 코드를 직접 읽는 것보다 좋은 것은 없다(대부분의 | ||
| 211 | 자잘한 부분들은 잘 코멘트되어 있다). 그런 툴들 중에 특히 추천할만한 | ||
| 212 | 것은 Linux Cross-Reference project이며 그것은 자기 참조 방식이며 | ||
| 213 | 소스코드를 인덱스된 웹 페이지들의 형태로 보여준다. 최신의 멋진 커널 | ||
| 214 | 코드 저장소는 다음을 통하여 참조할 수 있다. | ||
| 215 | http://sosdg.org/~coywolf/lxr/ | ||
| 216 | |||
| 217 | |||
| 218 | 개발 프로세스 | ||
| 219 | ------------- | ||
| 220 | |||
| 221 | 리눅스 커널 개발 프로세스는 현재 몇몇 다른 메인 커널 "브랜치들"과 | ||
| 222 | 서브시스템에 특화된 커널 브랜치들로 구성된다. 몇몇 다른 메인 | ||
| 223 | 브랜치들은 다음과 같다. | ||
| 224 | - main 2.6.x 커널 트리 | ||
| 225 | - 2.6.x.y - 안정된 커널 트리 | ||
| 226 | - 2.6.x -git 커널 패치들 | ||
| 227 | - 2.6.x -mm 커널 패치들 | ||
| 228 | - 서브시스템을 위한 커널 트리들과 패치들 | ||
| 229 | |||
| 230 | 2.6.x 커널 트리 | ||
| 231 | --------------- | ||
| 232 | |||
| 233 | 2.6.x 커널들은 Linux Torvalds가 관리하며 kernel.org의 pub/linux/kernel/v2.6/ | ||
| 234 | 디렉토리에서 참조될 수 있다.개발 프로세스는 다음과 같다. | ||
| 235 | - 새로운 커널이 배포되자마자 2주의 시간이 주어진다. 이 기간동은 | ||
| 236 | 메인트너들은 큰 diff들을 Linus에게 제출할 수 있다. 대개 이 패치들은 | ||
| 237 | 몇 주 동안 -mm 커널내에 이미 있었던 것들이다. 큰 변경들을 제출하는 데 | ||
| 238 | 선호되는 방법은 git(커널의 소스 관리 툴, 더 많은 정보들은 http://git.or.cz/ | ||
| 239 | 에서 참조할 수 있다)를 사용하는 것이지만 순수한 패치파일의 형식으로 보내도 | ||
| 240 | 것도 무관하다. | ||
| 241 | - 2주 후에 -rc1 커널이 배포되며 지금부터는 전체 커널의 안정성에 영향을 | ||
| 242 | 미칠수 있는 새로운 기능들을 포함하지 않는 패치들만을 추가될 수 있다. | ||
| 243 | 완전히 새로운 드라이버(혹은 파일시스템)는 -rc1 이후에만 받아들여진다는 | ||
| 244 | 것을 기억해라. 왜냐하면 변경이 자체내에서만 발생하고 추가된 코드가 | ||
| 245 | 드라이버 외부의 다른 부분에는 영향을 주지 않으므로 그런 변경은 | ||
| 246 | 퇴보(regression)를 일으킬 만한 위험을 가지고 있지 않기 때문이다. -rc1이 | ||
| 247 | 배포된 이후에 git를 사용하여 패치들을 Linus에게 보낼수 있지만 패치들은 | ||
| 248 | 공식적인 메일링 리스트로 보내서 검토를 받을 필요가 있다. | ||
| 249 | - 새로운 -rc는 Linus는 현재 git tree가 테스트 하기에 충분히 안정된 상태에 | ||
| 250 | 있다고 판단될 때마다 배포된다. 목표는 새로운 -rc 커널을 매주 배포하는 | ||
| 251 | 것이다. | ||
| 252 | - 이러한 프로세스는 커널이 "준비"되었다고 여겨질때까지 계속된다. | ||
| 253 | 프로세스는 대체로 6주간 지속된다. | ||
| 254 | - 각 -rc 배포에 있는 알려진 퇴보의 목록들은 다음 URI에 남겨진다. | ||
| 255 | http://kernelnewbies.org/known_regressions | ||
| 256 | |||
| 257 | 커널 배포에 있어서 언급할만한 가치가 있는 리눅스 커널 메일링 리스트의 | ||
| 258 | Andrew Morton의 글이 있다. | ||
| 259 | "커널이 언제 배포될지는 아무로 모른다. 왜냐하면 배포는 알려진 | ||
| 260 | 버그의 상황에 따라 배포되는 것이지 미리정해 놓은 시간에 따라 | ||
| 261 | 배포되는 것은 아니기 때문이다." | ||
| 262 | |||
| 263 | 2.6.x.y - 안정 커널 트리 | ||
| 264 | ------------------------ | ||
| 265 | |||
| 266 | 4 자리 숫자로 이루어진 버젼의 커널들은 -stable 커널들이다. 그것들은 2.6.x | ||
| 267 | 커널에서 발견된 큰 퇴보들이나 보안 문제들 중 비교적 작고 중요한 수정들을 | ||
| 268 | 포함한다. | ||
| 269 | |||
| 270 | 이것은 가장 최근의 안정적인 커널을 원하는 사용자에게 추천되는 브랜치이며, | ||
| 271 | 개발/실험적 버젼을 테스트하는 것을 돕는데는 별로 관심이 없다. | ||
| 272 | |||
| 273 | 어떤 2.6.x.y 커널도 사용가능하지 않다면 그때는 가장 높은 숫자의 2.6.x | ||
| 274 | 커널이 현재의 안정 커널이다. | ||
| 275 | |||
| 276 | 2.6.x.y는 "stable" 팀<stable@kernel.org>에 의해 관리되며 거의 매번 격주로 | ||
| 277 | 배포된다. | ||
| 278 | |||
| 279 | 커널 트리 문서들 내에 Documentation/stable_kernel_rules.txt 파일은 어떤 | ||
| 280 | 종류의 변경들이 -stable 트리로 들어왔는지와 배포 프로세스가 어떻게 | ||
| 281 | 진행되는지를 설명한다. | ||
| 282 | |||
| 283 | |||
| 284 | 2.6.x -git 패치들 | ||
| 285 | ------------------ | ||
| 286 | git 저장소(그러므로 -git이라는 이름이 붙음)에는 날마다 관리되는 Linus의 | ||
| 287 | 커널 트리의 snapshot 들이 있다. 이 패치들은 일반적으로 날마다 배포되며 | ||
| 288 | Linus의 트리의 현재 상태를 나타낸다. 이 패치들은 정상적인지 조금도 | ||
| 289 | 살펴보지 않고 자동적으로 생성된 것이므로 -rc 커널들 보다도 더 실험적이다. | ||
| 290 | |||
| 291 | 2.6.x -mm 커널 패치들 | ||
| 292 | --------------------- | ||
| 293 | Andrew Morton에 의해 배포된 실험적인 커널 패치들이다. Andrew는 모든 다른 | ||
| 294 | 서브시스템 커널 트리와 패치들을 가져와서 리눅스 커널 메일링 리스트로 | ||
| 295 | 온 많은 패치들과 한데 묶는다. 이 트리는 새로운 기능들과 패치들을 위한 | ||
| 296 | 장소를 제공하는 역할을 한다. 하나의 패치가 -mm에 한동안 있으면서 그 가치가 | ||
| 297 | 증명되게 되면 Andrew나 서브시스템 메인트너는 그것을 메인라인에 포함시키기 | ||
| 298 | 위하여 Linus에게 보낸다. | ||
| 299 | |||
| 300 | 커널 트리에 포함하고 싶은 모든 새로운 패치들은 Linus에게 보내지기 전에 | ||
| 301 | -mm 트리에서 테스트를 하는 것을 적극 추천한다. | ||
| 302 | |||
| 303 | 이 커널들은 안정되게 사용할 시스템에서에 실행하는 것은 적합하지 않으며 | ||
| 304 | 다른 브랜치들의 어떤 것들보다 위험하다. | ||
| 305 | |||
| 306 | 여러분이 커널 개발 프로세스를 돕길 원한다면 이 커널 배포들을 사용하고 | ||
| 307 | 테스트한 후 어떤 문제를 발견하거나 또는 모든 것이 잘 동작한다면 리눅스 | ||
| 308 | 커널 메일링 리스트로 피드백을 해달라. | ||
| 309 | |||
| 310 | 이 커널들은 일반적으로 모든 다른 실험적인 패치들과 배포될 당시의 | ||
| 311 | 사용가능한 메인라인 -git 커널들의 몇몇 변경을 포함한다. | ||
| 312 | |||
| 313 | -mm 커널들은 정해진 일정대로 배포되지 않는다. 하지만 대개 몇몇 -mm 커널들은 | ||
| 314 | 각 -rc 커널(1부터 3이 흔함) 사이에서 배포된다. | ||
| 315 | |||
| 316 | 서브시스템 커널 트리들과 패치들 | ||
| 317 | ------------------------------- | ||
| 318 | 많은 다른 커널 서브시스템 개발자들은 커널의 다른 부분들에서 무슨 일이 | ||
| 319 | 일어나고 있는지를 볼수 있도록 그들의 개발 트리를 공개한다. 이 트리들은 | ||
| 320 | 위에서 설명하였던 것 처럼 -mm 커널 배포들로 합쳐진다. | ||
| 321 | |||
| 322 | 다음은 활용가능한 커널 트리들을 나열한다. | ||
| 323 | git trees: | ||
| 324 | - Kbuild development tree, Sam Ravnborg < sam@ravnborg.org> | ||
| 325 | git.kernel.org:/pub/scm/linux/kernel/git/sam/kbuild.git | ||
| 326 | |||
| 327 | - ACPI development tree, Len Brown <len.brown@intel.com > | ||
| 328 | git.kernel.org:/pub/scm/linux/kernel/git/lenb/linux-acpi-2.6.git | ||
| 329 | |||
| 330 | - Block development tree, Jens Axboe <axboe@suse.de> | ||
| 331 | git.kernel.org:/pub/scm/linux/kernel/git/axboe/linux-2.6-block.git | ||
| 332 | |||
| 333 | - DRM development tree, Dave Airlie <airlied@linux.ie> | ||
| 334 | git.kernel.org:/pub/scm/linux/kernel/git/airlied/drm-2.6.git | ||
| 335 | |||
| 336 | - ia64 development tree, Tony Luck < tony.luck@intel.com> | ||
| 337 | git.kernel.org:/pub/scm/linux/kernel/git/aegl/linux-2.6.git | ||
| 338 | |||
| 339 | - infiniband, Roland Dreier <rolandd@cisco.com > | ||
| 340 | git.kernel.org:/pub/scm/linux/kernel/git/roland/infiniband.git | ||
| 341 | |||
| 342 | - libata, Jeff Garzik <jgarzik@pobox.com> | ||
| 343 | git.kernel.org:/pub/scm/linux/kernel/git/jgarzik/libata-dev.git | ||
| 344 | |||
| 345 | - network drivers, Jeff Garzik <jgarzik@pobox.com> | ||
| 346 | git.kernel.org:/pub/scm/linux/kernel/git/jgarzik/netdev-2.6.git | ||
| 347 | |||
| 348 | - pcmcia, Dominik Brodowski < linux@dominikbrodowski.net> | ||
| 349 | git.kernel.org:/pub/scm/linux/kernel/git/brodo/pcmcia-2.6.git | ||
| 350 | |||
| 351 | - SCSI, James Bottomley < James.Bottomley@SteelEye.com> | ||
| 352 | git.kernel.org:/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6.git | ||
| 353 | |||
| 354 | quilt trees: | ||
| 355 | - USB, PCI, Driver Core, and I2C, Greg Kroah-Hartman < gregkh@suse.de> | ||
| 356 | kernel.org/pub/linux/kernel/people/gregkh/gregkh-2.6/ | ||
| 357 | - x86-64, partly i386, Andi Kleen < ak@suse.de> | ||
| 358 | ftp.firstfloor.org:/pub/ak/x86_64/quilt/ | ||
| 359 | |||
| 360 | 다른 커널 트리들은 http://kernel.org/git와 MAINTAINERS 파일에서 참조할 수 | ||
| 361 | 있다. | ||
| 362 | |||
| 363 | 버그 보고 | ||
| 364 | --------- | ||
| 365 | bugzilla.kernel.org는 리눅스 커널 개발자들이 커널의 버그를 추적하는 곳이다. | ||
| 366 | 사용자들은 발견한 모든 버그들을 보고하기 위하여 이 툴을 사용할 것을 권장한다. | ||
| 367 | kernel bugzilla를 사용하는 자세한 방법은 다음을 참조하라. | ||
| 368 | http://test.kernel.org/bugzilla/faq.html | ||
| 369 | |||
| 370 | 메인 커널 소스 디렉토리에 있는 REPORTING-BUGS 파일은 커널 버그일 것 같은 | ||
| 371 | 것을 보고하는는 법에 관한 좋은 템플릿이고 문제를 추적하기 위해서 커널 | ||
| 372 | 개발자들이 필요로 하는 정보가 무엇들인지를 상세히 설명하고 있다. | ||
| 373 | |||
| 374 | |||
| 375 | 버그 리포트들의 관리 | ||
| 376 | -------------------- | ||
| 377 | |||
| 378 | 여러분의 해킹 기술을 연습하는 가장 좋은 방법 중의 하는 다른 사람들이 | ||
| 379 | 보고한 버그들을 수정하는 것이다. 여러분은 커널을 더욱 안정화시키는데 | ||
| 380 | 도움을 줄 뿐만이 아니라 실제있는 문제들을 수정하는 법을 배우게 되고 | ||
| 381 | 그와 함께 여러분들의 기술은 향상될 것이며 다른 개발자들이 여러분의 | ||
| 382 | 존재에 대해 알게 될 것이다. 버그를 수정하는 것은 개발자들 사이에서 | ||
| 383 | 점수를 얻을 수 있는 가장 좋은 방법중의 하나이다. 왜냐하면 많은 사람들은 | ||
| 384 | 다른 사람들의 버그들을 수정하기 위하여 시간을 낭비하지 않기 때문이다. | ||
| 385 | |||
| 386 | 이미 보고된 버그 리포트들을 가지고 작업하기 위해서 http://bugzilla.kernelorg를 | ||
| 387 | 참조하라. 여러분이 앞으로 생겨날 버그 리포트들의 조언자가 되길 원한다면 | ||
| 388 | bugme-new 메일링 리스트나(새로운 버그 리포트들만이 이곳에서 메일로 전해진다) | ||
| 389 | bugme-janitor 메일링 리스트(bugzilla에 모든 변화들이 여기서 메일로 전해진다) | ||
| 390 | 에 등록하면 된다. | ||
| 391 | |||
| 392 | http://lists.osdl.org/mailman/listinfo/bugme-new | ||
| 393 | http://lists.osdl.org/mailman/listinfo/bugme-janitors | ||
| 394 | |||
| 395 | |||
| 396 | |||
| 397 | 메일링 리스트들 | ||
| 398 | --------------- | ||
| 399 | |||
| 400 | 위의 몇몇 문서들이 설명하였지만 핵심 커널 개발자들의 대다수는 | ||
| 401 | 리눅스 커널 메일링 리스트에 참여하고 있다. 리스트에 등록하고 해지하는 | ||
| 402 | 방법에 관한 자세한 사항은 다음에서 참조할 수 있다. | ||
| 403 | http://vger.kernel.org/vger-lists.html#linux-kernel | ||
| 404 | 웹상의 많은 다른 곳에도 메일링 리스트의 아카이브들이 있다. | ||
| 405 | 이러한 아카이브들을 찾으려면 검색 엔진을 사용하라. 예를 들어: | ||
| 406 | http://dir.gmane.org/gmane.linux.kernel | ||
| 407 | 여러분이 새로운 문제에 관해 리스트에 올리기 전에 말하고 싶은 주제에 대한 | ||
| 408 | 것을 아카이브에서 먼저 찾기를 강력히 권장한다. 이미 상세하게 토론된 많은 | ||
| 409 | 것들이 메일링 리스트의 아카이브에 기록되어 있다. | ||
| 410 | |||
| 411 | 각각의 커널 서브시스템들의 대부분은 자신들의 개발에 관한 노력들로 이루어진 | ||
| 412 | 분리된 메일링 리스트를 따로 가지고 있다. 다른 그룹들이 무슨 리스트를 가지고 | ||
| 413 | 있는지는 MAINTAINERS 파일을 참조하라. | ||
| 414 | |||
| 415 | 많은 리스트들은 kernel.org에서 호스트되고 있다. 그 정보들은 다음에서 참조될 수 있다. | ||
| 416 | http://vger.kernel.org/vger-lists.html | ||
| 417 | |||
| 418 | 리스트들을 사용할 때는 올바른 예절을 따를 것을 유념해라. | ||
| 419 | 대단하진 않지만 다음 URL은 리스트(혹은 모든 리스트)와 대화하는 몇몇 간단한 | ||
| 420 | 가이드라인을 가지고 있다. | ||
| 421 | http://www.albion.com/netiquette/ | ||
| 422 | |||
| 423 | 여러 사람들이 여러분의 메일에 응답한다면 CC: 즉 수신 리스트는 꽤 커지게 | ||
| 424 | 될 것이다. 아무 이유없이 CC에서 어떤 사람도 제거하거나 리스트 주소로만 | ||
| 425 | 회신하지 마라. 메일을 보낸 사람으로서 하나를 받고 리스트로부터 또 | ||
| 426 | 하나를 받아 두번 받는 것에 익숙하여 있으니 mail-header를 조작하려고 하지 | ||
| 427 | 말아라. 사람들은 그런 것을 좋아하지 않을 것이다. | ||
| 428 | |||
| 429 | 여러분의 회신의 문맥을 원래대로 유지해야 한다. 여러분들의 회신의 윗부분에 | ||
| 430 | "John 커널해커는 작성했다...."를 유지하며 여러분들의 의견을 그 메일의 윗부분에 | ||
| 431 | 작성하지 말고 각 인용한 단락들 사이에 넣어라. | ||
| 432 | |||
| 433 | 여러분들이 패치들을 메일에 넣는다면 그것들은 Documentation/SubmittingPatches에 | ||
| 434 | 나와있는데로 명백히(plain) 읽을 수 있는 텍스트여야 한다. 커널 개발자들은 | ||
| 435 | 첨부파일이나 압축된 패치들을 원하지 않는다. 그들은 여러분들의 패치의 | ||
| 436 | 각 라인 단위로 코멘트를 하길 원하며 압축하거나 첨부하지 않고 보내는 것이 | ||
| 437 | 그렇게 할 수 있는 유일한 방법이다. 여러분들이 사용하는 메일 프로그램이 | ||
| 438 | 스페이스나 탭 문자들을 조작하지 않는지 확인하라. 가장 좋은 첫 테스트는 | ||
| 439 | 메일을 자신에게 보내보고 스스로 그 패치를 적용해보라. 그것이 동작하지 | ||
| 440 | 않는다면 여러분의 메일 프로그램을 고치던가 제대로 동작하는 프로그램으로 | ||
| 441 | 바꾸어라. | ||
| 442 | |||
| 443 | 무엇보다도 메일링 리스트의 다른 구독자들에게 보여주려 한다는 것을 기억하라. | ||
| 444 | |||
| 445 | |||
| 446 | 커뮤니티와 일하는 법 | ||
| 447 | -------------------- | ||
| 448 | |||
| 449 | 커널 커뮤니티의 목적은 가능한한 가장 좋은 커널을 제공하는 것이다. 여러분이 | ||
| 450 | 받아들여질 패치를 제출하게 되면 그 패치의 기술적인 이점으로 검토될 것이다. | ||
| 451 | 그럼 여러분들은 무엇을 기대하고 있어야 하는가? | ||
| 452 | - 비판 | ||
| 453 | - 의견 | ||
| 454 | - 변경을 위한 요구 | ||
| 455 | - 당위성을 위한 요구 | ||
| 456 | - 고요 | ||
| 457 | |||
| 458 | 기억하라. 이것들은 여러분의 패치가 커널로 들어가기 위한 과정이다. 여러분의 | ||
| 459 | 패치들은 비판과 다른 의견을 받을 수 있고 그것들을 기술적인 레벨로 평가하고 | ||
| 460 | 재작업하거나 또는 왜 수정하면 안되는지에 관하여 명료하고 간결한 이유를 | ||
| 461 | 말할 수 있어야 한다. 여러분이 제출한 것에 어떤 응답도 있지 않다면 몇 일을 | ||
| 462 | 기다려보고 다시 시도해라. 때론 너무 많은 메일들 속에 묻혀버리기도 한다. | ||
| 463 | |||
| 464 | 여러분은 무엇을 해서는 안되는가? | ||
| 465 | - 여러분의 패치가 아무 질문 없이 받아들여지기를 기대하는 것 | ||
| 466 | - 방어적이 되는 것 | ||
| 467 | - 의견을 무시하는 것 | ||
| 468 | - 요청된 변경을 하지 않고 패치를 다시 제출하는 것 | ||
| 469 | |||
| 470 | 가능한한 가장 좋은 기술적인 해답을 찾고 있는 커뮤니티에서는 항상 | ||
| 471 | 어떤 패치가 얼마나 좋은지에 관하여 다른 의견들이 있을 수 있다. 여러분은 | ||
| 472 | 협조적이어야 하고 기꺼이 여러분의 생각을 커널 내에 맞추어야 한다. 아니면 | ||
| 473 | 적어도 여러분의 것이 가치있다는 것을 중명하여야 한다. 잘못된 것도 여러분이 | ||
| 474 | 올바른 방향의 해결책으로 이끌어갈 의지가 있다면 받아들여질 것이라는 점을 | ||
| 475 | 기억하라. | ||
| 476 | |||
| 477 | 여러분의 첫 패치에 여러분이 수정해야하는 십여개 정도의 회신이 오는 | ||
| 478 | 경우도 흔하다. 이것은 여러분의 패치가 받아들여지지 않을 것이라는 것을 | ||
| 479 | 의미하는 것이 아니고 개인적으로 여러분에게 감정이 있어서 그러는 것도 | ||
| 480 | 아니다. 간단히 여러분의 패치에 제기된 문제들을 수정하고 그것을 다시 | ||
| 481 | 보내라. | ||
| 482 | |||
| 483 | |||
| 484 | 커널 커뮤니티와 기업 조직간의 차이점 | ||
| 485 | ----------------------------------------------------------------- | ||
| 486 | 커널 커뮤니티는 가장 전통적인 회사의 개발 환경과는 다르다. 여기에 여러분들의 | ||
| 487 | 문제를 피하기 위한 목록이 있다. | ||
| 488 | 여러분들이 제안한 변경들에 관하여 말할 때 좋은 것들 : | ||
| 489 | - " 이것은 여러 문제들을 해겹합니다." | ||
| 490 | - "이것은 2000 라인의 코드를 제거합니다." | ||
| 491 | - "이것은 내가 말하려는 것에 관해 설명하는 패치입니다." | ||
| 492 | - "나는 5개의 다른 아키텍쳐에서 그것을 테스트했슴으로..." | ||
| 493 | - "여기에 일련의 작은 패치들이 있습음로..." | ||
| 494 | - "이것은 일반적인 머신에서 성능을 향상시키므로..." | ||
| 495 | |||
| 496 | 여러분들이 말할 때 피해야 할 좋지 않은 것들 : | ||
| 497 | - "우리를 그것을 AIT/ptx/Solaris에서 이러한 방법으로 했다. 그러므로 그것은 좋은 것임에 틀립없다..." | ||
| 498 | - "나는 20년동안 이것을 해왔다. 그러므로..." | ||
| 499 | - "이것은 돈을 벌기위해 나의 회사가 필요로 하는 것이다." | ||
| 500 | - "이것은 우리의 엔터프라이즈 상품 라인을 위한 것이다." | ||
| 501 | - "여기에 나의 생각을 말하고 있는 1000 페이지 설계 문서가 있다." | ||
| 502 | - "나는 6달동안 이것을 했으니..." | ||
| 503 | - "여기세 5000라인 짜리 패치가 있으니..." | ||
| 504 | - "나는 현재 뒤죽박죽인 것을 재작성했다. 그리고 여기에..." | ||
| 505 | - "나는 마감시한을 가지고 있으므로 이 패치는 지금 적용될 필요가 있다." | ||
| 506 | |||
| 507 | 커널 커뮤니티가 전통적인 소프트웨어 엔지니어링 개발 환경들과 | ||
| 508 | 또 다른 점은 얼굴을 보지 않고 일한다는 점이다. 이메일과 irc를 대화의 | ||
| 509 | 주요수단으로 사용하는 것의 한가지 장점은 성별이나 인종의 차별이 | ||
| 510 | 없다는 것이다. 리눅스 커널의 작업 환경에서는 단지 이메일 주소만 | ||
| 511 | 알수 있기 때문에 여성과 소수 민족들도 모두 받아들여진다. 국제적으로 | ||
| 512 | 일하게 되는 측면은 사람의 이름에 근거하여 성별을 추측할 수 없게 | ||
| 513 | 하기때문에 차별을 없애는 데 도움을 준다. Andrea라는 이름을 가진 남자와 | ||
| 514 | Pat이라는 이름을 가진 여자가 있을 수도 있는 것이다. 리눅스 커널에서 | ||
| 515 | 작업하며 생각을 표현해왔던 대부분의 여성들은 긍정적인 경험을 가지고 | ||
| 516 | 있다. | ||
| 517 | |||
| 518 | 언어 장벽은 영어에 익숙하지 않은 몇몇 사람들에게 문제가 될 수도 있다. | ||
| 519 | 언어의 훌륭한 구사는 메일링 리스트에서 올바르게 자신의 생각을 | ||
| 520 | 표현하기 위하여 필요하다. 그래서 여러분은 이메일을 보내기 전에 | ||
| 521 | 영어를 올바르게 사용하고 있는지를 체크하는 것이 바람직하다. | ||
| 522 | |||
| 523 | |||
| 524 | 여러분의 변경을 나누어라 | ||
| 525 | ------------------------ | ||
| 526 | |||
| 527 | 리눅스 커널 커뮤니티는 한꺼번에 굉장히 큰 코드의 묶음을 쉽게 | ||
| 528 | 받아들이지 않는다. 변경은 적절하게 소개되고, 검토되고, 각각의 | ||
| 529 | 부분으로 작게 나누어져야 한다. 이것은 회사에서 하는 것과는 정확히 | ||
| 530 | 반대되는 것이다. 여러분들의 제안은 개발 초기에 일찍이 소개되야 한다. | ||
| 531 | 그래서 여러분들은 자신이 하고 있는 것에 관하여 피드백을 받을 수 있게 | ||
| 532 | 된다. 커뮤니티가 여러분들이 커뮤니티와 함께 일하고 있다는 것을 | ||
| 533 | 느끼도록 만들고 커뮤니티가 여러분의 기능을 위한 쓰레기 장으로서 | ||
| 534 | 사용되지 않고 있다는 것을 느끼게 하자. 그러나 메일링 리스트에 한번에 | ||
| 535 | 50개의 이메일을 보내지는 말아라. 여러분들의 일련의 패치들은 항상 | ||
| 536 | 더 작아야 한다. | ||
| 537 | |||
| 538 | 패치를 나누는 이유는 다음과 같다. | ||
| 539 | |||
| 540 | 1) 작은 패치들은 여러분의 패치들이 적용될 수 있는 확률을 높여준다. | ||
| 541 | 왜냐하면 다른 사람들은 정확성을 검증하기 위하여 많은 시간과 노력을 | ||
| 542 | 들이기를 원하지 않는다. 5줄의 패치는 메인트너가 거의 몇 초간 힐끗 | ||
| 543 | 보면 적용될 수 있다. 그러나 500 줄의 패치는 정확성을 검토하기 위하여 | ||
| 544 | 몇시간이 걸릴 수도 있다(걸리는 시간은 패치의 크기 혹은 다른 것에 | ||
| 545 | 비례하여 기하급수적으로 늘어난다). | ||
| 546 | |||
| 547 | 패치를 작게 만드는 것은 무엇인가 잘못되었을 때 디버그하는 것을 | ||
| 548 | 쉽게 만든다. 즉, 그렇게 만드는 것은 매우 큰 패치를 적용한 후에 | ||
| 549 | 조사하는 것 보다 작은 패치를 적용한 후에 (그리고 몇몇의 것이 | ||
| 550 | 깨졌을 때) 하나씩 패치들을 제거해가며 디버그 하기 쉽도록 만들어 준다. | ||
| 551 | |||
| 552 | 2) 작은 패치들을 보내는 것뿐만 아니라 패치들을 제출하기전에 재작성하고 | ||
| 553 | 간단하게(혹은 간단한게 재배치하여) 하는 것도 중요하다. | ||
| 554 | |||
| 555 | 여기에 커널 개발자 Al Viro의 이야기가 있다. | ||
| 556 | "학생의 수학 숙제를 채점하는 선생님을 생각해보라. 선생님은 학생들이 | ||
| 557 | 답을 얻을때까지 겪은 시행착오를 보길 원하지 않는다. 선생님들은 | ||
| 558 | 간결하고 가장 뛰어난 답을 보길 원한다. 훌륭한 학생은 이것을 알고 | ||
| 559 | 마지막으로 답을 얻기 전 중간 과정들을 제출하진 않는다. | ||
| 560 | |||
| 561 | 커널 개발도 마찬가지이다. 메인트너들과 검토하는 사람들은 문제를 | ||
| 562 | 풀어나가는 과정속에 숨겨진 과정을 보길 원하진 않는다. 그들은 | ||
| 563 | 간결하고 멋진 답을 보길 원한다." | ||
| 564 | |||
| 565 | 커뮤니티와 함께 일하며 뛰어난 답을 찾고 여러분들의 완성되지 않은 일들 | ||
| 566 | 사이에 균형을 유지해야 하는 어려움이 있을 수 있다. 그러므로 프로세스의 | ||
| 567 | 초반에 여러분의 일을 향상시키기위한 피드백을 얻는 것 뿐만 아니라 | ||
| 568 | 여러분들의 변경들을 작은 묶음으로 유지해서 심지어는 여러분의 작업의 | ||
| 569 | 모든 부분이 지금은 포함될 준비가 되어있지 않지만 작은 부분은 이미 | ||
| 570 | 받아들여질 수 있도록 유지하는 것이 바람직하다. | ||
| 571 | |||
| 572 | 또한 완성되지 않았고 "나중에 수정될 것이다." 와 같은 것들은 포함하는 | ||
| 573 | 패치들은 받아들여지지 않을 것이라는 점을 유념하라. | ||
| 574 | |||
| 575 | 변경을 정당화해라 | ||
| 576 | ----------------- | ||
| 577 | |||
| 578 | 여러분들의 나누어진 패치들을 리눅스 커뮤니티가 왜 반영해야 하는지를 | ||
| 579 | 알도록 하는 것은 매우 중요하다. 새로운 기능들이 필요하고 유용하다는 | ||
| 580 | 것은 반드시 그에 맞는 이유가 있어야 한다. | ||
| 581 | |||
| 582 | |||
| 583 | 변경을 문서화해라 | ||
| 584 | ----------------- | ||
| 585 | |||
| 586 | 여러분이 패치를 보내려 할때는 여러분이 무엇을 말하려고 하는지를 충분히 | ||
| 587 | 생각하여 이메일을 작성해야 한다. 이 정보는 패치를 위한 ChangeLog가 될 | ||
| 588 | 것이다. 그리고 항상 그 내용을 보길 원하는 모든 사람들을 위해 보존될 | ||
| 589 | 것이다. 패치는 완벽하게 다음과 같은 내용들을 포함하여 설명해야 한다. | ||
| 590 | - 변경이 왜 필요한지 | ||
| 591 | - 패치에 관한 전체 설계 어프로치 | ||
| 592 | - 구현 상세들 | ||
| 593 | - 테스트 결과들 | ||
| 594 | |||
| 595 | 이것이 무엇인지 더 자세한 것을 알고 싶다면 다음 문서의 ChageLog 항을 봐라. | ||
| 596 | "The Perfect Patch" | ||
| 597 | http://www.zip.com.au/~akpm/linux/patches/stuff/tpp.txt | ||
| 598 | |||
| 599 | |||
| 600 | |||
| 601 | |||
| 602 | 이 모든 것을 하는 것은 매우 어려운 일이다. 완벽히 소화하는 데는 적어도 몇년이 | ||
| 603 | 걸릴 수도 있다. 많은 인내와 결의가 필요한 계속되는 개선의 과정이다. 그러나 | ||
| 604 | 가능한한 포기하지 말라. 많은 사람들은 이전부터 해왔던 것이고 그 사람들도 | ||
| 605 | 정확하게 여러분들이 지금 서 있는 그 곳부터 시작했었다. | ||
| 606 | |||
| 607 | |||
| 608 | |||
| 609 | |||
| 610 | ---------- | ||
| 611 | "개발 프로세스"(http://linux.tar.gz/articles/2.6-development_process) 섹션을 | ||
| 612 | 작성하는데 있어 참고할 문서를 사용하도록 허락해준 Paolo Ciarrocchi에게 | ||
| 613 | 감사한다. 여러분들이 말해야 할 것과 말해서는 안되는 것의 목록 중 일부를 제공해준 | ||
| 614 | Randy Dunlap과 Gerrit Huizenga에게 감사한다. 또한 검토와 의견 그리고 | ||
| 615 | 공헌을 아끼지 않은 Pat Mochel, Hanna Linder, Randy Dunlap, Kay Sievers, | ||
| 616 | Vojtech Pavlik, Jan Kara, Josh Boyer, Kees Cook, Andrew Morton, Andi Kleen, | ||
| 617 | Vadim Lobanov, Jesper Juhl, Adrian Bunk, Keri Harris, Frans Pop, | ||
| 618 | David A. Wheeler, Junio Hamano, Michael Kerrisk, and Alex Shepard에게도 감사를 전한다. | ||
| 619 | 그들의 도움이 없었다면 이 문서는 존재하지 않았을 것이다. | ||
| 620 | |||
| 621 | |||
| 622 | |||
| 623 | 메인트너: Greg Kroah-Hartman <greg@kroah.com> | ||
diff --git a/Documentation/vm/numa_memory_policy.txt b/Documentation/vm/numa_memory_policy.txt new file mode 100644 index 000000000000..8242f52d0f22 --- /dev/null +++ b/Documentation/vm/numa_memory_policy.txt | |||
| @@ -0,0 +1,332 @@ | |||
| 1 | |||
| 2 | What is Linux Memory Policy? | ||
| 3 | |||
| 4 | In the Linux kernel, "memory policy" determines from which node the kernel will | ||
| 5 | allocate memory in a NUMA system or in an emulated NUMA system. Linux has | ||
| 6 | supported platforms with Non-Uniform Memory Access architectures since 2.4.?. | ||
| 7 | The current memory policy support was added to Linux 2.6 around May 2004. This | ||
| 8 | document attempts to describe the concepts and APIs of the 2.6 memory policy | ||
| 9 | support. | ||
| 10 | |||
| 11 | Memory policies should not be confused with cpusets (Documentation/cpusets.txt) | ||
| 12 | which is an administrative mechanism for restricting the nodes from which | ||
| 13 | memory may be allocated by a set of processes. Memory policies are a | ||
| 14 | programming interface that a NUMA-aware application can take advantage of. When | ||
| 15 | both cpusets and policies are applied to a task, the restrictions of the cpuset | ||
| 16 | takes priority. See "MEMORY POLICIES AND CPUSETS" below for more details. | ||
| 17 | |||
| 18 | MEMORY POLICY CONCEPTS | ||
| 19 | |||
| 20 | Scope of Memory Policies | ||
| 21 | |||
| 22 | The Linux kernel supports _scopes_ of memory policy, described here from | ||
| 23 | most general to most specific: | ||
| 24 | |||
| 25 | System Default Policy: this policy is "hard coded" into the kernel. It | ||
| 26 | is the policy that governs all page allocations that aren't controlled | ||
| 27 | by one of the more specific policy scopes discussed below. When the | ||
| 28 | system is "up and running", the system default policy will use "local | ||
| 29 | allocation" described below. However, during boot up, the system | ||
| 30 | default policy will be set to interleave allocations across all nodes | ||
| 31 | with "sufficient" memory, so as not to overload the initial boot node | ||
| 32 | with boot-time allocations. | ||
| 33 | |||
| 34 | Task/Process Policy: this is an optional, per-task policy. When defined | ||
| 35 | for a specific task, this policy controls all page allocations made by or | ||
| 36 | on behalf of the task that aren't controlled by a more specific scope. | ||
| 37 | If a task does not define a task policy, then all page allocations that | ||
| 38 | would have been controlled by the task policy "fall back" to the System | ||
| 39 | Default Policy. | ||
| 40 | |||
| 41 | The task policy applies to the entire address space of a task. Thus, | ||
| 42 | it is inheritable, and indeed is inherited, across both fork() | ||
| 43 | [clone() w/o the CLONE_VM flag] and exec*(). This allows a parent task | ||
| 44 | to establish the task policy for a child task exec()'d from an | ||
| 45 | executable image that has no awareness of memory policy. See the | ||
| 46 | MEMORY POLICY APIS section, below, for an overview of the system call | ||
| 47 | that a task may use to set/change it's task/process policy. | ||
| 48 | |||
| 49 | In a multi-threaded task, task policies apply only to the thread | ||
| 50 | [Linux kernel task] that installs the policy and any threads | ||
| 51 | subsequently created by that thread. Any sibling threads existing | ||
| 52 | at the time a new task policy is installed retain their current | ||
| 53 | policy. | ||
| 54 | |||
| 55 | A task policy applies only to pages allocated after the policy is | ||
| 56 | installed. Any pages already faulted in by the task when the task | ||
| 57 | changes its task policy remain where they were allocated based on | ||
| 58 | the policy at the time they were allocated. | ||
| 59 | |||
| 60 | VMA Policy: A "VMA" or "Virtual Memory Area" refers to a range of a task's | ||
| 61 | virtual adddress space. A task may define a specific policy for a range | ||
| 62 | of its virtual address space. See the MEMORY POLICIES APIS section, | ||
| 63 | below, for an overview of the mbind() system call used to set a VMA | ||
| 64 | policy. | ||
| 65 | |||
| 66 | A VMA policy will govern the allocation of pages that back this region of | ||
| 67 | the address space. Any regions of the task's address space that don't | ||
| 68 | have an explicit VMA policy will fall back to the task policy, which may | ||
| 69 | itself fall back to the System Default Policy. | ||
| 70 | |||
| 71 | VMA policies have a few complicating details: | ||
| 72 | |||
| 73 | VMA policy applies ONLY to anonymous pages. These include pages | ||
| 74 | allocated for anonymous segments, such as the task stack and heap, and | ||
| 75 | any regions of the address space mmap()ed with the MAP_ANONYMOUS flag. | ||
| 76 | If a VMA policy is applied to a file mapping, it will be ignored if | ||
| 77 | the mapping used the MAP_SHARED flag. If the file mapping used the | ||
| 78 | MAP_PRIVATE flag, the VMA policy will only be applied when an | ||
| 79 | anonymous page is allocated on an attempt to write to the mapping-- | ||
| 80 | i.e., at Copy-On-Write. | ||
| 81 | |||
| 82 | VMA policies are shared between all tasks that share a virtual address | ||
| 83 | space--a.k.a. threads--independent of when the policy is installed; and | ||
| 84 | they are inherited across fork(). However, because VMA policies refer | ||
| 85 | to a specific region of a task's address space, and because the address | ||
| 86 | space is discarded and recreated on exec*(), VMA policies are NOT | ||
| 87 | inheritable across exec(). Thus, only NUMA-aware applications may | ||
| 88 | use VMA policies. | ||
| 89 | |||
| 90 | A task may install a new VMA policy on a sub-range of a previously | ||
| 91 | mmap()ed region. When this happens, Linux splits the existing virtual | ||
| 92 | memory area into 2 or 3 VMAs, each with it's own policy. | ||
| 93 | |||
| 94 | By default, VMA policy applies only to pages allocated after the policy | ||
| 95 | is installed. Any pages already faulted into the VMA range remain | ||
| 96 | where they were allocated based on the policy at the time they were | ||
| 97 | allocated. However, since 2.6.16, Linux supports page migration via | ||
| 98 | the mbind() system call, so that page contents can be moved to match | ||
| 99 | a newly installed policy. | ||
| 100 | |||
| 101 | Shared Policy: Conceptually, shared policies apply to "memory objects" | ||
| 102 | mapped shared into one or more tasks' distinct address spaces. An | ||
| 103 | application installs a shared policies the same way as VMA policies--using | ||
| 104 | the mbind() system call specifying a range of virtual addresses that map | ||
| 105 | the shared object. However, unlike VMA policies, which can be considered | ||
| 106 | to be an attribute of a range of a task's address space, shared policies | ||
| 107 | apply directly to the shared object. Thus, all tasks that attach to the | ||
| 108 | object share the policy, and all pages allocated for the shared object, | ||
| 109 | by any task, will obey the shared policy. | ||
| 110 | |||
| 111 | As of 2.6.22, only shared memory segments, created by shmget() or | ||
| 112 | mmap(MAP_ANONYMOUS|MAP_SHARED), support shared policy. When shared | ||
| 113 | policy support was added to Linux, the associated data structures were | ||
| 114 | added to hugetlbfs shmem segments. At the time, hugetlbfs did not | ||
| 115 | support allocation at fault time--a.k.a lazy allocation--so hugetlbfs | ||
| 116 | shmem segments were never "hooked up" to the shared policy support. | ||
| 117 | Although hugetlbfs segments now support lazy allocation, their support | ||
| 118 | for shared policy has not been completed. | ||
| 119 | |||
| 120 | As mentioned above [re: VMA policies], allocations of page cache | ||
| 121 | pages for regular files mmap()ed with MAP_SHARED ignore any VMA | ||
| 122 | policy installed on the virtual address range backed by the shared | ||
| 123 | file mapping. Rather, shared page cache pages, including pages backing | ||
| 124 | private mappings that have not yet been written by the task, follow | ||
| 125 | task policy, if any, else System Default Policy. | ||
| 126 | |||
| 127 | The shared policy infrastructure supports different policies on subset | ||
| 128 | ranges of the shared object. However, Linux still splits the VMA of | ||
| 129 | the task that installs the policy for each range of distinct policy. | ||
| 130 | Thus, different tasks that attach to a shared memory segment can have | ||
| 131 | different VMA configurations mapping that one shared object. This | ||
| 132 | can be seen by examining the /proc/<pid>/numa_maps of tasks sharing | ||
| 133 | a shared memory region, when one task has installed shared policy on | ||
| 134 | one or more ranges of the region. | ||
| 135 | |||
| 136 | Components of Memory Policies | ||
| 137 | |||
| 138 | A Linux memory policy is a tuple consisting of a "mode" and an optional set | ||
| 139 | of nodes. The mode determine the behavior of the policy, while the | ||
| 140 | optional set of nodes can be viewed as the arguments to the behavior. | ||
| 141 | |||
| 142 | Internally, memory policies are implemented by a reference counted | ||
| 143 | structure, struct mempolicy. Details of this structure will be discussed | ||
| 144 | in context, below, as required to explain the behavior. | ||
| 145 | |||
| 146 | Note: in some functions AND in the struct mempolicy itself, the mode | ||
| 147 | is called "policy". However, to avoid confusion with the policy tuple, | ||
| 148 | this document will continue to use the term "mode". | ||
| 149 | |||
| 150 | Linux memory policy supports the following 4 behavioral modes: | ||
| 151 | |||
| 152 | Default Mode--MPOL_DEFAULT: The behavior specified by this mode is | ||
| 153 | context or scope dependent. | ||
| 154 | |||
| 155 | As mentioned in the Policy Scope section above, during normal | ||
| 156 | system operation, the System Default Policy is hard coded to | ||
| 157 | contain the Default mode. | ||
| 158 | |||
| 159 | In this context, default mode means "local" allocation--that is | ||
| 160 | attempt to allocate the page from the node associated with the cpu | ||
| 161 | where the fault occurs. If the "local" node has no memory, or the | ||
| 162 | node's memory can be exhausted [no free pages available], local | ||
| 163 | allocation will "fallback to"--attempt to allocate pages from-- | ||
| 164 | "nearby" nodes, in order of increasing "distance". | ||
| 165 | |||
| 166 | Implementation detail -- subject to change: "Fallback" uses | ||
| 167 | a per node list of sibling nodes--called zonelists--built at | ||
| 168 | boot time, or when nodes or memory are added or removed from | ||
| 169 | the system [memory hotplug]. These per node zonelist are | ||
| 170 | constructed with nodes in order of increasing distance based | ||
| 171 | on information provided by the platform firmware. | ||
| 172 | |||
| 173 | When a task/process policy or a shared policy contains the Default | ||
| 174 | mode, this also means "local allocation", as described above. | ||
| 175 | |||
| 176 | In the context of a VMA, Default mode means "fall back to task | ||
| 177 | policy"--which may or may not specify Default mode. Thus, Default | ||
| 178 | mode can not be counted on to mean local allocation when used | ||
| 179 | on a non-shared region of the address space. However, see | ||
| 180 | MPOL_PREFERRED below. | ||
| 181 | |||
| 182 | The Default mode does not use the optional set of nodes. | ||
| 183 | |||
| 184 | MPOL_BIND: This mode specifies that memory must come from the | ||
| 185 | set of nodes specified by the policy. | ||
| 186 | |||
| 187 | The memory policy APIs do not specify an order in which the nodes | ||
| 188 | will be searched. However, unlike "local allocation", the Bind | ||
| 189 | policy does not consider the distance between the nodes. Rather, | ||
| 190 | allocations will fallback to the nodes specified by the policy in | ||
| 191 | order of numeric node id. Like everything in Linux, this is subject | ||
| 192 | to change. | ||
| 193 | |||
| 194 | MPOL_PREFERRED: This mode specifies that the allocation should be | ||
| 195 | attempted from the single node specified in the policy. If that | ||
| 196 | allocation fails, the kernel will search other nodes, exactly as | ||
| 197 | it would for a local allocation that started at the preferred node | ||
| 198 | in increasing distance from the preferred node. "Local" allocation | ||
| 199 | policy can be viewed as a Preferred policy that starts at the node | ||
| 200 | containing the cpu where the allocation takes place. | ||
| 201 | |||
| 202 | Internally, the Preferred policy uses a single node--the | ||
| 203 | preferred_node member of struct mempolicy. A "distinguished | ||
| 204 | value of this preferred_node, currently '-1', is interpreted | ||
| 205 | as "the node containing the cpu where the allocation takes | ||
| 206 | place"--local allocation. This is the way to specify | ||
| 207 | local allocation for a specific range of addresses--i.e. for | ||
| 208 | VMA policies. | ||
| 209 | |||
| 210 | MPOL_INTERLEAVED: This mode specifies that page allocations be | ||
| 211 | interleaved, on a page granularity, across the nodes specified in | ||
| 212 | the policy. This mode also behaves slightly differently, based on | ||
| 213 | the context where it is used: | ||
| 214 | |||
| 215 | For allocation of anonymous pages and shared memory pages, | ||
| 216 | Interleave mode indexes the set of nodes specified by the policy | ||
| 217 | using the page offset of the faulting address into the segment | ||
| 218 | [VMA] containing the address modulo the number of nodes specified | ||
| 219 | by the policy. It then attempts to allocate a page, starting at | ||
| 220 | the selected node, as if the node had been specified by a Preferred | ||
| 221 | policy or had been selected by a local allocation. That is, | ||
| 222 | allocation will follow the per node zonelist. | ||
| 223 | |||
| 224 | For allocation of page cache pages, Interleave mode indexes the set | ||
| 225 | of nodes specified by the policy using a node counter maintained | ||
| 226 | per task. This counter wraps around to the lowest specified node | ||
| 227 | after it reaches the highest specified node. This will tend to | ||
| 228 | spread the pages out over the nodes specified by the policy based | ||
| 229 | on the order in which they are allocated, rather than based on any | ||
| 230 | page offset into an address range or file. During system boot up, | ||
| 231 | the temporary interleaved system default policy works in this | ||
| 232 | mode. | ||
| 233 | |||
| 234 | MEMORY POLICY APIs | ||
| 235 | |||
| 236 | Linux supports 3 system calls for controlling memory policy. These APIS | ||
| 237 | always affect only the calling task, the calling task's address space, or | ||
| 238 | some shared object mapped into the calling task's address space. | ||
| 239 | |||
| 240 | Note: the headers that define these APIs and the parameter data types | ||
| 241 | for user space applications reside in a package that is not part of | ||
| 242 | the Linux kernel. The kernel system call interfaces, with the 'sys_' | ||
| 243 | prefix, are defined in <linux/syscalls.h>; the mode and flag | ||
| 244 | definitions are defined in <linux/mempolicy.h>. | ||
| 245 | |||
| 246 | Set [Task] Memory Policy: | ||
| 247 | |||
| 248 | long set_mempolicy(int mode, const unsigned long *nmask, | ||
| 249 | unsigned long maxnode); | ||
| 250 | |||
| 251 | Set's the calling task's "task/process memory policy" to mode | ||
| 252 | specified by the 'mode' argument and the set of nodes defined | ||
| 253 | by 'nmask'. 'nmask' points to a bit mask of node ids containing | ||
| 254 | at least 'maxnode' ids. | ||
| 255 | |||
| 256 | See the set_mempolicy(2) man page for more details | ||
| 257 | |||
| 258 | |||
| 259 | Get [Task] Memory Policy or Related Information | ||
| 260 | |||
| 261 | long get_mempolicy(int *mode, | ||
| 262 | const unsigned long *nmask, unsigned long maxnode, | ||
| 263 | void *addr, int flags); | ||
| 264 | |||
| 265 | Queries the "task/process memory policy" of the calling task, or | ||
| 266 | the policy or location of a specified virtual address, depending | ||
| 267 | on the 'flags' argument. | ||
| 268 | |||
| 269 | See the get_mempolicy(2) man page for more details | ||
| 270 | |||
| 271 | |||
| 272 | Install VMA/Shared Policy for a Range of Task's Address Space | ||
| 273 | |||
| 274 | long mbind(void *start, unsigned long len, int mode, | ||
| 275 | const unsigned long *nmask, unsigned long maxnode, | ||
| 276 | unsigned flags); | ||
| 277 | |||
| 278 | mbind() installs the policy specified by (mode, nmask, maxnodes) as | ||
| 279 | a VMA policy for the range of the calling task's address space | ||
| 280 | specified by the 'start' and 'len' arguments. Additional actions | ||
| 281 | may be requested via the 'flags' argument. | ||
| 282 | |||
| 283 | See the mbind(2) man page for more details. | ||
| 284 | |||
| 285 | MEMORY POLICY COMMAND LINE INTERFACE | ||
| 286 | |||
| 287 | Although not strictly part of the Linux implementation of memory policy, | ||
| 288 | a command line tool, numactl(8), exists that allows one to: | ||
| 289 | |||
| 290 | + set the task policy for a specified program via set_mempolicy(2), fork(2) and | ||
| 291 | exec(2) | ||
| 292 | |||
| 293 | + set the shared policy for a shared memory segment via mbind(2) | ||
| 294 | |||
| 295 | The numactl(8) tool is packages with the run-time version of the library | ||
| 296 | containing the memory policy system call wrappers. Some distributions | ||
| 297 | package the headers and compile-time libraries in a separate development | ||
| 298 | package. | ||
| 299 | |||
| 300 | |||
| 301 | MEMORY POLICIES AND CPUSETS | ||
| 302 | |||
| 303 | Memory policies work within cpusets as described above. For memory policies | ||
| 304 | that require a node or set of nodes, the nodes are restricted to the set of | ||
| 305 | nodes whose memories are allowed by the cpuset constraints. If the | ||
| 306 | intersection of the set of nodes specified for the policy and the set of nodes | ||
| 307 | allowed by the cpuset is the empty set, the policy is considered invalid and | ||
| 308 | cannot be installed. | ||
| 309 | |||
| 310 | The interaction of memory policies and cpusets can be problematic for a | ||
| 311 | couple of reasons: | ||
| 312 | |||
| 313 | 1) the memory policy APIs take physical node id's as arguments. However, the | ||
| 314 | memory policy APIs do not provide a way to determine what nodes are valid | ||
| 315 | in the context where the application is running. An application MAY consult | ||
| 316 | the cpuset file system [directly or via an out of tree, and not generally | ||
| 317 | available, libcpuset API] to obtain this information, but then the | ||
| 318 | application must be aware that it is running in a cpuset and use what are | ||
| 319 | intended primarily as administrative APIs. | ||
| 320 | |||
| 321 | However, as long as the policy specifies at least one node that is valid | ||
| 322 | in the controlling cpuset, the policy can be used. | ||
| 323 | |||
| 324 | 2) when tasks in two cpusets share access to a memory region, such as shared | ||
| 325 | memory segments created by shmget() of mmap() with the MAP_ANONYMOUS and | ||
| 326 | MAP_SHARED flags, and any of the tasks install shared policy on the region, | ||
| 327 | only nodes whose memories are allowed in both cpusets may be used in the | ||
| 328 | policies. Again, obtaining this information requires "stepping outside" | ||
| 329 | the memory policy APIs, as well as knowing in what cpusets other task might | ||
| 330 | be attaching to the shared region, to use the cpuset information. | ||
| 331 | Furthermore, if the cpusets' allowed memory sets are disjoint, "local" | ||
| 332 | allocation is the only valid policy. | ||
diff --git a/Documentation/watchdog/00-INDEX b/Documentation/watchdog/00-INDEX new file mode 100644 index 000000000000..c3ea47e507fe --- /dev/null +++ b/Documentation/watchdog/00-INDEX | |||
| @@ -0,0 +1,10 @@ | |||
| 1 | 00-INDEX | ||
| 2 | - this file. | ||
| 3 | pcwd-watchdog.txt | ||
| 4 | - documentation for Berkshire Products PC Watchdog ISA cards. | ||
| 5 | src/ | ||
| 6 | - directory holding watchdog related example programs. | ||
| 7 | watchdog-api.txt | ||
| 8 | - description of the Linux Watchdog driver API. | ||
| 9 | wdt.txt | ||
| 10 | - description of the Watchdog Timer Interfaces for Linux. | ||
diff --git a/MAINTAINERS b/MAINTAINERS index c1609ea0fa1f..10a6f57776b2 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
| @@ -3452,7 +3452,7 @@ S: Maintained | |||
| 3452 | 3452 | ||
| 3453 | TPM DEVICE DRIVER | 3453 | TPM DEVICE DRIVER |
| 3454 | P: Kylene Hall | 3454 | P: Kylene Hall |
| 3455 | M: kjhall@us.ibm.com | 3455 | M: tpmdd-devel@lists.sourceforge.net |
| 3456 | W: http://tpmdd.sourceforge.net | 3456 | W: http://tpmdd.sourceforge.net |
| 3457 | P: Marcel Selhorst | 3457 | P: Marcel Selhorst |
| 3458 | M: tpm@selhorst.net | 3458 | M: tpm@selhorst.net |
diff --git a/arch/h8300/kernel/process.c b/arch/h8300/kernel/process.c index e061b63a0038..dfbe7ab9ffe2 100644 --- a/arch/h8300/kernel/process.c +++ b/arch/h8300/kernel/process.c | |||
| @@ -37,6 +37,7 @@ | |||
| 37 | #include <linux/a.out.h> | 37 | #include <linux/a.out.h> |
| 38 | #include <linux/interrupt.h> | 38 | #include <linux/interrupt.h> |
| 39 | #include <linux/reboot.h> | 39 | #include <linux/reboot.h> |
| 40 | #include <linux/fs.h> | ||
| 40 | 41 | ||
| 41 | #include <asm/uaccess.h> | 42 | #include <asm/uaccess.h> |
| 42 | #include <asm/system.h> | 43 | #include <asm/system.h> |
diff --git a/arch/h8300/kernel/sys_h8300.c b/arch/h8300/kernel/sys_h8300.c index de7688cfd573..ddc62727dc9f 100644 --- a/arch/h8300/kernel/sys_h8300.c +++ b/arch/h8300/kernel/sys_h8300.c | |||
| @@ -18,6 +18,7 @@ | |||
| 18 | #include <linux/mman.h> | 18 | #include <linux/mman.h> |
| 19 | #include <linux/file.h> | 19 | #include <linux/file.h> |
| 20 | #include <linux/utsname.h> | 20 | #include <linux/utsname.h> |
| 21 | #include <linux/fs.h> | ||
| 21 | 22 | ||
| 22 | #include <asm/setup.h> | 23 | #include <asm/setup.h> |
| 23 | #include <asm/uaccess.h> | 24 | #include <asm/uaccess.h> |
diff --git a/arch/i386/Kconfig b/arch/i386/Kconfig index f16a46e8849c..97b64d7d6bf6 100644 --- a/arch/i386/Kconfig +++ b/arch/i386/Kconfig | |||
| @@ -614,10 +614,14 @@ config X86_PAE | |||
| 614 | 614 | ||
| 615 | # Common NUMA Features | 615 | # Common NUMA Features |
| 616 | config NUMA | 616 | config NUMA |
| 617 | bool "Numa Memory Allocation and Scheduler Support" | 617 | bool "Numa Memory Allocation and Scheduler Support (EXPERIMENTAL)" |
| 618 | depends on SMP && HIGHMEM64G && (X86_NUMAQ || (X86_SUMMIT || X86_GENERICARCH) && ACPI) | 618 | depends on SMP && HIGHMEM64G && (X86_NUMAQ || (X86_SUMMIT || X86_GENERICARCH) && ACPI) && EXPERIMENTAL |
| 619 | default n if X86_PC | 619 | default n if X86_PC |
| 620 | default y if (X86_NUMAQ || X86_SUMMIT) | 620 | default y if (X86_NUMAQ || X86_SUMMIT) |
| 621 | help | ||
| 622 | NUMA support for i386. This is currently high experimental | ||
| 623 | and should be only used for kernel development. It might also | ||
| 624 | cause boot failures. | ||
| 621 | 625 | ||
| 622 | comment "NUMA (Summit) requires SMP, 64GB highmem support, ACPI" | 626 | comment "NUMA (Summit) requires SMP, 64GB highmem support, ACPI" |
| 623 | depends on X86_SUMMIT && (!HIGHMEM64G || !ACPI) | 627 | depends on X86_SUMMIT && (!HIGHMEM64G || !ACPI) |
diff --git a/arch/i386/mm/fault.c b/arch/i386/mm/fault.c index 01ffdd4964f0..fcb38e7f3543 100644 --- a/arch/i386/mm/fault.c +++ b/arch/i386/mm/fault.c | |||
| @@ -249,9 +249,10 @@ static inline pmd_t *vmalloc_sync_one(pgd_t *pgd, unsigned long address) | |||
| 249 | pmd_k = pmd_offset(pud_k, address); | 249 | pmd_k = pmd_offset(pud_k, address); |
| 250 | if (!pmd_present(*pmd_k)) | 250 | if (!pmd_present(*pmd_k)) |
| 251 | return NULL; | 251 | return NULL; |
| 252 | if (!pmd_present(*pmd)) | 252 | if (!pmd_present(*pmd)) { |
| 253 | set_pmd(pmd, *pmd_k); | 253 | set_pmd(pmd, *pmd_k); |
| 254 | else | 254 | arch_flush_lazy_mmu_mode(); |
| 255 | } else | ||
| 255 | BUG_ON(pmd_page(*pmd) != pmd_page(*pmd_k)); | 256 | BUG_ON(pmd_page(*pmd) != pmd_page(*pmd_k)); |
| 256 | return pmd_k; | 257 | return pmd_k; |
| 257 | } | 258 | } |
diff --git a/arch/i386/xen/xen-head.S b/arch/i386/xen/xen-head.S index bc71f3bc4014..f8d6937db2ec 100644 --- a/arch/i386/xen/xen-head.S +++ b/arch/i386/xen/xen-head.S | |||
| @@ -7,20 +7,20 @@ | |||
| 7 | #include <asm/boot.h> | 7 | #include <asm/boot.h> |
| 8 | #include <xen/interface/elfnote.h> | 8 | #include <xen/interface/elfnote.h> |
| 9 | 9 | ||
| 10 | .section .init.text | 10 | .pushsection .init.text |
| 11 | ENTRY(startup_xen) | 11 | ENTRY(startup_xen) |
| 12 | movl %esi,xen_start_info | 12 | movl %esi,xen_start_info |
| 13 | cld | 13 | cld |
| 14 | movl $(init_thread_union+THREAD_SIZE),%esp | 14 | movl $(init_thread_union+THREAD_SIZE),%esp |
| 15 | jmp xen_start_kernel | 15 | jmp xen_start_kernel |
| 16 | .popsection | ||
| 16 | 17 | ||
| 17 | .pushsection ".bss.page_aligned" | 18 | .pushsection .bss.page_aligned |
| 18 | .align PAGE_SIZE_asm | 19 | .align PAGE_SIZE_asm |
| 19 | ENTRY(hypercall_page) | 20 | ENTRY(hypercall_page) |
| 20 | .skip 0x1000 | 21 | .skip 0x1000 |
| 21 | .popsection | 22 | .popsection |
| 22 | 23 | ||
| 23 | .section .text | ||
| 24 | ELFNOTE(Xen, XEN_ELFNOTE_GUEST_OS, .asciz "linux") | 24 | ELFNOTE(Xen, XEN_ELFNOTE_GUEST_OS, .asciz "linux") |
| 25 | ELFNOTE(Xen, XEN_ELFNOTE_GUEST_VERSION, .asciz "2.6") | 25 | ELFNOTE(Xen, XEN_ELFNOTE_GUEST_VERSION, .asciz "2.6") |
| 26 | ELFNOTE(Xen, XEN_ELFNOTE_XEN_VERSION, .asciz "xen-3.0") | 26 | ELFNOTE(Xen, XEN_ELFNOTE_XEN_VERSION, .asciz "xen-3.0") |
diff --git a/arch/m68k/kernel/setup.c b/arch/m68k/kernel/setup.c index 7e6d5fb75390..ed3a4caec620 100644 --- a/arch/m68k/kernel/setup.c +++ b/arch/m68k/kernel/setup.c | |||
| @@ -62,7 +62,6 @@ EXPORT_SYMBOL(m68k_num_memory); | |||
| 62 | int m68k_realnum_memory; | 62 | int m68k_realnum_memory; |
| 63 | EXPORT_SYMBOL(m68k_realnum_memory); | 63 | EXPORT_SYMBOL(m68k_realnum_memory); |
| 64 | unsigned long m68k_memoffset; | 64 | unsigned long m68k_memoffset; |
| 65 | EXPORT_SYMBOL(m68k_memoffset); | ||
| 66 | struct mem_info m68k_memory[NUM_MEMINFO]; | 65 | struct mem_info m68k_memory[NUM_MEMINFO]; |
| 67 | EXPORT_SYMBOL(m68k_memory); | 66 | EXPORT_SYMBOL(m68k_memory); |
| 68 | 67 | ||
| @@ -200,7 +199,6 @@ static void __init m68k_parse_bootinfo(const struct bi_record *record) | |||
| 200 | (m68k_num_memory - 1)); | 199 | (m68k_num_memory - 1)); |
| 201 | m68k_num_memory = 1; | 200 | m68k_num_memory = 1; |
| 202 | } | 201 | } |
| 203 | m68k_memoffset = m68k_memory[0].addr-PAGE_OFFSET; | ||
| 204 | #endif | 202 | #endif |
| 205 | } | 203 | } |
| 206 | 204 | ||
diff --git a/arch/m68k/kernel/vmlinux-std.lds b/arch/m68k/kernel/vmlinux-std.lds index c42245775a4d..59fe285865ec 100644 --- a/arch/m68k/kernel/vmlinux-std.lds +++ b/arch/m68k/kernel/vmlinux-std.lds | |||
| @@ -19,6 +19,8 @@ SECTIONS | |||
| 19 | *(.gnu.warning) | 19 | *(.gnu.warning) |
| 20 | } :text = 0x4e75 | 20 | } :text = 0x4e75 |
| 21 | 21 | ||
| 22 | _etext = .; /* End of text section */ | ||
| 23 | |||
| 22 | . = ALIGN(16); /* Exception table */ | 24 | . = ALIGN(16); /* Exception table */ |
| 23 | __start___ex_table = .; | 25 | __start___ex_table = .; |
| 24 | __ex_table : { *(__ex_table) } | 26 | __ex_table : { *(__ex_table) } |
| @@ -26,8 +28,6 @@ SECTIONS | |||
| 26 | 28 | ||
| 27 | RODATA | 29 | RODATA |
| 28 | 30 | ||
| 29 | _etext = .; /* End of text section */ | ||
| 30 | |||
| 31 | .data : { /* Data */ | 31 | .data : { /* Data */ |
| 32 | DATA_DATA | 32 | DATA_DATA |
| 33 | CONSTRUCTORS | 33 | CONSTRUCTORS |
diff --git a/arch/m68k/mm/motorola.c b/arch/m68k/mm/motorola.c index 7d571a2b44dd..30d34f285024 100644 --- a/arch/m68k/mm/motorola.c +++ b/arch/m68k/mm/motorola.c | |||
| @@ -210,11 +210,7 @@ void __init paging_init(void) | |||
| 210 | int i; | 210 | int i; |
| 211 | 211 | ||
| 212 | #ifdef DEBUG | 212 | #ifdef DEBUG |
| 213 | { | 213 | printk ("start of paging_init (%p, %lx)\n", kernel_pg_dir, availmem); |
| 214 | extern unsigned long availmem; | ||
| 215 | printk ("start of paging_init (%p, %lx)\n", | ||
| 216 | kernel_pg_dir, availmem); | ||
| 217 | } | ||
| 218 | #endif | 214 | #endif |
| 219 | 215 | ||
| 220 | /* Fix the cache mode in the page descriptors for the 680[46]0. */ | 216 | /* Fix the cache mode in the page descriptors for the 680[46]0. */ |
diff --git a/arch/m68knommu/kernel/process.c b/arch/m68knommu/kernel/process.c index 846f97534685..47502d5ec19f 100644 --- a/arch/m68knommu/kernel/process.c +++ b/arch/m68knommu/kernel/process.c | |||
| @@ -28,6 +28,7 @@ | |||
| 28 | #include <linux/a.out.h> | 28 | #include <linux/a.out.h> |
| 29 | #include <linux/interrupt.h> | 29 | #include <linux/interrupt.h> |
| 30 | #include <linux/reboot.h> | 30 | #include <linux/reboot.h> |
| 31 | #include <linux/fs.h> | ||
| 31 | 32 | ||
| 32 | #include <asm/uaccess.h> | 33 | #include <asm/uaccess.h> |
| 33 | #include <asm/system.h> | 34 | #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 @@ | |||
| 18 | #include <linux/mman.h> | 18 | #include <linux/mman.h> |
| 19 | #include <linux/file.h> | 19 | #include <linux/file.h> |
| 20 | #include <linux/utsname.h> | 20 | #include <linux/utsname.h> |
| 21 | #include <linux/fs.h> | ||
| 21 | 22 | ||
| 22 | #include <asm/setup.h> | 23 | #include <asm/setup.h> |
| 23 | #include <asm/uaccess.h> | 24 | #include <asm/uaccess.h> |
diff --git a/arch/powerpc/sysdev/fsl_pci.c b/arch/powerpc/sysdev/fsl_pci.c index 9fb0ce5c7176..114c90f8f560 100644 --- a/arch/powerpc/sysdev/fsl_pci.c +++ b/arch/powerpc/sysdev/fsl_pci.c | |||
| @@ -251,6 +251,8 @@ DECLARE_PCI_FIXUP_EARLY(0x1957, PCI_DEVICE_ID_MPC8568E, quirk_fsl_pcie_transpare | |||
| 251 | DECLARE_PCI_FIXUP_EARLY(0x1957, PCI_DEVICE_ID_MPC8568, quirk_fsl_pcie_transparent); | 251 | DECLARE_PCI_FIXUP_EARLY(0x1957, PCI_DEVICE_ID_MPC8568, quirk_fsl_pcie_transparent); |
| 252 | DECLARE_PCI_FIXUP_EARLY(0x1957, PCI_DEVICE_ID_MPC8567E, quirk_fsl_pcie_transparent); | 252 | DECLARE_PCI_FIXUP_EARLY(0x1957, PCI_DEVICE_ID_MPC8567E, quirk_fsl_pcie_transparent); |
| 253 | DECLARE_PCI_FIXUP_EARLY(0x1957, PCI_DEVICE_ID_MPC8567, quirk_fsl_pcie_transparent); | 253 | DECLARE_PCI_FIXUP_EARLY(0x1957, PCI_DEVICE_ID_MPC8567, quirk_fsl_pcie_transparent); |
| 254 | DECLARE_PCI_FIXUP_EARLY(0x1957, PCI_DEVICE_ID_MPC8533E, quirk_fsl_pcie_transparent); | ||
| 255 | DECLARE_PCI_FIXUP_EARLY(0x1957, PCI_DEVICE_ID_MPC8533, quirk_fsl_pcie_transparent); | ||
| 254 | DECLARE_PCI_FIXUP_EARLY(0x1957, PCI_DEVICE_ID_MPC8544E, quirk_fsl_pcie_transparent); | 256 | DECLARE_PCI_FIXUP_EARLY(0x1957, PCI_DEVICE_ID_MPC8544E, quirk_fsl_pcie_transparent); |
| 255 | DECLARE_PCI_FIXUP_EARLY(0x1957, PCI_DEVICE_ID_MPC8544, quirk_fsl_pcie_transparent); | 257 | DECLARE_PCI_FIXUP_EARLY(0x1957, PCI_DEVICE_ID_MPC8544, quirk_fsl_pcie_transparent); |
| 256 | DECLARE_PCI_FIXUP_EARLY(0x1957, PCI_DEVICE_ID_MPC8641, quirk_fsl_pcie_transparent); | 258 | DECLARE_PCI_FIXUP_EARLY(0x1957, PCI_DEVICE_ID_MPC8641, quirk_fsl_pcie_transparent); |
diff --git a/arch/s390/hypfs/inode.c b/arch/s390/hypfs/inode.c index ad4ca75c0f04..5245717295b8 100644 --- a/arch/s390/hypfs/inode.c +++ b/arch/s390/hypfs/inode.c | |||
| @@ -60,17 +60,28 @@ static void hypfs_add_dentry(struct dentry *dentry) | |||
| 60 | hypfs_last_dentry = dentry; | 60 | hypfs_last_dentry = dentry; |
| 61 | } | 61 | } |
| 62 | 62 | ||
| 63 | static inline int hypfs_positive(struct dentry *dentry) | ||
| 64 | { | ||
| 65 | return dentry->d_inode && !d_unhashed(dentry); | ||
| 66 | } | ||
| 67 | |||
| 63 | static void hypfs_remove(struct dentry *dentry) | 68 | static void hypfs_remove(struct dentry *dentry) |
| 64 | { | 69 | { |
| 65 | struct dentry *parent; | 70 | struct dentry *parent; |
| 66 | 71 | ||
| 67 | parent = dentry->d_parent; | 72 | parent = dentry->d_parent; |
| 68 | if (S_ISDIR(dentry->d_inode->i_mode)) | 73 | if (!parent || !parent->d_inode) |
| 69 | simple_rmdir(parent->d_inode, dentry); | 74 | return; |
| 70 | else | 75 | mutex_lock(&parent->d_inode->i_mutex); |
| 71 | simple_unlink(parent->d_inode, dentry); | 76 | if (hypfs_positive(dentry)) { |
| 77 | if (S_ISDIR(dentry->d_inode->i_mode)) | ||
| 78 | simple_rmdir(parent->d_inode, dentry); | ||
| 79 | else | ||
| 80 | simple_unlink(parent->d_inode, dentry); | ||
| 81 | } | ||
| 72 | d_delete(dentry); | 82 | d_delete(dentry); |
| 73 | dput(dentry); | 83 | dput(dentry); |
| 84 | mutex_unlock(&parent->d_inode->i_mutex); | ||
| 74 | } | 85 | } |
| 75 | 86 | ||
| 76 | static void hypfs_delete_tree(struct dentry *root) | 87 | static void hypfs_delete_tree(struct dentry *root) |
| @@ -315,6 +326,7 @@ static int hypfs_fill_super(struct super_block *sb, void *data, int silent) | |||
| 315 | } | 326 | } |
| 316 | hypfs_update_update(sb); | 327 | hypfs_update_update(sb); |
| 317 | sb->s_root = root_dentry; | 328 | sb->s_root = root_dentry; |
| 329 | printk(KERN_INFO "hypfs: Hypervisor filesystem mounted\n"); | ||
| 318 | return 0; | 330 | return 0; |
| 319 | 331 | ||
| 320 | err_tree: | 332 | err_tree: |
| @@ -356,13 +368,17 @@ static struct dentry *hypfs_create_file(struct super_block *sb, | |||
| 356 | qname.name = name; | 368 | qname.name = name; |
| 357 | qname.len = strlen(name); | 369 | qname.len = strlen(name); |
| 358 | qname.hash = full_name_hash(name, qname.len); | 370 | qname.hash = full_name_hash(name, qname.len); |
| 371 | mutex_lock(&parent->d_inode->i_mutex); | ||
| 359 | dentry = lookup_one_len(name, parent, strlen(name)); | 372 | dentry = lookup_one_len(name, parent, strlen(name)); |
| 360 | if (IS_ERR(dentry)) | 373 | if (IS_ERR(dentry)) { |
| 361 | return ERR_PTR(-ENOMEM); | 374 | dentry = ERR_PTR(-ENOMEM); |
| 375 | goto fail; | ||
| 376 | } | ||
| 362 | inode = hypfs_make_inode(sb, mode); | 377 | inode = hypfs_make_inode(sb, mode); |
| 363 | if (!inode) { | 378 | if (!inode) { |
| 364 | dput(dentry); | 379 | dput(dentry); |
| 365 | return ERR_PTR(-ENOMEM); | 380 | dentry = ERR_PTR(-ENOMEM); |
| 381 | goto fail; | ||
| 366 | } | 382 | } |
| 367 | if (mode & S_IFREG) { | 383 | if (mode & S_IFREG) { |
| 368 | inode->i_fop = &hypfs_file_ops; | 384 | inode->i_fop = &hypfs_file_ops; |
| @@ -379,6 +395,8 @@ static struct dentry *hypfs_create_file(struct super_block *sb, | |||
| 379 | inode->i_private = data; | 395 | inode->i_private = data; |
| 380 | d_instantiate(dentry, inode); | 396 | d_instantiate(dentry, inode); |
| 381 | dget(dentry); | 397 | dget(dentry); |
| 398 | fail: | ||
| 399 | mutex_unlock(&parent->d_inode->i_mutex); | ||
| 382 | return dentry; | 400 | return dentry; |
| 383 | } | 401 | } |
| 384 | 402 | ||
| @@ -391,7 +409,6 @@ struct dentry *hypfs_mkdir(struct super_block *sb, struct dentry *parent, | |||
| 391 | if (IS_ERR(dentry)) | 409 | if (IS_ERR(dentry)) |
| 392 | return dentry; | 410 | return dentry; |
| 393 | hypfs_add_dentry(dentry); | 411 | hypfs_add_dentry(dentry); |
| 394 | parent->d_inode->i_nlink++; | ||
| 395 | return dentry; | 412 | return dentry; |
| 396 | } | 413 | } |
| 397 | 414 | ||
diff --git a/arch/s390/kernel/Makefile b/arch/s390/kernel/Makefile index 3195d375bd51..56cb71007cd9 100644 --- a/arch/s390/kernel/Makefile +++ b/arch/s390/kernel/Makefile | |||
| @@ -6,7 +6,7 @@ EXTRA_AFLAGS := -traditional | |||
| 6 | 6 | ||
| 7 | obj-y := bitmap.o traps.o time.o process.o base.o early.o \ | 7 | obj-y := bitmap.o traps.o time.o process.o base.o early.o \ |
| 8 | setup.o sys_s390.o ptrace.o signal.o cpcmd.o ebcdic.o \ | 8 | setup.o sys_s390.o ptrace.o signal.o cpcmd.o ebcdic.o \ |
| 9 | semaphore.o s390_ext.o debug.o irq.o ipl.o dis.o | 9 | semaphore.o s390_ext.o debug.o irq.o ipl.o dis.o diag.o |
| 10 | 10 | ||
| 11 | obj-y += $(if $(CONFIG_64BIT),entry64.o,entry.o) | 11 | obj-y += $(if $(CONFIG_64BIT),entry64.o,entry.o) |
| 12 | obj-y += $(if $(CONFIG_64BIT),reipl64.o,reipl.o) | 12 | obj-y += $(if $(CONFIG_64BIT),reipl64.o,reipl.o) |
diff --git a/arch/s390/kernel/diag.c b/arch/s390/kernel/diag.c new file mode 100644 index 000000000000..c032d11da8a1 --- /dev/null +++ b/arch/s390/kernel/diag.c | |||
| @@ -0,0 +1,102 @@ | |||
| 1 | /* | ||
| 2 | * Implementation of s390 diagnose codes | ||
| 3 | * | ||
| 4 | * Copyright IBM Corp. 2007 | ||
| 5 | * Author(s): Michael Holzheu <holzheu@de.ibm.com> | ||
| 6 | */ | ||
| 7 | |||
| 8 | #include <linux/module.h> | ||
| 9 | #include <asm/diag.h> | ||
| 10 | |||
| 11 | /* | ||
| 12 | * Diagnose 10: Release pages | ||
| 13 | */ | ||
| 14 | void diag10(unsigned long addr) | ||
| 15 | { | ||
| 16 | if (addr >= 0x7ff00000) | ||
| 17 | return; | ||
| 18 | asm volatile( | ||
| 19 | #ifdef CONFIG_64BIT | ||
| 20 | " sam31\n" | ||
| 21 | " diag %0,%0,0x10\n" | ||
| 22 | "0: sam64\n" | ||
| 23 | #else | ||
| 24 | " diag %0,%0,0x10\n" | ||
| 25 | "0:\n" | ||
| 26 | #endif | ||
| 27 | EX_TABLE(0b, 0b) | ||
| 28 | : : "a" (addr)); | ||
| 29 | } | ||
| 30 | EXPORT_SYMBOL(diag10); | ||
| 31 | |||
| 32 | /* | ||
| 33 | * Diagnose 14: Input spool file manipulation | ||
| 34 | */ | ||
| 35 | int diag14(unsigned long rx, unsigned long ry1, unsigned long subcode) | ||
| 36 | { | ||
| 37 | register unsigned long _ry1 asm("2") = ry1; | ||
| 38 | register unsigned long _ry2 asm("3") = subcode; | ||
| 39 | int rc = 0; | ||
| 40 | |||
| 41 | asm volatile( | ||
| 42 | #ifdef CONFIG_64BIT | ||
| 43 | " sam31\n" | ||
| 44 | " diag %2,2,0x14\n" | ||
| 45 | " sam64\n" | ||
| 46 | #else | ||
| 47 | " diag %2,2,0x14\n" | ||
| 48 | #endif | ||
| 49 | " ipm %0\n" | ||
| 50 | " srl %0,28\n" | ||
| 51 | : "=d" (rc), "+d" (_ry2) | ||
| 52 | : "d" (rx), "d" (_ry1) | ||
| 53 | : "cc"); | ||
| 54 | |||
| 55 | return rc; | ||
| 56 | } | ||
| 57 | EXPORT_SYMBOL(diag14); | ||
| 58 | |||
| 59 | /* | ||
| 60 | * Diagnose 210: Get information about a virtual device | ||
| 61 | */ | ||
| 62 | int diag210(struct diag210 *addr) | ||
| 63 | { | ||
| 64 | /* | ||
| 65 | * diag 210 needs its data below the 2GB border, so we | ||
| 66 | * use a static data area to be sure | ||
| 67 | */ | ||
| 68 | static struct diag210 diag210_tmp; | ||
| 69 | static DEFINE_SPINLOCK(diag210_lock); | ||
| 70 | unsigned long flags; | ||
| 71 | int ccode; | ||
| 72 | |||
| 73 | spin_lock_irqsave(&diag210_lock, flags); | ||
| 74 | diag210_tmp = *addr; | ||
| 75 | |||
| 76 | #ifdef CONFIG_64BIT | ||
| 77 | asm volatile( | ||
| 78 | " lhi %0,-1\n" | ||
| 79 | " sam31\n" | ||
| 80 | " diag %1,0,0x210\n" | ||
| 81 | "0: ipm %0\n" | ||
| 82 | " srl %0,28\n" | ||
| 83 | "1: sam64\n" | ||
| 84 | EX_TABLE(0b, 1b) | ||
| 85 | : "=&d" (ccode) : "a" (&diag210_tmp) : "cc", "memory"); | ||
| 86 | #else | ||
| 87 | asm volatile( | ||
| 88 | " lhi %0,-1\n" | ||
| 89 | " diag %1,0,0x210\n" | ||
| 90 | "0: ipm %0\n" | ||
| 91 | " srl %0,28\n" | ||
| 92 | "1:\n" | ||
| 93 | EX_TABLE(0b, 1b) | ||
| 94 | : "=&d" (ccode) : "a" (&diag210_tmp) : "cc", "memory"); | ||
| 95 | #endif | ||
| 96 | |||
| 97 | *addr = diag210_tmp; | ||
| 98 | spin_unlock_irqrestore(&diag210_lock, flags); | ||
| 99 | |||
| 100 | return ccode; | ||
| 101 | } | ||
| 102 | EXPORT_SYMBOL(diag210); | ||
diff --git a/arch/s390/kernel/dis.c b/arch/s390/kernel/dis.c index d3057318f2bf..50d2235df732 100644 --- a/arch/s390/kernel/dis.c +++ b/arch/s390/kernel/dis.c | |||
| @@ -577,7 +577,7 @@ static struct insn opcode_b2[] = { | |||
| 577 | { "esta", 0x4a, INSTR_RRE_RR }, | 577 | { "esta", 0x4a, INSTR_RRE_RR }, |
| 578 | { "lura", 0x4b, INSTR_RRE_RR }, | 578 | { "lura", 0x4b, INSTR_RRE_RR }, |
| 579 | { "tar", 0x4c, INSTR_RRE_AR }, | 579 | { "tar", 0x4c, INSTR_RRE_AR }, |
| 580 | { "cpya", INSTR_RRE_AA }, | 580 | { "cpya", 0x4d, INSTR_RRE_AA }, |
| 581 | { "sar", 0x4e, INSTR_RRE_AR }, | 581 | { "sar", 0x4e, INSTR_RRE_AR }, |
| 582 | { "ear", 0x4f, INSTR_RRE_RA }, | 582 | { "ear", 0x4f, INSTR_RRE_RA }, |
| 583 | { "csp", 0x50, INSTR_RRE_RR }, | 583 | { "csp", 0x50, INSTR_RRE_RR }, |
diff --git a/arch/s390/kernel/kprobes.c b/arch/s390/kernel/kprobes.c index 358d2bbbc481..e40373d9fbce 100644 --- a/arch/s390/kernel/kprobes.c +++ b/arch/s390/kernel/kprobes.c | |||
| @@ -85,7 +85,7 @@ void __kprobes get_instruction_type(struct arch_specific_insn *ainsn) | |||
| 85 | ainsn->reg = (*ainsn->insn & 0xf0) >> 4; | 85 | ainsn->reg = (*ainsn->insn & 0xf0) >> 4; |
| 86 | 86 | ||
| 87 | /* save the instruction length (pop 5-5) in bytes */ | 87 | /* save the instruction length (pop 5-5) in bytes */ |
| 88 | switch (*(__u8 *) (ainsn->insn) >> 4) { | 88 | switch (*(__u8 *) (ainsn->insn) >> 6) { |
| 89 | case 0: | 89 | case 0: |
| 90 | ainsn->ilen = 2; | 90 | ainsn->ilen = 2; |
| 91 | break; | 91 | break; |
diff --git a/arch/s390/kernel/s390_ksyms.c b/arch/s390/kernel/s390_ksyms.c index 90b5ef529eb7..7234c737f825 100644 --- a/arch/s390/kernel/s390_ksyms.c +++ b/arch/s390/kernel/s390_ksyms.c | |||
| @@ -25,7 +25,6 @@ EXPORT_SYMBOL(_oi_bitmap); | |||
| 25 | EXPORT_SYMBOL(_ni_bitmap); | 25 | EXPORT_SYMBOL(_ni_bitmap); |
| 26 | EXPORT_SYMBOL(_zb_findmap); | 26 | EXPORT_SYMBOL(_zb_findmap); |
| 27 | EXPORT_SYMBOL(_sb_findmap); | 27 | EXPORT_SYMBOL(_sb_findmap); |
| 28 | EXPORT_SYMBOL(diag10); | ||
| 29 | 28 | ||
| 30 | /* | 29 | /* |
| 31 | * semaphore ops | 30 | * semaphore ops |
diff --git a/arch/s390/mm/cmm.c b/arch/s390/mm/cmm.c index c5b2f4f078bc..fabc50adc46a 100644 --- a/arch/s390/mm/cmm.c +++ b/arch/s390/mm/cmm.c | |||
| @@ -20,6 +20,7 @@ | |||
| 20 | 20 | ||
| 21 | #include <asm/pgalloc.h> | 21 | #include <asm/pgalloc.h> |
| 22 | #include <asm/uaccess.h> | 22 | #include <asm/uaccess.h> |
| 23 | #include <asm/diag.h> | ||
| 23 | 24 | ||
| 24 | static char *sender = "VMRMSVM"; | 25 | static char *sender = "VMRMSVM"; |
| 25 | module_param(sender, charp, 0400); | 26 | module_param(sender, charp, 0400); |
diff --git a/arch/s390/mm/init.c b/arch/s390/mm/init.c index 9098531a2671..3a25bbf2eb0a 100644 --- a/arch/s390/mm/init.c +++ b/arch/s390/mm/init.c | |||
| @@ -42,23 +42,6 @@ DEFINE_PER_CPU(struct mmu_gather, mmu_gathers); | |||
| 42 | pgd_t swapper_pg_dir[PTRS_PER_PGD] __attribute__((__aligned__(PAGE_SIZE))); | 42 | pgd_t swapper_pg_dir[PTRS_PER_PGD] __attribute__((__aligned__(PAGE_SIZE))); |
| 43 | char empty_zero_page[PAGE_SIZE] __attribute__((__aligned__(PAGE_SIZE))); | 43 | char empty_zero_page[PAGE_SIZE] __attribute__((__aligned__(PAGE_SIZE))); |
| 44 | 44 | ||
| 45 | void diag10(unsigned long addr) | ||
| 46 | { | ||
| 47 | if (addr >= 0x7ff00000) | ||
| 48 | return; | ||
| 49 | asm volatile( | ||
| 50 | #ifdef CONFIG_64BIT | ||
| 51 | " sam31\n" | ||
| 52 | " diag %0,%0,0x10\n" | ||
| 53 | "0: sam64\n" | ||
| 54 | #else | ||
| 55 | " diag %0,%0,0x10\n" | ||
| 56 | "0:\n" | ||
| 57 | #endif | ||
| 58 | EX_TABLE(0b,0b) | ||
| 59 | : : "a" (addr)); | ||
| 60 | } | ||
| 61 | |||
| 62 | void show_mem(void) | 45 | void show_mem(void) |
| 63 | { | 46 | { |
| 64 | int i, total = 0, reserved = 0; | 47 | int i, total = 0, reserved = 0; |
diff --git a/arch/sparc/mm/init.c b/arch/sparc/mm/init.c index c13e6cd279ac..a1bef07755a9 100644 --- a/arch/sparc/mm/init.c +++ b/arch/sparc/mm/init.c | |||
| @@ -206,7 +206,8 @@ unsigned long __init bootmem_init(unsigned long *pages_avail) | |||
| 206 | #ifdef CONFIG_BLK_DEV_INITRD | 206 | #ifdef CONFIG_BLK_DEV_INITRD |
| 207 | /* Now have to check initial ramdisk, so that bootmap does not overwrite it */ | 207 | /* Now have to check initial ramdisk, so that bootmap does not overwrite it */ |
| 208 | if (sparc_ramdisk_image) { | 208 | if (sparc_ramdisk_image) { |
| 209 | sparc_ramdisk_image -= KERNBASE; | 209 | if (sparc_ramdisk_image >= (unsigned long)&_end - 2 * PAGE_SIZE) |
| 210 | sparc_ramdisk_image -= KERNBASE; | ||
| 210 | initrd_start = sparc_ramdisk_image + phys_base; | 211 | initrd_start = sparc_ramdisk_image + phys_base; |
| 211 | initrd_end = initrd_start + sparc_ramdisk_size; | 212 | initrd_end = initrd_start + sparc_ramdisk_size; |
| 212 | if (initrd_end > end_of_phys_memory) { | 213 | if (initrd_end > end_of_phys_memory) { |
diff --git a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c index aff661fe2ee1..0eabe73c964d 100644 --- a/arch/um/drivers/ubd_kern.c +++ b/arch/um/drivers/ubd_kern.c | |||
| @@ -612,6 +612,8 @@ static int ubd_open_dev(struct ubd *ubd_dev) | |||
| 612 | ubd_dev->fd = fd; | 612 | ubd_dev->fd = fd; |
| 613 | 613 | ||
| 614 | if(ubd_dev->cow.file != NULL){ | 614 | if(ubd_dev->cow.file != NULL){ |
| 615 | blk_queue_max_sectors(ubd_dev->queue, 8 * sizeof(long)); | ||
| 616 | |||
| 615 | err = -ENOMEM; | 617 | err = -ENOMEM; |
| 616 | ubd_dev->cow.bitmap = (void *) vmalloc(ubd_dev->cow.bitmap_len); | 618 | ubd_dev->cow.bitmap = (void *) vmalloc(ubd_dev->cow.bitmap_len); |
| 617 | if(ubd_dev->cow.bitmap == NULL){ | 619 | if(ubd_dev->cow.bitmap == NULL){ |
| @@ -712,8 +714,6 @@ static int ubd_add(int n, char **error_out) | |||
| 712 | ubd_dev->queue->queuedata = ubd_dev; | 714 | ubd_dev->queue->queuedata = ubd_dev; |
| 713 | 715 | ||
| 714 | blk_queue_max_hw_segments(ubd_dev->queue, MAX_SG); | 716 | blk_queue_max_hw_segments(ubd_dev->queue, MAX_SG); |
| 715 | if(ubd_dev->cow.file != NULL) | ||
| 716 | blk_queue_max_sectors(ubd_dev->queue, 8 * sizeof(long)); | ||
| 717 | err = ubd_disk_register(MAJOR_NR, ubd_dev->size, n, &ubd_gendisk[n]); | 717 | err = ubd_disk_register(MAJOR_NR, ubd_dev->size, n, &ubd_gendisk[n]); |
| 718 | if(err){ | 718 | if(err){ |
| 719 | *error_out = "Failed to register device"; | 719 | *error_out = "Failed to register device"; |
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) | |||
| 587 | itdev->want[1][1] = ATA_ANY; | 587 | itdev->want[1][1] = ATA_ANY; |
| 588 | itdev->last_device = -1; | 588 | itdev->last_device = -1; |
| 589 | 589 | ||
| 590 | if (pdev->revision == 0x11) { | 590 | if (pdev->revision == 0x10) { |
| 591 | itdev->timing10 = 1; | 591 | itdev->timing10 = 1; |
| 592 | /* Need to disable ATAPI DMA for this case */ | 592 | /* Need to disable ATAPI DMA for this case */ |
| 593 | if (!itdev->smart) | 593 | if (!itdev->smart) |
diff --git a/drivers/auxdisplay/cfag12864b.c b/drivers/auxdisplay/cfag12864b.c index cb44cb4f6a47..80bb06105387 100644 --- a/drivers/auxdisplay/cfag12864b.c +++ b/drivers/auxdisplay/cfag12864b.c | |||
| @@ -355,7 +355,7 @@ static int __init cfag12864b_init(void) | |||
| 355 | 355 | ||
| 356 | cfag12864b_cache = kmalloc(sizeof(unsigned char) * | 356 | cfag12864b_cache = kmalloc(sizeof(unsigned char) * |
| 357 | CFAG12864B_SIZE, GFP_KERNEL); | 357 | CFAG12864B_SIZE, GFP_KERNEL); |
| 358 | if (cfag12864b_buffer == NULL) { | 358 | if (cfag12864b_cache == NULL) { |
| 359 | printk(KERN_ERR CFAG12864B_NAME ": ERROR: " | 359 | printk(KERN_ERR CFAG12864B_NAME ": ERROR: " |
| 360 | "can't alloc cache buffer (%i bytes)\n", | 360 | "can't alloc cache buffer (%i bytes)\n", |
| 361 | CFAG12864B_SIZE); | 361 | CFAG12864B_SIZE); |
diff --git a/drivers/block/Kconfig b/drivers/block/Kconfig index ef32e977d307..4245b7f80a49 100644 --- a/drivers/block/Kconfig +++ b/drivers/block/Kconfig | |||
| @@ -68,6 +68,7 @@ config AMIGA_Z2RAM | |||
| 68 | config BLK_DEV_XD | 68 | config BLK_DEV_XD |
| 69 | tristate "XT hard disk support" | 69 | tristate "XT hard disk support" |
| 70 | depends on ISA && ISA_DMA_API | 70 | depends on ISA && ISA_DMA_API |
| 71 | select CHECK_SIGNATURE | ||
| 71 | help | 72 | help |
| 72 | Very old 8 bit hard disk controllers used in the IBM XT computer | 73 | Very old 8 bit hard disk controllers used in the IBM XT computer |
| 73 | will be supported if you say Y here. | 74 | will be supported if you say Y here. |
diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c index 96d2f9ee42d6..9b07f7851061 100644 --- a/drivers/char/ipmi/ipmi_si_intf.c +++ b/drivers/char/ipmi/ipmi_si_intf.c | |||
| @@ -2292,7 +2292,7 @@ static int __devinit ipmi_of_probe(struct of_device *dev, | |||
| 2292 | info->irq = irq_of_parse_and_map(dev->node, 0); | 2292 | info->irq = irq_of_parse_and_map(dev->node, 0); |
| 2293 | info->dev = &dev->dev; | 2293 | info->dev = &dev->dev; |
| 2294 | 2294 | ||
| 2295 | dev_dbg(&dev->dev, "addr 0x%lx regsize %ld spacing %ld irq %x\n", | 2295 | dev_dbg(&dev->dev, "addr 0x%lx regsize %d spacing %d irq %x\n", |
| 2296 | info->io.addr_data, info->io.regsize, info->io.regspacing, | 2296 | info->io.addr_data, info->io.regsize, info->io.regspacing, |
| 2297 | info->irq); | 2297 | info->irq); |
| 2298 | 2298 | ||
diff --git a/drivers/char/keyboard.c b/drivers/char/keyboard.c index 2ce0af1bd588..d95f316afb5a 100644 --- a/drivers/char/keyboard.c +++ b/drivers/char/keyboard.c | |||
| @@ -1022,10 +1022,6 @@ static const unsigned short x86_keycodes[256] = | |||
| 1022 | 308,310,313,314,315,317,318,319,320,357,322,323,324,325,276,330, | 1022 | 308,310,313,314,315,317,318,319,320,357,322,323,324,325,276,330, |
| 1023 | 332,340,365,342,343,344,345,346,356,270,341,368,369,370,371,372 }; | 1023 | 332,340,365,342,343,344,345,346,356,270,341,368,369,370,371,372 }; |
| 1024 | 1024 | ||
| 1025 | #ifdef CONFIG_MAC_EMUMOUSEBTN | ||
| 1026 | extern int mac_hid_mouse_emulate_buttons(int, int, int); | ||
| 1027 | #endif /* CONFIG_MAC_EMUMOUSEBTN */ | ||
| 1028 | |||
| 1029 | #ifdef CONFIG_SPARC | 1025 | #ifdef CONFIG_SPARC |
| 1030 | static int sparc_l1_a_state = 0; | 1026 | static int sparc_l1_a_state = 0; |
| 1031 | extern void sun_do_break(void); | 1027 | extern void sun_do_break(void); |
diff --git a/drivers/char/synclink_gt.c b/drivers/char/synclink_gt.c index bbb7f1292665..2f97d2f8f916 100644 --- a/drivers/char/synclink_gt.c +++ b/drivers/char/synclink_gt.c | |||
| @@ -1565,6 +1565,9 @@ static int hdlcdev_open(struct net_device *dev) | |||
| 1565 | int rc; | 1565 | int rc; |
| 1566 | unsigned long flags; | 1566 | unsigned long flags; |
| 1567 | 1567 | ||
| 1568 | if (!try_module_get(THIS_MODULE)) | ||
| 1569 | return -EBUSY; | ||
| 1570 | |||
| 1568 | DBGINFO(("%s hdlcdev_open\n", dev->name)); | 1571 | DBGINFO(("%s hdlcdev_open\n", dev->name)); |
| 1569 | 1572 | ||
| 1570 | /* generic HDLC layer open processing */ | 1573 | /* generic HDLC layer open processing */ |
| @@ -1634,6 +1637,7 @@ static int hdlcdev_close(struct net_device *dev) | |||
| 1634 | info->netcount=0; | 1637 | info->netcount=0; |
| 1635 | spin_unlock_irqrestore(&info->netlock, flags); | 1638 | spin_unlock_irqrestore(&info->netlock, flags); |
| 1636 | 1639 | ||
| 1640 | module_put(THIS_MODULE); | ||
| 1637 | return 0; | 1641 | return 0; |
| 1638 | } | 1642 | } |
| 1639 | 1643 | ||
diff --git a/drivers/char/tpm/tpm.c b/drivers/char/tpm/tpm.c index 9bb542913b86..39564b76d4a3 100644 --- a/drivers/char/tpm/tpm.c +++ b/drivers/char/tpm/tpm.c | |||
| @@ -7,7 +7,7 @@ | |||
| 7 | * Reiner Sailer <sailer@watson.ibm.com> | 7 | * Reiner Sailer <sailer@watson.ibm.com> |
| 8 | * Kylene Hall <kjhall@us.ibm.com> | 8 | * Kylene Hall <kjhall@us.ibm.com> |
| 9 | * | 9 | * |
| 10 | * Maintained by: <tpmdd_devel@lists.sourceforge.net> | 10 | * Maintained by: <tpmdd-devel@lists.sourceforge.net> |
| 11 | * | 11 | * |
| 12 | * Device driver for TCG/TCPA TPM (trusted platform module). | 12 | * Device driver for TCG/TCPA TPM (trusted platform module). |
| 13 | * Specifications at www.trustedcomputinggroup.org | 13 | * Specifications at www.trustedcomputinggroup.org |
diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h index b2e2b002a1bb..d15ccddc92eb 100644 --- a/drivers/char/tpm/tpm.h +++ b/drivers/char/tpm/tpm.h | |||
| @@ -7,7 +7,7 @@ | |||
| 7 | * Reiner Sailer <sailer@watson.ibm.com> | 7 | * Reiner Sailer <sailer@watson.ibm.com> |
| 8 | * Kylene Hall <kjhall@us.ibm.com> | 8 | * Kylene Hall <kjhall@us.ibm.com> |
| 9 | * | 9 | * |
| 10 | * Maintained by: <tpmdd_devel@lists.sourceforge.net> | 10 | * Maintained by: <tpmdd-devel@lists.sourceforge.net> |
| 11 | * | 11 | * |
| 12 | * Device driver for TCG/TCPA TPM (trusted platform module). | 12 | * Device driver for TCG/TCPA TPM (trusted platform module). |
| 13 | * Specifications at www.trustedcomputinggroup.org | 13 | * Specifications at www.trustedcomputinggroup.org |
diff --git a/drivers/char/tpm/tpm_atmel.c b/drivers/char/tpm/tpm_atmel.c index 1ab0896070be..d0e7926eb486 100644 --- a/drivers/char/tpm/tpm_atmel.c +++ b/drivers/char/tpm/tpm_atmel.c | |||
| @@ -7,7 +7,7 @@ | |||
| 7 | * Reiner Sailer <sailer@watson.ibm.com> | 7 | * Reiner Sailer <sailer@watson.ibm.com> |
| 8 | * Kylene Hall <kjhall@us.ibm.com> | 8 | * Kylene Hall <kjhall@us.ibm.com> |
| 9 | * | 9 | * |
| 10 | * Maintained by: <tpmdd_devel@lists.sourceforge.net> | 10 | * Maintained by: <tpmdd-devel@lists.sourceforge.net> |
| 11 | * | 11 | * |
| 12 | * Device driver for TCG/TCPA TPM (trusted platform module). | 12 | * Device driver for TCG/TCPA TPM (trusted platform module). |
| 13 | * Specifications at www.trustedcomputinggroup.org | 13 | * Specifications at www.trustedcomputinggroup.org |
diff --git a/drivers/char/tpm/tpm_atmel.h b/drivers/char/tpm/tpm_atmel.h index 9363bcf0a402..6c831f9466b7 100644 --- a/drivers/char/tpm/tpm_atmel.h +++ b/drivers/char/tpm/tpm_atmel.h | |||
| @@ -4,7 +4,7 @@ | |||
| 4 | * Authors: | 4 | * Authors: |
| 5 | * Kylene Hall <kjhall@us.ibm.com> | 5 | * Kylene Hall <kjhall@us.ibm.com> |
| 6 | * | 6 | * |
| 7 | * Maintained by: <tpmdd_devel@lists.sourceforge.net> | 7 | * Maintained by: <tpmdd-devel@lists.sourceforge.net> |
| 8 | * | 8 | * |
| 9 | * Device driver for TCG/TCPA TPM (trusted platform module). | 9 | * Device driver for TCG/TCPA TPM (trusted platform module). |
| 10 | * Specifications at www.trustedcomputinggroup.org | 10 | * Specifications at www.trustedcomputinggroup.org |
diff --git a/drivers/char/tpm/tpm_bios.c b/drivers/char/tpm/tpm_bios.c index 8677fc6a545e..60a2d2630e36 100644 --- a/drivers/char/tpm/tpm_bios.c +++ b/drivers/char/tpm/tpm_bios.c | |||
| @@ -7,6 +7,8 @@ | |||
| 7 | * Reiner Sailer <sailer@watson.ibm.com> | 7 | * Reiner Sailer <sailer@watson.ibm.com> |
| 8 | * Kylene Hall <kjhall@us.ibm.com> | 8 | * Kylene Hall <kjhall@us.ibm.com> |
| 9 | * | 9 | * |
| 10 | * Maintained by: <tpmdd-devel@lists.sourceforge.net> | ||
| 11 | * | ||
| 10 | * Access to the eventlog extended by the TCG BIOS of PC platform | 12 | * Access to the eventlog extended by the TCG BIOS of PC platform |
| 11 | * | 13 | * |
| 12 | * This program is free software; you can redistribute it and/or | 14 | * This program is free software; you can redistribute it and/or |
diff --git a/drivers/char/tpm/tpm_nsc.c b/drivers/char/tpm/tpm_nsc.c index 608f73071bef..6313326bc41f 100644 --- a/drivers/char/tpm/tpm_nsc.c +++ b/drivers/char/tpm/tpm_nsc.c | |||
| @@ -7,7 +7,7 @@ | |||
| 7 | * Reiner Sailer <sailer@watson.ibm.com> | 7 | * Reiner Sailer <sailer@watson.ibm.com> |
| 8 | * Kylene Hall <kjhall@us.ibm.com> | 8 | * Kylene Hall <kjhall@us.ibm.com> |
| 9 | * | 9 | * |
| 10 | * Maintained by: <tpmdd_devel@lists.sourceforge.net> | 10 | * Maintained by: <tpmdd-devel@lists.sourceforge.net> |
| 11 | * | 11 | * |
| 12 | * Device driver for TCG/TCPA TPM (trusted platform module). | 12 | * Device driver for TCG/TCPA TPM (trusted platform module). |
| 13 | * Specifications at www.trustedcomputinggroup.org | 13 | * Specifications at www.trustedcomputinggroup.org |
diff --git a/drivers/char/tpm/tpm_tis.c b/drivers/char/tpm/tpm_tis.c index 483f3f60013c..23fa18a6654c 100644 --- a/drivers/char/tpm/tpm_tis.c +++ b/drivers/char/tpm/tpm_tis.c | |||
| @@ -5,6 +5,8 @@ | |||
| 5 | * Leendert van Doorn <leendert@watson.ibm.com> | 5 | * Leendert van Doorn <leendert@watson.ibm.com> |
| 6 | * Kylene Hall <kjhall@us.ibm.com> | 6 | * Kylene Hall <kjhall@us.ibm.com> |
| 7 | * | 7 | * |
| 8 | * Maintained by: <tpmdd-devel@lists.sourceforge.net> | ||
| 9 | * | ||
| 8 | * Device driver for TCG/TCPA TPM (trusted platform module). | 10 | * Device driver for TCG/TCPA TPM (trusted platform module). |
| 9 | * Specifications at www.trustedcomputinggroup.org | 11 | * Specifications at www.trustedcomputinggroup.org |
| 10 | * | 12 | * |
diff --git a/drivers/char/watchdog/alim1535_wdt.c b/drivers/char/watchdog/alim1535_wdt.c index e3f6a7d0c83d..c404fc69e7e6 100644 --- a/drivers/char/watchdog/alim1535_wdt.c +++ b/drivers/char/watchdog/alim1535_wdt.c | |||
| @@ -312,6 +312,7 @@ static int ali_notify_sys(struct notifier_block *this, unsigned long code, void | |||
| 312 | */ | 312 | */ |
| 313 | 313 | ||
| 314 | static struct pci_device_id ali_pci_tbl[] = { | 314 | static struct pci_device_id ali_pci_tbl[] = { |
| 315 | { PCI_VENDOR_ID_AL, 0x1533, PCI_ANY_ID, PCI_ANY_ID,}, | ||
| 315 | { PCI_VENDOR_ID_AL, 0x1535, PCI_ANY_ID, PCI_ANY_ID,}, | 316 | { PCI_VENDOR_ID_AL, 0x1535, PCI_ANY_ID, PCI_ANY_ID,}, |
| 316 | { 0, }, | 317 | { 0, }, |
| 317 | }; | 318 | }; |
| @@ -329,9 +330,11 @@ static int __init ali_find_watchdog(void) | |||
| 329 | struct pci_dev *pdev; | 330 | struct pci_dev *pdev; |
| 330 | u32 wdog; | 331 | u32 wdog; |
| 331 | 332 | ||
| 332 | /* Check for a 1535 series bridge */ | 333 | /* Check for a 1533/1535 series bridge */ |
| 333 | pdev = pci_get_device(PCI_VENDOR_ID_AL, 0x1535, NULL); | 334 | pdev = pci_get_device(PCI_VENDOR_ID_AL, 0x1535, NULL); |
| 334 | if(pdev == NULL) | 335 | if (pdev == NULL) |
| 336 | pdev = pci_get_device(PCI_VENDOR_ID_AL, 0x1533, NULL); | ||
| 337 | if (pdev == NULL) | ||
| 335 | return -ENODEV; | 338 | return -ENODEV; |
| 336 | pci_dev_put(pdev); | 339 | pci_dev_put(pdev); |
| 337 | 340 | ||
diff --git a/drivers/char/watchdog/eurotechwdt.c b/drivers/char/watchdog/eurotechwdt.c index b070324e27a6..b14e9d1f164d 100644 --- a/drivers/char/watchdog/eurotechwdt.c +++ b/drivers/char/watchdog/eurotechwdt.c | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * Eurotech CPU-1220/1410 on board WDT driver | 2 | * Eurotech CPU-1220/1410/1420 on board WDT driver |
| 3 | * | 3 | * |
| 4 | * (c) Copyright 2001 Ascensit <support@ascensit.com> | 4 | * (c) Copyright 2001 Ascensit <support@ascensit.com> |
| 5 | * (c) Copyright 2001 Rodolfo Giometti <giometti@ascensit.com> | 5 | * (c) Copyright 2001 Rodolfo Giometti <giometti@ascensit.com> |
| @@ -25,6 +25,9 @@ | |||
| 25 | 25 | ||
| 26 | /* Changelog: | 26 | /* Changelog: |
| 27 | * | 27 | * |
| 28 | * 2001 - Rodolfo Giometti | ||
| 29 | * Initial release | ||
| 30 | * | ||
| 28 | * 2002/04/25 - Rob Radez | 31 | * 2002/04/25 - Rob Radez |
| 29 | * clean up #includes | 32 | * clean up #includes |
| 30 | * clean up locking | 33 | * clean up locking |
| @@ -33,13 +36,15 @@ | |||
| 33 | * add WDIOC_GETSTATUS and WDIOC_SETOPTIONS ioctls | 36 | * add WDIOC_GETSTATUS and WDIOC_SETOPTIONS ioctls |
| 34 | * add expect_close support | 37 | * add expect_close support |
| 35 | * | 38 | * |
| 36 | * 2001 - Rodolfo Giometti | ||
| 37 | * Initial release | ||
| 38 | * | ||
| 39 | * 2002.05.30 - Joel Becker <joel.becker@oracle.com> | 39 | * 2002.05.30 - Joel Becker <joel.becker@oracle.com> |
| 40 | * Added Matt Domsch's nowayout module option. | 40 | * Added Matt Domsch's nowayout module option. |
| 41 | */ | 41 | */ |
| 42 | 42 | ||
| 43 | /* | ||
| 44 | * The eurotech CPU-1220/1410/1420's watchdog is a part | ||
| 45 | * of the on-board SUPER I/O device SMSC FDC 37B782. | ||
| 46 | */ | ||
| 47 | |||
| 43 | #include <linux/interrupt.h> | 48 | #include <linux/interrupt.h> |
| 44 | #include <linux/module.h> | 49 | #include <linux/module.h> |
| 45 | #include <linux/moduleparam.h> | 50 | #include <linux/moduleparam.h> |
diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig index 9b26574f1466..d602b8fa7d46 100644 --- a/drivers/input/misc/Kconfig +++ b/drivers/input/misc/Kconfig | |||
| @@ -68,6 +68,7 @@ config INPUT_WISTRON_BTNS | |||
| 68 | select INPUT_POLLDEV | 68 | select INPUT_POLLDEV |
| 69 | select NEW_LEDS | 69 | select NEW_LEDS |
| 70 | select LEDS_CLASS | 70 | select LEDS_CLASS |
| 71 | select CHECK_SIGNATURE | ||
| 71 | help | 72 | help |
| 72 | Say Y here for support of Winstron laptop button interface, used on | 73 | Say Y here for support of Winstron laptop button interface, used on |
| 73 | laptops of various brands, including Acer and Fujitsu-Siemens. If | 74 | laptops of various brands, including Acer and Fujitsu-Siemens. If |
diff --git a/drivers/isdn/hisax/hfc_usb.c b/drivers/isdn/hisax/hfc_usb.c index b1a26e02df02..60843b3f3b6f 100644 --- a/drivers/isdn/hisax/hfc_usb.c +++ b/drivers/isdn/hisax/hfc_usb.c | |||
| @@ -1,12 +1,12 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * hfc_usb.c | 2 | * hfc_usb.c |
| 3 | * | 3 | * |
| 4 | * $Id: hfc_usb.c,v 2.3.2.13 2006/02/17 17:17:22 mbachem Exp $ | 4 | * $Id: hfc_usb.c,v 2.3.2.20 2007/08/20 14:07:54 mbachem Exp $ |
| 5 | * | 5 | * |
| 6 | * modular HiSax ISDN driver for Colognechip HFC-S USB chip | 6 | * modular HiSax ISDN driver for Colognechip HFC-S USB chip |
| 7 | * | 7 | * |
| 8 | * Authors : Peter Sprenger (sprenger@moving-bytes.de) | 8 | * Authors : Peter Sprenger (sprenger@moving-bytes.de) |
| 9 | * Martin Bachem (info@colognechip.com) | 9 | * Martin Bachem (m.bachem@gmx.de, info@colognechip.com) |
| 10 | * | 10 | * |
| 11 | * based on the first hfc_usb driver of | 11 | * based on the first hfc_usb driver of |
| 12 | * Werner Cornelius (werner@isdn-development.de) | 12 | * Werner Cornelius (werner@isdn-development.de) |
| @@ -37,24 +37,25 @@ | |||
| 37 | #include <linux/kernel_stat.h> | 37 | #include <linux/kernel_stat.h> |
| 38 | #include <linux/usb.h> | 38 | #include <linux/usb.h> |
| 39 | #include <linux/kernel.h> | 39 | #include <linux/kernel.h> |
| 40 | #include <linux/smp_lock.h> | ||
| 41 | #include <linux/sched.h> | ||
| 42 | #include <linux/moduleparam.h> | ||
| 40 | #include "hisax.h" | 43 | #include "hisax.h" |
| 41 | #include "hisax_if.h" | 44 | #include "hisax_if.h" |
| 42 | #include "hfc_usb.h" | 45 | #include "hfc_usb.h" |
| 43 | 46 | ||
| 44 | static const char *hfcusb_revision = | 47 | static const char *hfcusb_revision = |
| 45 | "$Revision: 2.3.2.13 $ $Date: 2006/02/17 17:17:22 $ "; | 48 | "$Revision: 2.3.2.20 $ $Date: 2007/08/20 14:07:54 $ "; |
| 46 | 49 | ||
| 47 | /* Hisax debug support | 50 | /* Hisax debug support |
| 48 | * use "modprobe debug=x" where x is bitfield of USB_DBG & ISDN_DBG | 51 | * debug flags defined in hfc_usb.h as HFCUSB_DBG_[*] |
| 49 | */ | 52 | */ |
| 50 | #ifdef CONFIG_HISAX_DEBUG | ||
| 51 | #include <linux/moduleparam.h> | ||
| 52 | #define __debug_variable hfc_debug | 53 | #define __debug_variable hfc_debug |
| 53 | #include "hisax_debug.h" | 54 | #include "hisax_debug.h" |
| 54 | static u_int debug; | 55 | static u_int debug; |
| 55 | module_param(debug, uint, 0); | 56 | module_param(debug, uint, 0); |
| 56 | static int hfc_debug; | 57 | static int hfc_debug; |
| 57 | #endif | 58 | |
| 58 | 59 | ||
| 59 | /* private vendor specific data */ | 60 | /* private vendor specific data */ |
| 60 | typedef struct { | 61 | typedef struct { |
| @@ -63,9 +64,7 @@ typedef struct { | |||
| 63 | char *vend_name; // device name | 64 | char *vend_name; // device name |
| 64 | } hfcsusb_vdata; | 65 | } hfcsusb_vdata; |
| 65 | 66 | ||
| 66 | /****************************************/ | 67 | /* VID/PID device list */ |
| 67 | /* data defining the devices to be used */ | ||
| 68 | /****************************************/ | ||
| 69 | static struct usb_device_id hfcusb_idtab[] = { | 68 | static struct usb_device_id hfcusb_idtab[] = { |
| 70 | { | 69 | { |
| 71 | USB_DEVICE(0x0959, 0x2bd0), | 70 | USB_DEVICE(0x0959, 0x2bd0), |
| @@ -90,49 +89,47 @@ static struct usb_device_id hfcusb_idtab[] = { | |||
| 90 | .driver_info = (unsigned long) &((hfcsusb_vdata) | 89 | .driver_info = (unsigned long) &((hfcsusb_vdata) |
| 91 | {LED_SCHEME1, {4, 0, 2, 1}, | 90 | {LED_SCHEME1, {4, 0, 2, 1}, |
| 92 | "Stollmann USB TA"}), | 91 | "Stollmann USB TA"}), |
| 93 | }, | 92 | }, |
| 94 | { | 93 | { |
| 95 | USB_DEVICE(0x0742, 0x2009), | 94 | USB_DEVICE(0x0742, 0x2009), |
| 96 | .driver_info = (unsigned long) &((hfcsusb_vdata) | 95 | .driver_info = (unsigned long) &((hfcsusb_vdata) |
| 97 | {LED_SCHEME1, {4, 0, 2, 1}, | 96 | {LED_SCHEME1, {4, 0, 2, 1}, |
| 98 | "Aceex USB ISDN TA"}), | 97 | "Aceex USB ISDN TA"}), |
| 99 | }, | 98 | }, |
| 100 | { | 99 | { |
| 101 | USB_DEVICE(0x0742, 0x200A), | 100 | USB_DEVICE(0x0742, 0x200A), |
| 102 | .driver_info = (unsigned long) &((hfcsusb_vdata) | 101 | .driver_info = (unsigned long) &((hfcsusb_vdata) |
| 103 | {LED_SCHEME1, {4, 0, 2, 1}, | 102 | {LED_SCHEME1, {4, 0, 2, 1}, |
| 104 | "OEM USB ISDN TA"}), | 103 | "OEM USB ISDN TA"}), |
| 105 | }, | 104 | }, |
| 106 | { | 105 | { |
| 107 | USB_DEVICE(0x08e3, 0x0301), | 106 | USB_DEVICE(0x08e3, 0x0301), |
| 108 | .driver_info = (unsigned long) &((hfcsusb_vdata) | 107 | .driver_info = (unsigned long) &((hfcsusb_vdata) |
| 109 | {LED_SCHEME1, {2, 0, 1, 4}, | 108 | {LED_SCHEME1, {2, 0, 1, 4}, |
| 110 | "Olitec USB RNIS"}), | 109 | "Olitec USB RNIS"}), |
| 111 | }, | 110 | }, |
| 112 | { | 111 | { |
| 113 | USB_DEVICE(0x07fa, 0x0846), | 112 | USB_DEVICE(0x07fa, 0x0846), |
| 114 | .driver_info = (unsigned long) &((hfcsusb_vdata) | 113 | .driver_info = (unsigned long) &((hfcsusb_vdata) |
| 115 | {LED_SCHEME1, {0x80, -64, -32, -16}, | 114 | {LED_SCHEME1, {0x80, -64, -32, -16}, |
| 116 | "Bewan Modem RNIS USB"}), | 115 | "Bewan Modem RNIS USB"}), |
| 117 | }, | 116 | }, |
| 118 | { | 117 | { |
| 119 | USB_DEVICE(0x07fa, 0x0847), | 118 | USB_DEVICE(0x07fa, 0x0847), |
| 120 | .driver_info = (unsigned long) &((hfcsusb_vdata) | 119 | .driver_info = (unsigned long) &((hfcsusb_vdata) |
| 121 | {LED_SCHEME1, {0x80, -64, -32, -16}, | 120 | {LED_SCHEME1, {0x80, -64, -32, -16}, |
| 122 | "Djinn Numeris USB"}), | 121 | "Djinn Numeris USB"}), |
| 123 | }, | 122 | }, |
| 124 | { | 123 | { |
| 125 | USB_DEVICE(0x07b0, 0x0006), | 124 | USB_DEVICE(0x07b0, 0x0006), |
| 126 | .driver_info = (unsigned long) &((hfcsusb_vdata) | 125 | .driver_info = (unsigned long) &((hfcsusb_vdata) |
| 127 | {LED_SCHEME1, {0x80, -64, -32, -16}, | 126 | {LED_SCHEME1, {0x80, -64, -32, -16}, |
| 128 | "Twister ISDN TA"}), | 127 | "Twister ISDN TA"}), |
| 129 | }, | 128 | }, |
| 130 | { } | 129 | { } |
| 131 | }; | 130 | }; |
| 132 | 131 | ||
| 133 | /***************************************************************/ | ||
| 134 | /* structure defining input+output fifos (interrupt/bulk mode) */ | 132 | /* structure defining input+output fifos (interrupt/bulk mode) */ |
| 135 | /***************************************************************/ | ||
| 136 | struct usb_fifo; /* forward definition */ | 133 | struct usb_fifo; /* forward definition */ |
| 137 | typedef struct iso_urb_struct { | 134 | typedef struct iso_urb_struct { |
| 138 | struct urb *purb; | 135 | struct urb *purb; |
| @@ -140,8 +137,8 @@ typedef struct iso_urb_struct { | |||
| 140 | struct usb_fifo *owner_fifo; /* pointer to owner fifo */ | 137 | struct usb_fifo *owner_fifo; /* pointer to owner fifo */ |
| 141 | } iso_urb_struct; | 138 | } iso_urb_struct; |
| 142 | 139 | ||
| 143 | |||
| 144 | struct hfcusb_data; /* forward definition */ | 140 | struct hfcusb_data; /* forward definition */ |
| 141 | |||
| 145 | typedef struct usb_fifo { | 142 | typedef struct usb_fifo { |
| 146 | int fifonum; /* fifo index attached to this structure */ | 143 | int fifonum; /* fifo index attached to this structure */ |
| 147 | int active; /* fifo is currently active */ | 144 | int active; /* fifo is currently active */ |
| @@ -160,15 +157,12 @@ typedef struct usb_fifo { | |||
| 160 | struct hisax_if *hif; /* hisax interface */ | 157 | struct hisax_if *hif; /* hisax interface */ |
| 161 | int delete_flg; /* only delete skbuff once */ | 158 | int delete_flg; /* only delete skbuff once */ |
| 162 | int last_urblen; /* remember length of last packet */ | 159 | int last_urblen; /* remember length of last packet */ |
| 163 | |||
| 164 | } usb_fifo; | 160 | } usb_fifo; |
| 165 | 161 | ||
| 166 | /*********************************************/ | ||
| 167 | /* structure holding all data for one device */ | 162 | /* structure holding all data for one device */ |
| 168 | /*********************************************/ | ||
| 169 | typedef struct hfcusb_data { | 163 | typedef struct hfcusb_data { |
| 170 | /* HiSax Interface for loadable Layer1 drivers */ | 164 | /* HiSax Interface for loadable Layer1 drivers */ |
| 171 | struct hisax_d_if d_if; /* see hisax_if.h */ | 165 | struct hisax_d_if d_if; /* see hisax_if.h */ |
| 172 | struct hisax_b_if b_if[2]; /* see hisax_if.h */ | 166 | struct hisax_b_if b_if[2]; /* see hisax_if.h */ |
| 173 | int protocol; | 167 | int protocol; |
| 174 | 168 | ||
| @@ -176,12 +170,13 @@ typedef struct hfcusb_data { | |||
| 176 | int if_used; /* used interface number */ | 170 | int if_used; /* used interface number */ |
| 177 | int alt_used; /* used alternate config */ | 171 | int alt_used; /* used alternate config */ |
| 178 | int ctrl_paksize; /* control pipe packet size */ | 172 | int ctrl_paksize; /* control pipe packet size */ |
| 179 | int ctrl_in_pipe, ctrl_out_pipe; /* handles for control pipe */ | 173 | int ctrl_in_pipe, /* handles for control pipe */ |
| 174 | ctrl_out_pipe; | ||
| 180 | int cfg_used; /* configuration index used */ | 175 | int cfg_used; /* configuration index used */ |
| 181 | int vend_idx; /* vendor found */ | 176 | int vend_idx; /* vendor found */ |
| 182 | int b_mode[2]; /* B-channel mode */ | 177 | int b_mode[2]; /* B-channel mode */ |
| 183 | int l1_activated; /* layer 1 activated */ | 178 | int l1_activated; /* layer 1 activated */ |
| 184 | int disc_flag; /* 'true' if device was disonnected to avoid some USB actions */ | 179 | int disc_flag; /* TRUE if device was disonnected to avoid some USB actions */ |
| 185 | int packet_size, iso_packet_size; | 180 | int packet_size, iso_packet_size; |
| 186 | 181 | ||
| 187 | /* control pipe background handling */ | 182 | /* control pipe background handling */ |
| @@ -208,7 +203,6 @@ typedef struct hfcusb_data { | |||
| 208 | static void collect_rx_frame(usb_fifo * fifo, __u8 * data, int len, | 203 | static void collect_rx_frame(usb_fifo * fifo, __u8 * data, int len, |
| 209 | int finish); | 204 | int finish); |
| 210 | 205 | ||
| 211 | |||
| 212 | static inline const char * | 206 | static inline const char * |
| 213 | symbolic(struct hfcusb_symbolic_list list[], const int num) | 207 | symbolic(struct hfcusb_symbolic_list list[], const int num) |
| 214 | { | 208 | { |
| @@ -219,10 +213,6 @@ symbolic(struct hfcusb_symbolic_list list[], const int num) | |||
| 219 | return "<unknown ERROR>"; | 213 | return "<unknown ERROR>"; |
| 220 | } | 214 | } |
| 221 | 215 | ||
| 222 | |||
| 223 | /******************************************************/ | ||
| 224 | /* start next background transfer for control channel */ | ||
| 225 | /******************************************************/ | ||
| 226 | static void | 216 | static void |
| 227 | ctrl_start_transfer(hfcusb_data * hfc) | 217 | ctrl_start_transfer(hfcusb_data * hfc) |
| 228 | { | 218 | { |
| @@ -240,10 +230,6 @@ ctrl_start_transfer(hfcusb_data * hfc) | |||
| 240 | } | 230 | } |
| 241 | } /* ctrl_start_transfer */ | 231 | } /* ctrl_start_transfer */ |
| 242 | 232 | ||
| 243 | /************************************/ | ||
| 244 | /* queue a control transfer request */ | ||
| 245 | /* return 0 on success. */ | ||
| 246 | /************************************/ | ||
| 247 | static int | 233 | static int |
| 248 | queue_control_request(hfcusb_data * hfc, __u8 reg, __u8 val, int action) | 234 | queue_control_request(hfcusb_data * hfc, __u8 reg, __u8 val, int action) |
| 249 | { | 235 | { |
| @@ -260,19 +246,8 @@ queue_control_request(hfcusb_data * hfc, __u8 reg, __u8 val, int action) | |||
| 260 | if (++hfc->ctrl_cnt == 1) | 246 | if (++hfc->ctrl_cnt == 1) |
| 261 | ctrl_start_transfer(hfc); | 247 | ctrl_start_transfer(hfc); |
| 262 | return (0); | 248 | return (0); |
| 263 | } /* queue_control_request */ | ||
| 264 | |||
| 265 | static int | ||
| 266 | control_action_handler(hfcusb_data * hfc, int reg, int val, int action) | ||
| 267 | { | ||
| 268 | if (!action) | ||
| 269 | return (1); /* no action defined */ | ||
| 270 | return (0); | ||
| 271 | } | 249 | } |
| 272 | 250 | ||
| 273 | /***************************************************************/ | ||
| 274 | /* control completion routine handling background control cmds */ | ||
| 275 | /***************************************************************/ | ||
| 276 | static void | 251 | static void |
| 277 | ctrl_complete(struct urb *urb) | 252 | ctrl_complete(struct urb *urb) |
| 278 | { | 253 | { |
| @@ -282,9 +257,6 @@ ctrl_complete(struct urb *urb) | |||
| 282 | urb->dev = hfc->dev; | 257 | urb->dev = hfc->dev; |
| 283 | if (hfc->ctrl_cnt) { | 258 | if (hfc->ctrl_cnt) { |
| 284 | buf = &hfc->ctrl_buff[hfc->ctrl_out_idx]; | 259 | buf = &hfc->ctrl_buff[hfc->ctrl_out_idx]; |
| 285 | control_action_handler(hfc, buf->hfc_reg, buf->reg_val, | ||
| 286 | buf->action); | ||
| 287 | |||
| 288 | hfc->ctrl_cnt--; /* decrement actual count */ | 260 | hfc->ctrl_cnt--; /* decrement actual count */ |
| 289 | if (++hfc->ctrl_out_idx >= HFC_CTRL_BUFSIZE) | 261 | if (++hfc->ctrl_out_idx >= HFC_CTRL_BUFSIZE) |
| 290 | hfc->ctrl_out_idx = 0; /* pointer wrap */ | 262 | hfc->ctrl_out_idx = 0; /* pointer wrap */ |
| @@ -293,9 +265,7 @@ ctrl_complete(struct urb *urb) | |||
| 293 | } | 265 | } |
| 294 | } /* ctrl_complete */ | 266 | } /* ctrl_complete */ |
| 295 | 267 | ||
| 296 | /***************************************************/ | ||
| 297 | /* write led data to auxport & invert if necessary */ | 268 | /* write led data to auxport & invert if necessary */ |
| 298 | /***************************************************/ | ||
| 299 | static void | 269 | static void |
| 300 | write_led(hfcusb_data * hfc, __u8 led_state) | 270 | write_led(hfcusb_data * hfc, __u8 led_state) |
| 301 | { | 271 | { |
| @@ -305,9 +275,6 @@ write_led(hfcusb_data * hfc, __u8 led_state) | |||
| 305 | } | 275 | } |
| 306 | } | 276 | } |
| 307 | 277 | ||
| 308 | /**************************/ | ||
| 309 | /* handle LED bits */ | ||
| 310 | /**************************/ | ||
| 311 | static void | 278 | static void |
| 312 | set_led_bit(hfcusb_data * hfc, signed short led_bits, int unset) | 279 | set_led_bit(hfcusb_data * hfc, signed short led_bits, int unset) |
| 313 | { | 280 | { |
| @@ -324,9 +291,7 @@ set_led_bit(hfcusb_data * hfc, signed short led_bits, int unset) | |||
| 324 | } | 291 | } |
| 325 | } | 292 | } |
| 326 | 293 | ||
| 327 | /**************************/ | 294 | /* handle LED requests */ |
| 328 | /* handle LED requests */ | ||
| 329 | /**************************/ | ||
| 330 | static void | 295 | static void |
| 331 | handle_led(hfcusb_data * hfc, int event) | 296 | handle_led(hfcusb_data * hfc, int event) |
| 332 | { | 297 | { |
| @@ -339,85 +304,73 @@ handle_led(hfcusb_data * hfc, int event) | |||
| 339 | 304 | ||
| 340 | switch (event) { | 305 | switch (event) { |
| 341 | case LED_POWER_ON: | 306 | case LED_POWER_ON: |
| 342 | set_led_bit(hfc, driver_info->led_bits[0], | 307 | set_led_bit(hfc, driver_info->led_bits[0], 0); |
| 343 | 0); | 308 | set_led_bit(hfc, driver_info->led_bits[1], 1); |
| 344 | set_led_bit(hfc, driver_info->led_bits[1], | 309 | set_led_bit(hfc, driver_info->led_bits[2], 1); |
| 345 | 1); | 310 | set_led_bit(hfc, driver_info->led_bits[3], 1); |
| 346 | set_led_bit(hfc, driver_info->led_bits[2], | ||
| 347 | 1); | ||
| 348 | set_led_bit(hfc, driver_info->led_bits[3], | ||
| 349 | 1); | ||
| 350 | break; | 311 | break; |
| 351 | case LED_POWER_OFF: /* no Power off handling */ | 312 | case LED_POWER_OFF: |
| 313 | set_led_bit(hfc, driver_info->led_bits[0], 1); | ||
| 314 | set_led_bit(hfc, driver_info->led_bits[1], 1); | ||
| 315 | set_led_bit(hfc, driver_info->led_bits[2], 1); | ||
| 316 | set_led_bit(hfc, driver_info->led_bits[3], 1); | ||
| 352 | break; | 317 | break; |
| 353 | case LED_S0_ON: | 318 | case LED_S0_ON: |
| 354 | set_led_bit(hfc, driver_info->led_bits[1], | 319 | set_led_bit(hfc, driver_info->led_bits[1], 0); |
| 355 | 0); | ||
| 356 | break; | 320 | break; |
| 357 | case LED_S0_OFF: | 321 | case LED_S0_OFF: |
| 358 | set_led_bit(hfc, driver_info->led_bits[1], | 322 | set_led_bit(hfc, driver_info->led_bits[1], 1); |
| 359 | 1); | ||
| 360 | break; | 323 | break; |
| 361 | case LED_B1_ON: | 324 | case LED_B1_ON: |
| 362 | set_led_bit(hfc, driver_info->led_bits[2], | 325 | set_led_bit(hfc, driver_info->led_bits[2], 0); |
| 363 | 0); | ||
| 364 | break; | 326 | break; |
| 365 | case LED_B1_OFF: | 327 | case LED_B1_OFF: |
| 366 | set_led_bit(hfc, driver_info->led_bits[2], | 328 | set_led_bit(hfc, driver_info->led_bits[2], 1); |
| 367 | 1); | ||
| 368 | break; | 329 | break; |
| 369 | case LED_B2_ON: | 330 | case LED_B2_ON: |
| 370 | set_led_bit(hfc, driver_info->led_bits[3], | 331 | set_led_bit(hfc, driver_info->led_bits[3], 0); |
| 371 | 0); | ||
| 372 | break; | 332 | break; |
| 373 | case LED_B2_OFF: | 333 | case LED_B2_OFF: |
| 374 | set_led_bit(hfc, driver_info->led_bits[3], | 334 | set_led_bit(hfc, driver_info->led_bits[3], 1); |
| 375 | 1); | ||
| 376 | break; | 335 | break; |
| 377 | } | 336 | } |
| 378 | write_led(hfc, hfc->led_state); | 337 | write_led(hfc, hfc->led_state); |
| 379 | } | 338 | } |
| 380 | 339 | ||
| 381 | /********************************/ | 340 | /* ISDN l1 timer T3 expires */ |
| 382 | /* called when timer t3 expires */ | ||
| 383 | /********************************/ | ||
| 384 | static void | 341 | static void |
| 385 | l1_timer_expire_t3(hfcusb_data * hfc) | 342 | l1_timer_expire_t3(hfcusb_data * hfc) |
| 386 | { | 343 | { |
| 387 | hfc->d_if.ifc.l1l2(&hfc->d_if.ifc, PH_DEACTIVATE | INDICATION, | 344 | hfc->d_if.ifc.l1l2(&hfc->d_if.ifc, PH_DEACTIVATE | INDICATION, |
| 388 | NULL); | 345 | NULL); |
| 389 | #ifdef CONFIG_HISAX_DEBUG | 346 | |
| 390 | DBG(ISDN_DBG, | 347 | DBG(HFCUSB_DBG_STATES, |
| 391 | "HFC-S USB: PH_DEACTIVATE | INDICATION sent (T3 expire)"); | 348 | "HFC-S USB: PH_DEACTIVATE | INDICATION sent (T3 expire)"); |
| 392 | #endif | 349 | |
| 393 | hfc->l1_activated = false; | 350 | hfc->l1_activated = 0; |
| 394 | handle_led(hfc, LED_S0_OFF); | 351 | handle_led(hfc, LED_S0_OFF); |
| 395 | /* deactivate : */ | 352 | /* deactivate : */ |
| 396 | queue_control_request(hfc, HFCUSB_STATES, 0x10, 1); | 353 | queue_control_request(hfc, HFCUSB_STATES, 0x10, 1); |
| 397 | queue_control_request(hfc, HFCUSB_STATES, 3, 1); | 354 | queue_control_request(hfc, HFCUSB_STATES, 3, 1); |
| 398 | } | 355 | } |
| 399 | 356 | ||
| 400 | /********************************/ | 357 | /* ISDN l1 timer T4 expires */ |
| 401 | /* called when timer t4 expires */ | ||
| 402 | /********************************/ | ||
| 403 | static void | 358 | static void |
| 404 | l1_timer_expire_t4(hfcusb_data * hfc) | 359 | l1_timer_expire_t4(hfcusb_data * hfc) |
| 405 | { | 360 | { |
| 406 | hfc->d_if.ifc.l1l2(&hfc->d_if.ifc, PH_DEACTIVATE | INDICATION, | 361 | hfc->d_if.ifc.l1l2(&hfc->d_if.ifc, PH_DEACTIVATE | INDICATION, |
| 407 | NULL); | 362 | NULL); |
| 408 | #ifdef CONFIG_HISAX_DEBUG | 363 | |
| 409 | DBG(ISDN_DBG, | 364 | DBG(HFCUSB_DBG_STATES, |
| 410 | "HFC-S USB: PH_DEACTIVATE | INDICATION sent (T4 expire)"); | 365 | "HFC-S USB: PH_DEACTIVATE | INDICATION sent (T4 expire)"); |
| 411 | #endif | 366 | |
| 412 | hfc->l1_activated = false; | 367 | hfc->l1_activated = 0; |
| 413 | handle_led(hfc, LED_S0_OFF); | 368 | handle_led(hfc, LED_S0_OFF); |
| 414 | } | 369 | } |
| 415 | 370 | ||
| 416 | /*****************************/ | 371 | /* S0 state changed */ |
| 417 | /* handle S0 state changes */ | ||
| 418 | /*****************************/ | ||
| 419 | static void | 372 | static void |
| 420 | state_handler(hfcusb_data * hfc, __u8 state) | 373 | s0_state_handler(hfcusb_data * hfc, __u8 state) |
| 421 | { | 374 | { |
| 422 | __u8 old_state; | 375 | __u8 old_state; |
| 423 | 376 | ||
| @@ -425,38 +378,29 @@ state_handler(hfcusb_data * hfc, __u8 state) | |||
| 425 | if (state == old_state || state < 1 || state > 8) | 378 | if (state == old_state || state < 1 || state > 8) |
| 426 | return; | 379 | return; |
| 427 | 380 | ||
| 428 | #ifdef CONFIG_HISAX_DEBUG | 381 | DBG(HFCUSB_DBG_STATES, "HFC-S USB: S0 statechange(%d -> %d)", |
| 429 | DBG(ISDN_DBG, "HFC-S USB: new S0 state:%d old_state:%d", state, | 382 | old_state, state); |
| 430 | old_state); | 383 | |
| 431 | #endif | ||
| 432 | if (state < 4 || state == 7 || state == 8) { | 384 | if (state < 4 || state == 7 || state == 8) { |
| 433 | if (timer_pending(&hfc->t3_timer)) | 385 | if (timer_pending(&hfc->t3_timer)) |
| 434 | del_timer(&hfc->t3_timer); | 386 | del_timer(&hfc->t3_timer); |
| 435 | #ifdef CONFIG_HISAX_DEBUG | 387 | DBG(HFCUSB_DBG_STATES, "HFC-S USB: T3 deactivated"); |
| 436 | DBG(ISDN_DBG, "HFC-S USB: T3 deactivated"); | ||
| 437 | #endif | ||
| 438 | } | 388 | } |
| 439 | if (state >= 7) { | 389 | if (state >= 7) { |
| 440 | if (timer_pending(&hfc->t4_timer)) | 390 | if (timer_pending(&hfc->t4_timer)) |
| 441 | del_timer(&hfc->t4_timer); | 391 | del_timer(&hfc->t4_timer); |
| 442 | #ifdef CONFIG_HISAX_DEBUG | 392 | DBG(HFCUSB_DBG_STATES, "HFC-S USB: T4 deactivated"); |
| 443 | DBG(ISDN_DBG, "HFC-S USB: T4 deactivated"); | ||
| 444 | #endif | ||
| 445 | } | 393 | } |
| 446 | 394 | ||
| 447 | if (state == 7 && !hfc->l1_activated) { | 395 | if (state == 7 && !hfc->l1_activated) { |
| 448 | hfc->d_if.ifc.l1l2(&hfc->d_if.ifc, | 396 | hfc->d_if.ifc.l1l2(&hfc->d_if.ifc, |
| 449 | PH_ACTIVATE | INDICATION, NULL); | 397 | PH_ACTIVATE | INDICATION, NULL); |
| 450 | #ifdef CONFIG_HISAX_DEBUG | 398 | DBG(HFCUSB_DBG_STATES, "HFC-S USB: PH_ACTIVATE | INDICATION sent"); |
| 451 | DBG(ISDN_DBG, "HFC-S USB: PH_ACTIVATE | INDICATION sent"); | 399 | hfc->l1_activated = 1; |
| 452 | #endif | ||
| 453 | hfc->l1_activated = true; | ||
| 454 | handle_led(hfc, LED_S0_ON); | 400 | handle_led(hfc, LED_S0_ON); |
| 455 | } else if (state <= 3 /* && activated */ ) { | 401 | } else if (state <= 3 /* && activated */ ) { |
| 456 | if (old_state == 7 || old_state == 8) { | 402 | if (old_state == 7 || old_state == 8) { |
| 457 | #ifdef CONFIG_HISAX_DEBUG | 403 | DBG(HFCUSB_DBG_STATES, "HFC-S USB: T4 activated"); |
| 458 | DBG(ISDN_DBG, "HFC-S USB: T4 activated"); | ||
| 459 | #endif | ||
| 460 | if (!timer_pending(&hfc->t4_timer)) { | 404 | if (!timer_pending(&hfc->t4_timer)) { |
| 461 | hfc->t4_timer.expires = | 405 | hfc->t4_timer.expires = |
| 462 | jiffies + (HFC_TIMER_T4 * HZ) / 1000; | 406 | jiffies + (HFC_TIMER_T4 * HZ) / 1000; |
| @@ -466,18 +410,15 @@ state_handler(hfcusb_data * hfc, __u8 state) | |||
| 466 | hfc->d_if.ifc.l1l2(&hfc->d_if.ifc, | 410 | hfc->d_if.ifc.l1l2(&hfc->d_if.ifc, |
| 467 | PH_DEACTIVATE | INDICATION, | 411 | PH_DEACTIVATE | INDICATION, |
| 468 | NULL); | 412 | NULL); |
| 469 | #ifdef CONFIG_HISAX_DEBUG | 413 | DBG(HFCUSB_DBG_STATES, |
| 470 | DBG(ISDN_DBG, | ||
| 471 | "HFC-S USB: PH_DEACTIVATE | INDICATION sent"); | 414 | "HFC-S USB: PH_DEACTIVATE | INDICATION sent"); |
| 472 | #endif | 415 | hfc->l1_activated = 0; |
| 473 | hfc->l1_activated = false; | ||
| 474 | handle_led(hfc, LED_S0_OFF); | 416 | handle_led(hfc, LED_S0_OFF); |
| 475 | } | 417 | } |
| 476 | } | 418 | } |
| 477 | hfc->l1_state = state; | 419 | hfc->l1_state = state; |
| 478 | } | 420 | } |
| 479 | 421 | ||
| 480 | /* prepare iso urb */ | ||
| 481 | static void | 422 | static void |
| 482 | fill_isoc_urb(struct urb *urb, struct usb_device *dev, unsigned int pipe, | 423 | fill_isoc_urb(struct urb *urb, struct usb_device *dev, unsigned int pipe, |
| 483 | void *buf, int num_packets, int packet_size, int interval, | 424 | void *buf, int num_packets, int packet_size, int interval, |
| @@ -503,15 +444,16 @@ fill_isoc_urb(struct urb *urb, struct usb_device *dev, unsigned int pipe, | |||
| 503 | } | 444 | } |
| 504 | 445 | ||
| 505 | /* allocs urbs and start isoc transfer with two pending urbs to avoid | 446 | /* allocs urbs and start isoc transfer with two pending urbs to avoid |
| 506 | gaps in the transfer chain */ | 447 | * gaps in the transfer chain |
| 448 | */ | ||
| 507 | static int | 449 | static int |
| 508 | start_isoc_chain(usb_fifo * fifo, int num_packets_per_urb, | 450 | start_isoc_chain(usb_fifo * fifo, int num_packets_per_urb, |
| 509 | usb_complete_t complete, int packet_size) | 451 | usb_complete_t complete, int packet_size) |
| 510 | { | 452 | { |
| 511 | int i, k, errcode; | 453 | int i, k, errcode; |
| 512 | 454 | ||
| 513 | printk(KERN_INFO "HFC-S USB: starting ISO-chain for Fifo %i\n", | 455 | DBG(HFCUSB_DBG_INIT, "HFC-S USB: starting ISO-URBs for fifo:%d\n", |
| 514 | fifo->fifonum); | 456 | fifo->fifonum); |
| 515 | 457 | ||
| 516 | /* allocate Memory for Iso out Urbs */ | 458 | /* allocate Memory for Iso out Urbs */ |
| 517 | for (i = 0; i < 2; i++) { | 459 | for (i = 0; i < 2; i++) { |
| @@ -556,10 +498,9 @@ start_isoc_chain(usb_fifo * fifo, int num_packets_per_urb, | |||
| 556 | 498 | ||
| 557 | errcode = usb_submit_urb(fifo->iso[i].purb, GFP_KERNEL); | 499 | errcode = usb_submit_urb(fifo->iso[i].purb, GFP_KERNEL); |
| 558 | fifo->active = (errcode >= 0) ? 1 : 0; | 500 | fifo->active = (errcode >= 0) ? 1 : 0; |
| 559 | if (errcode < 0) { | 501 | if (errcode < 0) |
| 560 | printk(KERN_INFO "HFC-S USB: %s URB nr:%d\n", | 502 | printk(KERN_INFO "HFC-S USB: usb_submit_urb URB nr:%d, error(%i): '%s'\n", |
| 561 | symbolic(urb_errlist, errcode), i); | 503 | i, errcode, symbolic(urb_errlist, errcode)); |
| 562 | }; | ||
| 563 | } | 504 | } |
| 564 | return (fifo->active); | 505 | return (fifo->active); |
| 565 | } | 506 | } |
| @@ -572,16 +513,15 @@ stop_isoc_chain(usb_fifo * fifo) | |||
| 572 | 513 | ||
| 573 | for (i = 0; i < 2; i++) { | 514 | for (i = 0; i < 2; i++) { |
| 574 | if (fifo->iso[i].purb) { | 515 | if (fifo->iso[i].purb) { |
| 575 | #ifdef CONFIG_HISAX_DEBUG | 516 | DBG(HFCUSB_DBG_INIT, |
| 576 | DBG(USB_DBG, | ||
| 577 | "HFC-S USB: Stopping iso chain for fifo %i.%i", | 517 | "HFC-S USB: Stopping iso chain for fifo %i.%i", |
| 578 | fifo->fifonum, i); | 518 | fifo->fifonum, i); |
| 579 | #endif | ||
| 580 | usb_kill_urb(fifo->iso[i].purb); | 519 | usb_kill_urb(fifo->iso[i].purb); |
| 581 | usb_free_urb(fifo->iso[i].purb); | 520 | usb_free_urb(fifo->iso[i].purb); |
| 582 | fifo->iso[i].purb = NULL; | 521 | fifo->iso[i].purb = NULL; |
| 583 | } | 522 | } |
| 584 | } | 523 | } |
| 524 | |||
| 585 | usb_kill_urb(fifo->urb); | 525 | usb_kill_urb(fifo->urb); |
| 586 | usb_free_urb(fifo->urb); | 526 | usb_free_urb(fifo->urb); |
| 587 | fifo->urb = NULL; | 527 | fifo->urb = NULL; |
| @@ -594,9 +534,6 @@ static int iso_packets[8] = | |||
| 594 | ISOC_PACKETS_D, ISOC_PACKETS_D, ISOC_PACKETS_D, ISOC_PACKETS_D | 534 | ISOC_PACKETS_D, ISOC_PACKETS_D, ISOC_PACKETS_D, ISOC_PACKETS_D |
| 595 | }; | 535 | }; |
| 596 | 536 | ||
| 597 | /*****************************************************/ | ||
| 598 | /* transmit completion routine for all ISO tx fifos */ | ||
| 599 | /*****************************************************/ | ||
| 600 | static void | 537 | static void |
| 601 | tx_iso_complete(struct urb *urb) | 538 | tx_iso_complete(struct urb *urb) |
| 602 | { | 539 | { |
| @@ -607,20 +544,38 @@ tx_iso_complete(struct urb *urb) | |||
| 607 | errcode; | 544 | errcode; |
| 608 | int frame_complete, transp_mode, fifon, status; | 545 | int frame_complete, transp_mode, fifon, status; |
| 609 | __u8 threshbit; | 546 | __u8 threshbit; |
| 610 | __u8 threshtable[8] = { 1, 2, 4, 8, 0x10, 0x20, 0x40, 0x80 }; | ||
| 611 | 547 | ||
| 612 | fifon = fifo->fifonum; | 548 | fifon = fifo->fifonum; |
| 613 | status = urb->status; | 549 | status = urb->status; |
| 614 | 550 | ||
| 615 | tx_offset = 0; | 551 | tx_offset = 0; |
| 616 | 552 | ||
| 553 | /* ISO transfer only partially completed, | ||
| 554 | look at individual frame status for details */ | ||
| 555 | if (status == -EXDEV) { | ||
| 556 | DBG(HFCUSB_DBG_VERBOSE_USB, "HFC-S USB: tx_iso_complete with -EXDEV" | ||
| 557 | ", urb->status %d, fifonum %d\n", | ||
| 558 | status, fifon); | ||
| 559 | |||
| 560 | for (k = 0; k < iso_packets[fifon]; ++k) { | ||
| 561 | errcode = urb->iso_frame_desc[k].status; | ||
| 562 | if (errcode) | ||
| 563 | DBG(HFCUSB_DBG_VERBOSE_USB, "HFC-S USB: tx_iso_complete " | ||
| 564 | "packet %i, status: %i\n", | ||
| 565 | k, errcode); | ||
| 566 | } | ||
| 567 | |||
| 568 | // clear status, so go on with ISO transfers | ||
| 569 | status = 0; | ||
| 570 | } | ||
| 571 | |||
| 617 | if (fifo->active && !status) { | 572 | if (fifo->active && !status) { |
| 618 | transp_mode = 0; | 573 | transp_mode = 0; |
| 619 | if (fifon < 4 && hfc->b_mode[fifon / 2] == L1_MODE_TRANS) | 574 | if (fifon < 4 && hfc->b_mode[fifon / 2] == L1_MODE_TRANS) |
| 620 | transp_mode = true; | 575 | transp_mode = 1; |
| 621 | 576 | ||
| 622 | /* is FifoFull-threshold set for our channel? */ | 577 | /* is FifoFull-threshold set for our channel? */ |
| 623 | threshbit = threshtable[fifon] & hfc->threshold_mask; | 578 | threshbit = (hfc->threshold_mask & (1 << fifon)); |
| 624 | num_isoc_packets = iso_packets[fifon]; | 579 | num_isoc_packets = iso_packets[fifon]; |
| 625 | 580 | ||
| 626 | /* predict dataflow to avoid fifo overflow */ | 581 | /* predict dataflow to avoid fifo overflow */ |
| @@ -635,8 +590,9 @@ tx_iso_complete(struct urb *urb) | |||
| 635 | tx_iso_complete, urb->context); | 590 | tx_iso_complete, urb->context); |
| 636 | memset(context_iso_urb->buffer, 0, | 591 | memset(context_iso_urb->buffer, 0, |
| 637 | sizeof(context_iso_urb->buffer)); | 592 | sizeof(context_iso_urb->buffer)); |
| 638 | frame_complete = false; | 593 | frame_complete = 0; |
| 639 | /* Generate next Iso Packets */ | 594 | |
| 595 | /* Generate next ISO Packets */ | ||
| 640 | for (k = 0; k < num_isoc_packets; ++k) { | 596 | for (k = 0; k < num_isoc_packets; ++k) { |
| 641 | if (fifo->skbuff) { | 597 | if (fifo->skbuff) { |
| 642 | len = fifo->skbuff->len; | 598 | len = fifo->skbuff->len; |
| @@ -661,7 +617,7 @@ tx_iso_complete(struct urb *urb) | |||
| 661 | /* add 2 byte flags and 16bit CRC at end of ISDN frame */ | 617 | /* add 2 byte flags and 16bit CRC at end of ISDN frame */ |
| 662 | fifo->bit_line += 32; | 618 | fifo->bit_line += 32; |
| 663 | } | 619 | } |
| 664 | frame_complete = true; | 620 | frame_complete = 1; |
| 665 | } | 621 | } |
| 666 | 622 | ||
| 667 | memcpy(context_iso_urb->buffer + | 623 | memcpy(context_iso_urb->buffer + |
| @@ -688,7 +644,7 @@ tx_iso_complete(struct urb *urb) | |||
| 688 | } | 644 | } |
| 689 | 645 | ||
| 690 | if (frame_complete) { | 646 | if (frame_complete) { |
| 691 | fifo->delete_flg = true; | 647 | fifo->delete_flg = 1; |
| 692 | fifo->hif->l1l2(fifo->hif, | 648 | fifo->hif->l1l2(fifo->hif, |
| 693 | PH_DATA | CONFIRM, | 649 | PH_DATA | CONFIRM, |
| 694 | (void *) (unsigned long) fifo->skbuff-> | 650 | (void *) (unsigned long) fifo->skbuff-> |
| @@ -696,30 +652,26 @@ tx_iso_complete(struct urb *urb) | |||
| 696 | if (fifo->skbuff && fifo->delete_flg) { | 652 | if (fifo->skbuff && fifo->delete_flg) { |
| 697 | dev_kfree_skb_any(fifo->skbuff); | 653 | dev_kfree_skb_any(fifo->skbuff); |
| 698 | fifo->skbuff = NULL; | 654 | fifo->skbuff = NULL; |
| 699 | fifo->delete_flg = false; | 655 | fifo->delete_flg = 0; |
| 700 | } | 656 | } |
| 701 | frame_complete = false; | 657 | frame_complete = 0; |
| 702 | } | 658 | } |
| 703 | } | 659 | } |
| 704 | errcode = usb_submit_urb(urb, GFP_ATOMIC); | 660 | errcode = usb_submit_urb(urb, GFP_ATOMIC); |
| 705 | if (errcode < 0) { | 661 | if (errcode < 0) { |
| 706 | printk(KERN_INFO | 662 | printk(KERN_INFO |
| 707 | "HFC-S USB: error submitting ISO URB: %d \n", | 663 | "HFC-S USB: error submitting ISO URB: %d\n", |
| 708 | errcode); | 664 | errcode); |
| 709 | } | 665 | } |
| 710 | } else { | 666 | } else { |
| 711 | if (status && !hfc->disc_flag) { | 667 | if (status && !hfc->disc_flag) { |
| 712 | printk(KERN_INFO | 668 | printk(KERN_INFO |
| 713 | "HFC-S USB: tx_iso_complete : urb->status %s (%i), fifonum=%d\n", | 669 | "HFC-S USB: tx_iso_complete: error(%i): '%s', fifonum=%d\n", |
| 714 | symbolic(urb_errlist, status), status, | 670 | status, symbolic(urb_errlist, status), fifon); |
| 715 | fifon); | ||
| 716 | } | 671 | } |
| 717 | } | 672 | } |
| 718 | } /* tx_iso_complete */ | 673 | } |
| 719 | 674 | ||
| 720 | /*****************************************************/ | ||
| 721 | /* receive completion routine for all ISO tx fifos */ | ||
| 722 | /*****************************************************/ | ||
| 723 | static void | 675 | static void |
| 724 | rx_iso_complete(struct urb *urb) | 676 | rx_iso_complete(struct urb *urb) |
| 725 | { | 677 | { |
| @@ -731,21 +683,25 @@ rx_iso_complete(struct urb *urb) | |||
| 731 | unsigned int iso_status; | 683 | unsigned int iso_status; |
| 732 | __u8 *buf; | 684 | __u8 *buf; |
| 733 | static __u8 eof[8]; | 685 | static __u8 eof[8]; |
| 734 | #ifdef CONFIG_HISAX_DEBUG | ||
| 735 | __u8 i; | ||
| 736 | #endif | ||
| 737 | 686 | ||
| 738 | fifon = fifo->fifonum; | 687 | fifon = fifo->fifonum; |
| 739 | status = urb->status; | 688 | status = urb->status; |
| 740 | 689 | ||
| 741 | if (urb->status == -EOVERFLOW) { | 690 | if (urb->status == -EOVERFLOW) { |
| 742 | #ifdef CONFIG_HISAX_DEBUG | 691 | DBG(HFCUSB_DBG_VERBOSE_USB, |
| 743 | DBG(USB_DBG, | 692 | "HFC-USB: ignoring USB DATAOVERRUN fifo(%i)", fifon); |
| 744 | "HFC-USB: ignoring USB DATAOVERRUN for fifo %i \n", | 693 | status = 0; |
| 745 | fifon); | 694 | } |
| 746 | #endif | 695 | |
| 696 | /* ISO transfer only partially completed, | ||
| 697 | look at individual frame status for details */ | ||
| 698 | if (status == -EXDEV) { | ||
| 699 | DBG(HFCUSB_DBG_VERBOSE_USB, "HFC-S USB: rx_iso_complete with -EXDEV " | ||
| 700 | "urb->status %d, fifonum %d\n", | ||
| 701 | status, fifon); | ||
| 747 | status = 0; | 702 | status = 0; |
| 748 | } | 703 | } |
| 704 | |||
| 749 | if (fifo->active && !status) { | 705 | if (fifo->active && !status) { |
| 750 | num_isoc_packets = iso_packets[fifon]; | 706 | num_isoc_packets = iso_packets[fifon]; |
| 751 | maxlen = fifo->usb_packet_maxlen; | 707 | maxlen = fifo->usb_packet_maxlen; |
| @@ -754,40 +710,38 @@ rx_iso_complete(struct urb *urb) | |||
| 754 | offset = urb->iso_frame_desc[k].offset; | 710 | offset = urb->iso_frame_desc[k].offset; |
| 755 | buf = context_iso_urb->buffer + offset; | 711 | buf = context_iso_urb->buffer + offset; |
| 756 | iso_status = urb->iso_frame_desc[k].status; | 712 | iso_status = urb->iso_frame_desc[k].status; |
| 757 | #ifdef CONFIG_HISAX_DEBUG | 713 | |
| 758 | if (iso_status && !hfc->disc_flag) | 714 | if (iso_status && !hfc->disc_flag) |
| 759 | DBG(USB_DBG, | 715 | DBG(HFCUSB_DBG_VERBOSE_USB, |
| 760 | "HFC-S USB: ISO packet failure - status:%x", | 716 | "HFC-S USB: rx_iso_complete " |
| 761 | iso_status); | 717 | "ISO packet %i, status: %i\n", |
| 718 | k, iso_status); | ||
| 762 | 719 | ||
| 763 | if ((fifon == 5) && (debug > 1)) { | 720 | if (fifon == HFCUSB_D_RX) { |
| 764 | printk(KERN_INFO | 721 | DBG(HFCUSB_DBG_VERBOSE_USB, |
| 765 | "HFC-S USB: ISO-D-RX lst_urblen:%2d " | 722 | "HFC-S USB: ISO-D-RX lst_urblen:%2d " |
| 766 | "act_urblen:%2d max-urblen:%2d " | 723 | "act_urblen:%2d max-urblen:%2d EOF:0x%0x", |
| 767 | "EOF:0x%0x DATA: ", | ||
| 768 | fifo->last_urblen, len, maxlen, | 724 | fifo->last_urblen, len, maxlen, |
| 769 | eof[5]); | 725 | eof[5]); |
| 770 | for (i = 0; i < len; i++) | 726 | |
| 771 | printk("%.2x ", buf[i]); | 727 | DBG_PACKET(HFCUSB_DBG_VERBOSE_USB, buf, len); |
| 772 | printk("\n"); | ||
| 773 | } | 728 | } |
| 774 | #endif | 729 | |
| 775 | if (fifo->last_urblen != maxlen) { | 730 | if (fifo->last_urblen != maxlen) { |
| 776 | /* the threshold mask is in the 2nd status byte */ | 731 | /* the threshold mask is in the 2nd status byte */ |
| 777 | hfc->threshold_mask = buf[1]; | 732 | hfc->threshold_mask = buf[1]; |
| 778 | /* care for L1 state only for D-Channel | 733 | /* care for L1 state only for D-Channel |
| 779 | to avoid overlapped iso completions */ | 734 | to avoid overlapped iso completions */ |
| 780 | if (fifon == 5) { | 735 | if (fifon == HFCUSB_D_RX) { |
| 781 | /* the S0 state is in the upper half | 736 | /* the S0 state is in the upper half |
| 782 | of the 1st status byte */ | 737 | of the 1st status byte */ |
| 783 | state_handler(hfc, buf[0] >> 4); | 738 | s0_state_handler(hfc, buf[0] >> 4); |
| 784 | } | 739 | } |
| 785 | eof[fifon] = buf[0] & 1; | 740 | eof[fifon] = buf[0] & 1; |
| 786 | if (len > 2) | 741 | if (len > 2) |
| 787 | collect_rx_frame(fifo, buf + 2, | 742 | collect_rx_frame(fifo, buf + 2, |
| 788 | len - 2, | 743 | len - 2, |
| 789 | (len < | 744 | (len < maxlen) ? |
| 790 | maxlen) ? | ||
| 791 | eof[fifon] : 0); | 745 | eof[fifon] : 0); |
| 792 | } else { | 746 | } else { |
| 793 | collect_rx_frame(fifo, buf, len, | 747 | collect_rx_frame(fifo, buf, len, |
| @@ -804,41 +758,37 @@ rx_iso_complete(struct urb *urb) | |||
| 804 | rx_iso_complete, urb->context); | 758 | rx_iso_complete, urb->context); |
| 805 | errcode = usb_submit_urb(urb, GFP_ATOMIC); | 759 | errcode = usb_submit_urb(urb, GFP_ATOMIC); |
| 806 | if (errcode < 0) { | 760 | if (errcode < 0) { |
| 807 | printk(KERN_INFO | 761 | printk(KERN_ERR |
| 808 | "HFC-S USB: error submitting ISO URB: %d \n", | 762 | "HFC-S USB: error submitting ISO URB: %d\n", |
| 809 | errcode); | 763 | errcode); |
| 810 | } | 764 | } |
| 811 | } else { | 765 | } else { |
| 812 | if (status && !hfc->disc_flag) { | 766 | if (status && !hfc->disc_flag) { |
| 813 | printk(KERN_INFO | 767 | printk(KERN_ERR |
| 814 | "HFC-S USB: rx_iso_complete : " | 768 | "HFC-S USB: rx_iso_complete : " |
| 815 | "urb->status %d, fifonum %d\n", | 769 | "urb->status %d, fifonum %d\n", |
| 816 | status, fifon); | 770 | status, fifon); |
| 817 | } | 771 | } |
| 818 | } | 772 | } |
| 819 | } /* rx_iso_complete */ | 773 | } |
| 820 | 774 | ||
| 821 | /*****************************************************/ | 775 | /* collect rx data from INT- and ISO-URBs */ |
| 822 | /* collect data from interrupt or isochron in */ | ||
| 823 | /*****************************************************/ | ||
| 824 | static void | 776 | static void |
| 825 | collect_rx_frame(usb_fifo * fifo, __u8 * data, int len, int finish) | 777 | collect_rx_frame(usb_fifo * fifo, __u8 * data, int len, int finish) |
| 826 | { | 778 | { |
| 827 | hfcusb_data *hfc = fifo->hfc; | 779 | hfcusb_data *hfc = fifo->hfc; |
| 828 | int transp_mode, fifon; | 780 | int transp_mode, fifon; |
| 829 | #ifdef CONFIG_HISAX_DEBUG | 781 | |
| 830 | int i; | ||
| 831 | #endif | ||
| 832 | fifon = fifo->fifonum; | 782 | fifon = fifo->fifonum; |
| 833 | transp_mode = 0; | 783 | transp_mode = 0; |
| 834 | if (fifon < 4 && hfc->b_mode[fifon / 2] == L1_MODE_TRANS) | 784 | if (fifon < 4 && hfc->b_mode[fifon / 2] == L1_MODE_TRANS) |
| 835 | transp_mode = true; | 785 | transp_mode = 1; |
| 836 | 786 | ||
| 837 | if (!fifo->skbuff) { | 787 | if (!fifo->skbuff) { |
| 838 | fifo->skbuff = dev_alloc_skb(fifo->max_size + 3); | 788 | fifo->skbuff = dev_alloc_skb(fifo->max_size + 3); |
| 839 | if (!fifo->skbuff) { | 789 | if (!fifo->skbuff) { |
| 840 | printk(KERN_INFO | 790 | printk(KERN_ERR |
| 841 | "HFC-S USB: cannot allocate buffer (dev_alloc_skb) fifo:%d\n", | 791 | "HFC-S USB: cannot allocate buffer for fifo(%d)\n", |
| 842 | fifon); | 792 | fifon); |
| 843 | return; | 793 | return; |
| 844 | } | 794 | } |
| @@ -847,17 +797,11 @@ collect_rx_frame(usb_fifo * fifo, __u8 * data, int len, int finish) | |||
| 847 | if (fifo->skbuff->len + len < fifo->max_size) { | 797 | if (fifo->skbuff->len + len < fifo->max_size) { |
| 848 | memcpy(skb_put(fifo->skbuff, len), data, len); | 798 | memcpy(skb_put(fifo->skbuff, len), data, len); |
| 849 | } else { | 799 | } else { |
| 850 | #ifdef CONFIG_HISAX_DEBUG | 800 | DBG(HFCUSB_DBG_FIFO_ERR, |
| 851 | printk(KERN_INFO "HFC-S USB: "); | 801 | "HCF-USB: got frame exceeded fifo->max_size(%d) fifo(%d)", |
| 852 | for (i = 0; i < 15; i++) | ||
| 853 | printk("%.2x ", | ||
| 854 | fifo->skbuff->data[fifo->skbuff-> | ||
| 855 | len - 15 + i]); | ||
| 856 | printk("\n"); | ||
| 857 | #endif | ||
| 858 | printk(KERN_INFO | ||
| 859 | "HCF-USB: got frame exceeded fifo->max_size:%d on fifo:%d\n", | ||
| 860 | fifo->max_size, fifon); | 802 | fifo->max_size, fifon); |
| 803 | DBG_SKB(HFCUSB_DBG_VERBOSE_USB, fifo->skbuff); | ||
| 804 | skb_trim(fifo->skbuff, 0); | ||
| 861 | } | 805 | } |
| 862 | } | 806 | } |
| 863 | if (transp_mode && fifo->skbuff->len >= 128) { | 807 | if (transp_mode && fifo->skbuff->len >= 128) { |
| @@ -870,6 +814,13 @@ collect_rx_frame(usb_fifo * fifo, __u8 * data, int len, int finish) | |||
| 870 | if (finish) { | 814 | if (finish) { |
| 871 | if ((!fifo->skbuff->data[fifo->skbuff->len - 1]) | 815 | if ((!fifo->skbuff->data[fifo->skbuff->len - 1]) |
| 872 | && (fifo->skbuff->len > 3)) { | 816 | && (fifo->skbuff->len > 3)) { |
| 817 | |||
| 818 | if (fifon == HFCUSB_D_RX) { | ||
| 819 | DBG(HFCUSB_DBG_DCHANNEL, | ||
| 820 | "HFC-S USB: D-RX len(%d)", fifo->skbuff->len); | ||
| 821 | DBG_SKB(HFCUSB_DBG_DCHANNEL, fifo->skbuff); | ||
| 822 | } | ||
| 823 | |||
| 873 | /* remove CRC & status */ | 824 | /* remove CRC & status */ |
| 874 | skb_trim(fifo->skbuff, fifo->skbuff->len - 3); | 825 | skb_trim(fifo->skbuff, fifo->skbuff->len - 3); |
| 875 | if (fifon == HFCUSB_PCM_RX) { | 826 | if (fifon == HFCUSB_PCM_RX) { |
| @@ -882,39 +833,17 @@ collect_rx_frame(usb_fifo * fifo, __u8 * data, int len, int finish) | |||
| 882 | fifo->skbuff); | 833 | fifo->skbuff); |
| 883 | fifo->skbuff = NULL; /* buffer was freed from upper layer */ | 834 | fifo->skbuff = NULL; /* buffer was freed from upper layer */ |
| 884 | } else { | 835 | } else { |
| 885 | if (fifo->skbuff->len > 3) { | 836 | DBG(HFCUSB_DBG_FIFO_ERR, |
| 886 | printk(KERN_INFO | 837 | "HFC-S USB: ERROR frame len(%d) fifo(%d)", |
| 887 | "HFC-S USB: got frame %d bytes but CRC ERROR on fifo:%d!!!\n", | 838 | fifo->skbuff->len, fifon); |
| 888 | fifo->skbuff->len, fifon); | 839 | DBG_SKB(HFCUSB_DBG_VERBOSE_USB, fifo->skbuff); |
| 889 | #ifdef CONFIG_HISAX_DEBUG | ||
| 890 | if (debug > 1) { | ||
| 891 | printk(KERN_INFO "HFC-S USB: "); | ||
| 892 | for (i = 0; i < 15; i++) | ||
| 893 | printk("%.2x ", | ||
| 894 | fifo->skbuff-> | ||
| 895 | data[fifo->skbuff-> | ||
| 896 | len - 15 + i]); | ||
| 897 | printk("\n"); | ||
| 898 | } | ||
| 899 | #endif | ||
| 900 | } | ||
| 901 | #ifdef CONFIG_HISAX_DEBUG | ||
| 902 | else { | ||
| 903 | printk(KERN_INFO | ||
| 904 | "HFC-S USB: frame to small (%d bytes)!!!\n", | ||
| 905 | fifo->skbuff->len); | ||
| 906 | } | ||
| 907 | #endif | ||
| 908 | skb_trim(fifo->skbuff, 0); | 840 | skb_trim(fifo->skbuff, 0); |
| 909 | } | 841 | } |
| 910 | } | 842 | } |
| 911 | } | 843 | } |
| 912 | 844 | ||
| 913 | /***********************************************/ | ||
| 914 | /* receive completion routine for all rx fifos */ | ||
| 915 | /***********************************************/ | ||
| 916 | static void | 845 | static void |
| 917 | rx_complete(struct urb *urb) | 846 | rx_int_complete(struct urb *urb) |
| 918 | { | 847 | { |
| 919 | int len; | 848 | int len; |
| 920 | int status; | 849 | int status; |
| @@ -922,18 +851,14 @@ rx_complete(struct urb *urb) | |||
| 922 | usb_fifo *fifo = (usb_fifo *) urb->context; | 851 | usb_fifo *fifo = (usb_fifo *) urb->context; |
| 923 | hfcusb_data *hfc = fifo->hfc; | 852 | hfcusb_data *hfc = fifo->hfc; |
| 924 | static __u8 eof[8]; | 853 | static __u8 eof[8]; |
| 925 | #ifdef CONFIG_HISAX_DEBUG | ||
| 926 | __u8 i; | ||
| 927 | #endif | ||
| 928 | 854 | ||
| 929 | urb->dev = hfc->dev; /* security init */ | 855 | urb->dev = hfc->dev; /* security init */ |
| 930 | 856 | ||
| 931 | fifon = fifo->fifonum; | 857 | fifon = fifo->fifonum; |
| 932 | if ((!fifo->active) || (urb->status)) { | 858 | if ((!fifo->active) || (urb->status)) { |
| 933 | #ifdef CONFIG_HISAX_DEBUG | 859 | DBG(HFCUSB_DBG_INIT, "HFC-S USB: RX-Fifo %i is going down (%i)", |
| 934 | DBG(USB_DBG, "HFC-S USB: RX-Fifo %i is going down (%i)", | ||
| 935 | fifon, urb->status); | 860 | fifon, urb->status); |
| 936 | #endif | 861 | |
| 937 | fifo->urb->interval = 0; /* cancel automatic rescheduling */ | 862 | fifo->urb->interval = 0; /* cancel automatic rescheduling */ |
| 938 | if (fifo->skbuff) { | 863 | if (fifo->skbuff) { |
| 939 | dev_kfree_skb_any(fifo->skbuff); | 864 | dev_kfree_skb_any(fifo->skbuff); |
| @@ -945,22 +870,20 @@ rx_complete(struct urb *urb) | |||
| 945 | buf = fifo->buffer; | 870 | buf = fifo->buffer; |
| 946 | maxlen = fifo->usb_packet_maxlen; | 871 | maxlen = fifo->usb_packet_maxlen; |
| 947 | 872 | ||
| 948 | #ifdef CONFIG_HISAX_DEBUG | 873 | if (fifon == HFCUSB_D_RX) { |
| 949 | if ((fifon == 5) && (debug > 1)) { | 874 | DBG(HFCUSB_DBG_VERBOSE_USB, |
| 950 | printk(KERN_INFO | 875 | "HFC-S USB: INT-D-RX lst_urblen:%2d " |
| 951 | "HFC-S USB: INT-D-RX lst_urblen:%2d act_urblen:%2d max-urblen:%2d EOF:0x%0x DATA: ", | 876 | "act_urblen:%2d max-urblen:%2d EOF:0x%0x", |
| 952 | fifo->last_urblen, len, maxlen, eof[5]); | 877 | fifo->last_urblen, len, maxlen, |
| 953 | for (i = 0; i < len; i++) | 878 | eof[5]); |
| 954 | printk("%.2x ", buf[i]); | 879 | DBG_PACKET(HFCUSB_DBG_VERBOSE_USB, buf, len); |
| 955 | printk("\n"); | ||
| 956 | } | 880 | } |
| 957 | #endif | ||
| 958 | 881 | ||
| 959 | if (fifo->last_urblen != fifo->usb_packet_maxlen) { | 882 | if (fifo->last_urblen != fifo->usb_packet_maxlen) { |
| 960 | /* the threshold mask is in the 2nd status byte */ | 883 | /* the threshold mask is in the 2nd status byte */ |
| 961 | hfc->threshold_mask = buf[1]; | 884 | hfc->threshold_mask = buf[1]; |
| 962 | /* the S0 state is in the upper half of the 1st status byte */ | 885 | /* the S0 state is in the upper half of the 1st status byte */ |
| 963 | state_handler(hfc, buf[0] >> 4); | 886 | s0_state_handler(hfc, buf[0] >> 4); |
| 964 | eof[fifon] = buf[0] & 1; | 887 | eof[fifon] = buf[0] & 1; |
| 965 | /* if we have more than the 2 status bytes -> collect data */ | 888 | /* if we have more than the 2 status bytes -> collect data */ |
| 966 | if (len > 2) | 889 | if (len > 2) |
| @@ -975,20 +898,19 @@ rx_complete(struct urb *urb) | |||
| 975 | status = usb_submit_urb(urb, GFP_ATOMIC); | 898 | status = usb_submit_urb(urb, GFP_ATOMIC); |
| 976 | if (status) { | 899 | if (status) { |
| 977 | printk(KERN_INFO | 900 | printk(KERN_INFO |
| 978 | "HFC-S USB: error resubmitting URN at rx_complete...\n"); | 901 | "HFC-S USB: %s error resubmitting URB fifo(%d)\n", |
| 902 | __FUNCTION__, fifon); | ||
| 979 | } | 903 | } |
| 980 | } /* rx_complete */ | 904 | } |
| 981 | 905 | ||
| 982 | /***************************************************/ | 906 | /* start initial INT-URB for certain fifo */ |
| 983 | /* start the interrupt transfer for the given fifo */ | ||
| 984 | /***************************************************/ | ||
| 985 | static void | 907 | static void |
| 986 | start_int_fifo(usb_fifo * fifo) | 908 | start_int_fifo(usb_fifo * fifo) |
| 987 | { | 909 | { |
| 988 | int errcode; | 910 | int errcode; |
| 989 | 911 | ||
| 990 | printk(KERN_INFO "HFC-S USB: starting intr IN fifo:%d\n", | 912 | DBG(HFCUSB_DBG_INIT, "HFC-S USB: starting RX INT-URB for fifo:%d\n", |
| 991 | fifo->fifonum); | 913 | fifo->fifonum); |
| 992 | 914 | ||
| 993 | if (!fifo->urb) { | 915 | if (!fifo->urb) { |
| 994 | fifo->urb = usb_alloc_urb(0, GFP_KERNEL); | 916 | fifo->urb = usb_alloc_urb(0, GFP_KERNEL); |
| @@ -997,33 +919,28 @@ start_int_fifo(usb_fifo * fifo) | |||
| 997 | } | 919 | } |
| 998 | usb_fill_int_urb(fifo->urb, fifo->hfc->dev, fifo->pipe, | 920 | usb_fill_int_urb(fifo->urb, fifo->hfc->dev, fifo->pipe, |
| 999 | fifo->buffer, fifo->usb_packet_maxlen, | 921 | fifo->buffer, fifo->usb_packet_maxlen, |
| 1000 | rx_complete, fifo, fifo->intervall); | 922 | rx_int_complete, fifo, fifo->intervall); |
| 1001 | fifo->active = 1; /* must be marked active */ | 923 | fifo->active = 1; /* must be marked active */ |
| 1002 | errcode = usb_submit_urb(fifo->urb, GFP_KERNEL); | 924 | errcode = usb_submit_urb(fifo->urb, GFP_KERNEL); |
| 1003 | if (errcode) { | 925 | if (errcode) { |
| 1004 | printk(KERN_INFO | 926 | printk(KERN_ERR |
| 1005 | "HFC-S USB: submit URB error(start_int_info): status:%i\n", | 927 | "HFC-S USB: submit URB error(start_int_info): status:%i\n", |
| 1006 | errcode); | 928 | errcode); |
| 1007 | fifo->active = 0; | 929 | fifo->active = 0; |
| 1008 | fifo->skbuff = NULL; | 930 | fifo->skbuff = NULL; |
| 1009 | } | 931 | } |
| 1010 | } /* start_int_fifo */ | 932 | } |
| 1011 | 933 | ||
| 1012 | /*****************************/ | ||
| 1013 | /* set the B-channel mode */ | ||
| 1014 | /*****************************/ | ||
| 1015 | static void | 934 | static void |
| 1016 | set_hfcmode(hfcusb_data * hfc, int channel, int mode) | 935 | setup_bchannel(hfcusb_data * hfc, int channel, int mode) |
| 1017 | { | 936 | { |
| 1018 | __u8 val, idx_table[2] = { 0, 2 }; | 937 | __u8 val, idx_table[2] = { 0, 2 }; |
| 1019 | 938 | ||
| 1020 | if (hfc->disc_flag) { | 939 | if (hfc->disc_flag) { |
| 1021 | return; | 940 | return; |
| 1022 | } | 941 | } |
| 1023 | #ifdef CONFIG_HISAX_DEBUG | 942 | DBG(HFCUSB_DBG_STATES, "HFC-S USB: setting channel %d to mode %d", |
| 1024 | DBG(ISDN_DBG, "HFC-S USB: setting channel %d to mode %d", channel, | 943 | channel, mode); |
| 1025 | mode); | ||
| 1026 | #endif | ||
| 1027 | hfc->b_mode[channel] = mode; | 944 | hfc->b_mode[channel] = mode; |
| 1028 | 945 | ||
| 1029 | /* setup CON_HDLC */ | 946 | /* setup CON_HDLC */ |
| @@ -1080,20 +997,17 @@ hfc_usb_l2l1(struct hisax_if *my_hisax_if, int pr, void *arg) | |||
| 1080 | switch (pr) { | 997 | switch (pr) { |
| 1081 | case PH_ACTIVATE | REQUEST: | 998 | case PH_ACTIVATE | REQUEST: |
| 1082 | if (fifo->fifonum == HFCUSB_D_TX) { | 999 | if (fifo->fifonum == HFCUSB_D_TX) { |
| 1083 | #ifdef CONFIG_HISAX_DEBUG | 1000 | DBG(HFCUSB_DBG_STATES, |
| 1084 | DBG(ISDN_DBG, | ||
| 1085 | "HFC_USB: hfc_usb_d_l2l1 D-chan: PH_ACTIVATE | REQUEST"); | 1001 | "HFC_USB: hfc_usb_d_l2l1 D-chan: PH_ACTIVATE | REQUEST"); |
| 1086 | #endif | 1002 | |
| 1087 | if (hfc->l1_state != 3 | 1003 | if (hfc->l1_state != 3 |
| 1088 | && hfc->l1_state != 7) { | 1004 | && hfc->l1_state != 7) { |
| 1089 | hfc->d_if.ifc.l1l2(&hfc->d_if.ifc, | 1005 | hfc->d_if.ifc.l1l2(&hfc->d_if.ifc, |
| 1090 | PH_DEACTIVATE | | 1006 | PH_DEACTIVATE | |
| 1091 | INDICATION, | 1007 | INDICATION, |
| 1092 | NULL); | 1008 | NULL); |
| 1093 | #ifdef CONFIG_HISAX_DEBUG | 1009 | DBG(HFCUSB_DBG_STATES, |
| 1094 | DBG(ISDN_DBG, | ||
| 1095 | "HFC-S USB: PH_DEACTIVATE | INDICATION sent (not state 3 or 7)"); | 1010 | "HFC-S USB: PH_DEACTIVATE | INDICATION sent (not state 3 or 7)"); |
| 1096 | #endif | ||
| 1097 | } else { | 1011 | } else { |
| 1098 | if (hfc->l1_state == 7) { /* l1 already active */ | 1012 | if (hfc->l1_state == 7) { /* l1 already active */ |
| 1099 | hfc->d_if.ifc.l1l2(&hfc-> | 1013 | hfc->d_if.ifc.l1l2(&hfc-> |
| @@ -1103,10 +1017,8 @@ hfc_usb_l2l1(struct hisax_if *my_hisax_if, int pr, void *arg) | |||
| 1103 | | | 1017 | | |
| 1104 | INDICATION, | 1018 | INDICATION, |
| 1105 | NULL); | 1019 | NULL); |
| 1106 | #ifdef CONFIG_HISAX_DEBUG | 1020 | DBG(HFCUSB_DBG_STATES, |
| 1107 | DBG(ISDN_DBG, | ||
| 1108 | "HFC-S USB: PH_ACTIVATE | INDICATION sent again ;)"); | 1021 | "HFC-S USB: PH_ACTIVATE | INDICATION sent again ;)"); |
| 1109 | #endif | ||
| 1110 | } else { | 1022 | } else { |
| 1111 | /* force sending sending INFO1 */ | 1023 | /* force sending sending INFO1 */ |
| 1112 | queue_control_request(hfc, | 1024 | queue_control_request(hfc, |
| @@ -1132,11 +1044,9 @@ hfc_usb_l2l1(struct hisax_if *my_hisax_if, int pr, void *arg) | |||
| 1132 | } | 1044 | } |
| 1133 | } | 1045 | } |
| 1134 | } else { | 1046 | } else { |
| 1135 | #ifdef CONFIG_HISAX_DEBUG | 1047 | DBG(HFCUSB_DBG_STATES, |
| 1136 | DBG(ISDN_DBG, | 1048 | "HFC_USB: hfc_usb_d_l2l1 B-chan: PH_ACTIVATE | REQUEST"); |
| 1137 | "HFC_USB: hfc_usb_d_l2l1 Bx-chan: PH_ACTIVATE | REQUEST"); | 1049 | setup_bchannel(hfc, |
| 1138 | #endif | ||
| 1139 | set_hfcmode(hfc, | ||
| 1140 | (fifo->fifonum == | 1050 | (fifo->fifonum == |
| 1141 | HFCUSB_B1_TX) ? 0 : 1, | 1051 | HFCUSB_B1_TX) ? 0 : 1, |
| 1142 | (long) arg); | 1052 | (long) arg); |
| @@ -1147,18 +1057,12 @@ hfc_usb_l2l1(struct hisax_if *my_hisax_if, int pr, void *arg) | |||
| 1147 | break; | 1057 | break; |
| 1148 | case PH_DEACTIVATE | REQUEST: | 1058 | case PH_DEACTIVATE | REQUEST: |
| 1149 | if (fifo->fifonum == HFCUSB_D_TX) { | 1059 | if (fifo->fifonum == HFCUSB_D_TX) { |
| 1150 | #ifdef CONFIG_HISAX_DEBUG | 1060 | DBG(HFCUSB_DBG_STATES, |
| 1151 | DBG(ISDN_DBG, | ||
| 1152 | "HFC_USB: hfc_usb_d_l2l1 D-chan: PH_DEACTIVATE | REQUEST"); | 1061 | "HFC_USB: hfc_usb_d_l2l1 D-chan: PH_DEACTIVATE | REQUEST"); |
| 1153 | #endif | ||
| 1154 | printk(KERN_INFO | ||
| 1155 | "HFC-S USB: ISDN TE device should not deativate...\n"); | ||
| 1156 | } else { | 1062 | } else { |
| 1157 | #ifdef CONFIG_HISAX_DEBUG | 1063 | DBG(HFCUSB_DBG_STATES, |
| 1158 | DBG(ISDN_DBG, | ||
| 1159 | "HFC_USB: hfc_usb_d_l2l1 Bx-chan: PH_DEACTIVATE | REQUEST"); | 1064 | "HFC_USB: hfc_usb_d_l2l1 Bx-chan: PH_DEACTIVATE | REQUEST"); |
| 1160 | #endif | 1065 | setup_bchannel(hfc, |
| 1161 | set_hfcmode(hfc, | ||
| 1162 | (fifo->fifonum == | 1066 | (fifo->fifonum == |
| 1163 | HFCUSB_B1_TX) ? 0 : 1, | 1067 | HFCUSB_B1_TX) ? 0 : 1, |
| 1164 | (int) L1_MODE_NULL); | 1068 | (int) L1_MODE_NULL); |
| @@ -1171,25 +1075,20 @@ hfc_usb_l2l1(struct hisax_if *my_hisax_if, int pr, void *arg) | |||
| 1171 | if (fifo->skbuff && fifo->delete_flg) { | 1075 | if (fifo->skbuff && fifo->delete_flg) { |
| 1172 | dev_kfree_skb_any(fifo->skbuff); | 1076 | dev_kfree_skb_any(fifo->skbuff); |
| 1173 | fifo->skbuff = NULL; | 1077 | fifo->skbuff = NULL; |
| 1174 | fifo->delete_flg = false; | 1078 | fifo->delete_flg = 0; |
| 1175 | } | 1079 | } |
| 1176 | fifo->skbuff = arg; /* we have a new buffer */ | 1080 | fifo->skbuff = arg; /* we have a new buffer */ |
| 1177 | break; | 1081 | break; |
| 1178 | default: | 1082 | default: |
| 1179 | printk(KERN_INFO | 1083 | DBG(HFCUSB_DBG_STATES, |
| 1180 | "HFC_USB: hfc_usb_d_l2l1: unkown state : %#x\n", | 1084 | "HFC_USB: hfc_usb_d_l2l1: unkown state : %#x", pr); |
| 1181 | pr); | ||
| 1182 | break; | 1085 | break; |
| 1183 | } | 1086 | } |
| 1184 | } | 1087 | } |
| 1185 | 1088 | ||
| 1186 | /***************************************************************************/ | 1089 | /* initial init HFC-S USB chip registers, HiSax interface, USB URBs */ |
| 1187 | /* usb_init is called once when a new matching device is detected to setup */ | ||
| 1188 | /* main parameters. It registers the driver at the main hisax module. */ | ||
| 1189 | /* on success 0 is returned. */ | ||
| 1190 | /***************************************************************************/ | ||
| 1191 | static int | 1090 | static int |
| 1192 | usb_init(hfcusb_data * hfc) | 1091 | hfc_usb_init(hfcusb_data * hfc) |
| 1193 | { | 1092 | { |
| 1194 | usb_fifo *fifo; | 1093 | usb_fifo *fifo; |
| 1195 | int i, err; | 1094 | int i, err; |
| @@ -1214,11 +1113,11 @@ usb_init(hfcusb_data * hfc) | |||
| 1214 | /* aux = output, reset off */ | 1113 | /* aux = output, reset off */ |
| 1215 | write_usb(hfc, HFCUSB_CIRM, 0x10); | 1114 | write_usb(hfc, HFCUSB_CIRM, 0x10); |
| 1216 | 1115 | ||
| 1217 | /* set USB_SIZE to match the wMaxPacketSize for INT or BULK transfers */ | 1116 | /* set USB_SIZE to match wMaxPacketSize for INT or BULK transfers */ |
| 1218 | write_usb(hfc, HFCUSB_USB_SIZE, | 1117 | write_usb(hfc, HFCUSB_USB_SIZE, |
| 1219 | (hfc->packet_size / 8) | ((hfc->packet_size / 8) << 4)); | 1118 | (hfc->packet_size / 8) | ((hfc->packet_size / 8) << 4)); |
| 1220 | 1119 | ||
| 1221 | /* set USB_SIZE_I to match the wMaxPacketSize for ISO transfers */ | 1120 | /* set USB_SIZE_I to match wMaxPacketSize for ISO transfers */ |
| 1222 | write_usb(hfc, HFCUSB_USB_SIZE_I, hfc->iso_packet_size); | 1121 | write_usb(hfc, HFCUSB_USB_SIZE_I, hfc->iso_packet_size); |
| 1223 | 1122 | ||
| 1224 | /* enable PCM/GCI master mode */ | 1123 | /* enable PCM/GCI master mode */ |
| @@ -1257,8 +1156,8 @@ usb_init(hfcusb_data * hfc) | |||
| 1257 | hfc->b_mode[0] = L1_MODE_NULL; | 1156 | hfc->b_mode[0] = L1_MODE_NULL; |
| 1258 | hfc->b_mode[1] = L1_MODE_NULL; | 1157 | hfc->b_mode[1] = L1_MODE_NULL; |
| 1259 | 1158 | ||
| 1260 | hfc->l1_activated = false; | 1159 | hfc->l1_activated = 0; |
| 1261 | hfc->disc_flag = false; | 1160 | hfc->disc_flag = 0; |
| 1262 | hfc->led_state = 0; | 1161 | hfc->led_state = 0; |
| 1263 | hfc->led_new_data = 0; | 1162 | hfc->led_new_data = 0; |
| 1264 | hfc->old_led_state = 0; | 1163 | hfc->old_led_state = 0; |
| @@ -1349,11 +1248,9 @@ usb_init(hfcusb_data * hfc) | |||
| 1349 | handle_led(hfc, LED_POWER_ON); | 1248 | handle_led(hfc, LED_POWER_ON); |
| 1350 | 1249 | ||
| 1351 | return (0); | 1250 | return (0); |
| 1352 | } /* usb_init */ | 1251 | } |
| 1353 | 1252 | ||
| 1354 | /*************************************************/ | 1253 | /* initial callback for each plugged USB device */ |
| 1355 | /* function called to probe a new plugged device */ | ||
| 1356 | /*************************************************/ | ||
| 1357 | static int | 1254 | static int |
| 1358 | hfc_usb_probe(struct usb_interface *intf, const struct usb_device_id *id) | 1255 | hfc_usb_probe(struct usb_interface *intf, const struct usb_device_id *id) |
| 1359 | { | 1256 | { |
| @@ -1378,11 +1275,6 @@ hfc_usb_probe(struct usb_interface *intf, const struct usb_device_id *id) | |||
| 1378 | } | 1275 | } |
| 1379 | } | 1276 | } |
| 1380 | 1277 | ||
| 1381 | #ifdef CONFIG_HISAX_DEBUG | ||
| 1382 | DBG(USB_DBG, | ||
| 1383 | "HFC-USB: probing interface(%d) actalt(%d) minor(%d)\n", ifnum, | ||
| 1384 | iface->desc.bAlternateSetting, intf->minor); | ||
| 1385 | #endif | ||
| 1386 | printk(KERN_INFO | 1278 | printk(KERN_INFO |
| 1387 | "HFC-S USB: probing interface(%d) actalt(%d) minor(%d)\n", | 1279 | "HFC-S USB: probing interface(%d) actalt(%d) minor(%d)\n", |
| 1388 | ifnum, iface->desc.bAlternateSetting, intf->minor); | 1280 | ifnum, iface->desc.bAlternateSetting, intf->minor); |
| @@ -1403,15 +1295,11 @@ hfc_usb_probe(struct usb_interface *intf, const struct usb_device_id *id) | |||
| 1403 | 1295 | ||
| 1404 | /* check for config EOL element */ | 1296 | /* check for config EOL element */ |
| 1405 | while (validconf[cfg_used][0]) { | 1297 | while (validconf[cfg_used][0]) { |
| 1406 | cfg_found = true; | 1298 | cfg_found = 1; |
| 1407 | vcf = validconf[cfg_used]; | 1299 | vcf = validconf[cfg_used]; |
| 1408 | /* first endpoint descriptor */ | 1300 | /* first endpoint descriptor */ |
| 1409 | ep = iface->endpoint; | 1301 | ep = iface->endpoint; |
| 1410 | #ifdef CONFIG_HISAX_DEBUG | 1302 | |
| 1411 | DBG(USB_DBG, | ||
| 1412 | "HFC-S USB: (if=%d alt=%d cfg_used=%d)\n", | ||
| 1413 | ifnum, probe_alt_setting, cfg_used); | ||
| 1414 | #endif | ||
| 1415 | memcpy(cmptbl, vcf, 16 * sizeof(int)); | 1303 | memcpy(cmptbl, vcf, 16 * sizeof(int)); |
| 1416 | 1304 | ||
| 1417 | /* check for all endpoints in this alternate setting */ | 1305 | /* check for all endpoints in this alternate setting */ |
| @@ -1425,7 +1313,7 @@ hfc_usb_probe(struct usb_interface *intf, const struct usb_device_id *id) | |||
| 1425 | idx++; | 1313 | idx++; |
| 1426 | attr = ep->desc.bmAttributes; | 1314 | attr = ep->desc.bmAttributes; |
| 1427 | if (cmptbl[idx] == EP_NUL) { | 1315 | if (cmptbl[idx] == EP_NUL) { |
| 1428 | cfg_found = false; | 1316 | cfg_found = 0; |
| 1429 | } | 1317 | } |
| 1430 | if (attr == USB_ENDPOINT_XFER_INT | 1318 | if (attr == USB_ENDPOINT_XFER_INT |
| 1431 | && cmptbl[idx] == EP_INT) | 1319 | && cmptbl[idx] == EP_INT) |
| @@ -1438,16 +1326,9 @@ hfc_usb_probe(struct usb_interface *intf, const struct usb_device_id *id) | |||
| 1438 | cmptbl[idx] = EP_NUL; | 1326 | cmptbl[idx] = EP_NUL; |
| 1439 | 1327 | ||
| 1440 | /* check if all INT endpoints match minimum interval */ | 1328 | /* check if all INT endpoints match minimum interval */ |
| 1441 | if (attr == USB_ENDPOINT_XFER_INT | 1329 | if ((attr == USB_ENDPOINT_XFER_INT) |
| 1442 | && ep->desc.bInterval < | 1330 | && (ep->desc.bInterval < vcf[17])) { |
| 1443 | vcf[17]) { | 1331 | cfg_found = 0; |
| 1444 | #ifdef CONFIG_HISAX_DEBUG | ||
| 1445 | if (cfg_found) | ||
| 1446 | DBG(USB_DBG, | ||
| 1447 | "HFC-S USB: Interrupt Endpoint interval < %d found - skipping config", | ||
| 1448 | vcf[17]); | ||
| 1449 | #endif | ||
| 1450 | cfg_found = false; | ||
| 1451 | } | 1332 | } |
| 1452 | ep++; | 1333 | ep++; |
| 1453 | } | 1334 | } |
| @@ -1455,7 +1336,7 @@ hfc_usb_probe(struct usb_interface *intf, const struct usb_device_id *id) | |||
| 1455 | /* all entries must be EP_NOP or EP_NUL for a valid config */ | 1336 | /* all entries must be EP_NOP or EP_NUL for a valid config */ |
| 1456 | if (cmptbl[i] != EP_NOP | 1337 | if (cmptbl[i] != EP_NOP |
| 1457 | && cmptbl[i] != EP_NUL) | 1338 | && cmptbl[i] != EP_NUL) |
| 1458 | cfg_found = false; | 1339 | cfg_found = 0; |
| 1459 | } | 1340 | } |
| 1460 | if (cfg_found) { | 1341 | if (cfg_found) { |
| 1461 | if (cfg_used < small_match) { | 1342 | if (cfg_used < small_match) { |
| @@ -1464,23 +1345,16 @@ hfc_usb_probe(struct usb_interface *intf, const struct usb_device_id *id) | |||
| 1464 | probe_alt_setting; | 1345 | probe_alt_setting; |
| 1465 | iface_used = iface; | 1346 | iface_used = iface; |
| 1466 | } | 1347 | } |
| 1467 | #ifdef CONFIG_HISAX_DEBUG | ||
| 1468 | DBG(USB_DBG, | ||
| 1469 | "HFC-USB: small_match=%x %x\n", | ||
| 1470 | small_match, alt_used); | ||
| 1471 | #endif | ||
| 1472 | } | 1348 | } |
| 1473 | cfg_used++; | 1349 | cfg_used++; |
| 1474 | } | 1350 | } |
| 1475 | alt_idx++; | 1351 | alt_idx++; |
| 1476 | } /* (alt_idx < intf->num_altsetting) */ | 1352 | } /* (alt_idx < intf->num_altsetting) */ |
| 1477 | 1353 | ||
| 1478 | /* found a valid USB Ta Endpint config */ | 1354 | /* found a valid USB Ta Endpint config */ |
| 1479 | if (small_match != 0xffff) { | 1355 | if (small_match != 0xffff) { |
| 1480 | iface = iface_used; | 1356 | iface = iface_used; |
| 1481 | if (! | 1357 | if (!(context = kzalloc(sizeof(hfcusb_data), GFP_KERNEL))) |
| 1482 | (context = | ||
| 1483 | kzalloc(sizeof(hfcusb_data), GFP_KERNEL))) | ||
| 1484 | return (-ENOMEM); /* got no mem */ | 1358 | return (-ENOMEM); /* got no mem */ |
| 1485 | 1359 | ||
| 1486 | ep = iface->endpoint; | 1360 | ep = iface->endpoint; |
| @@ -1613,20 +1487,15 @@ hfc_usb_probe(struct usb_interface *intf, const struct usb_device_id *id) | |||
| 1613 | driver_info; | 1487 | driver_info; |
| 1614 | printk(KERN_INFO "HFC-S USB: detected \"%s\"\n", | 1488 | printk(KERN_INFO "HFC-S USB: detected \"%s\"\n", |
| 1615 | driver_info->vend_name); | 1489 | driver_info->vend_name); |
| 1616 | #ifdef CONFIG_HISAX_DEBUG | 1490 | |
| 1617 | DBG(USB_DBG, | 1491 | DBG(HFCUSB_DBG_INIT, |
| 1618 | "HFC-S USB: Endpoint-Config: %s (if=%d alt=%d)\n", | 1492 | "HFC-S USB: Endpoint-Config: %s (if=%d alt=%d), E-Channel(%d)", |
| 1619 | conf_str[small_match], context->if_used, | 1493 | conf_str[small_match], context->if_used, |
| 1620 | context->alt_used); | 1494 | context->alt_used, |
| 1621 | printk(KERN_INFO | 1495 | validconf[small_match][18]); |
| 1622 | "HFC-S USB: E-channel (\"ECHO:\") logging "); | 1496 | |
| 1623 | if (validconf[small_match][18]) | ||
| 1624 | printk(" possible\n"); | ||
| 1625 | else | ||
| 1626 | printk("NOT possible\n"); | ||
| 1627 | #endif | ||
| 1628 | /* init the chip and register the driver */ | 1497 | /* init the chip and register the driver */ |
| 1629 | if (usb_init(context)) { | 1498 | if (hfc_usb_init(context)) { |
| 1630 | usb_kill_urb(context->ctrl_urb); | 1499 | usb_kill_urb(context->ctrl_urb); |
| 1631 | usb_free_urb(context->ctrl_urb); | 1500 | usb_free_urb(context->ctrl_urb); |
| 1632 | context->ctrl_urb = NULL; | 1501 | context->ctrl_urb = NULL; |
| @@ -1643,17 +1512,19 @@ hfc_usb_probe(struct usb_interface *intf, const struct usb_device_id *id) | |||
| 1643 | return (-EIO); | 1512 | return (-EIO); |
| 1644 | } | 1513 | } |
| 1645 | 1514 | ||
| 1646 | /****************************************************/ | 1515 | /* callback for unplugged USB device */ |
| 1647 | /* function called when an active device is removed */ | ||
| 1648 | /****************************************************/ | ||
| 1649 | static void | 1516 | static void |
| 1650 | hfc_usb_disconnect(struct usb_interface | 1517 | hfc_usb_disconnect(struct usb_interface |
| 1651 | *intf) | 1518 | *intf) |
| 1652 | { | 1519 | { |
| 1653 | hfcusb_data *context = usb_get_intfdata(intf); | 1520 | hfcusb_data *context = usb_get_intfdata(intf); |
| 1654 | int i; | 1521 | int i; |
| 1522 | |||
| 1523 | handle_led(context, LED_POWER_OFF); | ||
| 1524 | schedule_timeout((10 * HZ) / 1000); | ||
| 1525 | |||
| 1655 | printk(KERN_INFO "HFC-S USB: device disconnect\n"); | 1526 | printk(KERN_INFO "HFC-S USB: device disconnect\n"); |
| 1656 | context->disc_flag = true; | 1527 | context->disc_flag = 1; |
| 1657 | usb_set_intfdata(intf, NULL); | 1528 | usb_set_intfdata(intf, NULL); |
| 1658 | if (!context) | 1529 | if (!context) |
| 1659 | return; | 1530 | return; |
| @@ -1661,25 +1532,22 @@ hfc_usb_disconnect(struct usb_interface | |||
| 1661 | del_timer(&context->t3_timer); | 1532 | del_timer(&context->t3_timer); |
| 1662 | if (timer_pending(&context->t4_timer)) | 1533 | if (timer_pending(&context->t4_timer)) |
| 1663 | del_timer(&context->t4_timer); | 1534 | del_timer(&context->t4_timer); |
| 1535 | |||
| 1664 | /* tell all fifos to terminate */ | 1536 | /* tell all fifos to terminate */ |
| 1665 | for (i = 0; i < HFCUSB_NUM_FIFOS; i++) { | 1537 | for (i = 0; i < HFCUSB_NUM_FIFOS; i++) { |
| 1666 | if (context->fifos[i].usb_transfer_mode == USB_ISOC) { | 1538 | if (context->fifos[i].usb_transfer_mode == USB_ISOC) { |
| 1667 | if (context->fifos[i].active > 0) { | 1539 | if (context->fifos[i].active > 0) { |
| 1668 | stop_isoc_chain(&context->fifos[i]); | 1540 | stop_isoc_chain(&context->fifos[i]); |
| 1669 | #ifdef CONFIG_HISAX_DEBUG | 1541 | DBG(HFCUSB_DBG_INIT, |
| 1670 | DBG(USB_DBG, | 1542 | "HFC-S USB: %s stopping ISOC chain Fifo(%i)", |
| 1671 | "HFC-S USB: hfc_usb_disconnect: stopping ISOC chain Fifo no %i", | 1543 | __FUNCTION__, i); |
| 1672 | i); | ||
| 1673 | #endif | ||
| 1674 | } | 1544 | } |
| 1675 | } else { | 1545 | } else { |
| 1676 | if (context->fifos[i].active > 0) { | 1546 | if (context->fifos[i].active > 0) { |
| 1677 | context->fifos[i].active = 0; | 1547 | context->fifos[i].active = 0; |
| 1678 | #ifdef CONFIG_HISAX_DEBUG | 1548 | DBG(HFCUSB_DBG_INIT, |
| 1679 | DBG(USB_DBG, | 1549 | "HFC-S USB: %s unlinking URB for Fifo(%i)", |
| 1680 | "HFC-S USB: hfc_usb_disconnect: unlinking URB for Fifo no %i", | 1550 | __FUNCTION__, i); |
| 1681 | i); | ||
| 1682 | #endif | ||
| 1683 | } | 1551 | } |
| 1684 | usb_kill_urb(context->fifos[i].urb); | 1552 | usb_kill_urb(context->fifos[i].urb); |
| 1685 | usb_free_urb(context->fifos[i].urb); | 1553 | usb_free_urb(context->fifos[i].urb); |
| @@ -1692,34 +1560,29 @@ hfc_usb_disconnect(struct usb_interface | |||
| 1692 | context->ctrl_urb = NULL; | 1560 | context->ctrl_urb = NULL; |
| 1693 | hisax_unregister(&context->d_if); | 1561 | hisax_unregister(&context->d_if); |
| 1694 | kfree(context); /* free our structure again */ | 1562 | kfree(context); /* free our structure again */ |
| 1695 | } /* hfc_usb_disconnect */ | 1563 | } |
| 1696 | 1564 | ||
| 1697 | /************************************/ | ||
| 1698 | /* our driver information structure */ | ||
| 1699 | /************************************/ | ||
| 1700 | static struct usb_driver hfc_drv = { | 1565 | static struct usb_driver hfc_drv = { |
| 1701 | .name = "hfc_usb", | 1566 | .name = "hfc_usb", |
| 1702 | .id_table = hfcusb_idtab, | 1567 | .id_table = hfcusb_idtab, |
| 1703 | .probe = hfc_usb_probe, | 1568 | .probe = hfc_usb_probe, |
| 1704 | .disconnect = hfc_usb_disconnect, | 1569 | .disconnect = hfc_usb_disconnect, |
| 1705 | }; | 1570 | }; |
| 1571 | |||
| 1706 | static void __exit | 1572 | static void __exit |
| 1707 | hfc_usb_exit(void) | 1573 | hfc_usb_mod_exit(void) |
| 1708 | { | 1574 | { |
| 1709 | #ifdef CONFIG_HISAX_DEBUG | 1575 | usb_deregister(&hfc_drv); /* release our driver */ |
| 1710 | DBG(USB_DBG, "HFC-S USB: calling \"hfc_usb_exit\" ..."); | ||
| 1711 | #endif | ||
| 1712 | usb_deregister(&hfc_drv); /* release our driver */ | ||
| 1713 | printk(KERN_INFO "HFC-S USB: module removed\n"); | 1576 | printk(KERN_INFO "HFC-S USB: module removed\n"); |
| 1714 | } | 1577 | } |
| 1715 | 1578 | ||
| 1716 | static int __init | 1579 | static int __init |
| 1717 | hfc_usb_init(void) | 1580 | hfc_usb_mod_init(void) |
| 1718 | { | 1581 | { |
| 1582 | char revstr[30], datestr[30], dummy[30]; | ||
| 1719 | #ifndef CONFIG_HISAX_DEBUG | 1583 | #ifndef CONFIG_HISAX_DEBUG |
| 1720 | unsigned int debug = -1; | 1584 | hfc_debug = debug; |
| 1721 | #endif | 1585 | #endif |
| 1722 | char revstr[30], datestr[30], dummy[30]; | ||
| 1723 | sscanf(hfcusb_revision, | 1586 | sscanf(hfcusb_revision, |
| 1724 | "%s %s $ %s %s %s $ ", dummy, revstr, | 1587 | "%s %s $ %s %s %s $ ", dummy, revstr, |
| 1725 | dummy, datestr, dummy); | 1588 | dummy, datestr, dummy); |
| @@ -1734,8 +1597,8 @@ hfc_usb_init(void) | |||
| 1734 | return (0); | 1597 | return (0); |
| 1735 | } | 1598 | } |
| 1736 | 1599 | ||
| 1737 | module_init(hfc_usb_init); | 1600 | module_init(hfc_usb_mod_init); |
| 1738 | module_exit(hfc_usb_exit); | 1601 | module_exit(hfc_usb_mod_exit); |
| 1739 | MODULE_AUTHOR(DRIVER_AUTHOR); | 1602 | MODULE_AUTHOR(DRIVER_AUTHOR); |
| 1740 | MODULE_DESCRIPTION(DRIVER_DESC); | 1603 | MODULE_DESCRIPTION(DRIVER_DESC); |
| 1741 | MODULE_LICENSE("GPL"); | 1604 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/isdn/hisax/hfc_usb.h b/drivers/isdn/hisax/hfc_usb.h index 471f2354dfde..e79f56568d30 100644 --- a/drivers/isdn/hisax/hfc_usb.h +++ b/drivers/isdn/hisax/hfc_usb.h | |||
| @@ -1,8 +1,8 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * hfc_usb.h | 2 | * hfc_usb.h |
| 3 | * | 3 | * |
| 4 | * $Id: hfc_usb.h,v 4.2 2005/04/07 15:27:17 martinb1 Exp $ | 4 | * $Id: hfc_usb.h,v 1.1.2.5 2007/08/20 14:36:03 mbachem Exp $ |
| 5 | */ | 5 | */ |
| 6 | 6 | ||
| 7 | #ifndef __HFC_USB_H__ | 7 | #ifndef __HFC_USB_H__ |
| 8 | #define __HFC_USB_H__ | 8 | #define __HFC_USB_H__ |
| @@ -10,25 +10,20 @@ | |||
| 10 | #define DRIVER_AUTHOR "Peter Sprenger (sprenger@moving-byters.de)" | 10 | #define DRIVER_AUTHOR "Peter Sprenger (sprenger@moving-byters.de)" |
| 11 | #define DRIVER_DESC "HFC-S USB based HiSAX ISDN driver" | 11 | #define DRIVER_DESC "HFC-S USB based HiSAX ISDN driver" |
| 12 | 12 | ||
| 13 | #define VERBOSE_USB_DEBUG | ||
| 14 | 13 | ||
| 14 | #define HFC_CTRL_TIMEOUT 20 /* 5ms timeout writing/reading regs */ | ||
| 15 | #define HFC_TIMER_T3 8000 /* timeout for l1 activation timer */ | ||
| 16 | #define HFC_TIMER_T4 500 /* time for state change interval */ | ||
| 15 | 17 | ||
| 16 | /***********/ | 18 | #define HFCUSB_L1_STATECHANGE 0 /* L1 state changed */ |
| 17 | /* defines */ | 19 | #define HFCUSB_L1_DRX 1 /* D-frame received */ |
| 18 | /***********/ | 20 | #define HFCUSB_L1_ERX 2 /* E-frame received */ |
| 19 | #define HFC_CTRL_TIMEOUT 20 /* 5ms timeout writing/reading regs */ | 21 | #define HFCUSB_L1_DTX 4 /* D-frames completed */ |
| 20 | #define HFC_TIMER_T3 8000 /* timeout for l1 activation timer */ | ||
| 21 | #define HFC_TIMER_T4 500 /* time for state change interval */ | ||
| 22 | 22 | ||
| 23 | #define HFCUSB_L1_STATECHANGE 0 /* L1 state changed */ | 23 | #define MAX_BCH_SIZE 2048 /* allowed B-channel packet size */ |
| 24 | #define HFCUSB_L1_DRX 1 /* D-frame received */ | ||
| 25 | #define HFCUSB_L1_ERX 2 /* E-frame received */ | ||
| 26 | #define HFCUSB_L1_DTX 4 /* D-frames completed */ | ||
| 27 | 24 | ||
| 28 | #define MAX_BCH_SIZE 2048 /* allowed B-channel packet size */ | 25 | #define HFCUSB_RX_THRESHOLD 64 /* threshold for fifo report bit rx */ |
| 29 | 26 | #define HFCUSB_TX_THRESHOLD 64 /* threshold for fifo report bit tx */ | |
| 30 | #define HFCUSB_RX_THRESHOLD 64 /* threshold for fifo report bit rx */ | ||
| 31 | #define HFCUSB_TX_THRESHOLD 64 /* threshold for fifo report bit tx */ | ||
| 32 | 27 | ||
| 33 | #define HFCUSB_CHIP_ID 0x16 /* Chip ID register index */ | 28 | #define HFCUSB_CHIP_ID 0x16 /* Chip ID register index */ |
| 34 | #define HFCUSB_CIRM 0x00 /* cirm register index */ | 29 | #define HFCUSB_CIRM 0x00 /* cirm register index */ |
| @@ -52,9 +47,8 @@ | |||
| 52 | 47 | ||
| 53 | #define HFCUSB_CHIPID 0x40 /* ID value of HFC-S USB */ | 48 | #define HFCUSB_CHIPID 0x40 /* ID value of HFC-S USB */ |
| 54 | 49 | ||
| 55 | /******************/ | 50 | |
| 56 | /* fifo registers */ | 51 | /* fifo registers */ |
| 57 | /******************/ | ||
| 58 | #define HFCUSB_NUM_FIFOS 8 /* maximum number of fifos */ | 52 | #define HFCUSB_NUM_FIFOS 8 /* maximum number of fifos */ |
| 59 | #define HFCUSB_B1_TX 0 /* index for B1 transmit bulk/int */ | 53 | #define HFCUSB_B1_TX 0 /* index for B1 transmit bulk/int */ |
| 60 | #define HFCUSB_B1_RX 1 /* index for B1 receive bulk/int */ | 54 | #define HFCUSB_B1_RX 1 /* index for B1 receive bulk/int */ |
| @@ -66,9 +60,9 @@ | |||
| 66 | #define HFCUSB_PCM_RX 7 | 60 | #define HFCUSB_PCM_RX 7 |
| 67 | 61 | ||
| 68 | /* | 62 | /* |
| 69 | * used to switch snd_transfer_mode for different TA modes e.g. the Billion USB TA just | 63 | * used to switch snd_transfer_mode for different TA modes e.g. the Billion USB TA just |
| 70 | * supports ISO out, while the Cologne Chip EVAL TA just supports BULK out | 64 | * supports ISO out, while the Cologne Chip EVAL TA just supports BULK out |
| 71 | */ | 65 | */ |
| 72 | #define USB_INT 0 | 66 | #define USB_INT 0 |
| 73 | #define USB_BULK 1 | 67 | #define USB_BULK 1 |
| 74 | #define USB_ISOC 2 | 68 | #define USB_ISOC 2 |
| @@ -77,49 +71,36 @@ | |||
| 77 | #define ISOC_PACKETS_B 8 | 71 | #define ISOC_PACKETS_B 8 |
| 78 | #define ISO_BUFFER_SIZE 128 | 72 | #define ISO_BUFFER_SIZE 128 |
| 79 | 73 | ||
| 80 | // ISO send definitions | 74 | /* Fifo flow Control for TX ISO */ |
| 81 | #define SINK_MAX 68 | 75 | #define SINK_MAX 68 |
| 82 | #define SINK_MIN 48 | 76 | #define SINK_MIN 48 |
| 83 | #define SINK_DMIN 12 | 77 | #define SINK_DMIN 12 |
| 84 | #define SINK_DMAX 18 | 78 | #define SINK_DMAX 18 |
| 85 | #define BITLINE_INF (-64*8) | 79 | #define BITLINE_INF (-64*8) |
| 86 | 80 | ||
| 87 | 81 | /* HFC-S USB register access by Control-URSs */ | |
| 88 | /**********/ | ||
| 89 | /* macros */ | ||
| 90 | /**********/ | ||
| 91 | #define write_usb(a,b,c)usb_control_msg((a)->dev,(a)->ctrl_out_pipe,0,0x40,(c),(b),NULL,0,HFC_CTRL_TIMEOUT) | 82 | #define write_usb(a,b,c)usb_control_msg((a)->dev,(a)->ctrl_out_pipe,0,0x40,(c),(b),NULL,0,HFC_CTRL_TIMEOUT) |
| 92 | #define read_usb(a,b,c) usb_control_msg((a)->dev,(a)->ctrl_in_pipe,1,0xC0,0,(b),(c),1,HFC_CTRL_TIMEOUT) | 83 | #define read_usb(a,b,c) usb_control_msg((a)->dev,(a)->ctrl_in_pipe,1,0xC0,0,(b),(c),1,HFC_CTRL_TIMEOUT) |
| 93 | |||
| 94 | |||
| 95 | /*******************/ | ||
| 96 | /* Debugging Flags */ | ||
| 97 | /*******************/ | ||
| 98 | #define USB_DBG 1 | ||
| 99 | #define ISDN_DBG 2 | ||
| 100 | |||
| 101 | |||
| 102 | /* *********************/ | ||
| 103 | /* USB related defines */ | ||
| 104 | /***********************/ | ||
| 105 | #define HFC_CTRL_BUFSIZE 32 | 84 | #define HFC_CTRL_BUFSIZE 32 |
| 106 | 85 | ||
| 107 | |||
| 108 | |||
| 109 | /*************************************************/ | ||
| 110 | /* entry and size of output/input control buffer */ | 86 | /* entry and size of output/input control buffer */ |
| 111 | /*************************************************/ | ||
| 112 | typedef struct { | 87 | typedef struct { |
| 113 | __u8 hfc_reg; /* register number */ | 88 | __u8 hfc_reg; /* register number */ |
| 114 | __u8 reg_val; /* value to be written (or read) */ | 89 | __u8 reg_val; /* value to be written (or read) */ |
| 115 | int action; /* data for action handler */ | 90 | int action; /* data for action handler */ |
| 116 | } ctrl_buft; | 91 | } ctrl_buft; |
| 117 | 92 | ||
| 93 | /* Debugging Flags */ | ||
| 94 | #define HFCUSB_DBG_INIT 0x0001 | ||
| 95 | #define HFCUSB_DBG_STATES 0x0002 | ||
| 96 | #define HFCUSB_DBG_DCHANNEL 0x0080 | ||
| 97 | #define HFCUSB_DBG_FIFO_ERR 0x4000 | ||
| 98 | #define HFCUSB_DBG_VERBOSE_USB 0x8000 | ||
| 118 | 99 | ||
| 119 | /********************/ | 100 | /* |
| 120 | /* URB error codes: */ | 101 | * URB error codes: |
| 121 | /********************/ | 102 | * Used to represent a list of values and their respective symbolic names |
| 122 | /* Used to represent a list of values and their respective symbolic names */ | 103 | */ |
| 123 | struct hfcusb_symbolic_list { | 104 | struct hfcusb_symbolic_list { |
| 124 | const int num; | 105 | const int num; |
| 125 | const char *name; | 106 | const char *name; |
| @@ -134,20 +115,20 @@ static struct hfcusb_symbolic_list urb_errlist[] = { | |||
| 134 | {-ENXIO, "URB already queued"}, | 115 | {-ENXIO, "URB already queued"}, |
| 135 | {-EFBIG, "Too much ISO frames requested"}, | 116 | {-EFBIG, "Too much ISO frames requested"}, |
| 136 | {-ENOSR, "Buffer error (overrun)"}, | 117 | {-ENOSR, "Buffer error (overrun)"}, |
| 137 | {-EPIPE, "Specified endpoint is stalled"}, | 118 | {-EPIPE, "Specified endpoint is stalled (device not responding)"}, |
| 138 | {-EOVERFLOW, "Babble (bad cable?)"}, | 119 | {-EOVERFLOW, "Babble (bad cable?)"}, |
| 139 | {-EPROTO, "Bit-stuff error (bad cable?)"}, | 120 | {-EPROTO, "Bit-stuff error (bad cable?)"}, |
| 140 | {-EILSEQ, "CRC or missing token"}, | 121 | {-EILSEQ, "CRC/Timeout"}, |
| 141 | {-ETIME, "Device did not respond"}, | 122 | {-ETIMEDOUT, "NAK (device does not respond)"}, |
| 142 | {-ESHUTDOWN, "Device unplugged"}, | 123 | {-ESHUTDOWN, "Device unplugged"}, |
| 143 | {-1, NULL} | 124 | {-1, NULL} |
| 144 | }; | 125 | }; |
| 145 | 126 | ||
| 146 | 127 | ||
| 147 | /*****************************************************/ | 128 | /* |
| 148 | /* device dependant information to support different */ | 129 | * device dependant information to support different |
| 149 | /* ISDN Ta's using the HFC-S USB chip */ | 130 | * ISDN Ta's using the HFC-S USB chip |
| 150 | /*****************************************************/ | 131 | */ |
| 151 | 132 | ||
| 152 | /* USB descriptor need to contain one of the following EndPoint combination: */ | 133 | /* USB descriptor need to contain one of the following EndPoint combination: */ |
| 153 | #define CNF_4INT3ISO 1 // 4 INT IN, 3 ISO OUT | 134 | #define CNF_4INT3ISO 1 // 4 INT IN, 3 ISO OUT |
| @@ -155,16 +136,19 @@ static struct hfcusb_symbolic_list urb_errlist[] = { | |||
| 155 | #define CNF_4ISO3ISO 3 // 4 ISO IN, 3 ISO OUT | 136 | #define CNF_4ISO3ISO 3 // 4 ISO IN, 3 ISO OUT |
| 156 | #define CNF_3ISO3ISO 4 // 3 ISO IN, 3 ISO OUT | 137 | #define CNF_3ISO3ISO 4 // 3 ISO IN, 3 ISO OUT |
| 157 | 138 | ||
| 158 | #define EP_NUL 1 // Endpoint at this position not allowed | 139 | #define EP_NUL 1 // Endpoint at this position not allowed |
| 159 | #define EP_NOP 2 // all type of endpoints allowed at this position | 140 | #define EP_NOP 2 // all type of endpoints allowed at this position |
| 160 | #define EP_ISO 3 // Isochron endpoint mandatory at this position | 141 | #define EP_ISO 3 // Isochron endpoint mandatory at this position |
| 161 | #define EP_BLK 4 // Bulk endpoint mandatory at this position | 142 | #define EP_BLK 4 // Bulk endpoint mandatory at this position |
| 162 | #define EP_INT 5 // Interrupt endpoint mandatory at this position | 143 | #define EP_INT 5 // Interrupt endpoint mandatory at this position |
| 163 | 144 | ||
| 164 | /* this array represents all endpoints possible in the HCF-USB the last | 145 | /* |
| 165 | * 3 entries are the configuration number, the minimum interval for | 146 | * List of all supported endpoint configuration sets, used to find the |
| 166 | * Interrupt endpoints & boolean if E-channel logging possible | 147 | * best matching endpoint configuration within a devices' USB descriptor. |
| 167 | */ | 148 | * We need at least 3 RX endpoints, and 3 TX endpoints, either |
| 149 | * INT-in and ISO-out, or ISO-in and ISO-out) | ||
| 150 | * with 4 RX endpoints even E-Channel logging is possible | ||
| 151 | */ | ||
| 168 | static int validconf[][19] = { | 152 | static int validconf[][19] = { |
| 169 | // INT in, ISO out config | 153 | // INT in, ISO out config |
| 170 | {EP_NUL, EP_INT, EP_NUL, EP_INT, EP_NUL, EP_INT, EP_NOP, EP_INT, | 154 | {EP_NUL, EP_INT, EP_NUL, EP_INT, EP_NUL, EP_INT, EP_NOP, EP_INT, |
| @@ -193,7 +177,6 @@ static char *conf_str[] = { | |||
| 193 | }; | 177 | }; |
| 194 | #endif | 178 | #endif |
| 195 | 179 | ||
| 196 | |||
| 197 | typedef struct { | 180 | typedef struct { |
| 198 | int vendor; // vendor id | 181 | int vendor; // vendor id |
| 199 | int prod_id; // product id | 182 | int prod_id; // product id |
| @@ -202,9 +185,9 @@ typedef struct { | |||
| 202 | signed short led_bits[8]; // array of 8 possible LED bitmask settings | 185 | signed short led_bits[8]; // array of 8 possible LED bitmask settings |
| 203 | } vendor_data; | 186 | } vendor_data; |
| 204 | 187 | ||
| 205 | #define LED_OFF 0 // no LED support | 188 | #define LED_OFF 0 // no LED support |
| 206 | #define LED_SCHEME1 1 // LED standard scheme | 189 | #define LED_SCHEME1 1 // LED standard scheme |
| 207 | #define LED_SCHEME2 2 // not used yet... | 190 | #define LED_SCHEME2 2 // not used yet... |
| 208 | 191 | ||
| 209 | #define LED_POWER_ON 1 | 192 | #define LED_POWER_ON 1 |
| 210 | #define LED_POWER_OFF 2 | 193 | #define LED_POWER_OFF 2 |
| @@ -217,11 +200,8 @@ typedef struct { | |||
| 217 | #define LED_B2_OFF 9 | 200 | #define LED_B2_OFF 9 |
| 218 | #define LED_B2_DATA 10 | 201 | #define LED_B2_DATA 10 |
| 219 | 202 | ||
| 220 | #define LED_NORMAL 0 // LEDs are normal | 203 | #define LED_NORMAL 0 // LEDs are normal |
| 221 | #define LED_INVERTED 1 // LEDs are inverted | 204 | #define LED_INVERTED 1 // LEDs are inverted |
| 222 | |||
| 223 | /* time in ms to perform a Flashing LED when B-Channel has traffic */ | ||
| 224 | #define LED_TIME 250 | ||
| 225 | 205 | ||
| 226 | 206 | ||
| 227 | #endif // __HFC_USB_H__ | 207 | #endif // __HFC_USB_H__ |
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 @@ | |||
| 1 | config LGUEST | 1 | config LGUEST |
| 2 | tristate "Linux hypervisor example code" | 2 | tristate "Linux hypervisor example code" |
| 3 | depends on X86 && PARAVIRT && EXPERIMENTAL && !X86_PAE | 3 | depends on X86 && PARAVIRT && EXPERIMENTAL && !X86_PAE && FUTEX |
| 4 | select LGUEST_GUEST | 4 | select LGUEST_GUEST |
| 5 | select HVC_DRIVER | 5 | select HVC_DRIVER |
| 6 | ---help--- | 6 | ---help--- |
diff --git a/drivers/macintosh/mac_hid.c b/drivers/macintosh/mac_hid.c index 76c1e8e4a487..33dee3a773ed 100644 --- a/drivers/macintosh/mac_hid.c +++ b/drivers/macintosh/mac_hid.c | |||
| @@ -13,6 +13,7 @@ | |||
| 13 | #include <linux/sysctl.h> | 13 | #include <linux/sysctl.h> |
| 14 | #include <linux/input.h> | 14 | #include <linux/input.h> |
| 15 | #include <linux/module.h> | 15 | #include <linux/module.h> |
| 16 | #include <linux/kbd_kern.h> | ||
| 16 | 17 | ||
| 17 | 18 | ||
| 18 | static struct input_dev *emumousebtn; | 19 | static struct input_dev *emumousebtn; |
diff --git a/drivers/macintosh/via-pmu68k.c b/drivers/macintosh/via-pmu68k.c index dfdf11c1eec4..e2f84da09e7c 100644 --- a/drivers/macintosh/via-pmu68k.c +++ b/drivers/macintosh/via-pmu68k.c | |||
| @@ -818,243 +818,3 @@ pmu_present(void) | |||
| 818 | { | 818 | { |
| 819 | return (pmu_kind != PMU_UNKNOWN); | 819 | return (pmu_kind != PMU_UNKNOWN); |
| 820 | } | 820 | } |
| 821 | |||
| 822 | #if 0 /* needs some work for 68K */ | ||
| 823 | |||
| 824 | /* | ||
| 825 | * This struct is used to store config register values for | ||
| 826 | * PCI devices which may get powered off when we sleep. | ||
| 827 | */ | ||
| 828 | static struct pci_save { | ||
| 829 | u16 command; | ||
| 830 | u16 cache_lat; | ||
| 831 | u16 intr; | ||
| 832 | } *pbook_pci_saves; | ||
| 833 | static int n_pbook_pci_saves; | ||
| 834 | |||
| 835 | static inline void | ||
| 836 | pbook_pci_save(void) | ||
| 837 | { | ||
| 838 | int npci; | ||
| 839 | struct pci_dev *pd = NULL; | ||
| 840 | struct pci_save *ps; | ||
| 841 | |||
| 842 | npci = 0; | ||
| 843 | while ((pd = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pd)) != NULL) | ||
| 844 | ++npci; | ||
| 845 | n_pbook_pci_saves = npci; | ||
| 846 | if (npci == 0) | ||
| 847 | return; | ||
| 848 | ps = kmalloc(npci * sizeof(*ps), GFP_KERNEL); | ||
| 849 | pbook_pci_saves = ps; | ||
| 850 | if (ps == NULL) | ||
| 851 | return; | ||
| 852 | |||
| 853 | pd = NULL; | ||
| 854 | while ((pd = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pd)) != NULL) { | ||
| 855 | pci_read_config_word(pd, PCI_COMMAND, &ps->command); | ||
| 856 | pci_read_config_word(pd, PCI_CACHE_LINE_SIZE, &ps->cache_lat); | ||
| 857 | pci_read_config_word(pd, PCI_INTERRUPT_LINE, &ps->intr); | ||
| 858 | ++ps; | ||
| 859 | --npci; | ||
| 860 | } | ||
| 861 | } | ||
| 862 | |||
| 863 | static inline void | ||
| 864 | pbook_pci_restore(void) | ||
| 865 | { | ||
| 866 | u16 cmd; | ||
| 867 | struct pci_save *ps = pbook_pci_saves; | ||
| 868 | struct pci_dev *pd = NULL; | ||
| 869 | int j; | ||
| 870 | |||
| 871 | while ((pd = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pd)) != NULL) { | ||
| 872 | if (ps->command == 0) | ||
| 873 | continue; | ||
| 874 | pci_read_config_word(pd, PCI_COMMAND, &cmd); | ||
| 875 | if ((ps->command & ~cmd) == 0) | ||
| 876 | continue; | ||
| 877 | switch (pd->hdr_type) { | ||
| 878 | case PCI_HEADER_TYPE_NORMAL: | ||
| 879 | for (j = 0; j < 6; ++j) | ||
| 880 | pci_write_config_dword(pd, | ||
| 881 | PCI_BASE_ADDRESS_0 + j*4, | ||
| 882 | pd->resource[j].start); | ||
| 883 | pci_write_config_dword(pd, PCI_ROM_ADDRESS, | ||
| 884 | pd->resource[PCI_ROM_RESOURCE].start); | ||
| 885 | pci_write_config_word(pd, PCI_CACHE_LINE_SIZE, | ||
| 886 | ps->cache_lat); | ||
| 887 | pci_write_config_word(pd, PCI_INTERRUPT_LINE, | ||
| 888 | ps->intr); | ||
| 889 | pci_write_config_word(pd, PCI_COMMAND, ps->command); | ||
| 890 | break; | ||
| 891 | /* other header types not restored at present */ | ||
| 892 | } | ||
| 893 | } | ||
| 894 | } | ||
| 895 | |||
| 896 | /* | ||
| 897 | * Put the powerbook to sleep. | ||
| 898 | */ | ||
| 899 | #define IRQ_ENABLE ((unsigned int *)0xf3000024) | ||
| 900 | #define MEM_CTRL ((unsigned int *)0xf8000070) | ||
| 901 | |||
| 902 | int powerbook_sleep(void) | ||
| 903 | { | ||
| 904 | int ret, i, x; | ||
| 905 | static int save_backlight; | ||
| 906 | static unsigned int save_irqen; | ||
| 907 | unsigned long msr; | ||
| 908 | unsigned int hid0; | ||
| 909 | unsigned long p, wait; | ||
| 910 | struct adb_request sleep_req; | ||
| 911 | |||
| 912 | /* Notify device drivers */ | ||
| 913 | ret = blocking_notifier_call_chain(&sleep_notifier_list, | ||
| 914 | PBOOK_SLEEP, NULL); | ||
| 915 | if (ret & NOTIFY_STOP_MASK) | ||
| 916 | return -EBUSY; | ||
| 917 | |||
| 918 | /* Sync the disks. */ | ||
| 919 | /* XXX It would be nice to have some way to ensure that | ||
| 920 | * nobody is dirtying any new buffers while we wait. */ | ||
| 921 | sys_sync(); | ||
| 922 | |||
| 923 | /* Turn off the display backlight */ | ||
| 924 | save_backlight = backlight_enabled; | ||
| 925 | if (save_backlight) | ||
| 926 | pmu_enable_backlight(0); | ||
| 927 | |||
| 928 | /* Give the disks a little time to actually finish writing */ | ||
| 929 | for (wait = jiffies + (HZ/4); time_before(jiffies, wait); ) | ||
| 930 | mb(); | ||
| 931 | |||
| 932 | /* Disable all interrupts except pmu */ | ||
| 933 | save_irqen = in_le32(IRQ_ENABLE); | ||
| 934 | for (i = 0; i < 32; ++i) | ||
| 935 | if (i != vias->intrs[0].line && (save_irqen & (1 << i))) | ||
| 936 | disable_irq(i); | ||
| 937 | asm volatile("mtdec %0" : : "r" (0x7fffffff)); | ||
| 938 | |||
| 939 | /* Save the state of PCI config space for some slots */ | ||
| 940 | pbook_pci_save(); | ||
| 941 | |||
| 942 | /* Set the memory controller to keep the memory refreshed | ||
| 943 | while we're asleep */ | ||
| 944 | for (i = 0x403f; i >= 0x4000; --i) { | ||
| 945 | out_be32(MEM_CTRL, i); | ||
| 946 | do { | ||
| 947 | x = (in_be32(MEM_CTRL) >> 16) & 0x3ff; | ||
| 948 | } while (x == 0); | ||
| 949 | if (x >= 0x100) | ||
| 950 | break; | ||
| 951 | } | ||
| 952 | |||
| 953 | /* Ask the PMU to put us to sleep */ | ||
| 954 | pmu_request(&sleep_req, NULL, 5, PMU_SLEEP, 'M', 'A', 'T', 'T'); | ||
| 955 | while (!sleep_req.complete) | ||
| 956 | mb(); | ||
| 957 | /* displacement-flush the L2 cache - necessary? */ | ||
| 958 | for (p = KERNELBASE; p < KERNELBASE + 0x100000; p += 0x1000) | ||
| 959 | i = *(volatile int *)p; | ||
| 960 | asleep = 1; | ||
| 961 | |||
| 962 | /* Put the CPU into sleep mode */ | ||
| 963 | asm volatile("mfspr %0,1008" : "=r" (hid0) :); | ||
| 964 | hid0 = (hid0 & ~(HID0_NAP | HID0_DOZE)) | HID0_SLEEP; | ||
| 965 | asm volatile("mtspr 1008,%0" : : "r" (hid0)); | ||
| 966 | local_save_flags(msr); | ||
| 967 | msr |= MSR_POW | MSR_EE; | ||
| 968 | local_irq_restore(msr); | ||
| 969 | udelay(10); | ||
| 970 | |||
| 971 | /* OK, we're awake again, start restoring things */ | ||
| 972 | out_be32(MEM_CTRL, 0x3f); | ||
| 973 | pbook_pci_restore(); | ||
| 974 | |||
| 975 | /* wait for the PMU interrupt sequence to complete */ | ||
| 976 | while (asleep) | ||
| 977 | mb(); | ||
| 978 | |||
| 979 | /* reenable interrupts */ | ||
| 980 | for (i = 0; i < 32; ++i) | ||
| 981 | if (i != vias->intrs[0].line && (save_irqen & (1 << i))) | ||
| 982 | enable_irq(i); | ||
| 983 | |||
| 984 | /* Notify drivers */ | ||
| 985 | blocking_notifier_call_chain(&sleep_notifier_list, PBOOK_WAKE, NULL); | ||
| 986 | |||
| 987 | /* reenable ADB autopoll */ | ||
| 988 | pmu_adb_autopoll(adb_dev_map); | ||
| 989 | |||
| 990 | /* Turn on the screen backlight, if it was on before */ | ||
| 991 | if (save_backlight) | ||
| 992 | pmu_enable_backlight(1); | ||
| 993 | |||
| 994 | /* Wait for the hard disk to spin up */ | ||
| 995 | |||
| 996 | return 0; | ||
| 997 | } | ||
| 998 | |||
| 999 | /* | ||
| 1000 | * Support for /dev/pmu device | ||
| 1001 | */ | ||
| 1002 | static int pmu_open(struct inode *inode, struct file *file) | ||
| 1003 | { | ||
| 1004 | return 0; | ||
| 1005 | } | ||
| 1006 | |||
| 1007 | static ssize_t pmu_read(struct file *file, char *buf, | ||
| 1008 | size_t count, loff_t *ppos) | ||
| 1009 | { | ||
| 1010 | return 0; | ||
| 1011 | } | ||
| 1012 | |||
| 1013 | static ssize_t pmu_write(struct file *file, const char *buf, | ||
| 1014 | size_t count, loff_t *ppos) | ||
| 1015 | { | ||
| 1016 | return 0; | ||
| 1017 | } | ||
| 1018 | |||
| 1019 | static int pmu_ioctl(struct inode * inode, struct file *filp, | ||
| 1020 | u_int cmd, u_long arg) | ||
| 1021 | { | ||
| 1022 | int error; | ||
| 1023 | __u32 value; | ||
| 1024 | |||
| 1025 | switch (cmd) { | ||
| 1026 | case PMU_IOC_SLEEP: | ||
| 1027 | return -ENOSYS; | ||
| 1028 | case PMU_IOC_GET_BACKLIGHT: | ||
| 1029 | return put_user(backlight_level, (__u32 *)arg); | ||
| 1030 | case PMU_IOC_SET_BACKLIGHT: | ||
| 1031 | error = get_user(value, (__u32 *)arg); | ||
| 1032 | if (!error) | ||
| 1033 | pmu_set_brightness(value); | ||
| 1034 | return error; | ||
| 1035 | case PMU_IOC_GET_MODEL: | ||
| 1036 | return put_user(pmu_kind, (__u32 *)arg); | ||
| 1037 | } | ||
| 1038 | return -EINVAL; | ||
| 1039 | } | ||
| 1040 | |||
| 1041 | static const struct file_operations pmu_device_fops = { | ||
| 1042 | .read = pmu_read, | ||
| 1043 | .write = pmu_write, | ||
| 1044 | .ioctl = pmu_ioctl, | ||
| 1045 | .open = pmu_open, | ||
| 1046 | }; | ||
| 1047 | |||
| 1048 | static struct miscdevice pmu_device = { | ||
| 1049 | PMU_MINOR, "pmu", &pmu_device_fops | ||
| 1050 | }; | ||
| 1051 | |||
| 1052 | void pmu_device_init(void) | ||
| 1053 | { | ||
| 1054 | if (!via) | ||
| 1055 | return; | ||
| 1056 | if (misc_register(&pmu_device) < 0) | ||
| 1057 | printk(KERN_ERR "via-pmu68k: cannot register misc device.\n"); | ||
| 1058 | } | ||
| 1059 | #endif /* CONFIG_PMAC_PBOOK */ | ||
| 1060 | |||
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c index 650991bddd8e..f33a729960ca 100644 --- a/drivers/md/raid1.c +++ b/drivers/md/raid1.c | |||
| @@ -1972,7 +1972,8 @@ static int run(mddev_t *mddev) | |||
| 1972 | !test_bit(In_sync, &disk->rdev->flags)) { | 1972 | !test_bit(In_sync, &disk->rdev->flags)) { |
| 1973 | disk->head_position = 0; | 1973 | disk->head_position = 0; |
| 1974 | mddev->degraded++; | 1974 | mddev->degraded++; |
| 1975 | conf->fullsync = 1; | 1975 | if (disk->rdev) |
| 1976 | conf->fullsync = 1; | ||
| 1976 | } | 1977 | } |
| 1977 | } | 1978 | } |
| 1978 | if (mddev->degraded == conf->raid_disks) { | 1979 | if (mddev->degraded == conf->raid_disks) { |
| @@ -2153,11 +2154,25 @@ static int raid1_reshape(mddev_t *mddev) | |||
| 2153 | oldpool = conf->r1bio_pool; | 2154 | oldpool = conf->r1bio_pool; |
| 2154 | conf->r1bio_pool = newpool; | 2155 | conf->r1bio_pool = newpool; |
| 2155 | 2156 | ||
| 2156 | for (d=d2=0; d < conf->raid_disks; d++) | 2157 | for (d = d2 = 0; d < conf->raid_disks; d++) { |
| 2157 | if (conf->mirrors[d].rdev) { | 2158 | mdk_rdev_t *rdev = conf->mirrors[d].rdev; |
| 2158 | conf->mirrors[d].rdev->raid_disk = d2; | 2159 | if (rdev && rdev->raid_disk != d2) { |
| 2159 | newmirrors[d2++].rdev = conf->mirrors[d].rdev; | 2160 | char nm[20]; |
| 2161 | sprintf(nm, "rd%d", rdev->raid_disk); | ||
| 2162 | sysfs_remove_link(&mddev->kobj, nm); | ||
| 2163 | rdev->raid_disk = d2; | ||
| 2164 | sprintf(nm, "rd%d", rdev->raid_disk); | ||
| 2165 | sysfs_remove_link(&mddev->kobj, nm); | ||
| 2166 | if (sysfs_create_link(&mddev->kobj, | ||
| 2167 | &rdev->kobj, nm)) | ||
| 2168 | printk(KERN_WARNING | ||
| 2169 | "md/raid1: cannot register " | ||
| 2170 | "%s for %s\n", | ||
| 2171 | nm, mdname(mddev)); | ||
| 2160 | } | 2172 | } |
| 2173 | if (rdev) | ||
| 2174 | newmirrors[d2++].rdev = rdev; | ||
| 2175 | } | ||
| 2161 | kfree(conf->mirrors); | 2176 | kfree(conf->mirrors); |
| 2162 | conf->mirrors = newmirrors; | 2177 | conf->mirrors = newmirrors; |
| 2163 | kfree(conf->poolinfo); | 2178 | kfree(conf->poolinfo); |
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, | |||
| 1772 | if (dev->alt_max_pkt_size == NULL) { | 1772 | if (dev->alt_max_pkt_size == NULL) { |
| 1773 | em28xx_errdev("out of memory!\n"); | 1773 | em28xx_errdev("out of memory!\n"); |
| 1774 | em28xx_devused&=~(1<<nr); | 1774 | em28xx_devused&=~(1<<nr); |
| 1775 | kfree(dev); | ||
| 1775 | return -ENOMEM; | 1776 | return -ENOMEM; |
| 1776 | } | 1777 | } |
| 1777 | 1778 | ||
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) | |||
| 1196 | return 0; | 1196 | return 0; |
| 1197 | } | 1197 | } |
| 1198 | 1198 | ||
| 1199 | |||
| 1200 | static void pwc_cleanup(struct pwc_device *pdev) | ||
| 1201 | { | ||
| 1202 | pwc_remove_sysfs_files(pdev->vdev); | ||
| 1203 | video_unregister_device(pdev->vdev); | ||
| 1204 | } | ||
| 1205 | |||
| 1199 | /* Note that all cleanup is done in the reverse order as in _open */ | 1206 | /* Note that all cleanup is done in the reverse order as in _open */ |
| 1200 | static int pwc_video_close(struct inode *inode, struct file *file) | 1207 | static int pwc_video_close(struct inode *inode, struct file *file) |
| 1201 | { | 1208 | { |
| 1202 | struct video_device *vdev = file->private_data; | 1209 | struct video_device *vdev = file->private_data; |
| 1203 | struct pwc_device *pdev; | 1210 | struct pwc_device *pdev; |
| 1204 | int i; | 1211 | int i, hint; |
| 1205 | 1212 | ||
| 1206 | PWC_DEBUG_OPEN(">> video_close called(vdev = 0x%p).\n", vdev); | 1213 | PWC_DEBUG_OPEN(">> video_close called(vdev = 0x%p).\n", vdev); |
| 1207 | 1214 | ||
| @@ -1224,8 +1231,9 @@ static int pwc_video_close(struct inode *inode, struct file *file) | |||
| 1224 | pwc_isoc_cleanup(pdev); | 1231 | pwc_isoc_cleanup(pdev); |
| 1225 | pwc_free_buffers(pdev); | 1232 | pwc_free_buffers(pdev); |
| 1226 | 1233 | ||
| 1234 | lock_kernel(); | ||
| 1227 | /* Turn off LEDS and power down camera, but only when not unplugged */ | 1235 | /* Turn off LEDS and power down camera, but only when not unplugged */ |
| 1228 | if (pdev->error_status != EPIPE) { | 1236 | if (!pdev->unplugged) { |
| 1229 | /* Turn LEDs off */ | 1237 | /* Turn LEDs off */ |
| 1230 | if (pwc_set_leds(pdev, 0, 0) < 0) | 1238 | if (pwc_set_leds(pdev, 0, 0) < 0) |
| 1231 | PWC_DEBUG_MODULE("Failed to set LED on/off time.\n"); | 1239 | 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) | |||
| 1234 | if (i < 0) | 1242 | if (i < 0) |
| 1235 | PWC_ERROR("Failed to power down camera (%d)\n", i); | 1243 | PWC_ERROR("Failed to power down camera (%d)\n", i); |
| 1236 | } | 1244 | } |
| 1245 | pdev->vopen--; | ||
| 1246 | PWC_DEBUG_OPEN("<< video_close() vopen=%d\n", i); | ||
| 1247 | } else { | ||
| 1248 | pwc_cleanup(pdev); | ||
| 1249 | /* Free memory (don't set pdev to 0 just yet) */ | ||
| 1250 | kfree(pdev); | ||
| 1251 | /* search device_hint[] table if we occupy a slot, by any chance */ | ||
| 1252 | for (hint = 0; hint < MAX_DEV_HINTS; hint++) | ||
| 1253 | if (device_hint[hint].pdev == pdev) | ||
| 1254 | device_hint[hint].pdev = NULL; | ||
| 1237 | } | 1255 | } |
| 1238 | pdev->vopen--; | 1256 | unlock_kernel(); |
| 1239 | PWC_DEBUG_OPEN("<< video_close() vopen=%d\n", pdev->vopen); | 1257 | |
| 1240 | return 0; | 1258 | return 0; |
| 1241 | } | 1259 | } |
| 1242 | 1260 | ||
| @@ -1791,21 +1809,21 @@ static void usb_pwc_disconnect(struct usb_interface *intf) | |||
| 1791 | /* Alert waiting processes */ | 1809 | /* Alert waiting processes */ |
| 1792 | wake_up_interruptible(&pdev->frameq); | 1810 | wake_up_interruptible(&pdev->frameq); |
| 1793 | /* Wait until device is closed */ | 1811 | /* Wait until device is closed */ |
| 1794 | while (pdev->vopen) | 1812 | if(pdev->vopen) { |
| 1795 | schedule(); | 1813 | pdev->unplugged = 1; |
| 1796 | /* Device is now closed, so we can safely unregister it */ | 1814 | } else { |
| 1797 | PWC_DEBUG_PROBE("Unregistering video device in disconnect().\n"); | 1815 | /* Device is closed, so we can safely unregister it */ |
| 1798 | pwc_remove_sysfs_files(pdev->vdev); | 1816 | PWC_DEBUG_PROBE("Unregistering video device in disconnect().\n"); |
| 1799 | video_unregister_device(pdev->vdev); | 1817 | pwc_cleanup(pdev); |
| 1800 | 1818 | /* Free memory (don't set pdev to 0 just yet) */ | |
| 1801 | /* Free memory (don't set pdev to 0 just yet) */ | 1819 | kfree(pdev); |
| 1802 | kfree(pdev); | ||
| 1803 | 1820 | ||
| 1804 | disconnect_out: | 1821 | disconnect_out: |
| 1805 | /* search device_hint[] table if we occupy a slot, by any chance */ | 1822 | /* search device_hint[] table if we occupy a slot, by any chance */ |
| 1806 | for (hint = 0; hint < MAX_DEV_HINTS; hint++) | 1823 | for (hint = 0; hint < MAX_DEV_HINTS; hint++) |
| 1807 | if (device_hint[hint].pdev == pdev) | 1824 | if (device_hint[hint].pdev == pdev) |
| 1808 | device_hint[hint].pdev = NULL; | 1825 | device_hint[hint].pdev = NULL; |
| 1826 | } | ||
| 1809 | 1827 | ||
| 1810 | unlock_kernel(); | 1828 | unlock_kernel(); |
| 1811 | } | 1829 | } |
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 | |||
| 193 | char vsnapshot; /* snapshot mode */ | 193 | char vsnapshot; /* snapshot mode */ |
| 194 | char vsync; /* used by isoc handler */ | 194 | char vsync; /* used by isoc handler */ |
| 195 | char vmirror; /* for ToUCaM series */ | 195 | char vmirror; /* for ToUCaM series */ |
| 196 | char unplugged; | ||
| 196 | 197 | ||
| 197 | int cmd_len; | 198 | int cmd_len; |
| 198 | unsigned char cmd_buf[13]; | 199 | unsigned char cmd_buf[13]; |
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) | |||
| 186 | { | 186 | { |
| 187 | struct mmc_card *card; | 187 | struct mmc_card *card; |
| 188 | 188 | ||
| 189 | card = kmalloc(sizeof(struct mmc_card), GFP_KERNEL); | 189 | card = kzalloc(sizeof(struct mmc_card), GFP_KERNEL); |
| 190 | if (!card) | 190 | if (!card) |
| 191 | return ERR_PTR(-ENOMEM); | 191 | return ERR_PTR(-ENOMEM); |
| 192 | 192 | ||
| 193 | memset(card, 0, sizeof(struct mmc_card)); | ||
| 194 | |||
| 195 | card->host = host; | 193 | card->host = host; |
| 196 | 194 | ||
| 197 | device_initialize(&card->dev); | 195 | 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) | |||
| 58 | { | 58 | { |
| 59 | struct mmc_host *host; | 59 | struct mmc_host *host; |
| 60 | 60 | ||
| 61 | host = kmalloc(sizeof(struct mmc_host) + extra, GFP_KERNEL); | 61 | host = kzalloc(sizeof(struct mmc_host) + extra, GFP_KERNEL); |
| 62 | if (!host) | 62 | if (!host) |
| 63 | return NULL; | 63 | return NULL; |
| 64 | 64 | ||
| 65 | memset(host, 0, sizeof(struct mmc_host) + extra); | ||
| 66 | |||
| 67 | host->parent = dev; | 65 | host->parent = dev; |
| 68 | host->class_dev.parent = dev; | 66 | host->class_dev.parent = dev; |
| 69 | host->class_dev.class = &mmc_host_class; | 67 | 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) | |||
| 385 | BUG_ON(data->blksz > host->mmc->max_blk_size); | 385 | BUG_ON(data->blksz > host->mmc->max_blk_size); |
| 386 | BUG_ON(data->blocks > 65535); | 386 | BUG_ON(data->blocks > 65535); |
| 387 | 387 | ||
| 388 | host->data = data; | ||
| 389 | host->data_early = 0; | ||
| 390 | |||
| 388 | /* timeout in us */ | 391 | /* timeout in us */ |
| 389 | target_timeout = data->timeout_ns / 1000 + | 392 | target_timeout = data->timeout_ns / 1000 + |
| 390 | data->timeout_clks / host->clock; | 393 | data->timeout_clks / host->clock; |
| @@ -443,11 +446,11 @@ static void sdhci_set_transfer_mode(struct sdhci_host *host, | |||
| 443 | { | 446 | { |
| 444 | u16 mode; | 447 | u16 mode; |
| 445 | 448 | ||
| 446 | WARN_ON(host->data); | ||
| 447 | |||
| 448 | if (data == NULL) | 449 | if (data == NULL) |
| 449 | return; | 450 | return; |
| 450 | 451 | ||
| 452 | WARN_ON(!host->data); | ||
| 453 | |||
| 451 | mode = SDHCI_TRNS_BLK_CNT_EN; | 454 | mode = SDHCI_TRNS_BLK_CNT_EN; |
| 452 | if (data->blocks > 1) | 455 | if (data->blocks > 1) |
| 453 | mode |= SDHCI_TRNS_MULTI; | 456 | mode |= SDHCI_TRNS_MULTI; |
| @@ -477,8 +480,8 @@ static void sdhci_finish_data(struct sdhci_host *host) | |||
| 477 | /* | 480 | /* |
| 478 | * Controller doesn't count down when in single block mode. | 481 | * Controller doesn't count down when in single block mode. |
| 479 | */ | 482 | */ |
| 480 | if ((data->blocks == 1) && (data->error == MMC_ERR_NONE)) | 483 | if (data->blocks == 1) |
| 481 | blocks = 0; | 484 | blocks = (data->error == MMC_ERR_NONE) ? 0 : 1; |
| 482 | else | 485 | else |
| 483 | blocks = readw(host->ioaddr + SDHCI_BLOCK_COUNT); | 486 | blocks = readw(host->ioaddr + SDHCI_BLOCK_COUNT); |
| 484 | data->bytes_xfered = data->blksz * (data->blocks - blocks); | 487 | data->bytes_xfered = data->blksz * (data->blocks - blocks); |
| @@ -600,9 +603,10 @@ static void sdhci_finish_command(struct sdhci_host *host) | |||
| 600 | 603 | ||
| 601 | host->cmd->error = MMC_ERR_NONE; | 604 | host->cmd->error = MMC_ERR_NONE; |
| 602 | 605 | ||
| 603 | if (host->cmd->data) | 606 | if (host->data && host->data_early) |
| 604 | host->data = host->cmd->data; | 607 | sdhci_finish_data(host); |
| 605 | else | 608 | |
| 609 | if (!host->cmd->data) | ||
| 606 | tasklet_schedule(&host->finish_tasklet); | 610 | tasklet_schedule(&host->finish_tasklet); |
| 607 | 611 | ||
| 608 | host->cmd = NULL; | 612 | host->cmd = NULL; |
| @@ -929,9 +933,9 @@ static void sdhci_cmd_irq(struct sdhci_host *host, u32 intmask) | |||
| 929 | BUG_ON(intmask == 0); | 933 | BUG_ON(intmask == 0); |
| 930 | 934 | ||
| 931 | if (!host->cmd) { | 935 | if (!host->cmd) { |
| 932 | printk(KERN_ERR "%s: Got command interrupt even though no " | 936 | printk(KERN_ERR "%s: Got command interrupt 0x%08x even " |
| 933 | "command operation was in progress.\n", | 937 | "though no command operation was in progress.\n", |
| 934 | mmc_hostname(host->mmc)); | 938 | mmc_hostname(host->mmc), (unsigned)intmask); |
| 935 | sdhci_dumpregs(host); | 939 | sdhci_dumpregs(host); |
| 936 | return; | 940 | return; |
| 937 | } | 941 | } |
| @@ -961,9 +965,9 @@ static void sdhci_data_irq(struct sdhci_host *host, u32 intmask) | |||
| 961 | if (intmask & SDHCI_INT_DATA_END) | 965 | if (intmask & SDHCI_INT_DATA_END) |
| 962 | return; | 966 | return; |
| 963 | 967 | ||
| 964 | printk(KERN_ERR "%s: Got data interrupt even though no " | 968 | printk(KERN_ERR "%s: Got data interrupt 0x%08x even " |
| 965 | "data operation was in progress.\n", | 969 | "though no data operation was in progress.\n", |
| 966 | mmc_hostname(host->mmc)); | 970 | mmc_hostname(host->mmc), (unsigned)intmask); |
| 967 | sdhci_dumpregs(host); | 971 | sdhci_dumpregs(host); |
| 968 | 972 | ||
| 969 | return; | 973 | return; |
| @@ -991,8 +995,18 @@ static void sdhci_data_irq(struct sdhci_host *host, u32 intmask) | |||
| 991 | writel(readl(host->ioaddr + SDHCI_DMA_ADDRESS), | 995 | writel(readl(host->ioaddr + SDHCI_DMA_ADDRESS), |
| 992 | host->ioaddr + SDHCI_DMA_ADDRESS); | 996 | host->ioaddr + SDHCI_DMA_ADDRESS); |
| 993 | 997 | ||
| 994 | if (intmask & SDHCI_INT_DATA_END) | 998 | if (intmask & SDHCI_INT_DATA_END) { |
| 995 | sdhci_finish_data(host); | 999 | if (host->cmd) { |
| 1000 | /* | ||
| 1001 | * Data managed to finish before the | ||
| 1002 | * command completed. Make sure we do | ||
| 1003 | * things in the proper order. | ||
| 1004 | */ | ||
| 1005 | host->data_early = 1; | ||
| 1006 | } else { | ||
| 1007 | sdhci_finish_data(host); | ||
| 1008 | } | ||
| 1009 | } | ||
| 996 | } | 1010 | } |
| 997 | } | 1011 | } |
| 998 | 1012 | ||
| @@ -1347,12 +1361,11 @@ static int __devinit sdhci_probe_slot(struct pci_dev *pdev, int slot) | |||
| 1347 | */ | 1361 | */ |
| 1348 | mmc->max_blk_size = (caps & SDHCI_MAX_BLOCK_MASK) >> SDHCI_MAX_BLOCK_SHIFT; | 1362 | mmc->max_blk_size = (caps & SDHCI_MAX_BLOCK_MASK) >> SDHCI_MAX_BLOCK_SHIFT; |
| 1349 | if (mmc->max_blk_size >= 3) { | 1363 | if (mmc->max_blk_size >= 3) { |
| 1350 | printk(KERN_ERR "%s: Invalid maximum block size.\n", | 1364 | printk(KERN_WARNING "%s: Invalid maximum block size, assuming 512\n", |
| 1351 | host->slot_descr); | 1365 | host->slot_descr); |
| 1352 | ret = -ENODEV; | 1366 | mmc->max_blk_size = 512; |
| 1353 | goto unmap; | 1367 | } else |
| 1354 | } | 1368 | mmc->max_blk_size = 512 << mmc->max_blk_size; |
| 1355 | mmc->max_blk_size = 512 << mmc->max_blk_size; | ||
| 1356 | 1369 | ||
| 1357 | /* | 1370 | /* |
| 1358 | * Maximum block count. | 1371 | * 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 { | |||
| 182 | struct mmc_request *mrq; /* Current request */ | 182 | struct mmc_request *mrq; /* Current request */ |
| 183 | struct mmc_command *cmd; /* Current command */ | 183 | struct mmc_command *cmd; /* Current command */ |
| 184 | struct mmc_data *data; /* Current data request */ | 184 | struct mmc_data *data; /* Current data request */ |
| 185 | int data_early:1; /* Data finished before cmd */ | ||
| 185 | 186 | ||
| 186 | struct scatterlist *cur_sg; /* We're working on this */ | 187 | struct scatterlist *cur_sg; /* We're working on this */ |
| 187 | int num_sg; /* Entries left */ | 188 | int num_sg; /* Entries left */ |
diff --git a/drivers/net/ppp_generic.c b/drivers/net/ppp_generic.c index ef3325b69233..9293c82ef2af 100644 --- a/drivers/net/ppp_generic.c +++ b/drivers/net/ppp_generic.c | |||
| @@ -1726,7 +1726,7 @@ ppp_decompress_frame(struct ppp *ppp, struct sk_buff *skb) | |||
| 1726 | } | 1726 | } |
| 1727 | /* the decompressor still expects the A/C bytes in the hdr */ | 1727 | /* the decompressor still expects the A/C bytes in the hdr */ |
| 1728 | len = ppp->rcomp->decompress(ppp->rc_state, skb->data - 2, | 1728 | len = ppp->rcomp->decompress(ppp->rc_state, skb->data - 2, |
| 1729 | skb->len + 2, ns->data, ppp->mru + PPP_HDRLEN); | 1729 | skb->len + 2, ns->data, obuff_size); |
| 1730 | if (len < 0) { | 1730 | if (len < 0) { |
| 1731 | /* Pass the compressed frame to pppd as an | 1731 | /* Pass the compressed frame to pppd as an |
| 1732 | error indication. */ | 1732 | error indication. */ |
diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c index e7a2eadcc3b0..757592436390 100644 --- a/drivers/net/sky2.c +++ b/drivers/net/sky2.c | |||
| @@ -696,8 +696,8 @@ static void sky2_mac_init(struct sky2_hw *hw, unsigned port) | |||
| 696 | int i; | 696 | int i; |
| 697 | const u8 *addr = hw->dev[port]->dev_addr; | 697 | const u8 *addr = hw->dev[port]->dev_addr; |
| 698 | 698 | ||
| 699 | sky2_write32(hw, SK_REG(port, GPHY_CTRL), GPC_RST_SET); | 699 | sky2_write8(hw, SK_REG(port, GPHY_CTRL), GPC_RST_SET); |
| 700 | sky2_write32(hw, SK_REG(port, GPHY_CTRL), GPC_RST_CLR); | 700 | sky2_write8(hw, SK_REG(port, GPHY_CTRL), GPC_RST_CLR); |
| 701 | 701 | ||
| 702 | sky2_write8(hw, SK_REG(port, GMAC_CTRL), GMC_RST_CLR); | 702 | sky2_write8(hw, SK_REG(port, GMAC_CTRL), GMC_RST_CLR); |
| 703 | 703 | ||
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) | |||
| 1746 | static int event_thread(void* data) | 1746 | static int event_thread(void* data) |
| 1747 | { | 1747 | { |
| 1748 | struct controller *ctrl; | 1748 | struct controller *ctrl; |
| 1749 | lock_kernel(); | 1749 | |
| 1750 | daemonize("phpd_event"); | 1750 | daemonize("phpd_event"); |
| 1751 | |||
| 1752 | unlock_kernel(); | ||
| 1753 | 1751 | ||
| 1754 | while (1) { | 1752 | while (1) { |
| 1755 | dbg("!!!!event_thread sleeping\n"); | 1753 | 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, | |||
| 5 | extern int pci_create_sysfs_dev_files(struct pci_dev *pdev); | 5 | extern int pci_create_sysfs_dev_files(struct pci_dev *pdev); |
| 6 | extern void pci_remove_sysfs_dev_files(struct pci_dev *pdev); | 6 | extern void pci_remove_sysfs_dev_files(struct pci_dev *pdev); |
| 7 | extern void pci_cleanup_rom(struct pci_dev *dev); | 7 | extern void pci_cleanup_rom(struct pci_dev *dev); |
| 8 | extern int pci_bus_alloc_resource(struct pci_bus *bus, struct resource *res, | 8 | |
| 9 | resource_size_t size, resource_size_t align, | ||
| 10 | resource_size_t min, unsigned int type_mask, | ||
| 11 | void (*alignf)(void *, struct resource *, | ||
| 12 | resource_size_t, resource_size_t), | ||
| 13 | void *alignf_data); | ||
| 14 | /* Firmware callbacks */ | 9 | /* Firmware callbacks */ |
| 15 | extern pci_power_t (*platform_pci_choose_state)(struct pci_dev *dev, pm_message_t state); | 10 | extern pci_power_t (*platform_pci_choose_state)(struct pci_dev *dev, pm_message_t state); |
| 16 | extern int (*platform_pci_set_power_state)(struct pci_dev *dev, pci_power_t state); | 11 | 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; } | |||
| 35 | 30 | ||
| 36 | /* Functions for PCI Hotplug drivers to use */ | 31 | /* Functions for PCI Hotplug drivers to use */ |
| 37 | extern unsigned int pci_do_scan_bus(struct pci_bus *bus); | 32 | extern unsigned int pci_do_scan_bus(struct pci_bus *bus); |
| 38 | extern int pci_bus_find_capability (struct pci_bus *bus, unsigned int devfn, int cap); | ||
| 39 | 33 | ||
| 40 | extern void pci_remove_legacy_files(struct pci_bus *bus); | 34 | extern void pci_remove_legacy_files(struct pci_bus *bus); |
| 41 | 35 | ||
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 | |||
| 653 | 653 | ||
| 654 | sprintf(child->name, (is_cardbus ? "PCI CardBus #%02x" : "PCI Bus #%02x"), child->number); | 654 | sprintf(child->name, (is_cardbus ? "PCI CardBus #%02x" : "PCI Bus #%02x"), child->number); |
| 655 | 655 | ||
| 656 | /* Has only triggered on CardBus, fixup is in yenta_socket */ | ||
| 656 | while (bus->parent) { | 657 | while (bus->parent) { |
| 657 | if ((child->subordinate > bus->subordinate) || | 658 | if ((child->subordinate > bus->subordinate) || |
| 658 | (child->number > bus->subordinate) || | 659 | (child->number > bus->subordinate) || |
| 659 | (child->number < bus->number) || | 660 | (child->number < bus->number) || |
| 660 | (child->subordinate < bus->number)) { | 661 | (child->subordinate < bus->number)) { |
| 661 | printk(KERN_WARNING "PCI: Bus #%02x (-#%02x) is " | 662 | pr_debug("PCI: Bus #%02x (-#%02x) is %s" |
| 662 | "hidden behind%s bridge #%02x (-#%02x)%s\n", | 663 | "hidden behind%s bridge #%02x (-#%02x)\n", |
| 663 | child->number, child->subordinate, | 664 | child->number, child->subordinate, |
| 664 | bus->self->transparent ? " transparent" : " ", | 665 | (bus->number > child->subordinate && |
| 665 | bus->number, bus->subordinate, | 666 | bus->subordinate < child->number) ? |
| 666 | pcibios_assign_all_busses() ? " " : | 667 | "wholly " : " partially", |
| 667 | " (try 'pci=assign-busses')"); | 668 | bus->self->transparent ? " transparent" : " ", |
| 668 | printk(KERN_WARNING "Please report the result to " | 669 | bus->number, bus->subordinate); |
| 669 | "<bk@suse.de> to fix this permanently\n"); | ||
| 670 | } | 670 | } |
| 671 | bus = bus->parent; | 671 | bus = bus->parent; |
| 672 | } | 672 | } |
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) | |||
| 947 | unsigned char val; | 947 | unsigned char val; |
| 948 | 948 | ||
| 949 | pci_read_config_byte(dev, 0x50, &val); | 949 | pci_read_config_byte(dev, 0x50, &val); |
| 950 | if (val == 0x88 || val == 0xc8) { | 950 | if (val == 0xc8) { |
| 951 | /* Assume it's probably a MSI-K8T-Neo2Fir */ | 951 | /* Assume it's probably a MSI-K8T-Neo2Fir */ |
| 952 | printk(KERN_INFO "PCI: MSI-K8T-Neo2Fir, attempting to turn soundcard ON\n"); | 952 | printk(KERN_INFO "PCI: MSI-K8T-Neo2Fir, attempting to turn soundcard ON\n"); |
| 953 | pci_write_config_byte(dev, 0x50, val & (~0x40)); | 953 | pci_write_config_byte(dev, 0x50, val & (~0x40)); |
| @@ -1485,7 +1485,7 @@ static void __devinit quirk_e100_interrupt(struct pci_dev *dev) | |||
| 1485 | 1485 | ||
| 1486 | iounmap(csr); | 1486 | iounmap(csr); |
| 1487 | } | 1487 | } |
| 1488 | DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, PCI_ANY_ID, quirk_e100_interrupt); | 1488 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_ANY_ID, quirk_e100_interrupt); |
| 1489 | 1489 | ||
| 1490 | static void __devinit fixup_rev1_53c810(struct pci_dev* dev) | 1490 | static void __devinit fixup_rev1_53c810(struct pci_dev* dev) |
| 1491 | { | 1491 | { |
| @@ -1650,6 +1650,9 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_GCN | |||
| 1650 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_HT1000_PCIX, quirk_disable_all_msi); | 1650 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_HT1000_PCIX, quirk_disable_all_msi); |
| 1651 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RS400_200, quirk_disable_all_msi); | 1651 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RS400_200, quirk_disable_all_msi); |
| 1652 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RS480, quirk_disable_all_msi); | 1652 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RS480, quirk_disable_all_msi); |
| 1653 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RD580, quirk_disable_all_msi); | ||
| 1654 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RX790, quirk_disable_all_msi); | ||
| 1655 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RS690, quirk_disable_all_msi); | ||
| 1653 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_VT3351, quirk_disable_all_msi); | 1656 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_VT3351, quirk_disable_all_msi); |
| 1654 | 1657 | ||
| 1655 | /* Disable MSI on chipsets that are known to not support it */ | 1658 | /* Disable MSI on chipsets that are known to not support it */ |
diff --git a/drivers/rtc/rtc-m41t80.c b/drivers/rtc/rtc-m41t80.c index 80c4a8463065..1cb33cac1237 100644 --- a/drivers/rtc/rtc-m41t80.c +++ b/drivers/rtc/rtc-m41t80.c | |||
| @@ -892,7 +892,7 @@ static int m41t80_remove(struct i2c_client *client) | |||
| 892 | 892 | ||
| 893 | static struct i2c_driver m41t80_driver = { | 893 | static struct i2c_driver m41t80_driver = { |
| 894 | .driver = { | 894 | .driver = { |
| 895 | .name = "m41t80", | 895 | .name = "rtc-m41t80", |
| 896 | }, | 896 | }, |
| 897 | .probe = m41t80_probe, | 897 | .probe = m41t80_probe, |
| 898 | .remove = m41t80_remove, | 898 | .remove = m41t80_remove, |
diff --git a/drivers/rtc/rtc-max6902.c b/drivers/rtc/rtc-max6902.c index d94170728075..3e183cfee10f 100644 --- a/drivers/rtc/rtc-max6902.c +++ b/drivers/rtc/rtc-max6902.c | |||
| @@ -13,7 +13,7 @@ | |||
| 13 | * | 13 | * |
| 14 | * 24-May-2006: Raphael Assenat <raph@8d.com> | 14 | * 24-May-2006: Raphael Assenat <raph@8d.com> |
| 15 | * - Major rework | 15 | * - Major rework |
| 16 | * Converted to rtc_device and uses the SPI layer. | 16 | * Converted to rtc_device and uses the SPI layer. |
| 17 | * | 17 | * |
| 18 | * ??-???-2005: Someone at Compulab | 18 | * ??-???-2005: Someone at Compulab |
| 19 | * - Initial driver creation. | 19 | * - Initial driver creation. |
| @@ -259,11 +259,11 @@ static int __devexit max6902_remove(struct spi_device *spi) | |||
| 259 | 259 | ||
| 260 | static struct spi_driver max6902_driver = { | 260 | static struct spi_driver max6902_driver = { |
| 261 | .driver = { | 261 | .driver = { |
| 262 | .name = "max6902", | 262 | .name = "rtc-max6902", |
| 263 | .bus = &spi_bus_type, | 263 | .bus = &spi_bus_type, |
| 264 | .owner = THIS_MODULE, | 264 | .owner = THIS_MODULE, |
| 265 | }, | 265 | }, |
| 266 | .probe = max6902_probe, | 266 | .probe = max6902_probe, |
| 267 | .remove = __devexit_p(max6902_remove), | 267 | .remove = __devexit_p(max6902_remove), |
| 268 | }; | 268 | }; |
| 269 | 269 | ||
diff --git a/drivers/s390/block/dasd_diag.c b/drivers/s390/block/dasd_diag.c index eccac1c3b71b..d32c60dbdd82 100644 --- a/drivers/s390/block/dasd_diag.c +++ b/drivers/s390/block/dasd_diag.c | |||
| @@ -24,6 +24,7 @@ | |||
| 24 | #include <asm/s390_ext.h> | 24 | #include <asm/s390_ext.h> |
| 25 | #include <asm/todclk.h> | 25 | #include <asm/todclk.h> |
| 26 | #include <asm/vtoc.h> | 26 | #include <asm/vtoc.h> |
| 27 | #include <asm/diag.h> | ||
| 27 | 28 | ||
| 28 | #include "dasd_int.h" | 29 | #include "dasd_int.h" |
| 29 | #include "dasd_diag.h" | 30 | #include "dasd_diag.h" |
diff --git a/drivers/s390/char/raw3270.c b/drivers/s390/char/raw3270.c index 4f2f81b16cfa..2edd5fb6d3dc 100644 --- a/drivers/s390/char/raw3270.c +++ b/drivers/s390/char/raw3270.c | |||
| @@ -21,6 +21,7 @@ | |||
| 21 | #include <asm/ccwdev.h> | 21 | #include <asm/ccwdev.h> |
| 22 | #include <asm/cio.h> | 22 | #include <asm/cio.h> |
| 23 | #include <asm/ebcdic.h> | 23 | #include <asm/ebcdic.h> |
| 24 | #include <asm/diag.h> | ||
| 24 | 25 | ||
| 25 | #include "raw3270.h" | 26 | #include "raw3270.h" |
| 26 | 27 | ||
diff --git a/drivers/s390/char/vmur.c b/drivers/s390/char/vmur.c index 04b19bdc09da..d70a6e65bf14 100644 --- a/drivers/s390/char/vmur.c +++ b/drivers/s390/char/vmur.c | |||
| @@ -14,6 +14,7 @@ | |||
| 14 | #include <asm/cio.h> | 14 | #include <asm/cio.h> |
| 15 | #include <asm/ccwdev.h> | 15 | #include <asm/ccwdev.h> |
| 16 | #include <asm/debug.h> | 16 | #include <asm/debug.h> |
| 17 | #include <asm/diag.h> | ||
| 17 | 18 | ||
| 18 | #include "vmur.h" | 19 | #include "vmur.h" |
| 19 | 20 | ||
| @@ -68,8 +69,26 @@ static struct ccw_driver ur_driver = { | |||
| 68 | .set_offline = ur_set_offline, | 69 | .set_offline = ur_set_offline, |
| 69 | }; | 70 | }; |
| 70 | 71 | ||
| 72 | static DEFINE_MUTEX(vmur_mutex); | ||
| 73 | |||
| 71 | /* | 74 | /* |
| 72 | * Allocation, freeing, getting and putting of urdev structures | 75 | * Allocation, freeing, getting and putting of urdev structures |
| 76 | * | ||
| 77 | * Each ur device (urd) contains a reference to its corresponding ccw device | ||
| 78 | * (cdev) using the urd->cdev pointer. Each ccw device has a reference to the | ||
| 79 | * ur device using the cdev->dev.driver_data pointer. | ||
| 80 | * | ||
| 81 | * urd references: | ||
| 82 | * - ur_probe gets a urd reference, ur_remove drops the reference | ||
| 83 | * (cdev->dev.driver_data) | ||
| 84 | * - ur_open gets a urd reference, ur_relase drops the reference | ||
| 85 | * (urf->urd) | ||
| 86 | * | ||
| 87 | * cdev references: | ||
| 88 | * - urdev_alloc get a cdev reference (urd->cdev) | ||
| 89 | * - urdev_free drops the cdev reference (urd->cdev) | ||
| 90 | * | ||
| 91 | * Setting and clearing of cdev->dev.driver_data is protected by the ccwdev lock | ||
| 73 | */ | 92 | */ |
| 74 | static struct urdev *urdev_alloc(struct ccw_device *cdev) | 93 | static struct urdev *urdev_alloc(struct ccw_device *cdev) |
| 75 | { | 94 | { |
| @@ -78,42 +97,61 @@ static struct urdev *urdev_alloc(struct ccw_device *cdev) | |||
| 78 | urd = kzalloc(sizeof(struct urdev), GFP_KERNEL); | 97 | urd = kzalloc(sizeof(struct urdev), GFP_KERNEL); |
| 79 | if (!urd) | 98 | if (!urd) |
| 80 | return NULL; | 99 | return NULL; |
| 81 | urd->cdev = cdev; | ||
| 82 | urd->reclen = cdev->id.driver_info; | 100 | urd->reclen = cdev->id.driver_info; |
| 83 | ccw_device_get_id(cdev, &urd->dev_id); | 101 | ccw_device_get_id(cdev, &urd->dev_id); |
| 84 | mutex_init(&urd->io_mutex); | 102 | mutex_init(&urd->io_mutex); |
| 85 | mutex_init(&urd->open_mutex); | 103 | mutex_init(&urd->open_mutex); |
| 104 | atomic_set(&urd->ref_count, 1); | ||
| 105 | urd->cdev = cdev; | ||
| 106 | get_device(&cdev->dev); | ||
| 86 | return urd; | 107 | return urd; |
| 87 | } | 108 | } |
| 88 | 109 | ||
| 89 | static void urdev_free(struct urdev *urd) | 110 | static void urdev_free(struct urdev *urd) |
| 90 | { | 111 | { |
| 112 | TRACE("urdev_free: %p\n", urd); | ||
| 113 | if (urd->cdev) | ||
| 114 | put_device(&urd->cdev->dev); | ||
| 91 | kfree(urd); | 115 | kfree(urd); |
| 92 | } | 116 | } |
| 93 | 117 | ||
| 94 | /* | 118 | static void urdev_get(struct urdev *urd) |
| 95 | * This is how the character device driver gets a reference to a | 119 | { |
| 96 | * ur device. When this call returns successfully, a reference has | 120 | atomic_inc(&urd->ref_count); |
| 97 | * been taken (by get_device) on the underlying kobject. The recipient | 121 | } |
| 98 | * of this urdev pointer must eventually drop it with urdev_put(urd) | 122 | |
| 99 | * which does the corresponding put_device(). | 123 | static struct urdev *urdev_get_from_cdev(struct ccw_device *cdev) |
| 100 | */ | 124 | { |
| 125 | struct urdev *urd; | ||
| 126 | unsigned long flags; | ||
| 127 | |||
| 128 | spin_lock_irqsave(get_ccwdev_lock(cdev), flags); | ||
| 129 | urd = cdev->dev.driver_data; | ||
| 130 | if (urd) | ||
| 131 | urdev_get(urd); | ||
| 132 | spin_unlock_irqrestore(get_ccwdev_lock(cdev), flags); | ||
| 133 | return urd; | ||
| 134 | } | ||
| 135 | |||
| 101 | static struct urdev *urdev_get_from_devno(u16 devno) | 136 | static struct urdev *urdev_get_from_devno(u16 devno) |
| 102 | { | 137 | { |
| 103 | char bus_id[16]; | 138 | char bus_id[16]; |
| 104 | struct ccw_device *cdev; | 139 | struct ccw_device *cdev; |
| 140 | struct urdev *urd; | ||
| 105 | 141 | ||
| 106 | sprintf(bus_id, "0.0.%04x", devno); | 142 | sprintf(bus_id, "0.0.%04x", devno); |
| 107 | cdev = get_ccwdev_by_busid(&ur_driver, bus_id); | 143 | cdev = get_ccwdev_by_busid(&ur_driver, bus_id); |
| 108 | if (!cdev) | 144 | if (!cdev) |
| 109 | return NULL; | 145 | return NULL; |
| 110 | 146 | urd = urdev_get_from_cdev(cdev); | |
| 111 | return cdev->dev.driver_data; | 147 | put_device(&cdev->dev); |
| 148 | return urd; | ||
| 112 | } | 149 | } |
| 113 | 150 | ||
| 114 | static void urdev_put(struct urdev *urd) | 151 | static void urdev_put(struct urdev *urd) |
| 115 | { | 152 | { |
| 116 | put_device(&urd->cdev->dev); | 153 | if (atomic_dec_and_test(&urd->ref_count)) |
| 154 | urdev_free(urd); | ||
| 117 | } | 155 | } |
| 118 | 156 | ||
| 119 | /* | 157 | /* |
| @@ -245,6 +283,7 @@ static void ur_int_handler(struct ccw_device *cdev, unsigned long intparm, | |||
| 245 | return; | 283 | return; |
| 246 | } | 284 | } |
| 247 | urd = cdev->dev.driver_data; | 285 | urd = cdev->dev.driver_data; |
| 286 | BUG_ON(!urd); | ||
| 248 | /* On special conditions irb is an error pointer */ | 287 | /* On special conditions irb is an error pointer */ |
| 249 | if (IS_ERR(irb)) | 288 | if (IS_ERR(irb)) |
| 250 | urd->io_request_rc = PTR_ERR(irb); | 289 | urd->io_request_rc = PTR_ERR(irb); |
| @@ -262,9 +301,15 @@ static void ur_int_handler(struct ccw_device *cdev, unsigned long intparm, | |||
| 262 | static ssize_t ur_attr_reclen_show(struct device *dev, | 301 | static ssize_t ur_attr_reclen_show(struct device *dev, |
| 263 | struct device_attribute *attr, char *buf) | 302 | struct device_attribute *attr, char *buf) |
| 264 | { | 303 | { |
| 265 | struct urdev *urd = dev->driver_data; | 304 | struct urdev *urd; |
| 305 | int rc; | ||
| 266 | 306 | ||
| 267 | return sprintf(buf, "%zu\n", urd->reclen); | 307 | urd = urdev_get_from_cdev(to_ccwdev(dev)); |
| 308 | if (!urd) | ||
| 309 | return -ENODEV; | ||
| 310 | rc = sprintf(buf, "%zu\n", urd->reclen); | ||
| 311 | urdev_put(urd); | ||
| 312 | return rc; | ||
| 268 | } | 313 | } |
| 269 | 314 | ||
| 270 | static DEVICE_ATTR(reclen, 0444, ur_attr_reclen_show, NULL); | 315 | static DEVICE_ATTR(reclen, 0444, ur_attr_reclen_show, NULL); |
| @@ -379,31 +424,6 @@ static ssize_t ur_write(struct file *file, const char __user *udata, | |||
| 379 | return do_write(urf->urd, udata, count, urf->dev_reclen, ppos); | 424 | return do_write(urf->urd, udata, count, urf->dev_reclen, ppos); |
| 380 | } | 425 | } |
| 381 | 426 | ||
| 382 | static int do_diag_14(unsigned long rx, unsigned long ry1, | ||
| 383 | unsigned long subcode) | ||
| 384 | { | ||
| 385 | register unsigned long _ry1 asm("2") = ry1; | ||
| 386 | register unsigned long _ry2 asm("3") = subcode; | ||
| 387 | int rc = 0; | ||
| 388 | |||
| 389 | asm volatile( | ||
| 390 | #ifdef CONFIG_64BIT | ||
| 391 | " sam31\n" | ||
| 392 | " diag %2,2,0x14\n" | ||
| 393 | " sam64\n" | ||
| 394 | #else | ||
| 395 | " diag %2,2,0x14\n" | ||
| 396 | #endif | ||
| 397 | " ipm %0\n" | ||
| 398 | " srl %0,28\n" | ||
| 399 | : "=d" (rc), "+d" (_ry2) | ||
| 400 | : "d" (rx), "d" (_ry1) | ||
| 401 | : "cc"); | ||
| 402 | |||
| 403 | TRACE("diag 14: subcode=0x%lx, cc=%i\n", subcode, rc); | ||
| 404 | return rc; | ||
| 405 | } | ||
| 406 | |||
| 407 | /* | 427 | /* |
| 408 | * diagnose code 0x14 subcode 0x0028 - position spool file to designated | 428 | * diagnose code 0x14 subcode 0x0028 - position spool file to designated |
| 409 | * record | 429 | * record |
| @@ -415,7 +435,7 @@ static int diag_position_to_record(int devno, int record) | |||
| 415 | { | 435 | { |
| 416 | int cc; | 436 | int cc; |
| 417 | 437 | ||
| 418 | cc = do_diag_14(record, devno, 0x28); | 438 | cc = diag14(record, devno, 0x28); |
| 419 | switch (cc) { | 439 | switch (cc) { |
| 420 | case 0: | 440 | case 0: |
| 421 | return 0; | 441 | return 0; |
| @@ -440,7 +460,7 @@ static int diag_read_file(int devno, char *buf) | |||
| 440 | { | 460 | { |
| 441 | int cc; | 461 | int cc; |
| 442 | 462 | ||
| 443 | cc = do_diag_14((unsigned long) buf, devno, 0x00); | 463 | cc = diag14((unsigned long) buf, devno, 0x00); |
| 444 | switch (cc) { | 464 | switch (cc) { |
| 445 | case 0: | 465 | case 0: |
| 446 | return 0; | 466 | return 0; |
| @@ -533,7 +553,7 @@ static int diag_read_next_file_info(struct file_control_block *buf, int spid) | |||
| 533 | { | 553 | { |
| 534 | int cc; | 554 | int cc; |
| 535 | 555 | ||
| 536 | cc = do_diag_14((unsigned long) buf, spid, 0xfff); | 556 | cc = diag14((unsigned long) buf, spid, 0xfff); |
| 537 | switch (cc) { | 557 | switch (cc) { |
| 538 | case 0: | 558 | case 0: |
| 539 | return 0; | 559 | return 0; |
| @@ -750,64 +770,63 @@ static struct file_operations ur_fops = { | |||
| 750 | 770 | ||
| 751 | /* | 771 | /* |
| 752 | * ccw_device infrastructure: | 772 | * ccw_device infrastructure: |
| 753 | * ur_probe gets its own ref to the device (i.e. get_device), | 773 | * ur_probe creates the struct urdev (with refcount = 1), the device |
| 754 | * creates the struct urdev, the device attributes, sets up | 774 | * attributes, sets up the interrupt handler and validates the virtual |
| 755 | * the interrupt handler and validates the virtual unit record device. | 775 | * unit record device. |
| 756 | * ur_remove removes the device attributes, frees the struct urdev | 776 | * ur_remove removes the device attributes and drops the reference to |
| 757 | * and drops (put_device) the ref to the device we got in ur_probe. | 777 | * struct urdev. |
| 778 | * | ||
| 779 | * ur_probe, ur_remove, ur_set_online and ur_set_offline are serialized | ||
| 780 | * by the vmur_mutex lock. | ||
| 781 | * | ||
| 782 | * urd->char_device is used as indication that the online function has | ||
| 783 | * been completed successfully. | ||
| 758 | */ | 784 | */ |
| 759 | static int ur_probe(struct ccw_device *cdev) | 785 | static int ur_probe(struct ccw_device *cdev) |
| 760 | { | 786 | { |
| 761 | struct urdev *urd; | 787 | struct urdev *urd; |
| 762 | int rc; | 788 | int rc; |
| 763 | 789 | ||
| 764 | TRACE("ur_probe: cdev=%p state=%d\n", cdev, *(int *) cdev->private); | 790 | TRACE("ur_probe: cdev=%p\n", cdev); |
| 765 | |||
| 766 | if (!get_device(&cdev->dev)) | ||
| 767 | return -ENODEV; | ||
| 768 | 791 | ||
| 792 | mutex_lock(&vmur_mutex); | ||
| 769 | urd = urdev_alloc(cdev); | 793 | urd = urdev_alloc(cdev); |
| 770 | if (!urd) { | 794 | if (!urd) { |
| 771 | rc = -ENOMEM; | 795 | rc = -ENOMEM; |
| 772 | goto fail; | 796 | goto fail_unlock; |
| 773 | } | 797 | } |
| 798 | |||
| 774 | rc = ur_create_attributes(&cdev->dev); | 799 | rc = ur_create_attributes(&cdev->dev); |
| 775 | if (rc) { | 800 | if (rc) { |
| 776 | rc = -ENOMEM; | 801 | rc = -ENOMEM; |
| 777 | goto fail; | 802 | goto fail_urdev_put; |
| 778 | } | 803 | } |
| 779 | cdev->dev.driver_data = urd; | ||
| 780 | cdev->handler = ur_int_handler; | 804 | cdev->handler = ur_int_handler; |
| 781 | 805 | ||
| 782 | /* validate virtual unit record device */ | 806 | /* validate virtual unit record device */ |
| 783 | urd->class = get_urd_class(urd); | 807 | urd->class = get_urd_class(urd); |
| 784 | if (urd->class < 0) { | 808 | if (urd->class < 0) { |
| 785 | rc = urd->class; | 809 | rc = urd->class; |
| 786 | goto fail; | 810 | goto fail_remove_attr; |
| 787 | } | 811 | } |
| 788 | if ((urd->class != DEV_CLASS_UR_I) && (urd->class != DEV_CLASS_UR_O)) { | 812 | if ((urd->class != DEV_CLASS_UR_I) && (urd->class != DEV_CLASS_UR_O)) { |
| 789 | rc = -ENOTSUPP; | 813 | rc = -ENOTSUPP; |
| 790 | goto fail; | 814 | goto fail_remove_attr; |
| 791 | } | 815 | } |
| 816 | spin_lock_irq(get_ccwdev_lock(cdev)); | ||
| 817 | cdev->dev.driver_data = urd; | ||
| 818 | spin_unlock_irq(get_ccwdev_lock(cdev)); | ||
| 792 | 819 | ||
| 820 | mutex_unlock(&vmur_mutex); | ||
| 793 | return 0; | 821 | return 0; |
| 794 | 822 | ||
| 795 | fail: | 823 | fail_remove_attr: |
| 796 | urdev_free(urd); | ||
| 797 | put_device(&cdev->dev); | ||
| 798 | return rc; | ||
| 799 | } | ||
| 800 | |||
| 801 | static void ur_remove(struct ccw_device *cdev) | ||
| 802 | { | ||
| 803 | struct urdev *urd = cdev->dev.driver_data; | ||
| 804 | |||
| 805 | TRACE("ur_remove\n"); | ||
| 806 | if (cdev->online) | ||
| 807 | ur_set_offline(cdev); | ||
| 808 | ur_remove_attributes(&cdev->dev); | 824 | ur_remove_attributes(&cdev->dev); |
| 809 | urdev_free(urd); | 825 | fail_urdev_put: |
| 810 | put_device(&cdev->dev); | 826 | urdev_put(urd); |
| 827 | fail_unlock: | ||
| 828 | mutex_unlock(&vmur_mutex); | ||
| 829 | return rc; | ||
| 811 | } | 830 | } |
| 812 | 831 | ||
| 813 | static int ur_set_online(struct ccw_device *cdev) | 832 | static int ur_set_online(struct ccw_device *cdev) |
| @@ -816,20 +835,29 @@ static int ur_set_online(struct ccw_device *cdev) | |||
| 816 | int minor, major, rc; | 835 | int minor, major, rc; |
| 817 | char node_id[16]; | 836 | char node_id[16]; |
| 818 | 837 | ||
| 819 | TRACE("ur_set_online: cdev=%p state=%d\n", cdev, | 838 | TRACE("ur_set_online: cdev=%p\n", cdev); |
| 820 | *(int *) cdev->private); | ||
| 821 | 839 | ||
| 822 | if (!try_module_get(ur_driver.owner)) | 840 | mutex_lock(&vmur_mutex); |
| 823 | return -EINVAL; | 841 | urd = urdev_get_from_cdev(cdev); |
| 842 | if (!urd) { | ||
| 843 | /* ur_remove already deleted our urd */ | ||
| 844 | rc = -ENODEV; | ||
| 845 | goto fail_unlock; | ||
| 846 | } | ||
| 847 | |||
| 848 | if (urd->char_device) { | ||
| 849 | /* Another ur_set_online was faster */ | ||
| 850 | rc = -EBUSY; | ||
| 851 | goto fail_urdev_put; | ||
| 852 | } | ||
| 824 | 853 | ||
| 825 | urd = (struct urdev *) cdev->dev.driver_data; | ||
| 826 | minor = urd->dev_id.devno; | 854 | minor = urd->dev_id.devno; |
| 827 | major = MAJOR(ur_first_dev_maj_min); | 855 | major = MAJOR(ur_first_dev_maj_min); |
| 828 | 856 | ||
| 829 | urd->char_device = cdev_alloc(); | 857 | urd->char_device = cdev_alloc(); |
| 830 | if (!urd->char_device) { | 858 | if (!urd->char_device) { |
| 831 | rc = -ENOMEM; | 859 | rc = -ENOMEM; |
| 832 | goto fail_module_put; | 860 | goto fail_urdev_put; |
| 833 | } | 861 | } |
| 834 | 862 | ||
| 835 | cdev_init(urd->char_device, &ur_fops); | 863 | cdev_init(urd->char_device, &ur_fops); |
| @@ -858,29 +886,79 @@ static int ur_set_online(struct ccw_device *cdev) | |||
| 858 | TRACE("ur_set_online: device_create rc=%d\n", rc); | 886 | TRACE("ur_set_online: device_create rc=%d\n", rc); |
| 859 | goto fail_free_cdev; | 887 | goto fail_free_cdev; |
| 860 | } | 888 | } |
| 861 | 889 | urdev_put(urd); | |
| 890 | mutex_unlock(&vmur_mutex); | ||
| 862 | return 0; | 891 | return 0; |
| 863 | 892 | ||
| 864 | fail_free_cdev: | 893 | fail_free_cdev: |
| 865 | cdev_del(urd->char_device); | 894 | cdev_del(urd->char_device); |
| 866 | fail_module_put: | 895 | urd->char_device = NULL; |
| 867 | module_put(ur_driver.owner); | 896 | fail_urdev_put: |
| 868 | 897 | urdev_put(urd); | |
| 898 | fail_unlock: | ||
| 899 | mutex_unlock(&vmur_mutex); | ||
| 869 | return rc; | 900 | return rc; |
| 870 | } | 901 | } |
| 871 | 902 | ||
| 872 | static int ur_set_offline(struct ccw_device *cdev) | 903 | static int ur_set_offline_force(struct ccw_device *cdev, int force) |
| 873 | { | 904 | { |
| 874 | struct urdev *urd; | 905 | struct urdev *urd; |
| 906 | int rc; | ||
| 875 | 907 | ||
| 876 | TRACE("ur_set_offline: cdev=%p cdev->private=%p state=%d\n", | 908 | TRACE("ur_set_offline: cdev=%p\n", cdev); |
| 877 | cdev, cdev->private, *(int *) cdev->private); | 909 | urd = urdev_get_from_cdev(cdev); |
| 878 | urd = (struct urdev *) cdev->dev.driver_data; | 910 | if (!urd) |
| 911 | /* ur_remove already deleted our urd */ | ||
| 912 | return -ENODEV; | ||
| 913 | if (!urd->char_device) { | ||
| 914 | /* Another ur_set_offline was faster */ | ||
| 915 | rc = -EBUSY; | ||
| 916 | goto fail_urdev_put; | ||
| 917 | } | ||
| 918 | if (!force && (atomic_read(&urd->ref_count) > 2)) { | ||
| 919 | /* There is still a user of urd (e.g. ur_open) */ | ||
| 920 | TRACE("ur_set_offline: BUSY\n"); | ||
| 921 | rc = -EBUSY; | ||
| 922 | goto fail_urdev_put; | ||
| 923 | } | ||
| 879 | device_destroy(vmur_class, urd->char_device->dev); | 924 | device_destroy(vmur_class, urd->char_device->dev); |
| 880 | cdev_del(urd->char_device); | 925 | cdev_del(urd->char_device); |
| 881 | module_put(ur_driver.owner); | 926 | urd->char_device = NULL; |
| 927 | rc = 0; | ||
| 882 | 928 | ||
| 883 | return 0; | 929 | fail_urdev_put: |
| 930 | urdev_put(urd); | ||
| 931 | return rc; | ||
| 932 | } | ||
| 933 | |||
| 934 | static int ur_set_offline(struct ccw_device *cdev) | ||
| 935 | { | ||
| 936 | int rc; | ||
| 937 | |||
| 938 | mutex_lock(&vmur_mutex); | ||
| 939 | rc = ur_set_offline_force(cdev, 0); | ||
| 940 | mutex_unlock(&vmur_mutex); | ||
| 941 | return rc; | ||
| 942 | } | ||
| 943 | |||
| 944 | static void ur_remove(struct ccw_device *cdev) | ||
| 945 | { | ||
| 946 | unsigned long flags; | ||
| 947 | |||
| 948 | TRACE("ur_remove\n"); | ||
| 949 | |||
| 950 | mutex_lock(&vmur_mutex); | ||
| 951 | |||
| 952 | if (cdev->online) | ||
| 953 | ur_set_offline_force(cdev, 1); | ||
| 954 | ur_remove_attributes(&cdev->dev); | ||
| 955 | |||
| 956 | spin_lock_irqsave(get_ccwdev_lock(cdev), flags); | ||
| 957 | urdev_put(cdev->dev.driver_data); | ||
| 958 | cdev->dev.driver_data = NULL; | ||
| 959 | spin_unlock_irqrestore(get_ccwdev_lock(cdev), flags); | ||
| 960 | |||
| 961 | mutex_unlock(&vmur_mutex); | ||
| 884 | } | 962 | } |
| 885 | 963 | ||
| 886 | /* | 964 | /* |
diff --git a/drivers/s390/char/vmur.h b/drivers/s390/char/vmur.h index 2b3c564e0472..fa959644735a 100644 --- a/drivers/s390/char/vmur.h +++ b/drivers/s390/char/vmur.h | |||
| @@ -70,6 +70,7 @@ struct urdev { | |||
| 70 | size_t reclen; /* Record length for *write* CCWs */ | 70 | size_t reclen; /* Record length for *write* CCWs */ |
| 71 | int class; /* VM device class */ | 71 | int class; /* VM device class */ |
| 72 | int io_request_rc; /* return code from I/O request */ | 72 | int io_request_rc; /* return code from I/O request */ |
| 73 | atomic_t ref_count; /* reference counter */ | ||
| 73 | }; | 74 | }; |
| 74 | 75 | ||
| 75 | /* | 76 | /* |
diff --git a/drivers/s390/cio/cmf.c b/drivers/s390/cio/cmf.c index 02fd00b55e1b..34a796913b06 100644 --- a/drivers/s390/cio/cmf.c +++ b/drivers/s390/cio/cmf.c | |||
| @@ -594,6 +594,9 @@ alloc_cmb (struct ccw_device *cdev) | |||
| 594 | free_pages((unsigned long)mem, get_order(size)); | 594 | free_pages((unsigned long)mem, get_order(size)); |
| 595 | } else if (!mem) { | 595 | } else if (!mem) { |
| 596 | /* no luck */ | 596 | /* no luck */ |
| 597 | printk(KERN_WARNING "cio: failed to allocate area " | ||
| 598 | "for measuring %d subchannels\n", | ||
| 599 | cmb_area.num_channels); | ||
| 597 | ret = -ENOMEM; | 600 | ret = -ENOMEM; |
| 598 | goto out; | 601 | goto out; |
| 599 | } else { | 602 | } else { |
| @@ -1279,13 +1282,6 @@ init_cmf(void) | |||
| 1279 | case CMF_BASIC: | 1282 | case CMF_BASIC: |
| 1280 | format_string = "basic"; | 1283 | format_string = "basic"; |
| 1281 | cmbops = &cmbops_basic; | 1284 | cmbops = &cmbops_basic; |
| 1282 | if (cmb_area.num_channels > 4096 || cmb_area.num_channels < 1) { | ||
| 1283 | printk(KERN_ERR "cio: Basic channel measurement " | ||
| 1284 | "facility can only use 1 to 4096 devices\n" | ||
| 1285 | KERN_ERR "when the cmf driver is built" | ||
| 1286 | " as a loadable module\n"); | ||
| 1287 | return 1; | ||
| 1288 | } | ||
| 1289 | break; | 1285 | break; |
| 1290 | case CMF_EXTENDED: | 1286 | case CMF_EXTENDED: |
| 1291 | format_string = "extended"; | 1287 | format_string = "extended"; |
diff --git a/drivers/s390/cio/device.c b/drivers/s390/cio/device.c index 297659fa0e26..e44d92eac8e9 100644 --- a/drivers/s390/cio/device.c +++ b/drivers/s390/cio/device.c | |||
| @@ -117,7 +117,10 @@ static int ccw_uevent(struct device *dev, char **envp, int num_envp, | |||
| 117 | snprint_alias(modalias_buf, sizeof(modalias_buf), id, ""); | 117 | snprint_alias(modalias_buf, sizeof(modalias_buf), id, ""); |
| 118 | ret = add_uevent_var(envp, num_envp, &i, buffer, buffer_size, &len, | 118 | ret = add_uevent_var(envp, num_envp, &i, buffer, buffer_size, &len, |
| 119 | "MODALIAS=%s", modalias_buf); | 119 | "MODALIAS=%s", modalias_buf); |
| 120 | return ret; | 120 | if (ret) |
| 121 | return ret; | ||
| 122 | envp[i] = NULL; | ||
| 123 | return 0; | ||
| 121 | } | 124 | } |
| 122 | 125 | ||
| 123 | struct bus_type ccw_bus_type; | 126 | struct bus_type ccw_bus_type; |
diff --git a/drivers/s390/cio/device_id.c b/drivers/s390/cio/device_id.c index 60b9347f7c92..f232832f2b22 100644 --- a/drivers/s390/cio/device_id.c +++ b/drivers/s390/cio/device_id.c | |||
| @@ -17,6 +17,7 @@ | |||
| 17 | #include <asm/delay.h> | 17 | #include <asm/delay.h> |
| 18 | #include <asm/cio.h> | 18 | #include <asm/cio.h> |
| 19 | #include <asm/lowcore.h> | 19 | #include <asm/lowcore.h> |
| 20 | #include <asm/diag.h> | ||
| 20 | 21 | ||
| 21 | #include "cio.h" | 22 | #include "cio.h" |
| 22 | #include "cio_debug.h" | 23 | #include "cio_debug.h" |
| @@ -25,51 +26,6 @@ | |||
| 25 | #include "ioasm.h" | 26 | #include "ioasm.h" |
| 26 | 27 | ||
| 27 | /* | 28 | /* |
| 28 | * diag210 is used under VM to get information about a virtual device | ||
| 29 | */ | ||
| 30 | int | ||
| 31 | diag210(struct diag210 * addr) | ||
| 32 | { | ||
| 33 | /* | ||
| 34 | * diag 210 needs its data below the 2GB border, so we | ||
| 35 | * use a static data area to be sure | ||
| 36 | */ | ||
| 37 | static struct diag210 diag210_tmp; | ||
| 38 | static DEFINE_SPINLOCK(diag210_lock); | ||
| 39 | unsigned long flags; | ||
| 40 | int ccode; | ||
| 41 | |||
| 42 | spin_lock_irqsave(&diag210_lock, flags); | ||
| 43 | diag210_tmp = *addr; | ||
| 44 | |||
| 45 | #ifdef CONFIG_64BIT | ||
| 46 | asm volatile( | ||
| 47 | " lhi %0,-1\n" | ||
| 48 | " sam31\n" | ||
| 49 | " diag %1,0,0x210\n" | ||
| 50 | "0: ipm %0\n" | ||
| 51 | " srl %0,28\n" | ||
| 52 | "1: sam64\n" | ||
| 53 | EX_TABLE(0b,1b) | ||
| 54 | : "=&d" (ccode) : "a" (&diag210_tmp) : "cc", "memory"); | ||
| 55 | #else | ||
| 56 | asm volatile( | ||
| 57 | " lhi %0,-1\n" | ||
| 58 | " diag %1,0,0x210\n" | ||
| 59 | "0: ipm %0\n" | ||
| 60 | " srl %0,28\n" | ||
| 61 | "1:\n" | ||
| 62 | EX_TABLE(0b,1b) | ||
| 63 | : "=&d" (ccode) : "a" (&diag210_tmp) : "cc", "memory"); | ||
| 64 | #endif | ||
| 65 | |||
| 66 | *addr = diag210_tmp; | ||
| 67 | spin_unlock_irqrestore(&diag210_lock, flags); | ||
| 68 | |||
| 69 | return ccode; | ||
| 70 | } | ||
| 71 | |||
| 72 | /* | ||
| 73 | * Input : | 29 | * Input : |
| 74 | * devno - device number | 30 | * devno - device number |
| 75 | * ps - pointer to sense ID data area | 31 | * ps - pointer to sense ID data area |
| @@ -349,5 +305,3 @@ ccw_device_sense_id_irq(struct ccw_device *cdev, enum dev_event dev_event) | |||
| 349 | break; | 305 | break; |
| 350 | } | 306 | } |
| 351 | } | 307 | } |
| 352 | |||
| 353 | EXPORT_SYMBOL(diag210); | ||
diff --git a/drivers/s390/cio/qdio.c b/drivers/s390/cio/qdio.c index 03347aed2b3e..d8d479876ec7 100644 --- a/drivers/s390/cio/qdio.c +++ b/drivers/s390/cio/qdio.c | |||
| @@ -195,6 +195,8 @@ qdio_do_eqbs(struct qdio_q *q, unsigned char *state, | |||
| 195 | again: | 195 | again: |
| 196 | ccq = do_eqbs(irq->sch_token, state, q_no, start, cnt); | 196 | ccq = do_eqbs(irq->sch_token, state, q_no, start, cnt); |
| 197 | rc = qdio_check_ccq(q, ccq); | 197 | rc = qdio_check_ccq(q, ccq); |
| 198 | if ((ccq == 96) && (tmp_cnt != *cnt)) | ||
| 199 | rc = 0; | ||
| 198 | if (rc == 1) { | 200 | if (rc == 1) { |
| 199 | QDIO_DBF_TEXT5(1,trace,"eqAGAIN"); | 201 | QDIO_DBF_TEXT5(1,trace,"eqAGAIN"); |
| 200 | goto again; | 202 | goto again; |
| @@ -740,7 +742,8 @@ qdio_get_outbound_buffer_frontier(struct qdio_q *q) | |||
| 740 | first_not_to_check=f+qdio_min(atomic_read(&q->number_of_buffers_used), | 742 | first_not_to_check=f+qdio_min(atomic_read(&q->number_of_buffers_used), |
| 741 | (QDIO_MAX_BUFFERS_PER_Q-1)); | 743 | (QDIO_MAX_BUFFERS_PER_Q-1)); |
| 742 | 744 | ||
| 743 | if ((!q->is_iqdio_q)&&(!q->hydra_gives_outbound_pcis)) | 745 | if (((!q->is_iqdio_q) && (!q->hydra_gives_outbound_pcis)) || |
| 746 | (q->queue_type == QDIO_IQDIO_QFMT_ASYNCH)) | ||
| 744 | SYNC_MEMORY; | 747 | SYNC_MEMORY; |
| 745 | 748 | ||
| 746 | check_next: | 749 | check_next: |
diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig index d2b3898b750a..6f2c71ef47ee 100644 --- a/drivers/scsi/Kconfig +++ b/drivers/scsi/Kconfig | |||
| @@ -367,6 +367,7 @@ config SCSI_3W_9XXX | |||
| 367 | config SCSI_7000FASST | 367 | config SCSI_7000FASST |
| 368 | tristate "7000FASST SCSI support" | 368 | tristate "7000FASST SCSI support" |
| 369 | depends on ISA && SCSI && ISA_DMA_API | 369 | depends on ISA && SCSI && ISA_DMA_API |
| 370 | select CHECK_SIGNATURE | ||
| 370 | help | 371 | help |
| 371 | This driver supports the Western Digital 7000 SCSI host adapter | 372 | This driver supports the Western Digital 7000 SCSI host adapter |
| 372 | family. Some information is in the source: | 373 | family. Some information is in the source: |
| @@ -388,6 +389,7 @@ config SCSI_AHA152X | |||
| 388 | tristate "Adaptec AHA152X/2825 support" | 389 | tristate "Adaptec AHA152X/2825 support" |
| 389 | depends on ISA && SCSI && !64BIT | 390 | depends on ISA && SCSI && !64BIT |
| 390 | select SCSI_SPI_ATTRS | 391 | select SCSI_SPI_ATTRS |
| 392 | select CHECK_SIGNATURE | ||
| 391 | ---help--- | 393 | ---help--- |
| 392 | This is a driver for the AHA-1510, AHA-1520, AHA-1522, and AHA-2825 | 394 | This is a driver for the AHA-1510, AHA-1520, AHA-1522, and AHA-2825 |
| 393 | SCSI host adapters. It also works for the AVA-1505, but the IRQ etc. | 395 | SCSI host adapters. It also works for the AVA-1505, but the IRQ etc. |
| @@ -583,6 +585,7 @@ config SCSI_DTC3280 | |||
| 583 | tristate "DTC3180/3280 SCSI support" | 585 | tristate "DTC3180/3280 SCSI support" |
| 584 | depends on ISA && SCSI | 586 | depends on ISA && SCSI |
| 585 | select SCSI_SPI_ATTRS | 587 | select SCSI_SPI_ATTRS |
| 588 | select CHECK_SIGNATURE | ||
| 586 | help | 589 | help |
| 587 | This is support for DTC 3180/3280 SCSI Host Adapters. Please read | 590 | This is support for DTC 3180/3280 SCSI Host Adapters. Please read |
| 588 | the SCSI-HOWTO, available from | 591 | the SCSI-HOWTO, available from |
| @@ -657,6 +660,7 @@ config SCSI_EATA_PIO | |||
| 657 | config SCSI_FUTURE_DOMAIN | 660 | config SCSI_FUTURE_DOMAIN |
| 658 | tristate "Future Domain 16xx SCSI/AHA-2920A support" | 661 | tristate "Future Domain 16xx SCSI/AHA-2920A support" |
| 659 | depends on (ISA || PCI) && SCSI | 662 | depends on (ISA || PCI) && SCSI |
| 663 | select CHECK_SIGNATURE | ||
| 660 | ---help--- | 664 | ---help--- |
| 661 | This is support for Future Domain's 16-bit SCSI host adapters | 665 | This is support for Future Domain's 16-bit SCSI host adapters |
| 662 | (TMC-1660/1680, TMC-1650/1670, TMC-3260, TMC-1610M/MER/MEX) and | 666 | (TMC-1660/1680, TMC-1650/1670, TMC-3260, TMC-1610M/MER/MEX) and |
| @@ -1324,6 +1328,7 @@ config SCSI_LPFC | |||
| 1324 | config SCSI_SEAGATE | 1328 | config SCSI_SEAGATE |
| 1325 | tristate "Seagate ST-02 and Future Domain TMC-8xx SCSI support" | 1329 | tristate "Seagate ST-02 and Future Domain TMC-8xx SCSI support" |
| 1326 | depends on X86 && ISA && SCSI | 1330 | depends on X86 && ISA && SCSI |
| 1331 | select CHECK_SIGNATURE | ||
| 1327 | ---help--- | 1332 | ---help--- |
| 1328 | These are 8-bit SCSI controllers; the ST-01 is also supported by | 1333 | These are 8-bit SCSI controllers; the ST-01 is also supported by |
| 1329 | this driver. It is explained in section 3.9 of the SCSI-HOWTO, | 1334 | this driver. It is explained in section 3.9 of the SCSI-HOWTO, |
| @@ -1397,6 +1402,7 @@ config SCSI_T128 | |||
| 1397 | tristate "Trantor T128/T128F/T228 SCSI support" | 1402 | tristate "Trantor T128/T128F/T228 SCSI support" |
| 1398 | depends on ISA && SCSI | 1403 | depends on ISA && SCSI |
| 1399 | select SCSI_SPI_ATTRS | 1404 | select SCSI_SPI_ATTRS |
| 1405 | select CHECK_SIGNATURE | ||
| 1400 | ---help--- | 1406 | ---help--- |
| 1401 | This is support for a SCSI host adapter. It is explained in section | 1407 | This is support for a SCSI host adapter. It is explained in section |
| 1402 | 3.11 of the SCSI-HOWTO, available from | 1408 | 3.11 of the SCSI-HOWTO, available from |
| @@ -1561,7 +1567,7 @@ config A3000_SCSI | |||
| 1561 | built-in SCSI controller, say Y. Otherwise, say N. | 1567 | built-in SCSI controller, say Y. Otherwise, say N. |
| 1562 | 1568 | ||
| 1563 | To compile this driver as a module, choose M here: the | 1569 | To compile this driver as a module, choose M here: the |
| 1564 | module will be called wd33c93. | 1570 | module will be called a3000. |
| 1565 | 1571 | ||
| 1566 | config A2091_SCSI | 1572 | config A2091_SCSI |
| 1567 | tristate "A2091/A590 WD33C93A support" | 1573 | tristate "A2091/A590 WD33C93A support" |
| @@ -1571,7 +1577,7 @@ config A2091_SCSI | |||
| 1571 | say N. | 1577 | say N. |
| 1572 | 1578 | ||
| 1573 | To compile this driver as a module, choose M here: the | 1579 | To compile this driver as a module, choose M here: the |
| 1574 | module will be called wd33c93. | 1580 | module will be called a2091. |
| 1575 | 1581 | ||
| 1576 | config GVP11_SCSI | 1582 | config GVP11_SCSI |
| 1577 | tristate "GVP Series II WD33C93A support" | 1583 | tristate "GVP Series II WD33C93A support" |
diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c index 301313002f6b..f94109cbb46e 100644 --- a/drivers/serial/8250.c +++ b/drivers/serial/8250.c | |||
| @@ -129,7 +129,16 @@ struct uart_8250_port { | |||
| 129 | unsigned char mcr; | 129 | unsigned char mcr; |
| 130 | unsigned char mcr_mask; /* mask of user bits */ | 130 | unsigned char mcr_mask; /* mask of user bits */ |
| 131 | unsigned char mcr_force; /* mask of forced bits */ | 131 | unsigned char mcr_force; /* mask of forced bits */ |
| 132 | unsigned char lsr_break_flag; | 132 | |
| 133 | /* | ||
| 134 | * Some bits in registers are cleared on a read, so they must | ||
| 135 | * be saved whenever the register is read but the bits will not | ||
| 136 | * be immediately processed. | ||
| 137 | */ | ||
| 138 | #define LSR_SAVE_FLAGS UART_LSR_BRK_ERROR_BITS | ||
| 139 | unsigned char lsr_saved_flags; | ||
| 140 | #define MSR_SAVE_FLAGS UART_MSR_ANY_DELTA | ||
| 141 | unsigned char msr_saved_flags; | ||
| 133 | 142 | ||
| 134 | /* | 143 | /* |
| 135 | * We provide a per-port pm hook. | 144 | * We provide a per-port pm hook. |
| @@ -1238,6 +1247,7 @@ static void serial8250_start_tx(struct uart_port *port) | |||
| 1238 | if (up->bugs & UART_BUG_TXEN) { | 1247 | if (up->bugs & UART_BUG_TXEN) { |
| 1239 | unsigned char lsr, iir; | 1248 | unsigned char lsr, iir; |
| 1240 | lsr = serial_in(up, UART_LSR); | 1249 | lsr = serial_in(up, UART_LSR); |
| 1250 | up->lsr_saved_flags |= lsr & LSR_SAVE_FLAGS; | ||
| 1241 | iir = serial_in(up, UART_IIR) & 0x0f; | 1251 | iir = serial_in(up, UART_IIR) & 0x0f; |
| 1242 | if ((up->port.type == PORT_RM9000) ? | 1252 | if ((up->port.type == PORT_RM9000) ? |
| 1243 | (lsr & UART_LSR_THRE && | 1253 | (lsr & UART_LSR_THRE && |
| @@ -1290,18 +1300,10 @@ receive_chars(struct uart_8250_port *up, unsigned int *status) | |||
| 1290 | flag = TTY_NORMAL; | 1300 | flag = TTY_NORMAL; |
| 1291 | up->port.icount.rx++; | 1301 | up->port.icount.rx++; |
| 1292 | 1302 | ||
| 1293 | #ifdef CONFIG_SERIAL_8250_CONSOLE | 1303 | lsr |= up->lsr_saved_flags; |
| 1294 | /* | 1304 | up->lsr_saved_flags = 0; |
| 1295 | * Recover the break flag from console xmit | ||
| 1296 | */ | ||
| 1297 | if (up->port.line == up->port.cons->index) { | ||
| 1298 | lsr |= up->lsr_break_flag; | ||
| 1299 | up->lsr_break_flag = 0; | ||
| 1300 | } | ||
| 1301 | #endif | ||
| 1302 | 1305 | ||
| 1303 | if (unlikely(lsr & (UART_LSR_BI | UART_LSR_PE | | 1306 | if (unlikely(lsr & UART_LSR_BRK_ERROR_BITS)) { |
| 1304 | UART_LSR_FE | UART_LSR_OE))) { | ||
| 1305 | /* | 1307 | /* |
| 1306 | * For statistics only | 1308 | * For statistics only |
| 1307 | */ | 1309 | */ |
| @@ -1392,6 +1394,8 @@ static unsigned int check_modem_status(struct uart_8250_port *up) | |||
| 1392 | { | 1394 | { |
| 1393 | unsigned int status = serial_in(up, UART_MSR); | 1395 | unsigned int status = serial_in(up, UART_MSR); |
| 1394 | 1396 | ||
| 1397 | status |= up->msr_saved_flags; | ||
| 1398 | up->msr_saved_flags = 0; | ||
| 1395 | if (status & UART_MSR_ANY_DELTA && up->ier & UART_IER_MSI && | 1399 | if (status & UART_MSR_ANY_DELTA && up->ier & UART_IER_MSI && |
| 1396 | up->port.info != NULL) { | 1400 | up->port.info != NULL) { |
| 1397 | if (status & UART_MSR_TERI) | 1401 | if (status & UART_MSR_TERI) |
| @@ -1591,7 +1595,8 @@ static void serial8250_timeout(unsigned long data) | |||
| 1591 | static void serial8250_backup_timeout(unsigned long data) | 1595 | static void serial8250_backup_timeout(unsigned long data) |
| 1592 | { | 1596 | { |
| 1593 | struct uart_8250_port *up = (struct uart_8250_port *)data; | 1597 | struct uart_8250_port *up = (struct uart_8250_port *)data; |
| 1594 | unsigned int iir, ier = 0; | 1598 | unsigned int iir, ier = 0, lsr; |
| 1599 | unsigned long flags; | ||
| 1595 | 1600 | ||
| 1596 | /* | 1601 | /* |
| 1597 | * Must disable interrupts or else we risk racing with the interrupt | 1602 | * Must disable interrupts or else we risk racing with the interrupt |
| @@ -1610,9 +1615,13 @@ static void serial8250_backup_timeout(unsigned long data) | |||
| 1610 | * the "Diva" UART used on the management processor on many HP | 1615 | * the "Diva" UART used on the management processor on many HP |
| 1611 | * ia64 and parisc boxes. | 1616 | * ia64 and parisc boxes. |
| 1612 | */ | 1617 | */ |
| 1618 | spin_lock_irqsave(&up->port.lock, flags); | ||
| 1619 | lsr = serial_in(up, UART_LSR); | ||
| 1620 | up->lsr_saved_flags |= lsr & LSR_SAVE_FLAGS; | ||
| 1621 | spin_unlock_irqrestore(&up->port.lock, flags); | ||
| 1613 | if ((iir & UART_IIR_NO_INT) && (up->ier & UART_IER_THRI) && | 1622 | if ((iir & UART_IIR_NO_INT) && (up->ier & UART_IER_THRI) && |
| 1614 | (!uart_circ_empty(&up->port.info->xmit) || up->port.x_char) && | 1623 | (!uart_circ_empty(&up->port.info->xmit) || up->port.x_char) && |
| 1615 | (serial_in(up, UART_LSR) & UART_LSR_THRE)) { | 1624 | (lsr & UART_LSR_THRE)) { |
| 1616 | iir &= ~(UART_IIR_ID | UART_IIR_NO_INT); | 1625 | iir &= ~(UART_IIR_ID | UART_IIR_NO_INT); |
| 1617 | iir |= UART_IIR_THRI; | 1626 | iir |= UART_IIR_THRI; |
| 1618 | } | 1627 | } |
| @@ -1631,13 +1640,14 @@ static unsigned int serial8250_tx_empty(struct uart_port *port) | |||
| 1631 | { | 1640 | { |
| 1632 | struct uart_8250_port *up = (struct uart_8250_port *)port; | 1641 | struct uart_8250_port *up = (struct uart_8250_port *)port; |
| 1633 | unsigned long flags; | 1642 | unsigned long flags; |
| 1634 | unsigned int ret; | 1643 | unsigned int lsr; |
| 1635 | 1644 | ||
| 1636 | spin_lock_irqsave(&up->port.lock, flags); | 1645 | spin_lock_irqsave(&up->port.lock, flags); |
| 1637 | ret = serial_in(up, UART_LSR) & UART_LSR_TEMT ? TIOCSER_TEMT : 0; | 1646 | lsr = serial_in(up, UART_LSR); |
| 1647 | up->lsr_saved_flags |= lsr & LSR_SAVE_FLAGS; | ||
| 1638 | spin_unlock_irqrestore(&up->port.lock, flags); | 1648 | spin_unlock_irqrestore(&up->port.lock, flags); |
| 1639 | 1649 | ||
| 1640 | return ret; | 1650 | return lsr & UART_LSR_TEMT ? TIOCSER_TEMT : 0; |
| 1641 | } | 1651 | } |
| 1642 | 1652 | ||
| 1643 | static unsigned int serial8250_get_mctrl(struct uart_port *port) | 1653 | static unsigned int serial8250_get_mctrl(struct uart_port *port) |
| @@ -1708,8 +1718,7 @@ static inline void wait_for_xmitr(struct uart_8250_port *up, int bits) | |||
| 1708 | do { | 1718 | do { |
| 1709 | status = serial_in(up, UART_LSR); | 1719 | status = serial_in(up, UART_LSR); |
| 1710 | 1720 | ||
| 1711 | if (status & UART_LSR_BI) | 1721 | up->lsr_saved_flags |= status & LSR_SAVE_FLAGS; |
| 1712 | up->lsr_break_flag = UART_LSR_BI; | ||
| 1713 | 1722 | ||
| 1714 | if (--tmout == 0) | 1723 | if (--tmout == 0) |
| 1715 | break; | 1724 | break; |
| @@ -1718,8 +1727,12 @@ static inline void wait_for_xmitr(struct uart_8250_port *up, int bits) | |||
| 1718 | 1727 | ||
| 1719 | /* Wait up to 1s for flow control if necessary */ | 1728 | /* Wait up to 1s for flow control if necessary */ |
| 1720 | if (up->port.flags & UPF_CONS_FLOW) { | 1729 | if (up->port.flags & UPF_CONS_FLOW) { |
| 1721 | tmout = 1000000; | 1730 | unsigned int tmout; |
| 1722 | while (!(serial_in(up, UART_MSR) & UART_MSR_CTS) && --tmout) { | 1731 | for (tmout = 1000000; tmout; tmout--) { |
| 1732 | unsigned int msr = serial_in(up, UART_MSR); | ||
| 1733 | up->msr_saved_flags |= msr & MSR_SAVE_FLAGS; | ||
| 1734 | if (msr & UART_MSR_CTS) | ||
| 1735 | break; | ||
| 1723 | udelay(1); | 1736 | udelay(1); |
| 1724 | touch_nmi_watchdog(); | 1737 | touch_nmi_watchdog(); |
| 1725 | } | 1738 | } |
| @@ -1889,6 +1902,18 @@ static int serial8250_startup(struct uart_port *port) | |||
| 1889 | spin_unlock_irqrestore(&up->port.lock, flags); | 1902 | spin_unlock_irqrestore(&up->port.lock, flags); |
| 1890 | 1903 | ||
| 1891 | /* | 1904 | /* |
| 1905 | * Clear the interrupt registers again for luck, and clear the | ||
| 1906 | * saved flags to avoid getting false values from polling | ||
| 1907 | * routines or the previous session. | ||
| 1908 | */ | ||
| 1909 | serial_inp(up, UART_LSR); | ||
| 1910 | serial_inp(up, UART_RX); | ||
| 1911 | serial_inp(up, UART_IIR); | ||
| 1912 | serial_inp(up, UART_MSR); | ||
| 1913 | up->lsr_saved_flags = 0; | ||
| 1914 | up->msr_saved_flags = 0; | ||
| 1915 | |||
| 1916 | /* | ||
| 1892 | * Finally, enable interrupts. Note: Modem status interrupts | 1917 | * Finally, enable interrupts. Note: Modem status interrupts |
| 1893 | * are set via set_termios(), which will be occurring imminently | 1918 | * are set via set_termios(), which will be occurring imminently |
| 1894 | * anyway, so we don't enable them here. | 1919 | * anyway, so we don't enable them here. |
| @@ -1906,14 +1931,6 @@ static int serial8250_startup(struct uart_port *port) | |||
| 1906 | (void) inb_p(icp); | 1931 | (void) inb_p(icp); |
| 1907 | } | 1932 | } |
| 1908 | 1933 | ||
| 1909 | /* | ||
| 1910 | * And clear the interrupt registers again for luck. | ||
| 1911 | */ | ||
| 1912 | (void) serial_inp(up, UART_LSR); | ||
| 1913 | (void) serial_inp(up, UART_RX); | ||
| 1914 | (void) serial_inp(up, UART_IIR); | ||
| 1915 | (void) serial_inp(up, UART_MSR); | ||
| 1916 | |||
| 1917 | return 0; | 1934 | return 0; |
| 1918 | } | 1935 | } |
| 1919 | 1936 | ||
| @@ -2484,6 +2501,16 @@ serial8250_console_write(struct console *co, const char *s, unsigned int count) | |||
| 2484 | wait_for_xmitr(up, BOTH_EMPTY); | 2501 | wait_for_xmitr(up, BOTH_EMPTY); |
| 2485 | serial_out(up, UART_IER, ier); | 2502 | serial_out(up, UART_IER, ier); |
| 2486 | 2503 | ||
| 2504 | /* | ||
| 2505 | * The receive handling will happen properly because the | ||
| 2506 | * receive ready bit will still be set; it is not cleared | ||
| 2507 | * on read. However, modem control will not, we must | ||
| 2508 | * call it if we have saved something in the saved flags | ||
| 2509 | * while processing with interrupts off. | ||
| 2510 | */ | ||
| 2511 | if (up->msr_saved_flags) | ||
| 2512 | check_modem_status(up); | ||
| 2513 | |||
| 2487 | if (locked) | 2514 | if (locked) |
| 2488 | spin_unlock(&up->port.lock); | 2515 | spin_unlock(&up->port.lock); |
| 2489 | local_irq_restore(flags); | 2516 | local_irq_restore(flags); |
diff --git a/drivers/serial/8250_pci.c b/drivers/serial/8250_pci.c index 5e485876f54c..bd66339f7a3f 100644 --- a/drivers/serial/8250_pci.c +++ b/drivers/serial/8250_pci.c | |||
| @@ -580,6 +580,138 @@ static int pci_netmos_init(struct pci_dev *dev) | |||
| 580 | return num_serial; | 580 | return num_serial; |
| 581 | } | 581 | } |
| 582 | 582 | ||
| 583 | /* | ||
| 584 | * ITE support by Niels de Vos <niels.devos@wincor-nixdorf.com> | ||
| 585 | * | ||
| 586 | * These chips are available with optionally one parallel port and up to | ||
| 587 | * two serial ports. Unfortunately they all have the same product id. | ||
| 588 | * | ||
| 589 | * Basic configuration is done over a region of 32 I/O ports. The base | ||
| 590 | * ioport is called INTA or INTC, depending on docs/other drivers. | ||
| 591 | * | ||
| 592 | * The region of the 32 I/O ports is configured in POSIO0R... | ||
| 593 | */ | ||
| 594 | |||
| 595 | /* registers */ | ||
| 596 | #define ITE_887x_MISCR 0x9c | ||
| 597 | #define ITE_887x_INTCBAR 0x78 | ||
| 598 | #define ITE_887x_UARTBAR 0x7c | ||
| 599 | #define ITE_887x_PS0BAR 0x10 | ||
| 600 | #define ITE_887x_POSIO0 0x60 | ||
| 601 | |||
| 602 | /* I/O space size */ | ||
| 603 | #define ITE_887x_IOSIZE 32 | ||
| 604 | /* I/O space size (bits 26-24; 8 bytes = 011b) */ | ||
| 605 | #define ITE_887x_POSIO_IOSIZE_8 (3 << 24) | ||
| 606 | /* I/O space size (bits 26-24; 32 bytes = 101b) */ | ||
| 607 | #define ITE_887x_POSIO_IOSIZE_32 (5 << 24) | ||
| 608 | /* Decoding speed (1 = slow, 2 = medium, 3 = fast) */ | ||
| 609 | #define ITE_887x_POSIO_SPEED (3 << 29) | ||
| 610 | /* enable IO_Space bit */ | ||
| 611 | #define ITE_887x_POSIO_ENABLE (1 << 31) | ||
| 612 | |||
| 613 | static int __devinit pci_ite887x_init(struct pci_dev *dev) | ||
| 614 | { | ||
| 615 | /* inta_addr are the configuration addresses of the ITE */ | ||
| 616 | static const short inta_addr[] = { 0x2a0, 0x2c0, 0x220, 0x240, 0x1e0, | ||
| 617 | 0x200, 0x280, 0 }; | ||
| 618 | int ret, i, type; | ||
| 619 | struct resource *iobase = NULL; | ||
| 620 | u32 miscr, uartbar, ioport; | ||
| 621 | |||
| 622 | /* search for the base-ioport */ | ||
| 623 | i = 0; | ||
| 624 | while (inta_addr[i] && iobase == NULL) { | ||
| 625 | iobase = request_region(inta_addr[i], ITE_887x_IOSIZE, | ||
| 626 | "ite887x"); | ||
| 627 | if (iobase != NULL) { | ||
| 628 | /* write POSIO0R - speed | size | ioport */ | ||
| 629 | pci_write_config_dword(dev, ITE_887x_POSIO0, | ||
| 630 | ITE_887x_POSIO_ENABLE | ITE_887x_POSIO_SPEED | | ||
| 631 | ITE_887x_POSIO_IOSIZE_32 | inta_addr[i]); | ||
| 632 | /* write INTCBAR - ioport */ | ||
| 633 | pci_write_config_dword(dev, ITE_887x_INTCBAR, inta_addr[i]); | ||
| 634 | ret = inb(inta_addr[i]); | ||
| 635 | if (ret != 0xff) { | ||
| 636 | /* ioport connected */ | ||
| 637 | break; | ||
| 638 | } | ||
| 639 | release_region(iobase->start, ITE_887x_IOSIZE); | ||
| 640 | iobase = NULL; | ||
| 641 | } | ||
| 642 | i++; | ||
| 643 | } | ||
| 644 | |||
| 645 | if (!inta_addr[i]) { | ||
| 646 | printk(KERN_ERR "ite887x: could not find iobase\n"); | ||
| 647 | return -ENODEV; | ||
| 648 | } | ||
| 649 | |||
| 650 | /* start of undocumented type checking (see parport_pc.c) */ | ||
| 651 | type = inb(iobase->start + 0x18) & 0x0f; | ||
| 652 | |||
| 653 | switch (type) { | ||
| 654 | case 0x2: /* ITE8871 (1P) */ | ||
| 655 | case 0xa: /* ITE8875 (1P) */ | ||
| 656 | ret = 0; | ||
| 657 | break; | ||
| 658 | case 0xe: /* ITE8872 (2S1P) */ | ||
| 659 | ret = 2; | ||
| 660 | break; | ||
| 661 | case 0x6: /* ITE8873 (1S) */ | ||
| 662 | ret = 1; | ||
| 663 | break; | ||
| 664 | case 0x8: /* ITE8874 (2S) */ | ||
| 665 | ret = 2; | ||
| 666 | break; | ||
| 667 | default: | ||
| 668 | moan_device("Unknown ITE887x", dev); | ||
| 669 | ret = -ENODEV; | ||
| 670 | } | ||
| 671 | |||
| 672 | /* configure all serial ports */ | ||
| 673 | for (i = 0; i < ret; i++) { | ||
| 674 | /* read the I/O port from the device */ | ||
| 675 | pci_read_config_dword(dev, ITE_887x_PS0BAR + (0x4 * (i + 1)), | ||
| 676 | &ioport); | ||
| 677 | ioport &= 0x0000FF00; /* the actual base address */ | ||
| 678 | pci_write_config_dword(dev, ITE_887x_POSIO0 + (0x4 * (i + 1)), | ||
| 679 | ITE_887x_POSIO_ENABLE | ITE_887x_POSIO_SPEED | | ||
| 680 | ITE_887x_POSIO_IOSIZE_8 | ioport); | ||
| 681 | |||
| 682 | /* write the ioport to the UARTBAR */ | ||
| 683 | pci_read_config_dword(dev, ITE_887x_UARTBAR, &uartbar); | ||
| 684 | uartbar &= ~(0xffff << (16 * i)); /* clear half the reg */ | ||
| 685 | uartbar |= (ioport << (16 * i)); /* set the ioport */ | ||
| 686 | pci_write_config_dword(dev, ITE_887x_UARTBAR, uartbar); | ||
| 687 | |||
| 688 | /* get current config */ | ||
| 689 | pci_read_config_dword(dev, ITE_887x_MISCR, &miscr); | ||
| 690 | /* disable interrupts (UARTx_Routing[3:0]) */ | ||
| 691 | miscr &= ~(0xf << (12 - 4 * i)); | ||
| 692 | /* activate the UART (UARTx_En) */ | ||
| 693 | miscr |= 1 << (23 - i); | ||
| 694 | /* write new config with activated UART */ | ||
| 695 | pci_write_config_dword(dev, ITE_887x_MISCR, miscr); | ||
| 696 | } | ||
| 697 | |||
| 698 | if (ret <= 0) { | ||
| 699 | /* the device has no UARTs if we get here */ | ||
| 700 | release_region(iobase->start, ITE_887x_IOSIZE); | ||
| 701 | } | ||
| 702 | |||
| 703 | return ret; | ||
| 704 | } | ||
| 705 | |||
| 706 | static void __devexit pci_ite887x_exit(struct pci_dev *dev) | ||
| 707 | { | ||
| 708 | u32 ioport; | ||
| 709 | /* the ioport is bit 0-15 in POSIO0R */ | ||
| 710 | pci_read_config_dword(dev, ITE_887x_POSIO0, &ioport); | ||
| 711 | ioport &= 0xffff; | ||
| 712 | release_region(ioport, ITE_887x_IOSIZE); | ||
| 713 | } | ||
| 714 | |||
| 583 | static int | 715 | static int |
| 584 | pci_default_setup(struct serial_private *priv, struct pciserial_board *board, | 716 | pci_default_setup(struct serial_private *priv, struct pciserial_board *board, |
| 585 | struct uart_port *port, int idx) | 717 | struct uart_port *port, int idx) |
| @@ -653,6 +785,18 @@ static struct pci_serial_quirk pci_serial_quirks[] = { | |||
| 653 | .setup = pci_default_setup, | 785 | .setup = pci_default_setup, |
| 654 | }, | 786 | }, |
| 655 | /* | 787 | /* |
| 788 | * ITE | ||
| 789 | */ | ||
| 790 | { | ||
| 791 | .vendor = PCI_VENDOR_ID_ITE, | ||
| 792 | .device = PCI_DEVICE_ID_ITE_8872, | ||
| 793 | .subvendor = PCI_ANY_ID, | ||
| 794 | .subdevice = PCI_ANY_ID, | ||
| 795 | .init = pci_ite887x_init, | ||
| 796 | .setup = pci_default_setup, | ||
| 797 | .exit = __devexit_p(pci_ite887x_exit), | ||
| 798 | }, | ||
| 799 | /* | ||
| 656 | * Panacom | 800 | * Panacom |
| 657 | */ | 801 | */ |
| 658 | { | 802 | { |
| @@ -933,6 +1077,7 @@ enum pci_board_num_t { | |||
| 933 | 1077 | ||
| 934 | pbn_b1_2_1250000, | 1078 | pbn_b1_2_1250000, |
| 935 | 1079 | ||
| 1080 | pbn_b1_bt_1_115200, | ||
| 936 | pbn_b1_bt_2_921600, | 1081 | pbn_b1_bt_2_921600, |
| 937 | 1082 | ||
| 938 | pbn_b1_1_1382400, | 1083 | pbn_b1_1_1382400, |
| @@ -983,6 +1128,7 @@ enum pci_board_num_t { | |||
| 983 | pbn_exar_XR17C152, | 1128 | pbn_exar_XR17C152, |
| 984 | pbn_exar_XR17C154, | 1129 | pbn_exar_XR17C154, |
| 985 | pbn_exar_XR17C158, | 1130 | pbn_exar_XR17C158, |
| 1131 | pbn_pasemi_1682M, | ||
| 986 | }; | 1132 | }; |
| 987 | 1133 | ||
| 988 | /* | 1134 | /* |
| @@ -1211,6 +1357,13 @@ static struct pciserial_board pci_boards[] __devinitdata = { | |||
| 1211 | .uart_offset = 8, | 1357 | .uart_offset = 8, |
| 1212 | }, | 1358 | }, |
| 1213 | 1359 | ||
| 1360 | [pbn_b1_bt_1_115200] = { | ||
| 1361 | .flags = FL_BASE1|FL_BASE_BARS, | ||
| 1362 | .num_ports = 1, | ||
| 1363 | .base_baud = 115200, | ||
| 1364 | .uart_offset = 8, | ||
| 1365 | }, | ||
| 1366 | |||
| 1214 | [pbn_b1_bt_2_921600] = { | 1367 | [pbn_b1_bt_2_921600] = { |
| 1215 | .flags = FL_BASE1|FL_BASE_BARS, | 1368 | .flags = FL_BASE1|FL_BASE_BARS, |
| 1216 | .num_ports = 2, | 1369 | .num_ports = 2, |
| @@ -1498,6 +1651,18 @@ static struct pciserial_board pci_boards[] __devinitdata = { | |||
| 1498 | .base_baud = 921600, | 1651 | .base_baud = 921600, |
| 1499 | .uart_offset = 0x200, | 1652 | .uart_offset = 0x200, |
| 1500 | }, | 1653 | }, |
| 1654 | /* | ||
| 1655 | * PA Semi PWRficient PA6T-1682M on-chip UART | ||
| 1656 | */ | ||
| 1657 | [pbn_pasemi_1682M] = { | ||
| 1658 | .flags = FL_BASE0, | ||
| 1659 | .num_ports = 1, | ||
| 1660 | .base_baud = 8333333, | ||
| 1661 | }, | ||
| 1662 | }; | ||
| 1663 | |||
| 1664 | static const struct pci_device_id softmodem_blacklist[] = { | ||
| 1665 | { PCI_VDEVICE ( AL, 0x5457 ), }, /* ALi Corporation M5457 AC'97 Modem */ | ||
| 1501 | }; | 1666 | }; |
| 1502 | 1667 | ||
| 1503 | /* | 1668 | /* |
| @@ -1508,6 +1673,7 @@ static struct pciserial_board pci_boards[] __devinitdata = { | |||
| 1508 | static int __devinit | 1673 | static int __devinit |
| 1509 | serial_pci_guess_board(struct pci_dev *dev, struct pciserial_board *board) | 1674 | serial_pci_guess_board(struct pci_dev *dev, struct pciserial_board *board) |
| 1510 | { | 1675 | { |
| 1676 | const struct pci_device_id *blacklist; | ||
| 1511 | int num_iomem, num_port, first_port = -1, i; | 1677 | int num_iomem, num_port, first_port = -1, i; |
| 1512 | 1678 | ||
| 1513 | /* | 1679 | /* |
| @@ -1522,6 +1688,18 @@ serial_pci_guess_board(struct pci_dev *dev, struct pciserial_board *board) | |||
| 1522 | (dev->class & 0xff) > 6) | 1688 | (dev->class & 0xff) > 6) |
| 1523 | return -ENODEV; | 1689 | return -ENODEV; |
| 1524 | 1690 | ||
| 1691 | /* | ||
| 1692 | * Do not access blacklisted devices that are known not to | ||
| 1693 | * feature serial ports. | ||
| 1694 | */ | ||
| 1695 | for (blacklist = softmodem_blacklist; | ||
| 1696 | blacklist < softmodem_blacklist + ARRAY_SIZE(softmodem_blacklist); | ||
| 1697 | blacklist++) { | ||
| 1698 | if (dev->vendor == blacklist->vendor && | ||
| 1699 | dev->device == blacklist->device) | ||
| 1700 | return -ENODEV; | ||
| 1701 | } | ||
| 1702 | |||
| 1525 | num_iomem = num_port = 0; | 1703 | num_iomem = num_port = 0; |
| 1526 | for (i = 0; i < PCI_NUM_BAR_RESOURCES; i++) { | 1704 | for (i = 0; i < PCI_NUM_BAR_RESOURCES; i++) { |
| 1527 | if (pci_resource_flags(dev, i) & IORESOURCE_IO) { | 1705 | if (pci_resource_flags(dev, i) & IORESOURCE_IO) { |
| @@ -2364,6 +2542,13 @@ static struct pci_device_id serial_pci_tbl[] = { | |||
| 2364 | { PCI_VENDOR_ID_TOPIC, PCI_DEVICE_ID_TOPIC_TP560, | 2542 | { PCI_VENDOR_ID_TOPIC, PCI_DEVICE_ID_TOPIC_TP560, |
| 2365 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 2543 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
| 2366 | pbn_b0_1_115200 }, | 2544 | pbn_b0_1_115200 }, |
| 2545 | /* | ||
| 2546 | * ITE | ||
| 2547 | */ | ||
| 2548 | { PCI_VENDOR_ID_ITE, PCI_DEVICE_ID_ITE_8872, | ||
| 2549 | PCI_ANY_ID, PCI_ANY_ID, | ||
| 2550 | 0, 0, | ||
| 2551 | pbn_b1_bt_1_115200 }, | ||
| 2367 | 2552 | ||
| 2368 | /* | 2553 | /* |
| 2369 | * IntaShield IS-200 | 2554 | * IntaShield IS-200 |
| @@ -2382,6 +2567,13 @@ static struct pci_device_id serial_pci_tbl[] = { | |||
| 2382 | PCI_SUBVENDOR_ID_PERLE, PCI_SUBDEVICE_ID_PCI_RAS8, | 2567 | PCI_SUBVENDOR_ID_PERLE, PCI_SUBDEVICE_ID_PCI_RAS8, |
| 2383 | 0, 0, pbn_b2_8_921600 }, | 2568 | 0, 0, pbn_b2_8_921600 }, |
| 2384 | /* | 2569 | /* |
| 2570 | * PA Semi PA6T-1682M on-chip UART | ||
| 2571 | */ | ||
| 2572 | { PCI_VENDOR_ID_PASEMI, 0xa004, | ||
| 2573 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | ||
| 2574 | pbn_pasemi_1682M }, | ||
| 2575 | |||
| 2576 | /* | ||
| 2385 | * These entries match devices with class COMMUNICATION_SERIAL, | 2577 | * These entries match devices with class COMMUNICATION_SERIAL, |
| 2386 | * COMMUNICATION_MODEM or COMMUNICATION_MULTISERIAL | 2578 | * COMMUNICATION_MODEM or COMMUNICATION_MULTISERIAL |
| 2387 | */ | 2579 | */ |
diff --git a/drivers/serial/serial_core.c b/drivers/serial/serial_core.c index 030a6063541d..a055f58f342f 100644 --- a/drivers/serial/serial_core.c +++ b/drivers/serial/serial_core.c | |||
| @@ -1146,11 +1146,14 @@ static void uart_set_termios(struct tty_struct *tty, struct ktermios *old_termio | |||
| 1146 | 1146 | ||
| 1147 | /* | 1147 | /* |
| 1148 | * These are the bits that are used to setup various | 1148 | * These are the bits that are used to setup various |
| 1149 | * flags in the low level driver. | 1149 | * flags in the low level driver. We can ignore the Bfoo |
| 1150 | * bits in c_cflag; c_[io]speed will always be set | ||
| 1151 | * appropriately by set_termios() in tty_ioctl.c | ||
| 1150 | */ | 1152 | */ |
| 1151 | #define RELEVANT_IFLAG(iflag) ((iflag) & (IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK)) | 1153 | #define RELEVANT_IFLAG(iflag) ((iflag) & (IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK)) |
| 1152 | |||
| 1153 | if ((cflag ^ old_termios->c_cflag) == 0 && | 1154 | if ((cflag ^ old_termios->c_cflag) == 0 && |
| 1155 | tty->termios->c_ospeed == old_termios->c_ospeed && | ||
| 1156 | tty->termios->c_ispeed == old_termios->c_ispeed && | ||
| 1154 | RELEVANT_IFLAG(tty->termios->c_iflag ^ old_termios->c_iflag) == 0) | 1157 | RELEVANT_IFLAG(tty->termios->c_iflag ^ old_termios->c_iflag) == 0) |
| 1155 | return; | 1158 | return; |
| 1156 | 1159 | ||
diff --git a/drivers/serial/serial_txx9.c b/drivers/serial/serial_txx9.c index b8f91e018b21..0930e2a85514 100644 --- a/drivers/serial/serial_txx9.c +++ b/drivers/serial/serial_txx9.c | |||
| @@ -37,7 +37,7 @@ | |||
| 37 | 37 | ||
| 38 | #include <asm/io.h> | 38 | #include <asm/io.h> |
| 39 | 39 | ||
| 40 | static char *serial_version = "1.09"; | 40 | static char *serial_version = "1.10"; |
| 41 | static char *serial_name = "TX39/49 Serial driver"; | 41 | static char *serial_name = "TX39/49 Serial driver"; |
| 42 | 42 | ||
| 43 | #define PASS_LIMIT 256 | 43 | #define PASS_LIMIT 256 |
| @@ -436,8 +436,10 @@ static unsigned int serial_txx9_get_mctrl(struct uart_port *port) | |||
| 436 | struct uart_txx9_port *up = (struct uart_txx9_port *)port; | 436 | struct uart_txx9_port *up = (struct uart_txx9_port *)port; |
| 437 | unsigned int ret; | 437 | unsigned int ret; |
| 438 | 438 | ||
| 439 | ret = ((sio_in(up, TXX9_SIFLCR) & TXX9_SIFLCR_RTSSC) ? 0 : TIOCM_RTS) | 439 | /* no modem control lines */ |
| 440 | | ((sio_in(up, TXX9_SICISR) & TXX9_SICISR_CTSS) ? 0 : TIOCM_CTS); | 440 | ret = TIOCM_CAR | TIOCM_DSR; |
| 441 | ret |= (sio_in(up, TXX9_SIFLCR) & TXX9_SIFLCR_RTSSC) ? 0 : TIOCM_RTS; | ||
| 442 | ret |= (sio_in(up, TXX9_SICISR) & TXX9_SICISR_CTSS) ? 0 : TIOCM_CTS; | ||
| 441 | 443 | ||
| 442 | return ret; | 444 | return ret; |
| 443 | } | 445 | } |
| @@ -557,6 +559,12 @@ serial_txx9_set_termios(struct uart_port *port, struct ktermios *termios, | |||
| 557 | unsigned long flags; | 559 | unsigned long flags; |
| 558 | unsigned int baud, quot; | 560 | unsigned int baud, quot; |
| 559 | 561 | ||
| 562 | /* | ||
| 563 | * We don't support modem control lines. | ||
| 564 | */ | ||
| 565 | termios->c_cflag &= ~(HUPCL | CMSPAR); | ||
| 566 | termios->c_cflag |= CLOCAL; | ||
| 567 | |||
| 560 | cval = sio_in(up, TXX9_SILCR); | 568 | cval = sio_in(up, TXX9_SILCR); |
| 561 | /* byte size and parity */ | 569 | /* byte size and parity */ |
| 562 | cval &= ~TXX9_SILCR_UMODE_MASK; | 570 | cval &= ~TXX9_SILCR_UMODE_MASK; |
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 | |||
| 21 | default y if USB_ARCH_HAS_EHCI | 21 | default y if USB_ARCH_HAS_EHCI |
| 22 | default y if PCMCIA && !M32R # sl811_cs | 22 | default y if PCMCIA && !M32R # sl811_cs |
| 23 | default y if ARM # SL-811 | 23 | default y if ARM # SL-811 |
| 24 | default y if SUPERH # r8a66597-hcd | ||
| 24 | default PCI | 25 | default PCI |
| 25 | 26 | ||
| 26 | # many non-PCI SOC chips embed OHCI | 27 | # 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, | |||
| 456 | int* actual_length) | 456 | int* actual_length) |
| 457 | { | 457 | { |
| 458 | struct timer_list timer; | 458 | struct timer_list timer; |
| 459 | int status = urb->status; | ||
| 460 | 459 | ||
| 461 | init_timer(&timer); | 460 | init_timer(&timer); |
| 462 | timer.expires = jiffies + msecs_to_jiffies(CMD_TIMEOUT); | 461 | timer.expires = jiffies + msecs_to_jiffies(CMD_TIMEOUT); |
| @@ -468,7 +467,7 @@ static int cxacru_start_wait_urb(struct urb *urb, struct completion *done, | |||
| 468 | 467 | ||
| 469 | if (actual_length) | 468 | if (actual_length) |
| 470 | *actual_length = urb->actual_length; | 469 | *actual_length = urb->actual_length; |
| 471 | return status; | 470 | return urb->status; /* must read status after completion */ |
| 472 | } | 471 | } |
| 473 | 472 | ||
| 474 | static int cxacru_cm(struct cxacru_data *instance, enum cxacru_cm_request cm, | 473 | 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, | |||
| 1721 | 1721 | ||
| 1722 | ret = uea_boot(sc); | 1722 | ret = uea_boot(sc); |
| 1723 | if (ret < 0) | 1723 | if (ret < 0) |
| 1724 | goto error; | 1724 | goto error_rm_grp; |
| 1725 | 1725 | ||
| 1726 | return 0; | 1726 | return 0; |
| 1727 | |||
| 1728 | error_rm_grp: | ||
| 1729 | sysfs_remove_group(&intf->dev.kobj, &attr_grp); | ||
| 1727 | error: | 1730 | error: |
| 1728 | kfree(sc); | 1731 | kfree(sc); |
| 1729 | return ret; | 1732 | 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: | |||
| 921 | return -EINVAL; | 921 | return -EINVAL; |
| 922 | } | 922 | } |
| 923 | } | 923 | } |
| 924 | |||
| 925 | /* Accept probe requests only for the control interface */ | ||
| 926 | if (intf != control_interface) | ||
| 927 | return -ENODEV; | ||
| 924 | 928 | ||
| 925 | if (usb_interface_claimed(data_interface)) { /* valid in this context */ | 929 | if (usb_interface_claimed(data_interface)) { /* valid in this context */ |
| 926 | dev_dbg(&intf->dev,"The data interface isn't available"); | 930 | dev_dbg(&intf->dev,"The data interface isn't available"); |
| @@ -1109,10 +1113,12 @@ static void acm_disconnect(struct usb_interface *intf) | |||
| 1109 | return; | 1113 | return; |
| 1110 | } | 1114 | } |
| 1111 | if (acm->country_codes){ | 1115 | if (acm->country_codes){ |
| 1112 | device_remove_file(&intf->dev, &dev_attr_wCountryCodes); | 1116 | device_remove_file(&acm->control->dev, |
| 1113 | device_remove_file(&intf->dev, &dev_attr_iCountryCodeRelDate); | 1117 | &dev_attr_wCountryCodes); |
| 1118 | device_remove_file(&acm->control->dev, | ||
| 1119 | &dev_attr_iCountryCodeRelDate); | ||
| 1114 | } | 1120 | } |
| 1115 | device_remove_file(&intf->dev, &dev_attr_bmCapabilities); | 1121 | device_remove_file(&acm->control->dev, &dev_attr_bmCapabilities); |
| 1116 | acm->dev = NULL; | 1122 | acm->dev = NULL; |
| 1117 | usb_set_intfdata(acm->control, NULL); | 1123 | usb_set_intfdata(acm->control, NULL); |
| 1118 | usb_set_intfdata(acm->data, NULL); | 1124 | 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) | |||
| 1224 | udev->auto_pm = 1; | 1224 | udev->auto_pm = 1; |
| 1225 | udev->pm_usage_cnt += inc_usage_cnt; | 1225 | udev->pm_usage_cnt += inc_usage_cnt; |
| 1226 | WARN_ON(udev->pm_usage_cnt < 0); | 1226 | WARN_ON(udev->pm_usage_cnt < 0); |
| 1227 | if (inc_usage_cnt) | ||
| 1228 | udev->last_busy = jiffies; | ||
| 1227 | if (inc_usage_cnt >= 0 && udev->pm_usage_cnt > 0) { | 1229 | if (inc_usage_cnt >= 0 && udev->pm_usage_cnt > 0) { |
| 1228 | if (udev->state == USB_STATE_SUSPENDED) | 1230 | if (udev->state == USB_STATE_SUSPENDED) |
| 1229 | status = usb_resume_both(udev); | 1231 | status = usb_resume_both(udev); |
| @@ -1232,8 +1234,6 @@ static int usb_autopm_do_device(struct usb_device *udev, int inc_usage_cnt) | |||
| 1232 | else if (inc_usage_cnt) | 1234 | else if (inc_usage_cnt) |
| 1233 | udev->last_busy = jiffies; | 1235 | udev->last_busy = jiffies; |
| 1234 | } else if (inc_usage_cnt <= 0 && udev->pm_usage_cnt <= 0) { | 1236 | } else if (inc_usage_cnt <= 0 && udev->pm_usage_cnt <= 0) { |
| 1235 | if (inc_usage_cnt) | ||
| 1236 | udev->last_busy = jiffies; | ||
| 1237 | status = usb_suspend_both(udev, PMSG_SUSPEND); | 1237 | status = usb_suspend_both(udev, PMSG_SUSPEND); |
| 1238 | } | 1238 | } |
| 1239 | usb_pm_unlock(udev); | 1239 | usb_pm_unlock(udev); |
| @@ -1342,16 +1342,15 @@ static int usb_autopm_do_interface(struct usb_interface *intf, | |||
| 1342 | else { | 1342 | else { |
| 1343 | udev->auto_pm = 1; | 1343 | udev->auto_pm = 1; |
| 1344 | intf->pm_usage_cnt += inc_usage_cnt; | 1344 | intf->pm_usage_cnt += inc_usage_cnt; |
| 1345 | udev->last_busy = jiffies; | ||
| 1345 | if (inc_usage_cnt >= 0 && intf->pm_usage_cnt > 0) { | 1346 | if (inc_usage_cnt >= 0 && intf->pm_usage_cnt > 0) { |
| 1346 | if (udev->state == USB_STATE_SUSPENDED) | 1347 | if (udev->state == USB_STATE_SUSPENDED) |
| 1347 | status = usb_resume_both(udev); | 1348 | status = usb_resume_both(udev); |
| 1348 | if (status != 0) | 1349 | if (status != 0) |
| 1349 | intf->pm_usage_cnt -= inc_usage_cnt; | 1350 | intf->pm_usage_cnt -= inc_usage_cnt; |
| 1350 | else if (inc_usage_cnt) | 1351 | else |
| 1351 | udev->last_busy = jiffies; | 1352 | udev->last_busy = jiffies; |
| 1352 | } else if (inc_usage_cnt <= 0 && intf->pm_usage_cnt <= 0) { | 1353 | } else if (inc_usage_cnt <= 0 && intf->pm_usage_cnt <= 0) { |
| 1353 | if (inc_usage_cnt) | ||
| 1354 | udev->last_busy = jiffies; | ||
| 1355 | status = usb_suspend_both(udev, PMSG_SUSPEND); | 1354 | status = usb_suspend_both(udev, PMSG_SUSPEND); |
| 1356 | } | 1355 | } |
| 1357 | } | 1356 | } |
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) | |||
| 1644 | * and device drivers will know about any resume quirks. | 1644 | * and device drivers will know about any resume quirks. |
| 1645 | */ | 1645 | */ |
| 1646 | if (status == 0) { | 1646 | if (status == 0) { |
| 1647 | devstatus = 0; | ||
| 1647 | status = usb_get_status(udev, USB_RECIP_DEVICE, 0, &devstatus); | 1648 | status = usb_get_status(udev, USB_RECIP_DEVICE, 0, &devstatus); |
| 1648 | if (status >= 0) | 1649 | if (status >= 0) |
| 1649 | status = (status == 2 ? 0 : -ENODEV); | 1650 | status = (status > 0 ? 0 : -ENODEV); |
| 1650 | } | 1651 | } |
| 1651 | 1652 | ||
| 1652 | if (status) { | 1653 | 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 | |||
| 637 | memset(buf,0,size); // Make sure we parse really received data | 637 | memset(buf,0,size); // Make sure we parse really received data |
| 638 | 638 | ||
| 639 | for (i = 0; i < 3; ++i) { | 639 | for (i = 0; i < 3; ++i) { |
| 640 | /* retry on length 0 or stall; some devices are flakey */ | 640 | /* retry on length 0 or error; some devices are flakey */ |
| 641 | result = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), | 641 | result = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), |
| 642 | USB_REQ_GET_DESCRIPTOR, USB_DIR_IN, | 642 | USB_REQ_GET_DESCRIPTOR, USB_DIR_IN, |
| 643 | (type << 8) + index, 0, buf, size, | 643 | (type << 8) + index, 0, buf, size, |
| 644 | USB_CTRL_GET_TIMEOUT); | 644 | USB_CTRL_GET_TIMEOUT); |
| 645 | if (result == 0 || result == -EPIPE) | 645 | if (result <= 0 && result != -ETIMEDOUT) |
| 646 | continue; | 646 | continue; |
| 647 | if (result > 1 && ((u8 *)buf)[1] != type) { | 647 | if (result > 1 && ((u8 *)buf)[1] != type) { |
| 648 | result = -EPROTO; | 648 | result = -EPROTO; |
| @@ -1358,6 +1358,30 @@ static int usb_if_uevent(struct device *dev, char **envp, int num_envp, | |||
| 1358 | usb_dev = interface_to_usbdev(intf); | 1358 | usb_dev = interface_to_usbdev(intf); |
| 1359 | alt = intf->cur_altsetting; | 1359 | alt = intf->cur_altsetting; |
| 1360 | 1360 | ||
| 1361 | #ifdef CONFIG_USB_DEVICEFS | ||
| 1362 | if (add_uevent_var(envp, num_envp, &i, | ||
| 1363 | buffer, buffer_size, &length, | ||
| 1364 | "DEVICE=/proc/bus/usb/%03d/%03d", | ||
| 1365 | usb_dev->bus->busnum, usb_dev->devnum)) | ||
| 1366 | return -ENOMEM; | ||
| 1367 | #endif | ||
| 1368 | |||
| 1369 | if (add_uevent_var(envp, num_envp, &i, | ||
| 1370 | buffer, buffer_size, &length, | ||
| 1371 | "PRODUCT=%x/%x/%x", | ||
| 1372 | le16_to_cpu(usb_dev->descriptor.idVendor), | ||
| 1373 | le16_to_cpu(usb_dev->descriptor.idProduct), | ||
| 1374 | le16_to_cpu(usb_dev->descriptor.bcdDevice))) | ||
| 1375 | return -ENOMEM; | ||
| 1376 | |||
| 1377 | if (add_uevent_var(envp, num_envp, &i, | ||
| 1378 | buffer, buffer_size, &length, | ||
| 1379 | "TYPE=%d/%d/%d", | ||
| 1380 | usb_dev->descriptor.bDeviceClass, | ||
| 1381 | usb_dev->descriptor.bDeviceSubClass, | ||
| 1382 | usb_dev->descriptor.bDeviceProtocol)) | ||
| 1383 | return -ENOMEM; | ||
| 1384 | |||
| 1361 | if (add_uevent_var(envp, num_envp, &i, | 1385 | if (add_uevent_var(envp, num_envp, &i, |
| 1362 | buffer, buffer_size, &length, | 1386 | buffer, buffer_size, &length, |
| 1363 | "INTERFACE=%d/%d/%d", | 1387 | "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 @@ | |||
| 30 | static const struct usb_device_id usb_quirk_list[] = { | 30 | static const struct usb_device_id usb_quirk_list[] = { |
| 31 | /* HP 5300/5370C scanner */ | 31 | /* HP 5300/5370C scanner */ |
| 32 | { USB_DEVICE(0x03f0, 0x0701), .driver_info = USB_QUIRK_STRING_FETCH_255 }, | 32 | { USB_DEVICE(0x03f0, 0x0701), .driver_info = USB_QUIRK_STRING_FETCH_255 }, |
| 33 | /* Hewlett-Packard PhotoSmart 720 / PhotoSmart 935 (storage) */ | ||
| 34 | { USB_DEVICE(0x03f0, 0x4002), .driver_info = USB_QUIRK_NO_AUTOSUSPEND }, | ||
| 33 | /* Acer Peripherals Inc. (now BenQ Corp.) Prisa 640BU */ | 35 | /* Acer Peripherals Inc. (now BenQ Corp.) Prisa 640BU */ |
| 34 | { USB_DEVICE(0x04a5, 0x207e), .driver_info = USB_QUIRK_NO_AUTOSUSPEND }, | 36 | { USB_DEVICE(0x04a5, 0x207e), .driver_info = USB_QUIRK_NO_AUTOSUSPEND }, |
| 35 | /* Benq S2W 3300U */ | 37 | /* Benq S2W 3300U */ |
| @@ -56,6 +58,8 @@ static const struct usb_device_id usb_quirk_list[] = { | |||
| 56 | { USB_DEVICE(0x04b8, 0x0121), .driver_info = USB_QUIRK_NO_AUTOSUSPEND }, | 58 | { USB_DEVICE(0x04b8, 0x0121), .driver_info = USB_QUIRK_NO_AUTOSUSPEND }, |
| 57 | /* Seiko Epson Corp.*/ | 59 | /* Seiko Epson Corp.*/ |
| 58 | { USB_DEVICE(0x04b8, 0x0122), .driver_info = USB_QUIRK_NO_AUTOSUSPEND }, | 60 | { USB_DEVICE(0x04b8, 0x0122), .driver_info = USB_QUIRK_NO_AUTOSUSPEND }, |
| 61 | /* Samsung ML-2010 printer */ | ||
| 62 | { USB_DEVICE(0x04e8, 0x326c), .driver_info = USB_QUIRK_NO_AUTOSUSPEND }, | ||
| 59 | /* Samsung ML-2510 Series printer */ | 63 | /* Samsung ML-2510 Series printer */ |
| 60 | { USB_DEVICE(0x04e8, 0x327e), .driver_info = USB_QUIRK_NO_AUTOSUSPEND }, | 64 | { USB_DEVICE(0x04e8, 0x327e), .driver_info = USB_QUIRK_NO_AUTOSUSPEND }, |
| 61 | /* Elsa MicroLink 56k (V.250) */ | 65 | /* Elsa MicroLink 56k (V.250) */ |
| @@ -64,12 +68,20 @@ static const struct usb_device_id usb_quirk_list[] = { | |||
| 64 | { USB_DEVICE(0x05d8, 0x4005), .driver_info = USB_QUIRK_NO_AUTOSUSPEND }, | 68 | { USB_DEVICE(0x05d8, 0x4005), .driver_info = USB_QUIRK_NO_AUTOSUSPEND }, |
| 65 | /* Agfa Snapscan1212u */ | 69 | /* Agfa Snapscan1212u */ |
| 66 | { USB_DEVICE(0x06bd, 0x2061), .driver_info = USB_QUIRK_NO_AUTOSUSPEND }, | 70 | { USB_DEVICE(0x06bd, 0x2061), .driver_info = USB_QUIRK_NO_AUTOSUSPEND }, |
| 71 | /* Seagate RSS LLC */ | ||
| 72 | { USB_DEVICE(0x0bc2, 0x3000), .driver_info = USB_QUIRK_NO_AUTOSUSPEND }, | ||
| 67 | /* Umax [hex] Astra 3400U */ | 73 | /* Umax [hex] Astra 3400U */ |
| 68 | { USB_DEVICE(0x1606, 0x0060), .driver_info = USB_QUIRK_NO_AUTOSUSPEND }, | 74 | { USB_DEVICE(0x1606, 0x0060), .driver_info = USB_QUIRK_NO_AUTOSUSPEND }, |
| 69 | 75 | ||
| 70 | /* Philips PSC805 audio device */ | 76 | /* Philips PSC805 audio device */ |
| 71 | { USB_DEVICE(0x0471, 0x0155), .driver_info = USB_QUIRK_RESET_RESUME }, | 77 | { USB_DEVICE(0x0471, 0x0155), .driver_info = USB_QUIRK_RESET_RESUME }, |
| 72 | 78 | ||
| 79 | /* Alcor multi-card reader */ | ||
| 80 | { USB_DEVICE(0x058f, 0x6366), .driver_info = USB_QUIRK_NO_AUTOSUSPEND }, | ||
| 81 | |||
| 82 | /* Canon EOS 5D in PC Connection mode */ | ||
| 83 | { USB_DEVICE(0x04a9, 0x3101), .driver_info = USB_QUIRK_NO_AUTOSUSPEND }, | ||
| 84 | |||
| 73 | /* RIM Blackberry */ | 85 | /* RIM Blackberry */ |
| 74 | { USB_DEVICE(0x0fca, 0x0001), .driver_info = USB_QUIRK_NO_AUTOSUSPEND }, | 86 | { USB_DEVICE(0x0fca, 0x0001), .driver_info = USB_QUIRK_NO_AUTOSUSPEND }, |
| 75 | { USB_DEVICE(0x0fca, 0x0004), .driver_info = USB_QUIRK_NO_AUTOSUSPEND }, | 87 | { 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 @@ | |||
| 34 | * bypassing some hardware (and driver) issues. UML could help too. | 34 | * bypassing some hardware (and driver) issues. UML could help too. |
| 35 | */ | 35 | */ |
| 36 | 36 | ||
| 37 | #define DEBUG | ||
| 38 | |||
| 39 | #include <linux/module.h> | 37 | #include <linux/module.h> |
| 40 | #include <linux/kernel.h> | 38 | #include <linux/kernel.h> |
| 41 | #include <linux/delay.h> | 39 | #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 { | |||
| 599 | 599 | ||
| 600 | struct fsg_buffhd { | 600 | struct fsg_buffhd { |
| 601 | void *buf; | 601 | void *buf; |
| 602 | dma_addr_t dma; | ||
| 603 | enum fsg_buffer_state state; | 602 | enum fsg_buffer_state state; |
| 604 | struct fsg_buffhd *next; | 603 | struct fsg_buffhd *next; |
| 605 | 604 | ||
| @@ -1295,6 +1294,7 @@ static int class_setup_req(struct fsg_dev *fsg, | |||
| 1295 | struct usb_request *req = fsg->ep0req; | 1294 | struct usb_request *req = fsg->ep0req; |
| 1296 | int value = -EOPNOTSUPP; | 1295 | int value = -EOPNOTSUPP; |
| 1297 | u16 w_index = le16_to_cpu(ctrl->wIndex); | 1296 | u16 w_index = le16_to_cpu(ctrl->wIndex); |
| 1297 | u16 w_value = le16_to_cpu(ctrl->wValue); | ||
| 1298 | u16 w_length = le16_to_cpu(ctrl->wLength); | 1298 | u16 w_length = le16_to_cpu(ctrl->wLength); |
| 1299 | 1299 | ||
| 1300 | if (!fsg->config) | 1300 | if (!fsg->config) |
| @@ -1308,7 +1308,7 @@ static int class_setup_req(struct fsg_dev *fsg, | |||
| 1308 | if (ctrl->bRequestType != (USB_DIR_OUT | | 1308 | if (ctrl->bRequestType != (USB_DIR_OUT | |
| 1309 | USB_TYPE_CLASS | USB_RECIP_INTERFACE)) | 1309 | USB_TYPE_CLASS | USB_RECIP_INTERFACE)) |
| 1310 | break; | 1310 | break; |
| 1311 | if (w_index != 0) { | 1311 | if (w_index != 0 || w_value != 0) { |
| 1312 | value = -EDOM; | 1312 | value = -EDOM; |
| 1313 | break; | 1313 | break; |
| 1314 | } | 1314 | } |
| @@ -1324,7 +1324,7 @@ static int class_setup_req(struct fsg_dev *fsg, | |||
| 1324 | if (ctrl->bRequestType != (USB_DIR_IN | | 1324 | if (ctrl->bRequestType != (USB_DIR_IN | |
| 1325 | USB_TYPE_CLASS | USB_RECIP_INTERFACE)) | 1325 | USB_TYPE_CLASS | USB_RECIP_INTERFACE)) |
| 1326 | break; | 1326 | break; |
| 1327 | if (w_index != 0) { | 1327 | if (w_index != 0 || w_value != 0) { |
| 1328 | value = -EDOM; | 1328 | value = -EDOM; |
| 1329 | break; | 1329 | break; |
| 1330 | } | 1330 | } |
| @@ -1343,7 +1343,7 @@ static int class_setup_req(struct fsg_dev *fsg, | |||
| 1343 | if (ctrl->bRequestType != (USB_DIR_OUT | | 1343 | if (ctrl->bRequestType != (USB_DIR_OUT | |
| 1344 | USB_TYPE_CLASS | USB_RECIP_INTERFACE)) | 1344 | USB_TYPE_CLASS | USB_RECIP_INTERFACE)) |
| 1345 | break; | 1345 | break; |
| 1346 | if (w_index != 0) { | 1346 | if (w_index != 0 || w_value != 0) { |
| 1347 | value = -EDOM; | 1347 | value = -EDOM; |
| 1348 | break; | 1348 | break; |
| 1349 | } | 1349 | } |
| @@ -2611,7 +2611,6 @@ static int send_status(struct fsg_dev *fsg) | |||
| 2611 | 2611 | ||
| 2612 | fsg->intr_buffhd = bh; // Point to the right buffhd | 2612 | fsg->intr_buffhd = bh; // Point to the right buffhd |
| 2613 | fsg->intreq->buf = bh->inreq->buf; | 2613 | fsg->intreq->buf = bh->inreq->buf; |
| 2614 | fsg->intreq->dma = bh->inreq->dma; | ||
| 2615 | fsg->intreq->context = bh; | 2614 | fsg->intreq->context = bh; |
| 2616 | start_transfer(fsg, fsg->intr_in, fsg->intreq, | 2615 | start_transfer(fsg, fsg->intr_in, fsg->intreq, |
| 2617 | &fsg->intreq_busy, &bh->state); | 2616 | &fsg->intreq_busy, &bh->state); |
| @@ -3200,7 +3199,6 @@ reset: | |||
| 3200 | if ((rc = alloc_request(fsg, fsg->bulk_out, &bh->outreq)) != 0) | 3199 | if ((rc = alloc_request(fsg, fsg->bulk_out, &bh->outreq)) != 0) |
| 3201 | goto reset; | 3200 | goto reset; |
| 3202 | bh->inreq->buf = bh->outreq->buf = bh->buf; | 3201 | bh->inreq->buf = bh->outreq->buf = bh->buf; |
| 3203 | bh->inreq->dma = bh->outreq->dma = bh->dma; | ||
| 3204 | bh->inreq->context = bh->outreq->context = bh; | 3202 | bh->inreq->context = bh->outreq->context = bh; |
| 3205 | bh->inreq->complete = bulk_in_complete; | 3203 | bh->inreq->complete = bulk_in_complete; |
| 3206 | bh->outreq->complete = bulk_out_complete; | 3204 | 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, | |||
| 1277 | 1277 | ||
| 1278 | udc_reset_ep_queue(udc, 0); | 1278 | udc_reset_ep_queue(udc, 0); |
| 1279 | 1279 | ||
| 1280 | /* We process some stardard setup requests here */ | ||
| 1280 | switch (setup->bRequest) { | 1281 | switch (setup->bRequest) { |
| 1281 | /* Request that need Data+Status phase from udc */ | ||
| 1282 | case USB_REQ_GET_STATUS: | 1282 | case USB_REQ_GET_STATUS: |
| 1283 | if ((setup->bRequestType & (USB_DIR_IN | USB_TYPE_STANDARD)) | 1283 | /* Data+Status phase from udc */ |
| 1284 | if ((setup->bRequestType & (USB_DIR_IN | USB_TYPE_MASK)) | ||
| 1284 | != (USB_DIR_IN | USB_TYPE_STANDARD)) | 1285 | != (USB_DIR_IN | USB_TYPE_STANDARD)) |
| 1285 | break; | 1286 | break; |
| 1286 | ch9getstatus(udc, setup->bRequestType, wValue, wIndex, wLength); | 1287 | ch9getstatus(udc, setup->bRequestType, wValue, wIndex, wLength); |
| 1287 | break; | 1288 | return; |
| 1288 | 1289 | ||
| 1289 | /* Requests that need Status phase from udc */ | ||
| 1290 | case USB_REQ_SET_ADDRESS: | 1290 | case USB_REQ_SET_ADDRESS: |
| 1291 | /* Status phase from udc */ | ||
| 1291 | if (setup->bRequestType != (USB_DIR_OUT | USB_TYPE_STANDARD | 1292 | if (setup->bRequestType != (USB_DIR_OUT | USB_TYPE_STANDARD |
| 1292 | | USB_RECIP_DEVICE)) | 1293 | | USB_RECIP_DEVICE)) |
| 1293 | break; | 1294 | break; |
| 1294 | ch9setaddress(udc, wValue, wIndex, wLength); | 1295 | ch9setaddress(udc, wValue, wIndex, wLength); |
| 1295 | break; | 1296 | return; |
| 1296 | 1297 | ||
| 1297 | /* Handled by udc, no data, status by udc */ | ||
| 1298 | case USB_REQ_CLEAR_FEATURE: | 1298 | case USB_REQ_CLEAR_FEATURE: |
| 1299 | case USB_REQ_SET_FEATURE: | 1299 | case USB_REQ_SET_FEATURE: |
| 1300 | { /* status transaction */ | 1300 | /* Status phase from udc */ |
| 1301 | { | ||
| 1301 | int rc = -EOPNOTSUPP; | 1302 | int rc = -EOPNOTSUPP; |
| 1302 | 1303 | ||
| 1303 | if ((setup->bRequestType & USB_RECIP_MASK) | 1304 | if ((setup->bRequestType & (USB_RECIP_MASK | USB_TYPE_MASK)) |
| 1304 | == USB_RECIP_ENDPOINT) { | 1305 | == (USB_RECIP_ENDPOINT | USB_TYPE_STANDARD)) { |
| 1305 | int pipe = get_pipe_by_windex(wIndex); | 1306 | int pipe = get_pipe_by_windex(wIndex); |
| 1306 | struct fsl_ep *ep; | 1307 | struct fsl_ep *ep; |
| 1307 | 1308 | ||
| @@ -1315,8 +1316,9 @@ static void setup_received_irq(struct fsl_udc *udc, | |||
| 1315 | ? 1 : 0); | 1316 | ? 1 : 0); |
| 1316 | spin_lock(&udc->lock); | 1317 | spin_lock(&udc->lock); |
| 1317 | 1318 | ||
| 1318 | } else if ((setup->bRequestType & USB_RECIP_MASK) | 1319 | } else if ((setup->bRequestType & (USB_RECIP_MASK |
| 1319 | == USB_RECIP_DEVICE) { | 1320 | | USB_TYPE_MASK)) == (USB_RECIP_DEVICE |
| 1321 | | USB_TYPE_STANDARD)) { | ||
| 1320 | /* Note: The driver has not include OTG support yet. | 1322 | /* Note: The driver has not include OTG support yet. |
| 1321 | * This will be set when OTG support is added */ | 1323 | * This will be set when OTG support is added */ |
| 1322 | if (!udc->gadget.is_otg) | 1324 | if (!udc->gadget.is_otg) |
| @@ -1329,39 +1331,42 @@ static void setup_received_irq(struct fsl_udc *udc, | |||
| 1329 | USB_DEVICE_A_ALT_HNP_SUPPORT) | 1331 | USB_DEVICE_A_ALT_HNP_SUPPORT) |
| 1330 | udc->gadget.a_alt_hnp_support = 1; | 1332 | udc->gadget.a_alt_hnp_support = 1; |
| 1331 | rc = 0; | 1333 | rc = 0; |
| 1332 | } | 1334 | } else |
| 1335 | break; | ||
| 1336 | |||
| 1333 | if (rc == 0) { | 1337 | if (rc == 0) { |
| 1334 | if (ep0_prime_status(udc, EP_DIR_IN)) | 1338 | if (ep0_prime_status(udc, EP_DIR_IN)) |
| 1335 | ep0stall(udc); | 1339 | ep0stall(udc); |
| 1336 | } | 1340 | } |
| 1337 | break; | 1341 | return; |
| 1338 | } | 1342 | } |
| 1339 | /* Requests handled by gadget */ | ||
| 1340 | default: | ||
| 1341 | if (wLength) { | ||
| 1342 | /* Data phase from gadget, status phase from udc */ | ||
| 1343 | udc->ep0_dir = (setup->bRequestType & USB_DIR_IN) | ||
| 1344 | ? USB_DIR_IN : USB_DIR_OUT; | ||
| 1345 | spin_unlock(&udc->lock); | ||
| 1346 | if (udc->driver->setup(&udc->gadget, | ||
| 1347 | &udc->local_setup_buff) < 0) | ||
| 1348 | ep0stall(udc); | ||
| 1349 | spin_lock(&udc->lock); | ||
| 1350 | udc->ep0_state = (setup->bRequestType & USB_DIR_IN) | ||
| 1351 | ? DATA_STATE_XMIT : DATA_STATE_RECV; | ||
| 1352 | 1343 | ||
| 1353 | } else { | 1344 | default: |
| 1354 | /* No data phase, IN status from gadget */ | ||
| 1355 | udc->ep0_dir = USB_DIR_IN; | ||
| 1356 | spin_unlock(&udc->lock); | ||
| 1357 | if (udc->driver->setup(&udc->gadget, | ||
| 1358 | &udc->local_setup_buff) < 0) | ||
| 1359 | ep0stall(udc); | ||
| 1360 | spin_lock(&udc->lock); | ||
| 1361 | udc->ep0_state = WAIT_FOR_OUT_STATUS; | ||
| 1362 | } | ||
| 1363 | break; | 1345 | break; |
| 1364 | } | 1346 | } |
| 1347 | |||
| 1348 | /* Requests handled by gadget */ | ||
| 1349 | if (wLength) { | ||
| 1350 | /* Data phase from gadget, status phase from udc */ | ||
| 1351 | udc->ep0_dir = (setup->bRequestType & USB_DIR_IN) | ||
| 1352 | ? USB_DIR_IN : USB_DIR_OUT; | ||
| 1353 | spin_unlock(&udc->lock); | ||
| 1354 | if (udc->driver->setup(&udc->gadget, | ||
| 1355 | &udc->local_setup_buff) < 0) | ||
| 1356 | ep0stall(udc); | ||
| 1357 | spin_lock(&udc->lock); | ||
| 1358 | udc->ep0_state = (setup->bRequestType & USB_DIR_IN) | ||
| 1359 | ? DATA_STATE_XMIT : DATA_STATE_RECV; | ||
| 1360 | } else { | ||
| 1361 | /* No data phase, IN status from gadget */ | ||
| 1362 | udc->ep0_dir = USB_DIR_IN; | ||
| 1363 | spin_unlock(&udc->lock); | ||
| 1364 | if (udc->driver->setup(&udc->gadget, | ||
| 1365 | &udc->local_setup_buff) < 0) | ||
| 1366 | ep0stall(udc); | ||
| 1367 | spin_lock(&udc->lock); | ||
| 1368 | udc->ep0_state = WAIT_FOR_OUT_STATUS; | ||
| 1369 | } | ||
| 1365 | } | 1370 | } |
| 1366 | 1371 | ||
| 1367 | /* Process request for Data or Status phase of ep0 | 1372 | /* 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) | |||
| 967 | udc = container_of(_gadget, struct pxa2xx_udc, gadget); | 967 | udc = container_of(_gadget, struct pxa2xx_udc, gadget); |
| 968 | 968 | ||
| 969 | /* not all boards support pullup control */ | 969 | /* not all boards support pullup control */ |
| 970 | if (!udc->mach->udc_command) | 970 | if (!udc->mach->gpio_pullup && !udc->mach->udc_command) |
| 971 | return -EOPNOTSUPP; | 971 | return -EOPNOTSUPP; |
| 972 | 972 | ||
| 973 | is_active = (is_active != 0); | 973 | is_active = (is_active != 0); |
| @@ -2309,7 +2309,7 @@ static int pxa2xx_udc_suspend(struct platform_device *dev, pm_message_t state) | |||
| 2309 | { | 2309 | { |
| 2310 | struct pxa2xx_udc *udc = platform_get_drvdata(dev); | 2310 | struct pxa2xx_udc *udc = platform_get_drvdata(dev); |
| 2311 | 2311 | ||
| 2312 | if (!udc->mach->udc_command) | 2312 | if (!udc->mach->gpio_pullup && !udc->mach->udc_command) |
| 2313 | WARN("USB host won't detect disconnect!\n"); | 2313 | WARN("USB host won't detect disconnect!\n"); |
| 2314 | pullup(udc, 0); | 2314 | pullup(udc, 0); |
| 2315 | 2315 | ||
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 | |||
| 237 | module will be called "sl811_cs". | 237 | module will be called "sl811_cs". |
| 238 | 238 | ||
| 239 | config USB_R8A66597_HCD | 239 | config USB_R8A66597_HCD |
| 240 | tristate "R8A66597 HCD suppoort" | 240 | tristate "R8A66597 HCD support" |
| 241 | depends on USB | 241 | depends on USB |
| 242 | help | 242 | help |
| 243 | The R8A66597 is a USB 2.0 host and peripheral controller. | 243 | 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 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * EHCI HCD (Host Controller Driver) for USB. | 2 | * EHCI HCD (Host Controller Driver) for USB. |
| 3 | * | 3 | * |
| 4 | * (C) Copyright 2000-2004 David Brownell <dbrownell@users.sourceforge.net> | ||
| 5 | * | ||
| 6 | * Bus Glue for AMD Alchemy Au1xxx | 4 | * Bus Glue for AMD Alchemy Au1xxx |
| 7 | * | 5 | * |
| 8 | * Based on "ohci-au1xxx.c" by Matt Porter <mporter@kernel.crashing.org> | 6 | * 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 = { | |||
| 196 | 194 | ||
| 197 | /* | 195 | /* |
| 198 | * basic lifecycle operations | 196 | * basic lifecycle operations |
| 197 | * | ||
| 198 | * FIXME -- ehci_init() doesn't do enough here. | ||
| 199 | * See ehci-ppc-soc for a complete implementation. | ||
| 199 | */ | 200 | */ |
| 200 | .reset = ehci_init, | 201 | .reset = ehci_init, |
| 201 | .start = ehci_run, | 202 | .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 @@ | |||
| 6 | * Bus Glue for PPC On-Chip EHCI driver | 6 | * Bus Glue for PPC On-Chip EHCI driver |
| 7 | * Tested on AMCC 440EPx | 7 | * Tested on AMCC 440EPx |
| 8 | * | 8 | * |
| 9 | * Based on "ehci-au12xx.c" by David Brownell <dbrownell@users.sourceforge.net> | 9 | * Based on "ehci-au1xxx.c" by K.Boge <karsten.boge@amd.com> |
| 10 | * | 10 | * |
| 11 | * This file is licenced under the GPL. | 11 | * This file is licenced under the GPL. |
| 12 | */ | 12 | */ |
| @@ -15,6 +15,24 @@ | |||
| 15 | 15 | ||
| 16 | extern int usb_disabled(void); | 16 | extern int usb_disabled(void); |
| 17 | 17 | ||
| 18 | /* called during probe() after chip reset completes */ | ||
| 19 | static int ehci_ppc_soc_setup(struct usb_hcd *hcd) | ||
| 20 | { | ||
| 21 | struct ehci_hcd *ehci = hcd_to_ehci(hcd); | ||
| 22 | int retval; | ||
| 23 | |||
| 24 | retval = ehci_halt(ehci); | ||
| 25 | if (retval) | ||
| 26 | return retval; | ||
| 27 | |||
| 28 | retval = ehci_init(hcd); | ||
| 29 | if (retval) | ||
| 30 | return retval; | ||
| 31 | |||
| 32 | ehci->sbrn = 0x20; | ||
| 33 | return ehci_reset(ehci); | ||
| 34 | } | ||
| 35 | |||
| 18 | /** | 36 | /** |
| 19 | * usb_ehci_ppc_soc_probe - initialize PPC-SoC-based HCDs | 37 | * usb_ehci_ppc_soc_probe - initialize PPC-SoC-based HCDs |
| 20 | * Context: !in_interrupt() | 38 | * Context: !in_interrupt() |
| @@ -120,7 +138,7 @@ static const struct hc_driver ehci_ppc_soc_hc_driver = { | |||
| 120 | /* | 138 | /* |
| 121 | * basic lifecycle operations | 139 | * basic lifecycle operations |
| 122 | */ | 140 | */ |
| 123 | .reset = ehci_init, | 141 | .reset = ehci_ppc_soc_setup, |
| 124 | .start = ehci_run, | 142 | .start = ehci_run, |
| 125 | .stop = ehci_stop, | 143 | .stop = ehci_stop, |
| 126 | .shutdown = ehci_shutdown, | 144 | .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) | |||
| 74 | 74 | ||
| 75 | #define ohci_dbg_sw(ohci, next, size, format, arg...) \ | 75 | #define ohci_dbg_sw(ohci, next, size, format, arg...) \ |
| 76 | do { \ | 76 | do { \ |
| 77 | if (next) { \ | 77 | if (next != NULL) { \ |
| 78 | unsigned s_len; \ | 78 | unsigned s_len; \ |
| 79 | s_len = scnprintf (*next, *size, format, ## arg ); \ | 79 | s_len = scnprintf (*next, *size, format, ## arg ); \ |
| 80 | *size -= s_len; *next += s_len; \ | 80 | *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) | |||
| 2208 | clean_up: | 2208 | clean_up: |
| 2209 | if (reg) | 2209 | if (reg) |
| 2210 | iounmap(reg); | 2210 | iounmap(reg); |
| 2211 | if (res) | ||
| 2212 | release_mem_region(res->start, 1); | ||
| 2213 | 2211 | ||
| 2214 | return ret; | 2212 | return ret; |
| 2215 | } | 2213 | } |
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) | |||
| 1520 | } | 1520 | } |
| 1521 | } | 1521 | } |
| 1522 | } | 1522 | } |
| 1523 | #ifdef CONFIG_PM | ||
| 1523 | 1524 | ||
| 1524 | static void port_power(struct u132 *u132, int pn, int is_on) | 1525 | static void port_power(struct u132 *u132, int pn, int is_on) |
| 1525 | { | 1526 | { |
| 1526 | u132->port[pn].power = is_on; | 1527 | u132->port[pn].power = is_on; |
| 1527 | } | 1528 | } |
| 1528 | 1529 | ||
| 1530 | #endif | ||
| 1531 | |||
| 1529 | static void u132_power(struct u132 *u132, int is_on) | 1532 | static void u132_power(struct u132 *u132, int is_on) |
| 1530 | { | 1533 | { |
| 1531 | struct usb_hcd *hcd = u132_to_hcd(u132) | 1534 | 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 @@ | |||
| 18 | 18 | ||
| 19 | static struct usb_device_id id_table [] = { | 19 | static struct usb_device_id id_table [] = { |
| 20 | { USB_DEVICE(0x0c88, 0x17da) }, /* Kyocera Wireless KPC650/Passport */ | 20 | { USB_DEVICE(0x0c88, 0x17da) }, /* Kyocera Wireless KPC650/Passport */ |
| 21 | { USB_DEVICE(0x413c, 0x8115) }, /* Dell Wireless HSDPA 5500 */ | ||
| 22 | { }, | 21 | { }, |
| 23 | }; | 22 | }; |
| 24 | MODULE_DEVICE_TABLE(usb, id_table); | 23 | 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 | |||
| 383 | } | 383 | } |
| 384 | 384 | ||
| 385 | baud = tty_get_baud_rate(port->tty); | 385 | baud = tty_get_baud_rate(port->tty); |
| 386 | if (baud == 0) { | ||
| 387 | dbg("%s - tty_get_baud_rate says 0 baud", __FUNCTION__); | ||
| 388 | return; | ||
| 389 | } | ||
| 386 | urb_value = BELKIN_SA_BAUD(baud); | 390 | urb_value = BELKIN_SA_BAUD(baud); |
| 387 | /* Clip to maximum speed */ | 391 | /* Clip to maximum speed */ |
| 388 | if (urb_value == 0) | 392 | 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 [] = { | |||
| 538 | { USB_DEVICE(FTDI_VID, FTDI_TERATRONIK_VCP_PID) }, | 538 | { USB_DEVICE(FTDI_VID, FTDI_TERATRONIK_VCP_PID) }, |
| 539 | { USB_DEVICE(FTDI_VID, FTDI_TERATRONIK_D2XX_PID) }, | 539 | { USB_DEVICE(FTDI_VID, FTDI_TERATRONIK_D2XX_PID) }, |
| 540 | { USB_DEVICE(EVOLUTION_VID, EVOLUTION_ER1_PID) }, | 540 | { USB_DEVICE(EVOLUTION_VID, EVOLUTION_ER1_PID) }, |
| 541 | { USB_DEVICE(EVOLUTION_VID, EVO_HYBRID_PID) }, | ||
| 542 | { USB_DEVICE(EVOLUTION_VID, EVO_RCM4_PID) }, | ||
| 541 | { USB_DEVICE(FTDI_VID, FTDI_ARTEMIS_PID) }, | 543 | { USB_DEVICE(FTDI_VID, FTDI_ARTEMIS_PID) }, |
| 542 | { USB_DEVICE(FTDI_VID, FTDI_ATIK_ATK16_PID) }, | 544 | { USB_DEVICE(FTDI_VID, FTDI_ATIK_ATK16_PID) }, |
| 543 | { USB_DEVICE(FTDI_VID, FTDI_ATIK_ATK16C_PID) }, | 545 | { 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 @@ | |||
| 430 | */ | 430 | */ |
| 431 | #define EVOLUTION_VID 0xDEEE /* Vendor ID */ | 431 | #define EVOLUTION_VID 0xDEEE /* Vendor ID */ |
| 432 | #define EVOLUTION_ER1_PID 0x0300 /* ER1 Control Module */ | 432 | #define EVOLUTION_ER1_PID 0x0300 /* ER1 Control Module */ |
| 433 | #define EVO_8U232AM_PID 0x02FF /* Evolution robotics RCM2 (FT232AM)*/ | ||
| 434 | #define EVO_HYBRID_PID 0x0302 /* Evolution robotics RCM4 PID (FT232BM)*/ | ||
| 435 | #define EVO_RCM4_PID 0x0303 /* Evolution robotics RCM4 PID */ | ||
| 433 | 436 | ||
| 434 | /* Pyramid Computer GmbH */ | 437 | /* Pyramid Computer GmbH */ |
| 435 | #define FTDI_PYRAMID_PID 0xE6C8 /* Pyramid Appliance Display */ | 438 | #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 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * Garmin GPS driver | 2 | * Garmin GPS driver |
| 3 | * | 3 | * |
| 4 | * Copyright (C) 2006 Hermann Kneissel herkne@users.sourceforge.net | 4 | * Copyright (C) 2006,2007 Hermann Kneissel herkne@users.sourceforge.net |
| 5 | * | 5 | * |
| 6 | * The latest version of the driver can be found at | 6 | * The latest version of the driver can be found at |
| 7 | * http://sourceforge.net/projects/garmin-gps/ | 7 | * http://sourceforge.net/projects/garmin-gps/ |
| @@ -34,6 +34,7 @@ | |||
| 34 | #include <linux/module.h> | 34 | #include <linux/module.h> |
| 35 | #include <linux/spinlock.h> | 35 | #include <linux/spinlock.h> |
| 36 | #include <asm/uaccess.h> | 36 | #include <asm/uaccess.h> |
| 37 | #include <asm/atomic.h> | ||
| 37 | #include <linux/usb.h> | 38 | #include <linux/usb.h> |
| 38 | #include <linux/usb/serial.h> | 39 | #include <linux/usb/serial.h> |
| 39 | 40 | ||
| @@ -52,7 +53,7 @@ static int debug = 0; | |||
| 52 | */ | 53 | */ |
| 53 | 54 | ||
| 54 | #define VERSION_MAJOR 0 | 55 | #define VERSION_MAJOR 0 |
| 55 | #define VERSION_MINOR 28 | 56 | #define VERSION_MINOR 31 |
| 56 | 57 | ||
| 57 | #define _STR(s) #s | 58 | #define _STR(s) #s |
| 58 | #define _DRIVER_VERSION(a,b) "v" _STR(a) "." _STR(b) | 59 | #define _DRIVER_VERSION(a,b) "v" _STR(a) "." _STR(b) |
| @@ -141,6 +142,8 @@ struct garmin_data { | |||
| 141 | __u8 inbuffer [GPS_IN_BUFSIZ]; /* tty -> usb */ | 142 | __u8 inbuffer [GPS_IN_BUFSIZ]; /* tty -> usb */ |
| 142 | __u8 outbuffer[GPS_OUT_BUFSIZ]; /* usb -> tty */ | 143 | __u8 outbuffer[GPS_OUT_BUFSIZ]; /* usb -> tty */ |
| 143 | __u8 privpkt[4*6]; | 144 | __u8 privpkt[4*6]; |
| 145 | atomic_t req_count; | ||
| 146 | atomic_t resp_count; | ||
| 144 | spinlock_t lock; | 147 | spinlock_t lock; |
| 145 | struct list_head pktlist; | 148 | struct list_head pktlist; |
| 146 | }; | 149 | }; |
| @@ -171,8 +174,6 @@ struct garmin_data { | |||
| 171 | #define CLEAR_HALT_REQUIRED 0x0001 | 174 | #define CLEAR_HALT_REQUIRED 0x0001 |
| 172 | 175 | ||
| 173 | #define FLAGS_QUEUING 0x0100 | 176 | #define FLAGS_QUEUING 0x0100 |
| 174 | #define FLAGS_APP_RESP_SEEN 0x0200 | ||
| 175 | #define FLAGS_APP_REQ_SEEN 0x0400 | ||
| 176 | #define FLAGS_DROP_DATA 0x0800 | 177 | #define FLAGS_DROP_DATA 0x0800 |
| 177 | 178 | ||
| 178 | #define FLAGS_GSP_SKIP 0x1000 | 179 | #define FLAGS_GSP_SKIP 0x1000 |
| @@ -186,7 +187,8 @@ struct garmin_data { | |||
| 186 | /* function prototypes */ | 187 | /* function prototypes */ |
| 187 | static void gsp_next_packet(struct garmin_data * garmin_data_p); | 188 | static void gsp_next_packet(struct garmin_data * garmin_data_p); |
| 188 | static int garmin_write_bulk(struct usb_serial_port *port, | 189 | static int garmin_write_bulk(struct usb_serial_port *port, |
| 189 | const unsigned char *buf, int count); | 190 | const unsigned char *buf, int count, |
| 191 | int dismiss_ack); | ||
| 190 | 192 | ||
| 191 | /* some special packets to be send or received */ | 193 | /* some special packets to be send or received */ |
| 192 | static unsigned char const GARMIN_START_SESSION_REQ[] | 194 | static unsigned char const GARMIN_START_SESSION_REQ[] |
| @@ -233,9 +235,7 @@ static struct usb_driver garmin_driver = { | |||
| 233 | 235 | ||
| 234 | static inline int noResponseFromAppLayer(struct garmin_data * garmin_data_p) | 236 | static inline int noResponseFromAppLayer(struct garmin_data * garmin_data_p) |
| 235 | { | 237 | { |
| 236 | return ((garmin_data_p->flags | 238 | return atomic_read(&garmin_data_p->req_count) == atomic_read(&garmin_data_p->resp_count); |
| 237 | & (FLAGS_APP_REQ_SEEN|FLAGS_APP_RESP_SEEN)) | ||
| 238 | == FLAGS_APP_REQ_SEEN); | ||
| 239 | } | 239 | } |
| 240 | 240 | ||
| 241 | 241 | ||
| @@ -463,7 +463,7 @@ static int gsp_rec_packet(struct garmin_data * garmin_data_p, int count) | |||
| 463 | usbdata[2] = __cpu_to_le32(size); | 463 | usbdata[2] = __cpu_to_le32(size); |
| 464 | 464 | ||
| 465 | garmin_write_bulk (garmin_data_p->port, garmin_data_p->inbuffer, | 465 | garmin_write_bulk (garmin_data_p->port, garmin_data_p->inbuffer, |
| 466 | GARMIN_PKTHDR_LENGTH+size); | 466 | GARMIN_PKTHDR_LENGTH+size, 0); |
| 467 | 467 | ||
| 468 | /* if this was an abort-transfer command, flush all | 468 | /* if this was an abort-transfer command, flush all |
| 469 | queued data. */ | 469 | queued data. */ |
| @@ -818,7 +818,7 @@ static int nat_receive(struct garmin_data * garmin_data_p, | |||
| 818 | if (garmin_data_p->insize >= len) { | 818 | if (garmin_data_p->insize >= len) { |
| 819 | garmin_write_bulk (garmin_data_p->port, | 819 | garmin_write_bulk (garmin_data_p->port, |
| 820 | garmin_data_p->inbuffer, | 820 | garmin_data_p->inbuffer, |
| 821 | len); | 821 | len, 0); |
| 822 | garmin_data_p->insize = 0; | 822 | garmin_data_p->insize = 0; |
| 823 | 823 | ||
| 824 | /* if this was an abort-transfer command, | 824 | /* if this was an abort-transfer command, |
| @@ -893,10 +893,11 @@ static int garmin_clear(struct garmin_data * garmin_data_p) | |||
| 893 | 893 | ||
| 894 | struct usb_serial_port *port = garmin_data_p->port; | 894 | struct usb_serial_port *port = garmin_data_p->port; |
| 895 | 895 | ||
| 896 | if (port != NULL && garmin_data_p->flags & FLAGS_APP_RESP_SEEN) { | 896 | if (port != NULL && atomic_read(&garmin_data_p->resp_count)) { |
| 897 | /* send a terminate command */ | 897 | /* send a terminate command */ |
| 898 | status = garmin_write_bulk(port, GARMIN_STOP_TRANSFER_REQ, | 898 | status = garmin_write_bulk(port, GARMIN_STOP_TRANSFER_REQ, |
| 899 | sizeof(GARMIN_STOP_TRANSFER_REQ)); | 899 | sizeof(GARMIN_STOP_TRANSFER_REQ), |
| 900 | 1); | ||
| 900 | } | 901 | } |
| 901 | 902 | ||
| 902 | /* flush all queued data */ | 903 | /* flush all queued data */ |
| @@ -939,7 +940,8 @@ static int garmin_init_session(struct usb_serial_port *port) | |||
| 939 | dbg("%s - starting session ...", __FUNCTION__); | 940 | dbg("%s - starting session ...", __FUNCTION__); |
| 940 | garmin_data_p->state = STATE_ACTIVE; | 941 | garmin_data_p->state = STATE_ACTIVE; |
| 941 | status = garmin_write_bulk(port, GARMIN_START_SESSION_REQ, | 942 | status = garmin_write_bulk(port, GARMIN_START_SESSION_REQ, |
| 942 | sizeof(GARMIN_START_SESSION_REQ)); | 943 | sizeof(GARMIN_START_SESSION_REQ), |
| 944 | 0); | ||
| 943 | 945 | ||
| 944 | if (status >= 0) { | 946 | if (status >= 0) { |
| 945 | 947 | ||
| @@ -950,7 +952,8 @@ static int garmin_init_session(struct usb_serial_port *port) | |||
| 950 | /* not needed, but the win32 driver does it too ... */ | 952 | /* not needed, but the win32 driver does it too ... */ |
| 951 | status = garmin_write_bulk(port, | 953 | status = garmin_write_bulk(port, |
| 952 | GARMIN_START_SESSION_REQ2, | 954 | GARMIN_START_SESSION_REQ2, |
| 953 | sizeof(GARMIN_START_SESSION_REQ2)); | 955 | sizeof(GARMIN_START_SESSION_REQ2), |
| 956 | 0); | ||
| 954 | if (status >= 0) { | 957 | if (status >= 0) { |
| 955 | status = 0; | 958 | status = 0; |
| 956 | spin_lock_irqsave(&garmin_data_p->lock, flags); | 959 | spin_lock_irqsave(&garmin_data_p->lock, flags); |
| @@ -987,6 +990,8 @@ static int garmin_open (struct usb_serial_port *port, struct file *filp) | |||
| 987 | garmin_data_p->mode = initial_mode; | 990 | garmin_data_p->mode = initial_mode; |
| 988 | garmin_data_p->count = 0; | 991 | garmin_data_p->count = 0; |
| 989 | garmin_data_p->flags = 0; | 992 | garmin_data_p->flags = 0; |
| 993 | atomic_set(&garmin_data_p->req_count, 0); | ||
| 994 | atomic_set(&garmin_data_p->resp_count, 0); | ||
| 990 | spin_unlock_irqrestore(&garmin_data_p->lock, flags); | 995 | spin_unlock_irqrestore(&garmin_data_p->lock, flags); |
| 991 | 996 | ||
| 992 | /* shutdown any bulk reads that might be going on */ | 997 | /* shutdown any bulk reads that might be going on */ |
| @@ -1035,28 +1040,39 @@ static void garmin_write_bulk_callback (struct urb *urb) | |||
| 1035 | { | 1040 | { |
| 1036 | unsigned long flags; | 1041 | unsigned long flags; |
| 1037 | struct usb_serial_port *port = (struct usb_serial_port *)urb->context; | 1042 | struct usb_serial_port *port = (struct usb_serial_port *)urb->context; |
| 1038 | struct garmin_data * garmin_data_p = usb_get_serial_port_data(port); | ||
| 1039 | int status = urb->status; | 1043 | int status = urb->status; |
| 1040 | 1044 | ||
| 1041 | /* free up the transfer buffer, as usb_free_urb() does not do this */ | 1045 | if (port) { |
| 1042 | kfree (urb->transfer_buffer); | 1046 | struct garmin_data * garmin_data_p = usb_get_serial_port_data(port); |
| 1043 | 1047 | ||
| 1044 | dbg("%s - port %d", __FUNCTION__, port->number); | 1048 | dbg("%s - port %d", __FUNCTION__, port->number); |
| 1045 | 1049 | ||
| 1046 | if (status) { | 1050 | if (GARMIN_LAYERID_APPL == getLayerId(urb->transfer_buffer) |
| 1047 | dbg("%s - nonzero write bulk status received: %d", | 1051 | && (garmin_data_p->mode == MODE_GARMIN_SERIAL)) { |
| 1048 | __FUNCTION__, status); | 1052 | gsp_send_ack(garmin_data_p, ((__u8 *)urb->transfer_buffer)[4]); |
| 1049 | spin_lock_irqsave(&garmin_data_p->lock, flags); | 1053 | } |
| 1050 | garmin_data_p->flags |= CLEAR_HALT_REQUIRED; | 1054 | |
| 1051 | spin_unlock_irqrestore(&garmin_data_p->lock, flags); | 1055 | if (status) { |
| 1056 | dbg("%s - nonzero write bulk status received: %d", | ||
| 1057 | __FUNCTION__, urb->status); | ||
| 1058 | spin_lock_irqsave(&garmin_data_p->lock, flags); | ||
| 1059 | garmin_data_p->flags |= CLEAR_HALT_REQUIRED; | ||
| 1060 | spin_unlock_irqrestore(&garmin_data_p->lock, flags); | ||
| 1061 | } | ||
| 1062 | |||
| 1063 | usb_serial_port_softint(port); | ||
| 1052 | } | 1064 | } |
| 1053 | 1065 | ||
| 1054 | usb_serial_port_softint(port); | 1066 | /* Ignore errors that resulted from garmin_write_bulk with dismiss_ack=1 */ |
| 1067 | |||
| 1068 | /* free up the transfer buffer, as usb_free_urb() does not do this */ | ||
| 1069 | kfree (urb->transfer_buffer); | ||
| 1055 | } | 1070 | } |
| 1056 | 1071 | ||
| 1057 | 1072 | ||
| 1058 | static int garmin_write_bulk (struct usb_serial_port *port, | 1073 | static int garmin_write_bulk (struct usb_serial_port *port, |
| 1059 | const unsigned char *buf, int count) | 1074 | const unsigned char *buf, int count, |
| 1075 | int dismiss_ack) | ||
| 1060 | { | 1076 | { |
| 1061 | unsigned long flags; | 1077 | unsigned long flags; |
| 1062 | struct usb_serial *serial = port->serial; | 1078 | struct usb_serial *serial = port->serial; |
| @@ -1093,13 +1109,12 @@ static int garmin_write_bulk (struct usb_serial_port *port, | |||
| 1093 | usb_sndbulkpipe (serial->dev, | 1109 | usb_sndbulkpipe (serial->dev, |
| 1094 | port->bulk_out_endpointAddress), | 1110 | port->bulk_out_endpointAddress), |
| 1095 | buffer, count, | 1111 | buffer, count, |
| 1096 | garmin_write_bulk_callback, port); | 1112 | garmin_write_bulk_callback, |
| 1113 | dismiss_ack ? NULL : port); | ||
| 1097 | urb->transfer_flags |= URB_ZERO_PACKET; | 1114 | urb->transfer_flags |= URB_ZERO_PACKET; |
| 1098 | 1115 | ||
| 1099 | if (GARMIN_LAYERID_APPL == getLayerId(buffer)) { | 1116 | if (GARMIN_LAYERID_APPL == getLayerId(buffer)) { |
| 1100 | spin_lock_irqsave(&garmin_data_p->lock, flags); | 1117 | atomic_inc(&garmin_data_p->req_count); |
| 1101 | garmin_data_p->flags |= FLAGS_APP_REQ_SEEN; | ||
| 1102 | spin_unlock_irqrestore(&garmin_data_p->lock, flags); | ||
| 1103 | if (garmin_data_p->mode == MODE_GARMIN_SERIAL) { | 1118 | if (garmin_data_p->mode == MODE_GARMIN_SERIAL) { |
| 1104 | pkt_clear(garmin_data_p); | 1119 | pkt_clear(garmin_data_p); |
| 1105 | garmin_data_p->state = STATE_GSP_WAIT_DATA; | 1120 | garmin_data_p->state = STATE_GSP_WAIT_DATA; |
| @@ -1114,13 +1129,6 @@ static int garmin_write_bulk (struct usb_serial_port *port, | |||
| 1114 | "failed with status = %d\n", | 1129 | "failed with status = %d\n", |
| 1115 | __FUNCTION__, status); | 1130 | __FUNCTION__, status); |
| 1116 | count = status; | 1131 | count = status; |
| 1117 | } else { | ||
| 1118 | |||
| 1119 | if (GARMIN_LAYERID_APPL == getLayerId(buffer) | ||
| 1120 | && (garmin_data_p->mode == MODE_GARMIN_SERIAL)) { | ||
| 1121 | |||
| 1122 | gsp_send_ack(garmin_data_p, buffer[4]); | ||
| 1123 | } | ||
| 1124 | } | 1132 | } |
| 1125 | 1133 | ||
| 1126 | /* we are done with this urb, so let the host driver | 1134 | /* 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, | |||
| 1135 | static int garmin_write (struct usb_serial_port *port, | 1143 | static int garmin_write (struct usb_serial_port *port, |
| 1136 | const unsigned char *buf, int count) | 1144 | const unsigned char *buf, int count) |
| 1137 | { | 1145 | { |
| 1138 | unsigned long flags; | ||
| 1139 | int pktid, pktsiz, len; | 1146 | int pktid, pktsiz, len; |
| 1140 | struct garmin_data * garmin_data_p = usb_get_serial_port_data(port); | 1147 | struct garmin_data * garmin_data_p = usb_get_serial_port_data(port); |
| 1141 | __le32 *privpkt = (__le32 *)garmin_data_p->privpkt; | 1148 | __le32 *privpkt = (__le32 *)garmin_data_p->privpkt; |
| @@ -1186,9 +1193,7 @@ static int garmin_write (struct usb_serial_port *port, | |||
| 1186 | break; | 1193 | break; |
| 1187 | 1194 | ||
| 1188 | case PRIV_PKTID_RESET_REQ: | 1195 | case PRIV_PKTID_RESET_REQ: |
| 1189 | spin_lock_irqsave(&garmin_data_p->lock, flags); | 1196 | atomic_inc(&garmin_data_p->req_count); |
| 1190 | garmin_data_p->flags |= FLAGS_APP_REQ_SEEN; | ||
| 1191 | spin_unlock_irqrestore(&garmin_data_p->lock, flags); | ||
| 1192 | break; | 1197 | break; |
| 1193 | 1198 | ||
| 1194 | case PRIV_PKTID_SET_DEF_MODE: | 1199 | case PRIV_PKTID_SET_DEF_MODE: |
| @@ -1241,8 +1246,6 @@ static int garmin_chars_in_buffer (struct usb_serial_port *port) | |||
| 1241 | static void garmin_read_process(struct garmin_data * garmin_data_p, | 1246 | static void garmin_read_process(struct garmin_data * garmin_data_p, |
| 1242 | unsigned char *data, unsigned data_length) | 1247 | unsigned char *data, unsigned data_length) |
| 1243 | { | 1248 | { |
| 1244 | unsigned long flags; | ||
| 1245 | |||
| 1246 | if (garmin_data_p->flags & FLAGS_DROP_DATA) { | 1249 | if (garmin_data_p->flags & FLAGS_DROP_DATA) { |
| 1247 | /* abort-transfer cmd is actice */ | 1250 | /* abort-transfer cmd is actice */ |
| 1248 | dbg("%s - pkt dropped", __FUNCTION__); | 1251 | dbg("%s - pkt dropped", __FUNCTION__); |
| @@ -1254,9 +1257,7 @@ static void garmin_read_process(struct garmin_data * garmin_data_p, | |||
| 1254 | the device */ | 1257 | the device */ |
| 1255 | if (0 == memcmp(data, GARMIN_APP_LAYER_REPLY, | 1258 | if (0 == memcmp(data, GARMIN_APP_LAYER_REPLY, |
| 1256 | sizeof(GARMIN_APP_LAYER_REPLY))) { | 1259 | sizeof(GARMIN_APP_LAYER_REPLY))) { |
| 1257 | spin_lock_irqsave(&garmin_data_p->lock, flags); | 1260 | atomic_inc(&garmin_data_p->resp_count); |
| 1258 | garmin_data_p->flags |= FLAGS_APP_RESP_SEEN; | ||
| 1259 | spin_unlock_irqrestore(&garmin_data_p->lock, flags); | ||
| 1260 | } | 1261 | } |
| 1261 | 1262 | ||
| 1262 | /* if throttling is active or postprecessing is required | 1263 | /* 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 [] = { | |||
| 545 | { USB_DEVICE(0x413C, 0x4009) }, /* Dell Axim USB Sync */ | 545 | { USB_DEVICE(0x413C, 0x4009) }, /* Dell Axim USB Sync */ |
| 546 | { USB_DEVICE(0x4505, 0x0010) }, /* Smartphone */ | 546 | { USB_DEVICE(0x4505, 0x0010) }, /* Smartphone */ |
| 547 | { USB_DEVICE(0x5E04, 0xCE00) }, /* SAGEM Wireless Assistant */ | 547 | { USB_DEVICE(0x5E04, 0xCE00) }, /* SAGEM Wireless Assistant */ |
| 548 | { USB_DEVICE(0x0BB4, 0x00CF) }, /* HTC smartphone modems */ | ||
| 548 | { } /* Terminating entry */ | 549 | { } /* Terminating entry */ |
| 549 | }; | 550 | }; |
| 550 | 551 | ||
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); | |||
| 110 | #define HUAWEI_PRODUCT_E220 0x1003 | 110 | #define HUAWEI_PRODUCT_E220 0x1003 |
| 111 | 111 | ||
| 112 | #define NOVATELWIRELESS_VENDOR_ID 0x1410 | 112 | #define NOVATELWIRELESS_VENDOR_ID 0x1410 |
| 113 | #define DELL_VENDOR_ID 0x413C | ||
| 113 | 114 | ||
| 114 | #define ANYDATA_VENDOR_ID 0x16d5 | 115 | #define ANYDATA_VENDOR_ID 0x16d5 |
| 115 | #define ANYDATA_PRODUCT_ADU_E100A 0x6501 | 116 | #define ANYDATA_PRODUCT_ADU_E100A 0x6501 |
| @@ -119,8 +120,6 @@ static int option_send_setup(struct usb_serial_port *port); | |||
| 119 | #define BANDRICH_PRODUCT_C100_1 0x1002 | 120 | #define BANDRICH_PRODUCT_C100_1 0x1002 |
| 120 | #define BANDRICH_PRODUCT_C100_2 0x1003 | 121 | #define BANDRICH_PRODUCT_C100_2 0x1003 |
| 121 | 122 | ||
| 122 | #define DELL_VENDOR_ID 0x413C | ||
| 123 | |||
| 124 | static struct usb_device_id option_ids[] = { | 123 | static struct usb_device_id option_ids[] = { |
| 125 | { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COLT) }, | 124 | { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COLT) }, |
| 126 | { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_RICOLA) }, | 125 | { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_RICOLA) }, |
| @@ -171,11 +170,16 @@ static struct usb_device_id option_ids[] = { | |||
| 171 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, 0x2110) }, /* Novatel Merlin ES620 / Merlin ES720 / Ovation U720 */ | 170 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, 0x2110) }, /* Novatel Merlin ES620 / Merlin ES720 / Ovation U720 */ |
| 172 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, 0x2130) }, /* Novatel Merlin ES620 SM Bus */ | 171 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, 0x2130) }, /* Novatel Merlin ES620 SM Bus */ |
| 173 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, 0x2410) }, /* Novatel EU740 */ | 172 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, 0x2410) }, /* Novatel EU740 */ |
| 173 | { USB_DEVICE(DELL_VENDOR_ID, 0x8114) }, /* Dell Wireless 5700 Mobile Broadband CDMA/EVDO Mini-Card == Novatel Expedite EV620 CDMA/EV-DO */ | ||
| 174 | { USB_DEVICE(DELL_VENDOR_ID, 0x8115) }, /* Dell Wireless 5500 Mobile Broadband HSDPA Mini-Card == Novatel Expedite EU740 HSDPA/3G */ | ||
| 175 | { USB_DEVICE(DELL_VENDOR_ID, 0x8116) }, /* Dell Wireless 5505 Mobile Broadband HSDPA Mini-Card == Novatel Expedite EU740 HSDPA/3G */ | ||
| 176 | { USB_DEVICE(DELL_VENDOR_ID, 0x8117) }, /* Dell Wireless 5700 Mobile Broadband CDMA/EVDO ExpressCard == Novatel Merlin XV620 CDMA/EV-DO */ | ||
| 177 | { USB_DEVICE(DELL_VENDOR_ID, 0x8118) }, /* Dell Wireless 5510 Mobile Broadband HSDPA ExpressCard == Novatel Merlin XU870 HSDPA/3G */ | ||
| 178 | { USB_DEVICE(DELL_VENDOR_ID, 0x8128) }, /* Dell Wireless 5700 Mobile Broadband CDMA/EVDO Mini-Card == Novatel Expedite E720 CDMA/EV-DO */ | ||
| 174 | { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_E100A) }, | 179 | { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_E100A) }, |
| 175 | { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_500A) }, | 180 | { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_500A) }, |
| 176 | { USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_C100_1) }, | 181 | { USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_C100_1) }, |
| 177 | { USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_C100_2) }, | 182 | { USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_C100_2) }, |
| 178 | { USB_DEVICE(DELL_VENDOR_ID, 0x8118) }, /* Dell Wireless 5510 Mobile Broadband HSDPA ExpressCard */ | ||
| 179 | { } /* Terminating entry */ | 183 | { } /* Terminating entry */ |
| 180 | }; | 184 | }; |
| 181 | MODULE_DEVICE_TABLE(usb, option_ids); | 185 | 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, | |||
| 818 | 818 | ||
| 819 | switch (cmd) { | 819 | switch (cmd) { |
| 820 | case TCGETS: | 820 | case TCGETS: |
| 821 | if (copy_to_user(user_arg, port->tty->termios, | 821 | if (kernel_termios_to_user_termios((struct ktermios __user *)arg, |
| 822 | sizeof(struct ktermios))) { | 822 | port->tty->termios)) |
| 823 | return -EFAULT; | 823 | return -EFAULT; |
| 824 | } | ||
| 825 | return 0; | 824 | return 0; |
| 826 | 825 | ||
| 827 | case TCSETS: | 826 | case TCSETS: |
| 828 | case TCSETSW: /* FIXME: this is not the same! */ | 827 | case TCSETSW: /* FIXME: this is not the same! */ |
| 829 | case TCSETSF: /* FIXME: this is not the same! */ | 828 | case TCSETSF: /* FIXME: this is not the same! */ |
| 830 | if (copy_from_user(port->tty->termios, user_arg, | 829 | if (user_termios_to_kernel_termios(port->tty->termios, |
| 831 | sizeof(struct ktermios))) { | 830 | (struct ktermios __user *)arg)) |
| 832 | return -EFAULT; | 831 | return -EFAULT; |
| 833 | } | ||
| 834 | oti6858_set_termios(port, NULL); | 832 | oti6858_set_termios(port, NULL); |
| 835 | return 0; | 833 | return 0; |
| 836 | 834 | ||
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 @@ | |||
| 74 | #include <linux/usb/serial.h> | 74 | #include <linux/usb/serial.h> |
| 75 | 75 | ||
| 76 | 76 | ||
| 77 | #ifndef CONFIG_USB_SAFE_PADDED | 77 | #ifndef CONFIG_USB_SERIAL_SAFE_PADDED |
| 78 | #define CONFIG_USB_SAFE_PADDED 0 | 78 | #define CONFIG_USB_SERIAL_SAFE_PADDED 0 |
| 79 | #endif | 79 | #endif |
| 80 | 80 | ||
| 81 | static int debug; | 81 | static int debug; |
| 82 | static int safe = 1; | 82 | static int safe = 1; |
| 83 | static int padded = CONFIG_USB_SAFE_PADDED; | 83 | static int padded = CONFIG_USB_SERIAL_SAFE_PADDED; |
| 84 | 84 | ||
| 85 | #define DRIVER_VERSION "v0.0b" | 85 | #define DRIVER_VERSION "v0.0b" |
| 86 | #define DRIVER_AUTHOR "sl@lineo.com, tbr@lineo.com" | 86 | #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 [] = { | |||
| 104 | .driver_info = (kernel_ulong_t)&palm_os_4_probe }, | 104 | .driver_info = (kernel_ulong_t)&palm_os_4_probe }, |
| 105 | { USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_TJ25_ID), | 105 | { USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_TJ25_ID), |
| 106 | .driver_info = (kernel_ulong_t)&palm_os_4_probe }, | 106 | .driver_info = (kernel_ulong_t)&palm_os_4_probe }, |
| 107 | { USB_DEVICE(ACER_VENDOR_ID, ACER_S10_ID), | ||
| 108 | .driver_info = (kernel_ulong_t)&palm_os_4_probe }, | ||
| 107 | { USB_DEVICE(SAMSUNG_VENDOR_ID, SAMSUNG_SCH_I330_ID), | 109 | { USB_DEVICE(SAMSUNG_VENDOR_ID, SAMSUNG_SCH_I330_ID), |
| 108 | .driver_info = (kernel_ulong_t)&palm_os_4_probe }, | 110 | .driver_info = (kernel_ulong_t)&palm_os_4_probe }, |
| 109 | { USB_DEVICE(SAMSUNG_VENDOR_ID, SAMSUNG_SPH_I500_ID), | 111 | { 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 @@ | |||
| 48 | #define SONY_CLIE_UX50_ID 0x0144 | 48 | #define SONY_CLIE_UX50_ID 0x0144 |
| 49 | #define SONY_CLIE_TJ25_ID 0x0169 | 49 | #define SONY_CLIE_TJ25_ID 0x0169 |
| 50 | 50 | ||
| 51 | #define ACER_VENDOR_ID 0x0502 | ||
| 52 | #define ACER_S10_ID 0x0001 | ||
| 53 | |||
| 51 | #define SAMSUNG_VENDOR_ID 0x04E8 | 54 | #define SAMSUNG_VENDOR_ID 0x04E8 |
| 52 | #define SAMSUNG_SCH_I330_ID 0x8001 | 55 | #define SAMSUNG_SCH_I330_ID 0x8001 |
| 53 | #define SAMSUNG_SPH_I500_ID 0x6601 | 56 | #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, | |||
| 342 | US_FL_FIX_CAPACITY), | 342 | US_FL_FIX_CAPACITY), |
| 343 | 343 | ||
| 344 | /* Reported by Emil Larsson <emil@swip.net> */ | 344 | /* Reported by Emil Larsson <emil@swip.net> */ |
| 345 | UNUSUAL_DEV( 0x04b0, 0x0411, 0x0100, 0x0100, | 345 | UNUSUAL_DEV( 0x04b0, 0x0411, 0x0100, 0x0101, |
| 346 | "NIKON", | 346 | "NIKON", |
| 347 | "NIKON DSC D80", | 347 | "NIKON DSC D80", |
| 348 | US_SC_DEVICE, US_PR_DEVICE, NULL, | 348 | 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); | |||
| 112 | MODULE_PARM_DESC(delay_use, "seconds to delay before using a new device"); | 112 | MODULE_PARM_DESC(delay_use, "seconds to delay before using a new device"); |
| 113 | 113 | ||
| 114 | 114 | ||
| 115 | /* These are used to make sure the module doesn't unload before all the | ||
| 116 | * threads have exited. | ||
| 117 | */ | ||
| 118 | static atomic_t total_threads = ATOMIC_INIT(0); | ||
| 119 | static DECLARE_COMPLETION(threads_gone); | ||
| 120 | |||
| 121 | |||
| 122 | /* | 115 | /* |
| 123 | * The entries in this table correspond, line for line, | 116 | * The entries in this table correspond, line for line, |
| 124 | * with the entries of us_unusual_dev_list[]. | 117 | * with the entries of us_unusual_dev_list[]. |
| @@ -879,9 +872,6 @@ static void quiesce_and_remove_host(struct us_data *us) | |||
| 879 | usb_stor_stop_transport(us); | 872 | usb_stor_stop_transport(us); |
| 880 | wake_up(&us->delay_wait); | 873 | wake_up(&us->delay_wait); |
| 881 | 874 | ||
| 882 | /* It doesn't matter if the SCSI-scanning thread is still running. | ||
| 883 | * The thread will exit when it sees the DISCONNECTING flag. */ | ||
| 884 | |||
| 885 | /* queuecommand won't accept any new commands and the control | 875 | /* queuecommand won't accept any new commands and the control |
| 886 | * thread won't execute a previously-queued command. If there | 876 | * thread won't execute a previously-queued command. If there |
| 887 | * is such a command pending, complete it with an error. */ | 877 | * is such a command pending, complete it with an error. */ |
| @@ -891,12 +881,16 @@ static void quiesce_and_remove_host(struct us_data *us) | |||
| 891 | scsi_lock(host); | 881 | scsi_lock(host); |
| 892 | us->srb->scsi_done(us->srb); | 882 | us->srb->scsi_done(us->srb); |
| 893 | us->srb = NULL; | 883 | us->srb = NULL; |
| 884 | complete(&us->notify); /* in case of an abort */ | ||
| 894 | scsi_unlock(host); | 885 | scsi_unlock(host); |
| 895 | } | 886 | } |
| 896 | mutex_unlock(&us->dev_mutex); | 887 | mutex_unlock(&us->dev_mutex); |
| 897 | 888 | ||
| 898 | /* Now we own no commands so it's safe to remove the SCSI host */ | 889 | /* Now we own no commands so it's safe to remove the SCSI host */ |
| 899 | scsi_remove_host(host); | 890 | scsi_remove_host(host); |
| 891 | |||
| 892 | /* Wait for the SCSI-scanning thread to stop */ | ||
| 893 | wait_for_completion(&us->scanning_done); | ||
| 900 | } | 894 | } |
| 901 | 895 | ||
| 902 | /* Second stage of disconnect processing: deallocate all resources */ | 896 | /* Second stage of disconnect processing: deallocate all resources */ |
| @@ -947,9 +941,8 @@ retry: | |||
| 947 | /* Should we unbind if no devices were detected? */ | 941 | /* Should we unbind if no devices were detected? */ |
| 948 | } | 942 | } |
| 949 | 943 | ||
| 950 | scsi_host_put(us_to_host(us)); | ||
| 951 | usb_autopm_put_interface(us->pusb_intf); | 944 | usb_autopm_put_interface(us->pusb_intf); |
| 952 | complete_and_exit(&threads_gone, 0); | 945 | complete_and_exit(&us->scanning_done, 0); |
| 953 | } | 946 | } |
| 954 | 947 | ||
| 955 | 948 | ||
| @@ -984,6 +977,7 @@ static int storage_probe(struct usb_interface *intf, | |||
| 984 | init_MUTEX_LOCKED(&(us->sema)); | 977 | init_MUTEX_LOCKED(&(us->sema)); |
| 985 | init_completion(&(us->notify)); | 978 | init_completion(&(us->notify)); |
| 986 | init_waitqueue_head(&us->delay_wait); | 979 | init_waitqueue_head(&us->delay_wait); |
| 980 | init_completion(&us->scanning_done); | ||
| 987 | 981 | ||
| 988 | /* Associate the us_data structure with the USB device */ | 982 | /* Associate the us_data structure with the USB device */ |
| 989 | result = associate_dev(us, intf); | 983 | result = associate_dev(us, intf); |
| @@ -1033,11 +1027,6 @@ static int storage_probe(struct usb_interface *intf, | |||
| 1033 | goto BadDevice; | 1027 | goto BadDevice; |
| 1034 | } | 1028 | } |
| 1035 | 1029 | ||
| 1036 | /* Take a reference to the host for the scanning thread and | ||
| 1037 | * count it among all the threads we have launched. Then | ||
| 1038 | * start it up. */ | ||
| 1039 | scsi_host_get(us_to_host(us)); | ||
| 1040 | atomic_inc(&total_threads); | ||
| 1041 | usb_autopm_get_interface(intf); /* dropped in the scanning thread */ | 1030 | usb_autopm_get_interface(intf); /* dropped in the scanning thread */ |
| 1042 | wake_up_process(th); | 1031 | wake_up_process(th); |
| 1043 | 1032 | ||
| @@ -1104,16 +1093,6 @@ static void __exit usb_stor_exit(void) | |||
| 1104 | US_DEBUGP("-- calling usb_deregister()\n"); | 1093 | US_DEBUGP("-- calling usb_deregister()\n"); |
| 1105 | usb_deregister(&usb_storage_driver) ; | 1094 | usb_deregister(&usb_storage_driver) ; |
| 1106 | 1095 | ||
| 1107 | /* Don't return until all of our control and scanning threads | ||
| 1108 | * have exited. Since each thread signals threads_gone as its | ||
| 1109 | * last act, we have to call wait_for_completion the right number | ||
| 1110 | * of times. | ||
| 1111 | */ | ||
| 1112 | while (atomic_read(&total_threads) > 0) { | ||
| 1113 | wait_for_completion(&threads_gone); | ||
| 1114 | atomic_dec(&total_threads); | ||
| 1115 | } | ||
| 1116 | |||
| 1117 | usb_usual_clear_present(USB_US_TYPE_STOR); | 1096 | usb_usual_clear_present(USB_US_TYPE_STOR); |
| 1118 | } | 1097 | } |
| 1119 | 1098 | ||
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 { | |||
| 150 | struct semaphore sema; /* to sleep thread on */ | 150 | struct semaphore sema; /* to sleep thread on */ |
| 151 | struct completion notify; /* thread begin/end */ | 151 | struct completion notify; /* thread begin/end */ |
| 152 | wait_queue_head_t delay_wait; /* wait during scan, reset */ | 152 | wait_queue_head_t delay_wait; /* wait during scan, reset */ |
| 153 | struct completion scanning_done; /* wait for scan thread */ | ||
| 153 | 154 | ||
| 154 | /* subdriver information */ | 155 | /* subdriver information */ |
| 155 | void *extra; /* Any extra data */ | 156 | void *extra; /* Any extra data */ |
diff --git a/drivers/video/au1100fb.c b/drivers/video/au1100fb.c index 80a81eccad36..832e4613673a 100644 --- a/drivers/video/au1100fb.c +++ b/drivers/video/au1100fb.c | |||
| @@ -115,6 +115,52 @@ static int nocursor = 0; | |||
| 115 | module_param(nocursor, int, 0644); | 115 | module_param(nocursor, int, 0644); |
| 116 | MODULE_PARM_DESC(nocursor, "cursor enable/disable"); | 116 | MODULE_PARM_DESC(nocursor, "cursor enable/disable"); |
| 117 | 117 | ||
| 118 | /* fb_blank | ||
| 119 | * Blank the screen. Depending on the mode, the screen will be | ||
| 120 | * activated with the backlight color, or desactivated | ||
| 121 | */ | ||
| 122 | static int au1100fb_fb_blank(int blank_mode, struct fb_info *fbi) | ||
| 123 | { | ||
| 124 | struct au1100fb_device *fbdev = to_au1100fb_device(fbi); | ||
| 125 | |||
| 126 | print_dbg("fb_blank %d %p", blank_mode, fbi); | ||
| 127 | |||
| 128 | switch (blank_mode) { | ||
| 129 | |||
| 130 | case VESA_NO_BLANKING: | ||
| 131 | /* Turn on panel */ | ||
| 132 | fbdev->regs->lcd_control |= LCD_CONTROL_GO; | ||
| 133 | #ifdef CONFIG_MIPS_PB1100 | ||
| 134 | if (drv_info.panel_idx == 1) { | ||
| 135 | au_writew(au_readw(PB1100_G_CONTROL) | ||
| 136 | | (PB1100_G_CONTROL_BL | PB1100_G_CONTROL_VDD), | ||
| 137 | PB1100_G_CONTROL); | ||
| 138 | } | ||
| 139 | #endif | ||
| 140 | au_sync(); | ||
| 141 | break; | ||
| 142 | |||
| 143 | case VESA_VSYNC_SUSPEND: | ||
| 144 | case VESA_HSYNC_SUSPEND: | ||
| 145 | case VESA_POWERDOWN: | ||
| 146 | /* Turn off panel */ | ||
| 147 | fbdev->regs->lcd_control &= ~LCD_CONTROL_GO; | ||
| 148 | #ifdef CONFIG_MIPS_PB1100 | ||
| 149 | if (drv_info.panel_idx == 1) { | ||
| 150 | au_writew(au_readw(PB1100_G_CONTROL) | ||
| 151 | & ~(PB1100_G_CONTROL_BL | PB1100_G_CONTROL_VDD), | ||
| 152 | PB1100_G_CONTROL); | ||
| 153 | } | ||
| 154 | #endif | ||
| 155 | au_sync(); | ||
| 156 | break; | ||
| 157 | default: | ||
| 158 | break; | ||
| 159 | |||
| 160 | } | ||
| 161 | return 0; | ||
| 162 | } | ||
| 163 | |||
| 118 | /* | 164 | /* |
| 119 | * Set hardware with var settings. This will enable the controller with a specific | 165 | * Set hardware with var settings. This will enable the controller with a specific |
| 120 | * mode, normally validated with the fb_check_var method | 166 | * mode, normally validated with the fb_check_var method |
| @@ -272,52 +318,6 @@ int au1100fb_fb_setcolreg(unsigned regno, unsigned red, unsigned green, unsigned | |||
| 272 | return 0; | 318 | return 0; |
| 273 | } | 319 | } |
| 274 | 320 | ||
| 275 | /* fb_blank | ||
| 276 | * Blank the screen. Depending on the mode, the screen will be | ||
| 277 | * activated with the backlight color, or desactivated | ||
| 278 | */ | ||
| 279 | int au1100fb_fb_blank(int blank_mode, struct fb_info *fbi) | ||
| 280 | { | ||
| 281 | struct au1100fb_device *fbdev = to_au1100fb_device(fbi); | ||
| 282 | |||
| 283 | print_dbg("fb_blank %d %p", blank_mode, fbi); | ||
| 284 | |||
| 285 | switch (blank_mode) { | ||
| 286 | |||
| 287 | case VESA_NO_BLANKING: | ||
| 288 | /* Turn on panel */ | ||
| 289 | fbdev->regs->lcd_control |= LCD_CONTROL_GO; | ||
| 290 | #ifdef CONFIG_MIPS_PB1100 | ||
| 291 | if (drv_info.panel_idx == 1) { | ||
| 292 | au_writew(au_readw(PB1100_G_CONTROL) | ||
| 293 | | (PB1100_G_CONTROL_BL | PB1100_G_CONTROL_VDD), | ||
| 294 | PB1100_G_CONTROL); | ||
| 295 | } | ||
| 296 | #endif | ||
| 297 | au_sync(); | ||
| 298 | break; | ||
| 299 | |||
| 300 | case VESA_VSYNC_SUSPEND: | ||
| 301 | case VESA_HSYNC_SUSPEND: | ||
| 302 | case VESA_POWERDOWN: | ||
| 303 | /* Turn off panel */ | ||
| 304 | fbdev->regs->lcd_control &= ~LCD_CONTROL_GO; | ||
| 305 | #ifdef CONFIG_MIPS_PB1100 | ||
| 306 | if (drv_info.panel_idx == 1) { | ||
| 307 | au_writew(au_readw(PB1100_G_CONTROL) | ||
| 308 | & ~(PB1100_G_CONTROL_BL | PB1100_G_CONTROL_VDD), | ||
| 309 | PB1100_G_CONTROL); | ||
| 310 | } | ||
| 311 | #endif | ||
| 312 | au_sync(); | ||
| 313 | break; | ||
| 314 | default: | ||
| 315 | break; | ||
| 316 | |||
| 317 | } | ||
| 318 | return 0; | ||
| 319 | } | ||
| 320 | |||
| 321 | /* fb_pan_display | 321 | /* fb_pan_display |
| 322 | * Pan display in x and/or y as specified | 322 | * Pan display in x and/or y as specified |
| 323 | */ | 323 | */ |
diff --git a/drivers/video/console/newport_con.c b/drivers/video/console/newport_con.c index 7fa1afeae8dc..dda0586ab3f3 100644 --- a/drivers/video/console/newport_con.c +++ b/drivers/video/console/newport_con.c | |||
| @@ -738,9 +738,8 @@ const struct consw newport_con = { | |||
| 738 | #ifdef MODULE | 738 | #ifdef MODULE |
| 739 | static int __init newport_console_init(void) | 739 | static int __init newport_console_init(void) |
| 740 | { | 740 | { |
| 741 | |||
| 742 | if (!sgi_gfxaddr) | 741 | if (!sgi_gfxaddr) |
| 743 | return NULL; | 742 | return 0; |
| 744 | 743 | ||
| 745 | if (!npregs) | 744 | if (!npregs) |
| 746 | npregs = (struct newport_regs *)/* ioremap cannot fail */ | 745 | npregs = (struct newport_regs *)/* ioremap cannot fail */ |
diff --git a/drivers/video/imsttfb.c b/drivers/video/imsttfb.c index 5715b8ad0ddc..94f4511023d8 100644 --- a/drivers/video/imsttfb.c +++ b/drivers/video/imsttfb.c | |||
| @@ -1391,7 +1391,7 @@ init_imstt(struct fb_info *info) | |||
| 1391 | } | 1391 | } |
| 1392 | } | 1392 | } |
| 1393 | 1393 | ||
| 1394 | #if USE_NV_MODES && defined(CONFIG_PPC) | 1394 | #if USE_NV_MODES && defined(CONFIG_PPC32) |
| 1395 | { | 1395 | { |
| 1396 | int vmode = init_vmode, cmode = init_cmode; | 1396 | int vmode = init_vmode, cmode = init_cmode; |
| 1397 | 1397 | ||
diff --git a/drivers/w1/w1_int.c b/drivers/w1/w1_int.c index 2fbd8dd16df5..6840dfebe4d4 100644 --- a/drivers/w1/w1_int.c +++ b/drivers/w1/w1_int.c | |||
| @@ -170,22 +170,24 @@ void __w1_remove_master_device(struct w1_master *dev) | |||
| 170 | 170 | ||
| 171 | void w1_remove_master_device(struct w1_bus_master *bm) | 171 | void w1_remove_master_device(struct w1_bus_master *bm) |
| 172 | { | 172 | { |
| 173 | struct w1_master *dev = NULL; | 173 | struct w1_master *dev, *found = NULL; |
| 174 | 174 | ||
| 175 | list_for_each_entry(dev, &w1_masters, w1_master_entry) { | 175 | list_for_each_entry(dev, &w1_masters, w1_master_entry) { |
| 176 | if (!dev->initialized) | 176 | if (!dev->initialized) |
| 177 | continue; | 177 | continue; |
| 178 | 178 | ||
| 179 | if (dev->bus_master->data == bm->data) | 179 | if (dev->bus_master->data == bm->data) { |
| 180 | found = dev; | ||
| 180 | break; | 181 | break; |
| 182 | } | ||
| 181 | } | 183 | } |
| 182 | 184 | ||
| 183 | if (!dev) { | 185 | if (!found) { |
| 184 | printk(KERN_ERR "Device doesn't exist.\n"); | 186 | printk(KERN_ERR "Device doesn't exist.\n"); |
| 185 | return; | 187 | return; |
| 186 | } | 188 | } |
| 187 | 189 | ||
| 188 | __w1_remove_master_device(dev); | 190 | __w1_remove_master_device(found); |
| 189 | } | 191 | } |
| 190 | 192 | ||
| 191 | EXPORT_SYMBOL(w1_add_master_device); | 193 | EXPORT_SYMBOL(w1_add_master_device); |
diff --git a/drivers/zorro/zorro-sysfs.c b/drivers/zorro/zorro-sysfs.c index 9130f1c12c26..808b4f8675c5 100644 --- a/drivers/zorro/zorro-sysfs.c +++ b/drivers/zorro/zorro-sysfs.c | |||
| @@ -78,7 +78,7 @@ static ssize_t zorro_read_config(struct kobject *kobj, | |||
| 78 | static struct bin_attribute zorro_config_attr = { | 78 | static struct bin_attribute zorro_config_attr = { |
| 79 | .attr = { | 79 | .attr = { |
| 80 | .name = "config", | 80 | .name = "config", |
| 81 | .mode = S_IRUGO | S_IWUSR, | 81 | .mode = S_IRUGO, |
| 82 | }, | 82 | }, |
| 83 | .size = sizeof(struct ConfigDev), | 83 | .size = sizeof(struct ConfigDev), |
| 84 | .read = zorro_read_config, | 84 | .read = zorro_read_config, |
diff --git a/fs/autofs4/root.c b/fs/autofs4/root.c index 2d4c8a3e604e..45ff3d63b758 100644 --- a/fs/autofs4/root.c +++ b/fs/autofs4/root.c | |||
| @@ -587,19 +587,20 @@ static struct dentry *autofs4_lookup(struct inode *dir, struct dentry *dentry, s | |||
| 587 | unhashed = autofs4_lookup_unhashed(sbi, dentry->d_parent, &dentry->d_name); | 587 | unhashed = autofs4_lookup_unhashed(sbi, dentry->d_parent, &dentry->d_name); |
| 588 | if (!unhashed) { | 588 | if (!unhashed) { |
| 589 | /* | 589 | /* |
| 590 | * Mark the dentry incomplete, but add it. This is needed so | 590 | * Mark the dentry incomplete but don't hash it. We do this |
| 591 | * that the VFS layer knows about the dentry, and we can count | 591 | * to serialize our inode creation operations (symlink and |
| 592 | * on catching any lookups through the revalidate. | 592 | * mkdir) which prevents deadlock during the callback to |
| 593 | * | 593 | * the daemon. Subsequent user space lookups for the same |
| 594 | * Let all the hard work be done by the revalidate function that | 594 | * dentry are placed on the wait queue while the daemon |
| 595 | * needs to be able to do this anyway.. | 595 | * itself is allowed passage unresticted so the create |
| 596 | * | 596 | * operation itself can then hash the dentry. Finally, |
| 597 | * We need to do this before we release the directory semaphore. | 597 | * we check for the hashed dentry and return the newly |
| 598 | * hashed dentry. | ||
| 598 | */ | 599 | */ |
| 599 | dentry->d_op = &autofs4_root_dentry_operations; | 600 | dentry->d_op = &autofs4_root_dentry_operations; |
| 600 | 601 | ||
| 601 | dentry->d_fsdata = NULL; | 602 | dentry->d_fsdata = NULL; |
| 602 | d_add(dentry, NULL); | 603 | d_instantiate(dentry, NULL); |
| 603 | } else { | 604 | } else { |
| 604 | struct autofs_info *ino = autofs4_dentry_ino(unhashed); | 605 | struct autofs_info *ino = autofs4_dentry_ino(unhashed); |
| 605 | DPRINTK("rehash %p with %p", dentry, unhashed); | 606 | DPRINTK("rehash %p with %p", dentry, unhashed); |
| @@ -607,15 +608,17 @@ static struct dentry *autofs4_lookup(struct inode *dir, struct dentry *dentry, s | |||
| 607 | * If we are racing with expire the request might not | 608 | * If we are racing with expire the request might not |
| 608 | * be quite complete but the directory has been removed | 609 | * be quite complete but the directory has been removed |
| 609 | * so it must have been successful, so just wait for it. | 610 | * so it must have been successful, so just wait for it. |
| 611 | * We need to ensure the AUTOFS_INF_EXPIRING flag is clear | ||
| 612 | * before continuing as revalidate may fail when calling | ||
| 613 | * try_to_fill_dentry (returning EAGAIN) if we don't. | ||
| 610 | */ | 614 | */ |
| 611 | if (ino && (ino->flags & AUTOFS_INF_EXPIRING)) { | 615 | while (ino && (ino->flags & AUTOFS_INF_EXPIRING)) { |
| 612 | DPRINTK("wait for incomplete expire %p name=%.*s", | 616 | DPRINTK("wait for incomplete expire %p name=%.*s", |
| 613 | unhashed, unhashed->d_name.len, | 617 | unhashed, unhashed->d_name.len, |
| 614 | unhashed->d_name.name); | 618 | unhashed->d_name.name); |
| 615 | autofs4_wait(sbi, unhashed, NFY_NONE); | 619 | autofs4_wait(sbi, unhashed, NFY_NONE); |
| 616 | DPRINTK("request completed"); | 620 | DPRINTK("request completed"); |
| 617 | } | 621 | } |
| 618 | d_rehash(unhashed); | ||
| 619 | dentry = unhashed; | 622 | dentry = unhashed; |
| 620 | } | 623 | } |
| 621 | 624 | ||
| @@ -658,7 +661,7 @@ static struct dentry *autofs4_lookup(struct inode *dir, struct dentry *dentry, s | |||
| 658 | * for all system calls, but it should be OK for the operations | 661 | * for all system calls, but it should be OK for the operations |
| 659 | * we permit from an autofs. | 662 | * we permit from an autofs. |
| 660 | */ | 663 | */ |
| 661 | if (dentry->d_inode && d_unhashed(dentry)) { | 664 | if (!oz_mode && d_unhashed(dentry)) { |
| 662 | /* | 665 | /* |
| 663 | * A user space application can (and has done in the past) | 666 | * A user space application can (and has done in the past) |
| 664 | * remove and re-create this directory during the callback. | 667 | * remove and re-create this directory during the callback. |
| @@ -716,7 +719,7 @@ static int autofs4_dir_symlink(struct inode *dir, | |||
| 716 | strcpy(cp, symname); | 719 | strcpy(cp, symname); |
| 717 | 720 | ||
| 718 | inode = autofs4_get_inode(dir->i_sb, ino); | 721 | inode = autofs4_get_inode(dir->i_sb, ino); |
| 719 | d_instantiate(dentry, inode); | 722 | d_add(dentry, inode); |
| 720 | 723 | ||
| 721 | if (dir == dir->i_sb->s_root->d_inode) | 724 | if (dir == dir->i_sb->s_root->d_inode) |
| 722 | dentry->d_op = &autofs4_root_dentry_operations; | 725 | dentry->d_op = &autofs4_root_dentry_operations; |
| @@ -844,7 +847,7 @@ static int autofs4_dir_mkdir(struct inode *dir, struct dentry *dentry, int mode) | |||
| 844 | return -ENOSPC; | 847 | return -ENOSPC; |
| 845 | 848 | ||
| 846 | inode = autofs4_get_inode(dir->i_sb, ino); | 849 | inode = autofs4_get_inode(dir->i_sb, ino); |
| 847 | d_instantiate(dentry, inode); | 850 | d_add(dentry, inode); |
| 848 | 851 | ||
| 849 | if (dir == dir->i_sb->s_root->d_inode) | 852 | if (dir == dir->i_sb->s_root->d_inode) |
| 850 | dentry->d_op = &autofs4_root_dentry_operations; | 853 | dentry->d_op = &autofs4_root_dentry_operations; |
diff --git a/fs/ecryptfs/inode.c b/fs/ecryptfs/inode.c index 131954b3fb98..5d40ad13ab5c 100644 --- a/fs/ecryptfs/inode.c +++ b/fs/ecryptfs/inode.c | |||
| @@ -357,6 +357,10 @@ static struct dentry *ecryptfs_lookup(struct inode *dir, struct dentry *dentry, | |||
| 357 | ecryptfs_printk(KERN_DEBUG, "Is a special file; returning\n"); | 357 | ecryptfs_printk(KERN_DEBUG, "Is a special file; returning\n"); |
| 358 | goto out; | 358 | goto out; |
| 359 | } | 359 | } |
| 360 | if (special_file(lower_inode->i_mode)) { | ||
| 361 | ecryptfs_printk(KERN_DEBUG, "Is a special file; returning\n"); | ||
| 362 | goto out; | ||
| 363 | } | ||
| 360 | if (!nd) { | 364 | if (!nd) { |
| 361 | ecryptfs_printk(KERN_DEBUG, "We have a NULL nd, just leave" | 365 | ecryptfs_printk(KERN_DEBUG, "We have a NULL nd, just leave" |
| 362 | "as we *think* we are about to unlink\n"); | 366 | "as we *think* we are about to unlink\n"); |
| @@ -780,18 +780,11 @@ static int de_thread(struct task_struct *tsk) | |||
| 780 | int count; | 780 | int count; |
| 781 | 781 | ||
| 782 | /* | 782 | /* |
| 783 | * Tell all the sighand listeners that this sighand has | ||
| 784 | * been detached. The signalfd_detach() function grabs the | ||
| 785 | * sighand lock, if signal listeners are present on the sighand. | ||
| 786 | */ | ||
| 787 | signalfd_detach(tsk); | ||
| 788 | |||
| 789 | /* | ||
| 790 | * If we don't share sighandlers, then we aren't sharing anything | 783 | * If we don't share sighandlers, then we aren't sharing anything |
| 791 | * and we can just re-use it all. | 784 | * and we can just re-use it all. |
| 792 | */ | 785 | */ |
| 793 | if (atomic_read(&oldsighand->count) <= 1) { | 786 | if (atomic_read(&oldsighand->count) <= 1) { |
| 794 | BUG_ON(atomic_read(&sig->count) != 1); | 787 | signalfd_detach(tsk); |
| 795 | exit_itimers(sig); | 788 | exit_itimers(sig); |
| 796 | return 0; | 789 | return 0; |
| 797 | } | 790 | } |
| @@ -930,12 +923,11 @@ static int de_thread(struct task_struct *tsk) | |||
| 930 | sig->flags = 0; | 923 | sig->flags = 0; |
| 931 | 924 | ||
| 932 | no_thread_group: | 925 | no_thread_group: |
| 926 | signalfd_detach(tsk); | ||
| 933 | exit_itimers(sig); | 927 | exit_itimers(sig); |
| 934 | if (leader) | 928 | if (leader) |
| 935 | release_task(leader); | 929 | release_task(leader); |
| 936 | 930 | ||
| 937 | BUG_ON(atomic_read(&sig->count) != 1); | ||
| 938 | |||
| 939 | if (atomic_read(&oldsighand->count) == 1) { | 931 | if (atomic_read(&oldsighand->count) == 1) { |
| 940 | /* | 932 | /* |
| 941 | * Now that we nuked the rest of the thread group, | 933 | * Now that we nuked the rest of the thread group, |
diff --git a/fs/signalfd.c b/fs/signalfd.c index 7b941abbcde0..a8e293d30034 100644 --- a/fs/signalfd.c +++ b/fs/signalfd.c | |||
| @@ -56,12 +56,18 @@ static int signalfd_lock(struct signalfd_ctx *ctx, struct signalfd_lockctx *lk) | |||
| 56 | sighand = lock_task_sighand(lk->tsk, &lk->flags); | 56 | sighand = lock_task_sighand(lk->tsk, &lk->flags); |
| 57 | rcu_read_unlock(); | 57 | rcu_read_unlock(); |
| 58 | 58 | ||
| 59 | if (sighand && !ctx->tsk) { | 59 | if (!sighand) |
| 60 | return 0; | ||
| 61 | |||
| 62 | if (!ctx->tsk) { | ||
| 60 | unlock_task_sighand(lk->tsk, &lk->flags); | 63 | unlock_task_sighand(lk->tsk, &lk->flags); |
| 61 | sighand = NULL; | 64 | return 0; |
| 62 | } | 65 | } |
| 63 | 66 | ||
| 64 | return sighand != NULL; | 67 | if (lk->tsk->tgid == current->tgid) |
| 68 | lk->tsk = current; | ||
| 69 | |||
| 70 | return 1; | ||
| 65 | } | 71 | } |
| 66 | 72 | ||
| 67 | static void signalfd_unlock(struct signalfd_lockctx *lk) | 73 | static void signalfd_unlock(struct signalfd_lockctx *lk) |
| @@ -331,7 +337,7 @@ asmlinkage long sys_signalfd(int ufd, sigset_t __user *user_mask, size_t sizemas | |||
| 331 | 337 | ||
| 332 | init_waitqueue_head(&ctx->wqh); | 338 | init_waitqueue_head(&ctx->wqh); |
| 333 | ctx->sigmask = sigmask; | 339 | ctx->sigmask = sigmask; |
| 334 | ctx->tsk = current; | 340 | ctx->tsk = current->group_leader; |
| 335 | 341 | ||
| 336 | sighand = current->sighand; | 342 | sighand = current->sighand; |
| 337 | /* | 343 | /* |
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) | |||
| 248 | 248 | ||
| 249 | void sysfs_remove_bin_file(struct kobject * kobj, struct bin_attribute * attr) | 249 | void sysfs_remove_bin_file(struct kobject * kobj, struct bin_attribute * attr) |
| 250 | { | 250 | { |
| 251 | if (sysfs_hash_and_remove(kobj->sd, attr->attr.name) < 0) { | 251 | sysfs_hash_and_remove(kobj->sd, attr->attr.name); |
| 252 | printk(KERN_ERR "%s: " | ||
| 253 | "bad dentry or inode or no such file: \"%s\"\n", | ||
| 254 | __FUNCTION__, attr->attr.name); | ||
| 255 | dump_stack(); | ||
| 256 | } | ||
| 257 | } | 252 | } |
| 258 | 253 | ||
| 259 | EXPORT_SYMBOL_GPL(sysfs_create_bin_file); | 254 | 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) | |||
| 762 | static struct dentry * sysfs_lookup(struct inode *dir, struct dentry *dentry, | 762 | static struct dentry * sysfs_lookup(struct inode *dir, struct dentry *dentry, |
| 763 | struct nameidata *nd) | 763 | struct nameidata *nd) |
| 764 | { | 764 | { |
| 765 | struct dentry *ret = NULL; | ||
| 765 | struct sysfs_dirent * parent_sd = dentry->d_parent->d_fsdata; | 766 | struct sysfs_dirent * parent_sd = dentry->d_parent->d_fsdata; |
| 766 | struct sysfs_dirent * sd; | 767 | struct sysfs_dirent * sd; |
| 767 | struct bin_attribute *bin_attr; | 768 | struct bin_attribute *bin_attr; |
| 768 | struct inode *inode; | 769 | struct inode *inode; |
| 769 | int found = 0; | 770 | int found = 0; |
| 770 | 771 | ||
| 772 | mutex_lock(&sysfs_mutex); | ||
| 773 | |||
| 771 | for (sd = parent_sd->s_children; sd; sd = sd->s_sibling) { | 774 | for (sd = parent_sd->s_children; sd; sd = sd->s_sibling) { |
| 772 | if (sysfs_type(sd) && | 775 | if (sysfs_type(sd) && |
| 773 | !strcmp(sd->s_name, dentry->d_name.name)) { | 776 | !strcmp(sd->s_name, dentry->d_name.name)) { |
| @@ -778,14 +781,14 @@ static struct dentry * sysfs_lookup(struct inode *dir, struct dentry *dentry, | |||
| 778 | 781 | ||
| 779 | /* no such entry */ | 782 | /* no such entry */ |
| 780 | if (!found) | 783 | if (!found) |
| 781 | return NULL; | 784 | goto out_unlock; |
| 782 | 785 | ||
| 783 | /* attach dentry and inode */ | 786 | /* attach dentry and inode */ |
| 784 | inode = sysfs_get_inode(sd); | 787 | inode = sysfs_get_inode(sd); |
| 785 | if (!inode) | 788 | if (!inode) { |
| 786 | return ERR_PTR(-ENOMEM); | 789 | ret = ERR_PTR(-ENOMEM); |
| 787 | 790 | goto out_unlock; | |
| 788 | mutex_lock(&sysfs_mutex); | 791 | } |
| 789 | 792 | ||
| 790 | if (inode->i_state & I_NEW) { | 793 | if (inode->i_state & I_NEW) { |
| 791 | /* initialize inode according to type */ | 794 | /* initialize inode according to type */ |
| @@ -815,9 +818,9 @@ static struct dentry * sysfs_lookup(struct inode *dir, struct dentry *dentry, | |||
| 815 | sysfs_instantiate(dentry, inode); | 818 | sysfs_instantiate(dentry, inode); |
| 816 | sysfs_attach_dentry(sd, dentry); | 819 | sysfs_attach_dentry(sd, dentry); |
| 817 | 820 | ||
| 821 | out_unlock: | ||
| 818 | mutex_unlock(&sysfs_mutex); | 822 | mutex_unlock(&sysfs_mutex); |
| 819 | 823 | return ret; | |
| 820 | return NULL; | ||
| 821 | } | 824 | } |
| 822 | 825 | ||
| 823 | const struct inode_operations sysfs_dir_inode_operations = { | 826 | 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, | |||
| 942 | if (error) | 945 | if (error) |
| 943 | goto out_drop; | 946 | goto out_drop; |
| 944 | 947 | ||
| 948 | mutex_lock(&sysfs_mutex); | ||
| 949 | |||
| 945 | dup_name = sd->s_name; | 950 | dup_name = sd->s_name; |
| 946 | sd->s_name = new_name; | 951 | sd->s_name = new_name; |
| 947 | 952 | ||
| @@ -949,8 +954,6 @@ int sysfs_rename_dir(struct kobject *kobj, struct sysfs_dirent *new_parent_sd, | |||
| 949 | d_add(new_dentry, NULL); | 954 | d_add(new_dentry, NULL); |
| 950 | d_move(sd->s_dentry, new_dentry); | 955 | d_move(sd->s_dentry, new_dentry); |
| 951 | 956 | ||
| 952 | mutex_lock(&sysfs_mutex); | ||
| 953 | |||
| 954 | sysfs_unlink_sibling(sd); | 957 | sysfs_unlink_sibling(sd); |
| 955 | sysfs_get(new_parent_sd); | 958 | sysfs_get(new_parent_sd); |
| 956 | sysfs_put(sd->s_parent); | 959 | sysfs_put(sd->s_parent); |
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 | |||
| 112 | * writew/writel functions and the other mmio helpers. The returned | 112 | * writew/writel functions and the other mmio helpers. The returned |
| 113 | * address is not guaranteed to be usable directly as a virtual | 113 | * address is not guaranteed to be usable directly as a virtual |
| 114 | * address. | 114 | * address. |
| 115 | * | ||
| 116 | * If the area you are trying to map is a PCI BAR you should have a | ||
| 117 | * look at pci_iomap(). | ||
| 115 | */ | 118 | */ |
| 116 | 119 | ||
| 117 | static inline void __iomem * ioremap(unsigned long offset, unsigned long size) | 120 | static inline void __iomem * ioremap(unsigned long offset, unsigned long size) |
diff --git a/include/asm-m68k/ioctls.h b/include/asm-m68k/ioctls.h index 0c48929ab444..b8d2f4be7fd7 100644 --- a/include/asm-m68k/ioctls.h +++ b/include/asm-m68k/ioctls.h | |||
| @@ -46,6 +46,10 @@ | |||
| 46 | #define TIOCSBRK 0x5427 /* BSD compatibility */ | 46 | #define TIOCSBRK 0x5427 /* BSD compatibility */ |
| 47 | #define TIOCCBRK 0x5428 /* BSD compatibility */ | 47 | #define TIOCCBRK 0x5428 /* BSD compatibility */ |
| 48 | #define TIOCGSID 0x5429 /* Return the session ID of FD */ | 48 | #define TIOCGSID 0x5429 /* Return the session ID of FD */ |
| 49 | #define TCGETS2 _IOR('T',0x2A, struct termios2) | ||
| 50 | #define TCSETS2 _IOW('T',0x2B, struct termios2) | ||
| 51 | #define TCSETSW2 _IOW('T',0x2C, struct termios2) | ||
| 52 | #define TCSETSF2 _IOW('T',0x2D, struct termios2) | ||
| 49 | #define TIOCGPTN _IOR('T',0x30, unsigned int) /* Get Pty Number (of pty-mux device) */ | 53 | #define TIOCGPTN _IOR('T',0x30, unsigned int) /* Get Pty Number (of pty-mux device) */ |
| 50 | #define TIOCSPTLCK _IOW('T',0x31, int) /* Lock/unlock Pty */ | 54 | #define TIOCSPTLCK _IOW('T',0x31, int) /* Lock/unlock Pty */ |
| 51 | 55 | ||
diff --git a/include/asm-m68k/page.h b/include/asm-m68k/page.h index 9e6d0d6debdb..1431ea0b59e0 100644 --- a/include/asm-m68k/page.h +++ b/include/asm-m68k/page.h | |||
| @@ -4,17 +4,15 @@ | |||
| 4 | 4 | ||
| 5 | #ifdef __KERNEL__ | 5 | #ifdef __KERNEL__ |
| 6 | 6 | ||
| 7 | #include <linux/const.h> | ||
| 8 | |||
| 7 | /* PAGE_SHIFT determines the page size */ | 9 | /* PAGE_SHIFT determines the page size */ |
| 8 | #ifndef CONFIG_SUN3 | 10 | #ifndef CONFIG_SUN3 |
| 9 | #define PAGE_SHIFT (12) | 11 | #define PAGE_SHIFT (12) |
| 10 | #else | 12 | #else |
| 11 | #define PAGE_SHIFT (13) | 13 | #define PAGE_SHIFT (13) |
| 12 | #endif | 14 | #endif |
| 13 | #ifdef __ASSEMBLY__ | 15 | #define PAGE_SIZE (_AC(1, UL) << PAGE_SHIFT) |
| 14 | #define PAGE_SIZE (1 << PAGE_SHIFT) | ||
| 15 | #else | ||
| 16 | #define PAGE_SIZE (1UL << PAGE_SHIFT) | ||
| 17 | #endif | ||
| 18 | #define PAGE_MASK (~(PAGE_SIZE-1)) | 16 | #define PAGE_MASK (~(PAGE_SIZE-1)) |
| 19 | 17 | ||
| 20 | #include <asm/setup.h> | 18 | #include <asm/setup.h> |
| @@ -27,6 +25,8 @@ | |||
| 27 | 25 | ||
| 28 | #ifndef __ASSEMBLY__ | 26 | #ifndef __ASSEMBLY__ |
| 29 | 27 | ||
| 28 | #include <linux/compiler.h> | ||
| 29 | |||
| 30 | #include <asm/module.h> | 30 | #include <asm/module.h> |
| 31 | 31 | ||
| 32 | #define get_user_page(vaddr) __get_free_page(GFP_KERNEL) | 32 | #define get_user_page(vaddr) __get_free_page(GFP_KERNEL) |
diff --git a/include/asm-m68k/processor.h b/include/asm-m68k/processor.h index 8455f778b601..4453ec379c5d 100644 --- a/include/asm-m68k/processor.h +++ b/include/asm-m68k/processor.h | |||
| @@ -38,12 +38,8 @@ static inline void wrusp(unsigned long usp) | |||
| 38 | #ifndef CONFIG_SUN3 | 38 | #ifndef CONFIG_SUN3 |
| 39 | #define TASK_SIZE (0xF0000000UL) | 39 | #define TASK_SIZE (0xF0000000UL) |
| 40 | #else | 40 | #else |
| 41 | #ifdef __ASSEMBLY__ | ||
| 42 | #define TASK_SIZE (0x0E000000) | ||
| 43 | #else | ||
| 44 | #define TASK_SIZE (0x0E000000UL) | 41 | #define TASK_SIZE (0x0E000000UL) |
| 45 | #endif | 42 | #endif |
| 46 | #endif | ||
| 47 | 43 | ||
| 48 | /* This decides where the kernel will search for a free chunk of vm | 44 | /* This decides where the kernel will search for a free chunk of vm |
| 49 | * space during mmap's. | 45 | * space during mmap's. |
diff --git a/include/asm-m68k/termbits.h b/include/asm-m68k/termbits.h index 0e520f328f53..8c14170996bb 100644 --- a/include/asm-m68k/termbits.h +++ b/include/asm-m68k/termbits.h | |||
| @@ -141,6 +141,7 @@ struct ktermios { | |||
| 141 | #define HUPCL 0002000 | 141 | #define HUPCL 0002000 |
| 142 | #define CLOCAL 0004000 | 142 | #define CLOCAL 0004000 |
| 143 | #define CBAUDEX 0010000 | 143 | #define CBAUDEX 0010000 |
| 144 | #define BOTHER 0010000 | ||
| 144 | #define B57600 0010001 | 145 | #define B57600 0010001 |
| 145 | #define B115200 0010002 | 146 | #define B115200 0010002 |
| 146 | #define B230400 0010003 | 147 | #define B230400 0010003 |
| @@ -156,10 +157,12 @@ struct ktermios { | |||
| 156 | #define B3000000 0010015 | 157 | #define B3000000 0010015 |
| 157 | #define B3500000 0010016 | 158 | #define B3500000 0010016 |
| 158 | #define B4000000 0010017 | 159 | #define B4000000 0010017 |
| 159 | #define CIBAUD 002003600000 /* input baud rate (not used) */ | 160 | #define CIBAUD 002003600000 /* input baud rate */ |
| 160 | #define CMSPAR 010000000000 /* mark or space (stick) parity */ | 161 | #define CMSPAR 010000000000 /* mark or space (stick) parity */ |
| 161 | #define CRTSCTS 020000000000 /* flow control */ | 162 | #define CRTSCTS 020000000000 /* flow control */ |
| 162 | 163 | ||
| 164 | #define IBSHIFT 16 /* Shift from CBAUD to CIBAUD */ | ||
| 165 | |||
| 163 | /* c_lflag bits */ | 166 | /* c_lflag bits */ |
| 164 | #define ISIG 0000001 | 167 | #define ISIG 0000001 |
| 165 | #define ICANON 0000002 | 168 | #define ICANON 0000002 |
diff --git a/include/asm-m68k/termios.h b/include/asm-m68k/termios.h index 00edabd76168..0823032e4045 100644 --- a/include/asm-m68k/termios.h +++ b/include/asm-m68k/termios.h | |||
| @@ -82,8 +82,10 @@ struct termio { | |||
| 82 | copy_to_user((termio)->c_cc, (termios)->c_cc, NCC); \ | 82 | copy_to_user((termio)->c_cc, (termios)->c_cc, NCC); \ |
| 83 | }) | 83 | }) |
| 84 | 84 | ||
| 85 | #define user_termios_to_kernel_termios(k, u) copy_from_user(k, u, sizeof(struct termios)) | 85 | #define user_termios_to_kernel_termios(k, u) copy_from_user(k, u, sizeof(struct termios2)) |
| 86 | #define kernel_termios_to_user_termios(u, k) copy_to_user(u, k, sizeof(struct termios)) | 86 | #define kernel_termios_to_user_termios(u, k) copy_to_user(u, k, sizeof(struct termios2)) |
| 87 | #define user_termios_to_kernel_termios_1(k, u) copy_from_user(k, u, sizeof(struct termios)) | ||
| 88 | #define kernel_termios_to_user_termios_1(u, k) copy_to_user(u, k, sizeof(struct termios)) | ||
| 87 | 89 | ||
| 88 | #endif /* __KERNEL__ */ | 90 | #endif /* __KERNEL__ */ |
| 89 | 91 | ||
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); | |||
| 65 | #define VMALLOC_START 0 | 65 | #define VMALLOC_START 0 |
| 66 | #define VMALLOC_END 0xffffffff | 66 | #define VMALLOC_END 0xffffffff |
| 67 | 67 | ||
| 68 | #include <asm-generic/pgtable.h> | ||
| 69 | |||
| 68 | #endif /* _M68KNOMMU_PGTABLE_H */ | 70 | #endif /* _M68KNOMMU_PGTABLE_H */ |
diff --git a/include/asm-s390/atomic.h b/include/asm-s390/atomic.h index ea486952f778..2d184655bc5d 100644 --- a/include/asm-s390/atomic.h +++ b/include/asm-s390/atomic.h | |||
| @@ -67,8 +67,17 @@ typedef struct { | |||
| 67 | 67 | ||
| 68 | #endif /* __GNUC__ */ | 68 | #endif /* __GNUC__ */ |
| 69 | 69 | ||
| 70 | #define atomic_read(v) ((v)->counter) | 70 | static inline int atomic_read(const atomic_t *v) |
| 71 | #define atomic_set(v,i) (((v)->counter) = (i)) | 71 | { |
| 72 | barrier(); | ||
| 73 | return v->counter; | ||
| 74 | } | ||
| 75 | |||
| 76 | static inline void atomic_set(atomic_t *v, int i) | ||
| 77 | { | ||
| 78 | v->counter = i; | ||
| 79 | barrier(); | ||
| 80 | } | ||
| 72 | 81 | ||
| 73 | static __inline__ int atomic_add_return(int i, atomic_t * v) | 82 | static __inline__ int atomic_add_return(int i, atomic_t * v) |
| 74 | { | 83 | { |
| @@ -182,8 +191,17 @@ typedef struct { | |||
| 182 | 191 | ||
| 183 | #endif /* __GNUC__ */ | 192 | #endif /* __GNUC__ */ |
| 184 | 193 | ||
| 185 | #define atomic64_read(v) ((v)->counter) | 194 | static inline long long atomic64_read(const atomic64_t *v) |
| 186 | #define atomic64_set(v,i) (((v)->counter) = (i)) | 195 | { |
| 196 | barrier(); | ||
| 197 | return v->counter; | ||
| 198 | } | ||
| 199 | |||
| 200 | static inline void atomic64_set(atomic64_t *v, long long i) | ||
| 201 | { | ||
| 202 | v->counter = i; | ||
| 203 | barrier(); | ||
| 204 | } | ||
| 187 | 205 | ||
| 188 | static __inline__ long long atomic64_add_return(long long i, atomic64_t * v) | 206 | static __inline__ long long atomic64_add_return(long long i, atomic64_t * v) |
| 189 | { | 207 | { |
diff --git a/include/asm-s390/cio.h b/include/asm-s390/cio.h index f738d2827582..1982fb344164 100644 --- a/include/asm-s390/cio.h +++ b/include/asm-s390/cio.h | |||
| @@ -258,19 +258,6 @@ struct ciw { | |||
| 258 | /* Sick revalidation of device. */ | 258 | /* Sick revalidation of device. */ |
| 259 | #define CIO_REVALIDATE 0x0008 | 259 | #define CIO_REVALIDATE 0x0008 |
| 260 | 260 | ||
| 261 | struct diag210 { | ||
| 262 | __u16 vrdcdvno : 16; /* device number (input) */ | ||
| 263 | __u16 vrdclen : 16; /* data block length (input) */ | ||
| 264 | __u32 vrdcvcla : 8; /* virtual device class (output) */ | ||
| 265 | __u32 vrdcvtyp : 8; /* virtual device type (output) */ | ||
| 266 | __u32 vrdcvsta : 8; /* virtual device status (output) */ | ||
| 267 | __u32 vrdcvfla : 8; /* virtual device flags (output) */ | ||
| 268 | __u32 vrdcrccl : 8; /* real device class (output) */ | ||
| 269 | __u32 vrdccrty : 8; /* real device type (output) */ | ||
| 270 | __u32 vrdccrmd : 8; /* real device model (output) */ | ||
| 271 | __u32 vrdccrft : 8; /* real device feature (output) */ | ||
| 272 | } __attribute__ ((packed,aligned(4))); | ||
| 273 | |||
| 274 | struct ccw_dev_id { | 261 | struct ccw_dev_id { |
| 275 | u8 ssid; | 262 | u8 ssid; |
| 276 | u16 devno; | 263 | u16 devno; |
| @@ -285,8 +272,6 @@ static inline int ccw_dev_id_is_equal(struct ccw_dev_id *dev_id1, | |||
| 285 | return 0; | 272 | return 0; |
| 286 | } | 273 | } |
| 287 | 274 | ||
| 288 | extern int diag210(struct diag210 *addr); | ||
| 289 | |||
| 290 | extern void wait_cons_dev(void); | 275 | extern void wait_cons_dev(void); |
| 291 | 276 | ||
| 292 | extern void css_schedule_reprobe(void); | 277 | extern void css_schedule_reprobe(void); |
diff --git a/include/asm-s390/diag.h b/include/asm-s390/diag.h new file mode 100644 index 000000000000..72b2e2f2d32d --- /dev/null +++ b/include/asm-s390/diag.h | |||
| @@ -0,0 +1,39 @@ | |||
| 1 | /* | ||
| 2 | * s390 diagnose functions | ||
| 3 | * | ||
| 4 | * Copyright IBM Corp. 2007 | ||
| 5 | * Author(s): Michael Holzheu <holzheu@de.ibm.com> | ||
| 6 | */ | ||
| 7 | |||
| 8 | #ifndef _ASM_S390_DIAG_H | ||
| 9 | #define _ASM_S390_DIAG_H | ||
| 10 | |||
| 11 | /* | ||
| 12 | * Diagnose 10: Release pages | ||
| 13 | */ | ||
| 14 | extern void diag10(unsigned long addr); | ||
| 15 | |||
| 16 | /* | ||
| 17 | * Diagnose 14: Input spool file manipulation | ||
| 18 | */ | ||
| 19 | extern int diag14(unsigned long rx, unsigned long ry1, unsigned long subcode); | ||
| 20 | |||
| 21 | /* | ||
| 22 | * Diagnose 210: Get information about a virtual device | ||
| 23 | */ | ||
| 24 | struct diag210 { | ||
| 25 | u16 vrdcdvno; /* device number (input) */ | ||
| 26 | u16 vrdclen; /* data block length (input) */ | ||
| 27 | u8 vrdcvcla; /* virtual device class (output) */ | ||
| 28 | u8 vrdcvtyp; /* virtual device type (output) */ | ||
| 29 | u8 vrdcvsta; /* virtual device status (output) */ | ||
| 30 | u8 vrdcvfla; /* virtual device flags (output) */ | ||
| 31 | u8 vrdcrccl; /* real device class (output) */ | ||
| 32 | u8 vrdccrty; /* real device type (output) */ | ||
| 33 | u8 vrdccrmd; /* real device model (output) */ | ||
| 34 | u8 vrdccrft; /* real device feature (output) */ | ||
| 35 | } __attribute__((packed, aligned(4))); | ||
| 36 | |||
| 37 | extern int diag210(struct diag210 *addr); | ||
| 38 | |||
| 39 | #endif /* _ASM_S390_DIAG_H */ | ||
diff --git a/include/asm-s390/pgalloc.h b/include/asm-s390/pgalloc.h index 56c8a6c80e2e..e45d3c9a4b7e 100644 --- a/include/asm-s390/pgalloc.h +++ b/include/asm-s390/pgalloc.h | |||
| @@ -19,8 +19,6 @@ | |||
| 19 | 19 | ||
| 20 | #define check_pgt_cache() do {} while (0) | 20 | #define check_pgt_cache() do {} while (0) |
| 21 | 21 | ||
| 22 | extern void diag10(unsigned long addr); | ||
| 23 | |||
| 24 | /* | 22 | /* |
| 25 | * Page allocation orders. | 23 | * Page allocation orders. |
| 26 | */ | 24 | */ |
diff --git a/include/asm-sparc64/percpu.h b/include/asm-sparc64/percpu.h index caf8750792ff..a1f53a4da405 100644 --- a/include/asm-sparc64/percpu.h +++ b/include/asm-sparc64/percpu.h | |||
| @@ -3,6 +3,8 @@ | |||
| 3 | 3 | ||
| 4 | #include <linux/compiler.h> | 4 | #include <linux/compiler.h> |
| 5 | 5 | ||
| 6 | register unsigned long __local_per_cpu_offset asm("g5"); | ||
| 7 | |||
| 6 | #ifdef CONFIG_SMP | 8 | #ifdef CONFIG_SMP |
| 7 | 9 | ||
| 8 | #define setup_per_cpu_areas() do { } while (0) | 10 | #define setup_per_cpu_areas() do { } while (0) |
| @@ -23,8 +25,6 @@ extern unsigned long __per_cpu_shift; | |||
| 23 | __typeof__(type) per_cpu__##name \ | 25 | __typeof__(type) per_cpu__##name \ |
| 24 | ____cacheline_aligned_in_smp | 26 | ____cacheline_aligned_in_smp |
| 25 | 27 | ||
| 26 | register unsigned long __local_per_cpu_offset asm("g5"); | ||
| 27 | |||
| 28 | /* var is in discarded region: offset to particular copy we want */ | 28 | /* var is in discarded region: offset to particular copy we want */ |
| 29 | #define per_cpu(var, cpu) (*RELOC_HIDE(&per_cpu__##var, __per_cpu_offset(cpu))) | 29 | #define per_cpu(var, cpu) (*RELOC_HIDE(&per_cpu__##var, __per_cpu_offset(cpu))) |
| 30 | #define __get_cpu_var(var) (*RELOC_HIDE(&per_cpu__##var, __local_per_cpu_offset)) | 30 | #define __get_cpu_var(var) (*RELOC_HIDE(&per_cpu__##var, __local_per_cpu_offset)) |
diff --git a/include/asm-sparc64/system.h b/include/asm-sparc64/system.h index 64891cb10f05..3f175fa7e6d2 100644 --- a/include/asm-sparc64/system.h +++ b/include/asm-sparc64/system.h | |||
| @@ -141,7 +141,6 @@ do { \ | |||
| 141 | * not preserve it's value. Hairy, but it lets us remove 2 loads | 141 | * not preserve it's value. Hairy, but it lets us remove 2 loads |
| 142 | * and 2 stores in this critical code path. -DaveM | 142 | * and 2 stores in this critical code path. -DaveM |
| 143 | */ | 143 | */ |
| 144 | #define EXTRA_CLOBBER ,"%l1" | ||
| 145 | #define switch_to(prev, next, last) \ | 144 | #define switch_to(prev, next, last) \ |
| 146 | do { if (test_thread_flag(TIF_PERFCTR)) { \ | 145 | do { if (test_thread_flag(TIF_PERFCTR)) { \ |
| 147 | unsigned long __tmp; \ | 146 | unsigned long __tmp; \ |
| @@ -164,33 +163,34 @@ do { if (test_thread_flag(TIF_PERFCTR)) { \ | |||
| 164 | "stx %%i6, [%%sp + 2047 + 0x70]\n\t" \ | 163 | "stx %%i6, [%%sp + 2047 + 0x70]\n\t" \ |
| 165 | "stx %%i7, [%%sp + 2047 + 0x78]\n\t" \ | 164 | "stx %%i7, [%%sp + 2047 + 0x78]\n\t" \ |
| 166 | "rdpr %%wstate, %%o5\n\t" \ | 165 | "rdpr %%wstate, %%o5\n\t" \ |
| 167 | "stx %%o6, [%%g6 + %3]\n\t" \ | 166 | "stx %%o6, [%%g6 + %6]\n\t" \ |
| 168 | "stb %%o5, [%%g6 + %2]\n\t" \ | ||
| 169 | "rdpr %%cwp, %%o5\n\t" \ | ||
| 170 | "stb %%o5, [%%g6 + %5]\n\t" \ | 167 | "stb %%o5, [%%g6 + %5]\n\t" \ |
| 171 | "mov %1, %%g6\n\t" \ | 168 | "rdpr %%cwp, %%o5\n\t" \ |
| 172 | "ldub [%1 + %5], %%g1\n\t" \ | 169 | "stb %%o5, [%%g6 + %8]\n\t" \ |
| 170 | "mov %4, %%g6\n\t" \ | ||
| 171 | "ldub [%4 + %8], %%g1\n\t" \ | ||
| 173 | "wrpr %%g1, %%cwp\n\t" \ | 172 | "wrpr %%g1, %%cwp\n\t" \ |
| 174 | "ldx [%%g6 + %3], %%o6\n\t" \ | 173 | "ldx [%%g6 + %6], %%o6\n\t" \ |
| 175 | "ldub [%%g6 + %2], %%o5\n\t" \ | 174 | "ldub [%%g6 + %5], %%o5\n\t" \ |
| 176 | "ldub [%%g6 + %4], %%o7\n\t" \ | 175 | "ldub [%%g6 + %7], %%o7\n\t" \ |
| 177 | "wrpr %%o5, 0x0, %%wstate\n\t" \ | 176 | "wrpr %%o5, 0x0, %%wstate\n\t" \ |
| 178 | "ldx [%%sp + 2047 + 0x70], %%i6\n\t" \ | 177 | "ldx [%%sp + 2047 + 0x70], %%i6\n\t" \ |
| 179 | "ldx [%%sp + 2047 + 0x78], %%i7\n\t" \ | 178 | "ldx [%%sp + 2047 + 0x78], %%i7\n\t" \ |
| 180 | "ldx [%%g6 + %6], %%g4\n\t" \ | 179 | "ldx [%%g6 + %9], %%g4\n\t" \ |
| 181 | "brz,pt %%o7, 1f\n\t" \ | 180 | "brz,pt %%o7, 1f\n\t" \ |
| 182 | " mov %%g7, %0\n\t" \ | 181 | " mov %%g7, %0\n\t" \ |
| 183 | "b,a ret_from_syscall\n\t" \ | 182 | "b,a ret_from_syscall\n\t" \ |
| 184 | "1:\n\t" \ | 183 | "1:\n\t" \ |
| 185 | : "=&r" (last) \ | 184 | : "=&r" (last), "=r" (current), "=r" (current_thread_info_reg), \ |
| 185 | "=r" (__local_per_cpu_offset) \ | ||
| 186 | : "0" (task_thread_info(next)), \ | 186 | : "0" (task_thread_info(next)), \ |
| 187 | "i" (TI_WSTATE), "i" (TI_KSP), "i" (TI_NEW_CHILD), \ | 187 | "i" (TI_WSTATE), "i" (TI_KSP), "i" (TI_NEW_CHILD), \ |
| 188 | "i" (TI_CWP), "i" (TI_TASK) \ | 188 | "i" (TI_CWP), "i" (TI_TASK) \ |
| 189 | : "cc", \ | 189 | : "cc", \ |
| 190 | "g1", "g2", "g3", "g7", \ | 190 | "g1", "g2", "g3", "g7", \ |
| 191 | "l2", "l3", "l4", "l5", "l6", "l7", \ | 191 | "l1", "l2", "l3", "l4", "l5", "l6", "l7", \ |
| 192 | "i0", "i1", "i2", "i3", "i4", "i5", \ | 192 | "i0", "i1", "i2", "i3", "i4", "i5", \ |
| 193 | "o0", "o1", "o2", "o3", "o4", "o5", "o7" EXTRA_CLOBBER);\ | 193 | "o0", "o1", "o2", "o3", "o4", "o5", "o7"); \ |
| 194 | /* If you fuck with this, update ret_from_syscall code too. */ \ | 194 | /* If you fuck with this, update ret_from_syscall code too. */ \ |
| 195 | if (test_thread_flag(TIF_PERFCTR)) { \ | 195 | if (test_thread_flag(TIF_PERFCTR)) { \ |
| 196 | write_pcr(current_thread_info()->pcr_reg); \ | 196 | write_pcr(current_thread_info()->pcr_reg); \ |
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 @@ | |||
| 63 | #define AUDIT_ADD_RULE 1011 /* Add syscall filtering rule */ | 63 | #define AUDIT_ADD_RULE 1011 /* Add syscall filtering rule */ |
| 64 | #define AUDIT_DEL_RULE 1012 /* Delete syscall filtering rule */ | 64 | #define AUDIT_DEL_RULE 1012 /* Delete syscall filtering rule */ |
| 65 | #define AUDIT_LIST_RULES 1013 /* List syscall filtering rules */ | 65 | #define AUDIT_LIST_RULES 1013 /* List syscall filtering rules */ |
| 66 | #define AUDIT_TTY_GET 1014 /* Get TTY auditing status */ | 66 | #define AUDIT_TTY_GET 1016 /* Get TTY auditing status */ |
| 67 | #define AUDIT_TTY_SET 1015 /* Set TTY auditing status */ | 67 | #define AUDIT_TTY_SET 1017 /* Set TTY auditing status */ |
| 68 | 68 | ||
| 69 | #define AUDIT_FIRST_USER_MSG 1100 /* Userspace messages mostly uninteresting to kernel */ | 69 | #define AUDIT_FIRST_USER_MSG 1100 /* Userspace messages mostly uninteresting to kernel */ |
| 70 | #define AUDIT_USER_AVC 1107 /* We filter this differently */ | 70 | #define AUDIT_USER_AVC 1107 /* We filter this differently */ |
diff --git a/include/linux/kbd_kern.h b/include/linux/kbd_kern.h index 506ad20c18f8..8bdb16bfe5fb 100644 --- a/include/linux/kbd_kern.h +++ b/include/linux/kbd_kern.h | |||
| @@ -161,4 +161,7 @@ static inline void con_schedule_flip(struct tty_struct *t) | |||
| 161 | schedule_delayed_work(&t->buf.work, 0); | 161 | schedule_delayed_work(&t->buf.work, 0); |
| 162 | } | 162 | } |
| 163 | 163 | ||
| 164 | /* mac_hid.c */ | ||
| 165 | extern int mac_hid_mouse_emulate_buttons(int, unsigned int, int); | ||
| 166 | |||
| 164 | #endif | 167 | #endif |
diff --git a/include/linux/mempolicy.h b/include/linux/mempolicy.h index e147cf50529f..5bdd656e88cf 100644 --- a/include/linux/mempolicy.h +++ b/include/linux/mempolicy.h | |||
| @@ -166,7 +166,7 @@ extern enum zone_type policy_zone; | |||
| 166 | 166 | ||
| 167 | static inline void check_highest_zone(enum zone_type k) | 167 | static inline void check_highest_zone(enum zone_type k) |
| 168 | { | 168 | { |
| 169 | if (k > policy_zone) | 169 | if (k > policy_zone && k != ZONE_MOVABLE) |
| 170 | policy_zone = k; | 170 | policy_zone = k; |
| 171 | } | 171 | } |
| 172 | 172 | ||
diff --git a/include/linux/mm.h b/include/linux/mm.h index 655094dc9440..1692dd6cb915 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h | |||
| @@ -1042,7 +1042,7 @@ static inline void vma_nonlinear_insert(struct vm_area_struct *vma, | |||
| 1042 | } | 1042 | } |
| 1043 | 1043 | ||
| 1044 | /* mmap.c */ | 1044 | /* mmap.c */ |
| 1045 | extern int __vm_enough_memory(long pages, int cap_sys_admin); | 1045 | extern int __vm_enough_memory(struct mm_struct *mm, long pages, int cap_sys_admin); |
| 1046 | extern void vma_adjust(struct vm_area_struct *vma, unsigned long start, | 1046 | extern void vma_adjust(struct vm_area_struct *vma, unsigned long start, |
| 1047 | unsigned long end, pgoff_t pgoff, struct vm_area_struct *insert); | 1047 | unsigned long end, pgoff_t pgoff, struct vm_area_struct *insert); |
| 1048 | extern struct vm_area_struct *vma_merge(struct mm_struct *, | 1048 | extern struct vm_area_struct *vma_merge(struct mm_struct *, |
diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h index 3ea68cd3b61f..4e5627379b09 100644 --- a/include/linux/mmzone.h +++ b/include/linux/mmzone.h | |||
| @@ -410,6 +410,24 @@ struct zonelist { | |||
| 410 | #endif | 410 | #endif |
| 411 | }; | 411 | }; |
| 412 | 412 | ||
| 413 | #ifdef CONFIG_NUMA | ||
| 414 | /* | ||
| 415 | * Only custom zonelists like MPOL_BIND need to be filtered as part of | ||
| 416 | * policies. As described in the comment for struct zonelist_cache, these | ||
| 417 | * zonelists will not have a zlcache so zlcache_ptr will not be set. Use | ||
| 418 | * that to determine if the zonelists needs to be filtered or not. | ||
| 419 | */ | ||
| 420 | static inline int alloc_should_filter_zonelist(struct zonelist *zonelist) | ||
| 421 | { | ||
| 422 | return !zonelist->zlcache_ptr; | ||
| 423 | } | ||
| 424 | #else | ||
| 425 | static inline int alloc_should_filter_zonelist(struct zonelist *zonelist) | ||
| 426 | { | ||
| 427 | return 0; | ||
| 428 | } | ||
| 429 | #endif /* CONFIG_NUMA */ | ||
| 430 | |||
| 413 | #ifdef CONFIG_ARCH_POPULATES_NODE_MAP | 431 | #ifdef CONFIG_ARCH_POPULATES_NODE_MAP |
| 414 | struct node_active_region { | 432 | struct node_active_region { |
| 415 | unsigned long start_pfn; | 433 | unsigned long start_pfn; |
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); | |||
| 557 | int pcix_get_max_mmrbc(struct pci_dev *dev); | 557 | int pcix_get_max_mmrbc(struct pci_dev *dev); |
| 558 | int pcix_get_mmrbc(struct pci_dev *dev); | 558 | int pcix_get_mmrbc(struct pci_dev *dev); |
| 559 | int pcix_set_mmrbc(struct pci_dev *dev, int mmrbc); | 559 | int pcix_set_mmrbc(struct pci_dev *dev, int mmrbc); |
| 560 | int pcie_get_readrq(struct pci_dev *dev); | ||
| 560 | int pcie_set_readrq(struct pci_dev *dev, int rq); | 561 | int pcie_set_readrq(struct pci_dev *dev, int rq); |
| 561 | void pci_update_resource(struct pci_dev *dev, struct resource *res, int resno); | 562 | void pci_update_resource(struct pci_dev *dev, struct resource *res, int resno); |
| 562 | int __must_check pci_assign_resource(struct pci_dev *dev, int i); | 563 | 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); | |||
| 578 | pci_power_t pci_choose_state(struct pci_dev *dev, pm_message_t state); | 579 | pci_power_t pci_choose_state(struct pci_dev *dev, pm_message_t state); |
| 579 | int pci_enable_wake(struct pci_dev *dev, pci_power_t state, int enable); | 580 | int pci_enable_wake(struct pci_dev *dev, pci_power_t state, int enable); |
| 580 | 581 | ||
| 582 | /* Functions for PCI Hotplug drivers to use */ | ||
| 583 | int pci_bus_find_capability (struct pci_bus *bus, unsigned int devfn, int cap); | ||
| 584 | |||
| 581 | /* Helper functions for low-level code (drivers/pci/setup-[bus,res].c) */ | 585 | /* Helper functions for low-level code (drivers/pci/setup-[bus,res].c) */ |
| 582 | void pci_bus_assign_resources(struct pci_bus *bus); | 586 | void pci_bus_assign_resources(struct pci_bus *bus); |
| 583 | void pci_bus_size_bridges(struct pci_bus *bus); | 587 | void pci_bus_size_bridges(struct pci_bus *bus); |
diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index 07fc57429b58..f77944e432f2 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h | |||
| @@ -360,6 +360,9 @@ | |||
| 360 | #define PCI_DEVICE_ID_ATI_RS400_166 0x5a32 | 360 | #define PCI_DEVICE_ID_ATI_RS400_166 0x5a32 |
| 361 | #define PCI_DEVICE_ID_ATI_RS400_200 0x5a33 | 361 | #define PCI_DEVICE_ID_ATI_RS400_200 0x5a33 |
| 362 | #define PCI_DEVICE_ID_ATI_RS480 0x5950 | 362 | #define PCI_DEVICE_ID_ATI_RS480 0x5950 |
| 363 | #define PCI_DEVICE_ID_ATI_RD580 0x5952 | ||
| 364 | #define PCI_DEVICE_ID_ATI_RX790 0x5957 | ||
| 365 | #define PCI_DEVICE_ID_ATI_RS690 0x7910 | ||
| 363 | /* ATI IXP Chipset */ | 366 | /* ATI IXP Chipset */ |
| 364 | #define PCI_DEVICE_ID_ATI_IXP200_IDE 0x4349 | 367 | #define PCI_DEVICE_ID_ATI_IXP200_IDE 0x4349 |
| 365 | #define PCI_DEVICE_ID_ATI_IXP200_SMBUS 0x4353 | 368 | #define PCI_DEVICE_ID_ATI_IXP200_SMBUS 0x4353 |
| @@ -2092,8 +2095,10 @@ | |||
| 2092 | #define PCI_DEVICE_ID_MPC8568 0x0021 | 2095 | #define PCI_DEVICE_ID_MPC8568 0x0021 |
| 2093 | #define PCI_DEVICE_ID_MPC8567E 0x0022 | 2096 | #define PCI_DEVICE_ID_MPC8567E 0x0022 |
| 2094 | #define PCI_DEVICE_ID_MPC8567 0x0023 | 2097 | #define PCI_DEVICE_ID_MPC8567 0x0023 |
| 2095 | #define PCI_DEVICE_ID_MPC8544E 0x0030 | 2098 | #define PCI_DEVICE_ID_MPC8533E 0x0030 |
| 2096 | #define PCI_DEVICE_ID_MPC8544 0x0031 | 2099 | #define PCI_DEVICE_ID_MPC8533 0x0031 |
| 2100 | #define PCI_DEVICE_ID_MPC8544E 0x0032 | ||
| 2101 | #define PCI_DEVICE_ID_MPC8544 0x0033 | ||
| 2097 | #define PCI_DEVICE_ID_MPC8641 0x7010 | 2102 | #define PCI_DEVICE_ID_MPC8641 0x7010 |
| 2098 | #define PCI_DEVICE_ID_MPC8641D 0x7011 | 2103 | #define PCI_DEVICE_ID_MPC8641D 0x7011 |
| 2099 | 2104 | ||
diff --git a/include/linux/security.h b/include/linux/security.h index c11dc8aa0351..1a15526e9f67 100644 --- a/include/linux/security.h +++ b/include/linux/security.h | |||
| @@ -54,7 +54,7 @@ extern int cap_inode_removexattr(struct dentry *dentry, char *name); | |||
| 54 | extern int cap_task_post_setuid (uid_t old_ruid, uid_t old_euid, uid_t old_suid, int flags); | 54 | extern int cap_task_post_setuid (uid_t old_ruid, uid_t old_euid, uid_t old_suid, int flags); |
| 55 | extern void cap_task_reparent_to_init (struct task_struct *p); | 55 | extern void cap_task_reparent_to_init (struct task_struct *p); |
| 56 | extern int cap_syslog (int type); | 56 | extern int cap_syslog (int type); |
| 57 | extern int cap_vm_enough_memory (long pages); | 57 | extern int cap_vm_enough_memory (struct mm_struct *mm, long pages); |
| 58 | 58 | ||
| 59 | struct msghdr; | 59 | struct msghdr; |
| 60 | struct sk_buff; | 60 | struct sk_buff; |
| @@ -1125,6 +1125,7 @@ struct request_sock; | |||
| 1125 | * Return 0 if permission is granted. | 1125 | * Return 0 if permission is granted. |
| 1126 | * @vm_enough_memory: | 1126 | * @vm_enough_memory: |
| 1127 | * Check permissions for allocating a new virtual mapping. | 1127 | * Check permissions for allocating a new virtual mapping. |
| 1128 | * @mm contains the mm struct it is being added to. | ||
| 1128 | * @pages contains the number of pages. | 1129 | * @pages contains the number of pages. |
| 1129 | * Return 0 if permission is granted. | 1130 | * Return 0 if permission is granted. |
| 1130 | * | 1131 | * |
| @@ -1169,7 +1170,7 @@ struct security_operations { | |||
| 1169 | int (*quota_on) (struct dentry * dentry); | 1170 | int (*quota_on) (struct dentry * dentry); |
| 1170 | int (*syslog) (int type); | 1171 | int (*syslog) (int type); |
| 1171 | int (*settime) (struct timespec *ts, struct timezone *tz); | 1172 | int (*settime) (struct timespec *ts, struct timezone *tz); |
| 1172 | int (*vm_enough_memory) (long pages); | 1173 | int (*vm_enough_memory) (struct mm_struct *mm, long pages); |
| 1173 | 1174 | ||
| 1174 | int (*bprm_alloc_security) (struct linux_binprm * bprm); | 1175 | int (*bprm_alloc_security) (struct linux_binprm * bprm); |
| 1175 | void (*bprm_free_security) (struct linux_binprm * bprm); | 1176 | void (*bprm_free_security) (struct linux_binprm * bprm); |
| @@ -1469,10 +1470,14 @@ static inline int security_settime(struct timespec *ts, struct timezone *tz) | |||
| 1469 | return security_ops->settime(ts, tz); | 1470 | return security_ops->settime(ts, tz); |
| 1470 | } | 1471 | } |
| 1471 | 1472 | ||
| 1472 | |||
| 1473 | static inline int security_vm_enough_memory(long pages) | 1473 | static inline int security_vm_enough_memory(long pages) |
| 1474 | { | 1474 | { |
| 1475 | return security_ops->vm_enough_memory(pages); | 1475 | return security_ops->vm_enough_memory(current->mm, pages); |
| 1476 | } | ||
| 1477 | |||
| 1478 | static inline int security_vm_enough_memory_mm(struct mm_struct *mm, long pages) | ||
| 1479 | { | ||
| 1480 | return security_ops->vm_enough_memory(mm, pages); | ||
| 1476 | } | 1481 | } |
| 1477 | 1482 | ||
| 1478 | static inline int security_bprm_alloc (struct linux_binprm *bprm) | 1483 | static inline int security_bprm_alloc (struct linux_binprm *bprm) |
| @@ -2219,7 +2224,12 @@ static inline int security_settime(struct timespec *ts, struct timezone *tz) | |||
| 2219 | 2224 | ||
| 2220 | static inline int security_vm_enough_memory(long pages) | 2225 | static inline int security_vm_enough_memory(long pages) |
| 2221 | { | 2226 | { |
| 2222 | return cap_vm_enough_memory(pages); | 2227 | return cap_vm_enough_memory(current->mm, pages); |
| 2228 | } | ||
| 2229 | |||
| 2230 | static inline int security_vm_enough_memory_mm(struct mm_struct *mm, long pages) | ||
| 2231 | { | ||
| 2232 | return cap_vm_enough_memory(mm, pages); | ||
| 2223 | } | 2233 | } |
| 2224 | 2234 | ||
| 2225 | static inline int security_bprm_alloc (struct linux_binprm *bprm) | 2235 | static inline int security_bprm_alloc (struct linux_binprm *bprm) |
diff --git a/include/linux/selection.h b/include/linux/selection.h index ed3408b400f1..f9457861937c 100644 --- a/include/linux/selection.h +++ b/include/linux/selection.h | |||
| @@ -10,6 +10,8 @@ | |||
| 10 | #include <linux/tiocl.h> | 10 | #include <linux/tiocl.h> |
| 11 | #include <linux/vt_buffer.h> | 11 | #include <linux/vt_buffer.h> |
| 12 | 12 | ||
| 13 | struct tty_struct; | ||
| 14 | |||
| 13 | extern struct vc_data *sel_cons; | 15 | extern struct vc_data *sel_cons; |
| 14 | 16 | ||
| 15 | extern void clear_selection(void); | 17 | extern void clear_selection(void); |
diff --git a/include/linux/serial_reg.h b/include/linux/serial_reg.h index 1c5ed7d92b0f..96c0d93fc2ca 100644 --- a/include/linux/serial_reg.h +++ b/include/linux/serial_reg.h | |||
| @@ -118,6 +118,7 @@ | |||
| 118 | #define UART_LSR_PE 0x04 /* Parity error indicator */ | 118 | #define UART_LSR_PE 0x04 /* Parity error indicator */ |
| 119 | #define UART_LSR_OE 0x02 /* Overrun error indicator */ | 119 | #define UART_LSR_OE 0x02 /* Overrun error indicator */ |
| 120 | #define UART_LSR_DR 0x01 /* Receiver data ready */ | 120 | #define UART_LSR_DR 0x01 /* Receiver data ready */ |
| 121 | #define UART_LSR_BRK_ERROR_BITS 0x1E /* BI, FE, PE, OE bits */ | ||
| 121 | 122 | ||
| 122 | #define UART_MSR 6 /* In: Modem Status Register */ | 123 | #define UART_MSR 6 /* In: Modem Status Register */ |
| 123 | #define UART_MSR_DCD 0x80 /* Data Carrier Detect */ | 124 | #define UART_MSR_DCD 0x80 /* Data Carrier Detect */ |
diff --git a/kernel/auditsc.c b/kernel/auditsc.c index 3401293359e8..04f3ffb8d9d4 100644 --- a/kernel/auditsc.c +++ b/kernel/auditsc.c | |||
| @@ -2023,7 +2023,7 @@ int __audit_signal_info(int sig, struct task_struct *t) | |||
| 2023 | axp->d.next = ctx->aux_pids; | 2023 | axp->d.next = ctx->aux_pids; |
| 2024 | ctx->aux_pids = (void *)axp; | 2024 | ctx->aux_pids = (void *)axp; |
| 2025 | } | 2025 | } |
| 2026 | BUG_ON(axp->pid_count > AUDIT_AUX_PIDS); | 2026 | BUG_ON(axp->pid_count >= AUDIT_AUX_PIDS); |
| 2027 | 2027 | ||
| 2028 | axp->target_pid[axp->pid_count] = t->tgid; | 2028 | axp->target_pid[axp->pid_count] = t->tgid; |
| 2029 | selinux_get_task_sid(t, &axp->target_sid[axp->pid_count]); | 2029 | selinux_get_task_sid(t, &axp->target_sid[axp->pid_count]); |
diff --git a/kernel/futex.c b/kernel/futex.c index 3415e9ad1391..e8935b195e88 100644 --- a/kernel/futex.c +++ b/kernel/futex.c | |||
| @@ -1670,6 +1670,7 @@ pi_faulted: | |||
| 1670 | attempt); | 1670 | attempt); |
| 1671 | if (ret) | 1671 | if (ret) |
| 1672 | goto out; | 1672 | goto out; |
| 1673 | uval = 0; | ||
| 1673 | goto retry_unlocked; | 1674 | goto retry_unlocked; |
| 1674 | } | 1675 | } |
| 1675 | 1676 | ||
diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c index 203a518b6f14..853aefbd184b 100644 --- a/kernel/irq/manage.c +++ b/kernel/irq/manage.c | |||
| @@ -462,7 +462,9 @@ void free_irq(unsigned int irq, void *dev_id) | |||
| 462 | * We do this after actually deregistering it, to make sure that | 462 | * We do this after actually deregistering it, to make sure that |
| 463 | * a 'real' IRQ doesn't run in parallel with our fake | 463 | * a 'real' IRQ doesn't run in parallel with our fake |
| 464 | */ | 464 | */ |
| 465 | local_irq_save(flags); | ||
| 465 | handler(irq, dev_id); | 466 | handler(irq, dev_id); |
| 467 | local_irq_restore(flags); | ||
| 466 | } | 468 | } |
| 467 | #endif | 469 | #endif |
| 468 | } | 470 | } |
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); | |||
| 784 | static ssize_t show_refcnt(struct module_attribute *mattr, | 784 | static ssize_t show_refcnt(struct module_attribute *mattr, |
| 785 | struct module *mod, char *buffer) | 785 | struct module *mod, char *buffer) |
| 786 | { | 786 | { |
| 787 | /* sysfs holds a reference */ | 787 | return sprintf(buffer, "%u\n", module_refcount(mod)); |
| 788 | return sprintf(buffer, "%u\n", module_refcount(mod)-1); | ||
| 789 | } | 788 | } |
| 790 | 789 | ||
| 791 | static struct module_attribute refcnt = { | 790 | static struct module_attribute refcnt = { |
diff --git a/kernel/posix-timers.c b/kernel/posix-timers.c index 55b3761edaa9..7a15afb73ed0 100644 --- a/kernel/posix-timers.c +++ b/kernel/posix-timers.c | |||
| @@ -547,9 +547,9 @@ sys_timer_create(const clockid_t which_clock, | |||
| 547 | new_timer->it_process = process; | 547 | new_timer->it_process = process; |
| 548 | list_add(&new_timer->list, | 548 | list_add(&new_timer->list, |
| 549 | &process->signal->posix_timers); | 549 | &process->signal->posix_timers); |
| 550 | spin_unlock_irqrestore(&process->sighand->siglock, flags); | ||
| 551 | if (new_timer->it_sigev_notify == (SIGEV_SIGNAL|SIGEV_THREAD_ID)) | 550 | if (new_timer->it_sigev_notify == (SIGEV_SIGNAL|SIGEV_THREAD_ID)) |
| 552 | get_task_struct(process); | 551 | get_task_struct(process); |
| 552 | spin_unlock_irqrestore(&process->sighand->siglock, flags); | ||
| 553 | } else { | 553 | } else { |
| 554 | spin_unlock_irqrestore(&process->sighand->siglock, flags); | 554 | spin_unlock_irqrestore(&process->sighand->siglock, flags); |
| 555 | process = NULL; | 555 | process = NULL; |
| @@ -605,13 +605,14 @@ static struct k_itimer * lock_timer(timer_t timer_id, unsigned long *flags) | |||
| 605 | timr = (struct k_itimer *) idr_find(&posix_timers_id, (int) timer_id); | 605 | timr = (struct k_itimer *) idr_find(&posix_timers_id, (int) timer_id); |
| 606 | if (timr) { | 606 | if (timr) { |
| 607 | spin_lock(&timr->it_lock); | 607 | spin_lock(&timr->it_lock); |
| 608 | spin_unlock(&idr_lock); | ||
| 609 | 608 | ||
| 610 | if ((timr->it_id != timer_id) || !(timr->it_process) || | 609 | if ((timr->it_id != timer_id) || !(timr->it_process) || |
| 611 | timr->it_process->tgid != current->tgid) { | 610 | timr->it_process->tgid != current->tgid) { |
| 612 | unlock_timer(timr, *flags); | 611 | spin_unlock(&timr->it_lock); |
| 612 | spin_unlock_irqrestore(&idr_lock, *flags); | ||
| 613 | timr = NULL; | 613 | timr = NULL; |
| 614 | } | 614 | } else |
| 615 | spin_unlock(&idr_lock); | ||
| 615 | } else | 616 | } else |
| 616 | spin_unlock_irqrestore(&idr_lock, *flags); | 617 | spin_unlock_irqrestore(&idr_lock, *flags); |
| 617 | 618 | ||
diff --git a/kernel/printk.c b/kernel/printk.c index 5c7c325b29cc..8451dfc31d25 100644 --- a/kernel/printk.c +++ b/kernel/printk.c | |||
| @@ -1085,10 +1085,12 @@ EXPORT_SYMBOL(unregister_console); | |||
| 1085 | 1085 | ||
| 1086 | static int __init disable_boot_consoles(void) | 1086 | static int __init disable_boot_consoles(void) |
| 1087 | { | 1087 | { |
| 1088 | if (console_drivers->flags & CON_BOOT) { | 1088 | if (console_drivers != NULL) { |
| 1089 | printk(KERN_INFO "turn off boot console %s%d\n", | 1089 | if (console_drivers->flags & CON_BOOT) { |
| 1090 | console_drivers->name, console_drivers->index); | 1090 | printk(KERN_INFO "turn off boot console %s%d\n", |
| 1091 | return unregister_console(console_drivers); | 1091 | console_drivers->name, console_drivers->index); |
| 1092 | return unregister_console(console_drivers); | ||
| 1093 | } | ||
| 1092 | } | 1094 | } |
| 1093 | return 0; | 1095 | return 0; |
| 1094 | } | 1096 | } |
diff --git a/kernel/signal.c b/kernel/signal.c index b27c01a66448..ad63109e413c 100644 --- a/kernel/signal.c +++ b/kernel/signal.c | |||
| @@ -378,7 +378,7 @@ int dequeue_signal(struct task_struct *tsk, sigset_t *mask, siginfo_t *info) | |||
| 378 | /* We only dequeue private signals from ourselves, we don't let | 378 | /* We only dequeue private signals from ourselves, we don't let |
| 379 | * signalfd steal them | 379 | * signalfd steal them |
| 380 | */ | 380 | */ |
| 381 | if (tsk == current) | 381 | if (likely(tsk == current)) |
| 382 | signr = __dequeue_signal(&tsk->pending, mask, info); | 382 | signr = __dequeue_signal(&tsk->pending, mask, info); |
| 383 | if (!signr) { | 383 | if (!signr) { |
| 384 | signr = __dequeue_signal(&tsk->signal->shared_pending, | 384 | signr = __dequeue_signal(&tsk->signal->shared_pending, |
| @@ -425,7 +425,7 @@ int dequeue_signal(struct task_struct *tsk, sigset_t *mask, siginfo_t *info) | |||
| 425 | if (!(tsk->signal->flags & SIGNAL_GROUP_EXIT)) | 425 | if (!(tsk->signal->flags & SIGNAL_GROUP_EXIT)) |
| 426 | tsk->signal->flags |= SIGNAL_STOP_DEQUEUED; | 426 | tsk->signal->flags |= SIGNAL_STOP_DEQUEUED; |
| 427 | } | 427 | } |
| 428 | if ( signr && | 428 | if (signr && likely(tsk == current) && |
| 429 | ((info->si_code & __SI_MASK) == __SI_TIMER) && | 429 | ((info->si_code & __SI_MASK) == __SI_TIMER) && |
| 430 | info->si_sys_private){ | 430 | info->si_sys_private){ |
| 431 | /* | 431 | /* |
diff --git a/lib/Kconfig b/lib/Kconfig index e5c2c514174a..ba3d104994d9 100644 --- a/lib/Kconfig +++ b/lib/Kconfig | |||
| @@ -138,4 +138,7 @@ config HAS_DMA | |||
| 138 | depends on !NO_DMA | 138 | depends on !NO_DMA |
| 139 | default y | 139 | default y |
| 140 | 140 | ||
| 141 | config CHECK_SIGNATURE | ||
| 142 | bool | ||
| 143 | |||
| 141 | endmenu | 144 | endmenu |
diff --git a/lib/Makefile b/lib/Makefile index d9e5f1cd0bfb..6b0ba8cf4e5f 100644 --- a/lib/Makefile +++ b/lib/Makefile | |||
| @@ -21,7 +21,8 @@ CFLAGS_kobject_uevent.o += -DDEBUG | |||
| 21 | endif | 21 | endif |
| 22 | 22 | ||
| 23 | obj-$(CONFIG_GENERIC_IOMAP) += iomap.o | 23 | obj-$(CONFIG_GENERIC_IOMAP) += iomap.o |
| 24 | obj-$(CONFIG_HAS_IOMEM) += iomap_copy.o devres.o check_signature.o | 24 | obj-$(CONFIG_HAS_IOMEM) += iomap_copy.o devres.o |
| 25 | obj-$(CONFIG_CHECK_SIGNATURE) += check_signature.o | ||
| 25 | obj-$(CONFIG_DEBUG_LOCKING_API_SELFTESTS) += locking-selftest.o | 26 | obj-$(CONFIG_DEBUG_LOCKING_API_SELFTESTS) += locking-selftest.o |
| 26 | obj-$(CONFIG_DEBUG_SPINLOCK) += spinlock_debug.o | 27 | obj-$(CONFIG_DEBUG_SPINLOCK) += spinlock_debug.o |
| 27 | lib-$(CONFIG_RWSEM_GENERIC_SPINLOCK) += rwsem-spinlock.o | 28 | lib-$(CONFIG_RWSEM_GENERIC_SPINLOCK) += rwsem-spinlock.o |
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) | |||
| 240 | EXPORT_SYMBOL(ioport_map); | 240 | EXPORT_SYMBOL(ioport_map); |
| 241 | EXPORT_SYMBOL(ioport_unmap); | 241 | EXPORT_SYMBOL(ioport_unmap); |
| 242 | 242 | ||
| 243 | /* Create a virtual mapping cookie for a PCI BAR (memory or IO) */ | 243 | /** |
| 244 | * pci_iomap - create a virtual mapping cookie for a PCI BAR | ||
| 245 | * @dev: PCI device that owns the BAR | ||
| 246 | * @bar: BAR number | ||
| 247 | * @maxlen: length of the memory to map | ||
| 248 | * | ||
| 249 | * Using this function you will get a __iomem address to your device BAR. | ||
| 250 | * You can access it using ioread*() and iowrite*(). These functions hide | ||
| 251 | * the details if this is a MMIO or PIO address space and will just do what | ||
| 252 | * you expect from them in the correct way. | ||
| 253 | * | ||
| 254 | * @maxlen specifies the maximum length to map. If you want to get access to | ||
| 255 | * the complete BAR without checking for its length first, pass %0 here. | ||
| 256 | * */ | ||
| 244 | void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long maxlen) | 257 | void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long maxlen) |
| 245 | { | 258 | { |
| 246 | unsigned long start = pci_resource_start(dev, bar); | 259 | unsigned long start = pci_resource_start(dev, bar); |
diff --git a/mm/hugetlb.c b/mm/hugetlb.c index d7ca59d66c59..de4cf458d6e1 100644 --- a/mm/hugetlb.c +++ b/mm/hugetlb.c | |||
| @@ -643,7 +643,7 @@ int follow_hugetlb_page(struct mm_struct *mm, struct vm_area_struct *vma, | |||
| 643 | spin_unlock(&mm->page_table_lock); | 643 | spin_unlock(&mm->page_table_lock); |
| 644 | ret = hugetlb_fault(mm, vma, vaddr, 0); | 644 | ret = hugetlb_fault(mm, vma, vaddr, 0); |
| 645 | spin_lock(&mm->page_table_lock); | 645 | spin_lock(&mm->page_table_lock); |
| 646 | if (!(ret & VM_FAULT_MAJOR)) | 646 | if (!(ret & VM_FAULT_ERROR)) |
| 647 | continue; | 647 | continue; |
| 648 | 648 | ||
| 649 | remainder = 0; | 649 | remainder = 0; |
diff --git a/mm/mempolicy.c b/mm/mempolicy.c index 71b84b45154a..172abffeb2e3 100644 --- a/mm/mempolicy.c +++ b/mm/mempolicy.c | |||
| @@ -149,7 +149,7 @@ static struct zonelist *bind_zonelist(nodemask_t *nodes) | |||
| 149 | lower zones etc. Avoid empty zones because the memory allocator | 149 | lower zones etc. Avoid empty zones because the memory allocator |
| 150 | doesn't like them. If you implement node hot removal you | 150 | doesn't like them. If you implement node hot removal you |
| 151 | have to fix that. */ | 151 | have to fix that. */ |
| 152 | k = policy_zone; | 152 | k = MAX_NR_ZONES - 1; |
| 153 | while (1) { | 153 | while (1) { |
| 154 | for_each_node_mask(nd, *nodes) { | 154 | for_each_node_mask(nd, *nodes) { |
| 155 | struct zone *z = &NODE_DATA(nd)->node_zones[k]; | 155 | struct zone *z = &NODE_DATA(nd)->node_zones[k]; |
| @@ -93,7 +93,7 @@ atomic_t vm_committed_space = ATOMIC_INIT(0); | |||
| 93 | * Note this is a helper function intended to be used by LSMs which | 93 | * Note this is a helper function intended to be used by LSMs which |
| 94 | * wish to use this logic. | 94 | * wish to use this logic. |
| 95 | */ | 95 | */ |
| 96 | int __vm_enough_memory(long pages, int cap_sys_admin) | 96 | int __vm_enough_memory(struct mm_struct *mm, long pages, int cap_sys_admin) |
| 97 | { | 97 | { |
| 98 | unsigned long free, allowed; | 98 | unsigned long free, allowed; |
| 99 | 99 | ||
| @@ -166,7 +166,7 @@ int __vm_enough_memory(long pages, int cap_sys_admin) | |||
| 166 | 166 | ||
| 167 | /* Don't let a single process grow too big: | 167 | /* Don't let a single process grow too big: |
| 168 | leave 3% of the size of this process for other processes */ | 168 | leave 3% of the size of this process for other processes */ |
| 169 | allowed -= current->mm->total_vm / 32; | 169 | allowed -= mm->total_vm / 32; |
| 170 | 170 | ||
| 171 | /* | 171 | /* |
| 172 | * cast `allowed' as a signed long because vm_committed_space | 172 | * cast `allowed' as a signed long because vm_committed_space |
| @@ -2077,7 +2077,7 @@ int insert_vm_struct(struct mm_struct * mm, struct vm_area_struct * vma) | |||
| 2077 | if (__vma && __vma->vm_start < vma->vm_end) | 2077 | if (__vma && __vma->vm_start < vma->vm_end) |
| 2078 | return -ENOMEM; | 2078 | return -ENOMEM; |
| 2079 | if ((vma->vm_flags & VM_ACCOUNT) && | 2079 | if ((vma->vm_flags & VM_ACCOUNT) && |
| 2080 | security_vm_enough_memory(vma_pages(vma))) | 2080 | security_vm_enough_memory_mm(mm, vma_pages(vma))) |
| 2081 | return -ENOMEM; | 2081 | return -ENOMEM; |
| 2082 | vma_link(mm, vma, prev, rb_link, rb_parent); | 2082 | vma_link(mm, vma, prev, rb_link, rb_parent); |
| 2083 | return 0; | 2083 | return 0; |
diff --git a/mm/nommu.c b/mm/nommu.c index 9eef6a398555..8ed0cb43118a 100644 --- a/mm/nommu.c +++ b/mm/nommu.c | |||
| @@ -1270,7 +1270,7 @@ EXPORT_SYMBOL(get_unmapped_area); | |||
| 1270 | * Note this is a helper function intended to be used by LSMs which | 1270 | * Note this is a helper function intended to be used by LSMs which |
| 1271 | * wish to use this logic. | 1271 | * wish to use this logic. |
| 1272 | */ | 1272 | */ |
| 1273 | int __vm_enough_memory(long pages, int cap_sys_admin) | 1273 | int __vm_enough_memory(struct mm_struct *mm, long pages, int cap_sys_admin) |
| 1274 | { | 1274 | { |
| 1275 | unsigned long free, allowed; | 1275 | unsigned long free, allowed; |
| 1276 | 1276 | ||
diff --git a/mm/page_alloc.c b/mm/page_alloc.c index 3da85b81dabb..6427653023aa 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c | |||
| @@ -1157,6 +1157,7 @@ get_page_from_freelist(gfp_t gfp_mask, unsigned int order, | |||
| 1157 | nodemask_t *allowednodes = NULL;/* zonelist_cache approximation */ | 1157 | nodemask_t *allowednodes = NULL;/* zonelist_cache approximation */ |
| 1158 | int zlc_active = 0; /* set if using zonelist_cache */ | 1158 | int zlc_active = 0; /* set if using zonelist_cache */ |
| 1159 | int did_zlc_setup = 0; /* just call zlc_setup() one time */ | 1159 | int did_zlc_setup = 0; /* just call zlc_setup() one time */ |
| 1160 | enum zone_type highest_zoneidx = -1; /* Gets set for policy zonelists */ | ||
| 1160 | 1161 | ||
| 1161 | zonelist_scan: | 1162 | zonelist_scan: |
| 1162 | /* | 1163 | /* |
| @@ -1166,6 +1167,18 @@ zonelist_scan: | |||
| 1166 | z = zonelist->zones; | 1167 | z = zonelist->zones; |
| 1167 | 1168 | ||
| 1168 | do { | 1169 | do { |
| 1170 | /* | ||
| 1171 | * In NUMA, this could be a policy zonelist which contains | ||
| 1172 | * zones that may not be allowed by the current gfp_mask. | ||
| 1173 | * Check the zone is allowed by the current flags | ||
| 1174 | */ | ||
| 1175 | if (unlikely(alloc_should_filter_zonelist(zonelist))) { | ||
| 1176 | if (highest_zoneidx == -1) | ||
| 1177 | highest_zoneidx = gfp_zone(gfp_mask); | ||
| 1178 | if (zone_idx(*z) > highest_zoneidx) | ||
| 1179 | continue; | ||
| 1180 | } | ||
| 1181 | |||
| 1169 | if (NUMA_BUILD && zlc_active && | 1182 | if (NUMA_BUILD && zlc_active && |
| 1170 | !zlc_zone_worth_trying(zonelist, z, allowednodes)) | 1183 | !zlc_zone_worth_trying(zonelist, z, allowednodes)) |
| 1171 | continue; | 1184 | continue; |
| @@ -883,6 +883,7 @@ static void __slab_error(const char *function, struct kmem_cache *cachep, | |||
| 883 | */ | 883 | */ |
| 884 | 884 | ||
| 885 | static int use_alien_caches __read_mostly = 1; | 885 | static int use_alien_caches __read_mostly = 1; |
| 886 | static int numa_platform __read_mostly = 1; | ||
| 886 | static int __init noaliencache_setup(char *s) | 887 | static int __init noaliencache_setup(char *s) |
| 887 | { | 888 | { |
| 888 | use_alien_caches = 0; | 889 | use_alien_caches = 0; |
| @@ -1399,8 +1400,10 @@ void __init kmem_cache_init(void) | |||
| 1399 | int order; | 1400 | int order; |
| 1400 | int node; | 1401 | int node; |
| 1401 | 1402 | ||
| 1402 | if (num_possible_nodes() == 1) | 1403 | if (num_possible_nodes() == 1) { |
| 1403 | use_alien_caches = 0; | 1404 | use_alien_caches = 0; |
| 1405 | numa_platform = 0; | ||
| 1406 | } | ||
| 1404 | 1407 | ||
| 1405 | for (i = 0; i < NUM_INIT_LISTS; i++) { | 1408 | for (i = 0; i < NUM_INIT_LISTS; i++) { |
| 1406 | kmem_list3_init(&initkmem_list3[i]); | 1409 | kmem_list3_init(&initkmem_list3[i]); |
| @@ -3558,7 +3561,14 @@ static inline void __cache_free(struct kmem_cache *cachep, void *objp) | |||
| 3558 | check_irq_off(); | 3561 | check_irq_off(); |
| 3559 | objp = cache_free_debugcheck(cachep, objp, __builtin_return_address(0)); | 3562 | objp = cache_free_debugcheck(cachep, objp, __builtin_return_address(0)); |
| 3560 | 3563 | ||
| 3561 | if (cache_free_alien(cachep, objp)) | 3564 | /* |
| 3565 | * Skip calling cache_free_alien() when the platform is not numa. | ||
| 3566 | * This will avoid cache misses that happen while accessing slabp (which | ||
| 3567 | * is per page memory reference) to get nodeid. Instead use a global | ||
| 3568 | * variable to skip the call, which is mostly likely to be present in | ||
| 3569 | * the cache. | ||
| 3570 | */ | ||
| 3571 | if (numa_platform && cache_free_alien(cachep, objp)) | ||
| 3562 | return; | 3572 | return; |
| 3563 | 3573 | ||
| 3564 | if (likely(ac->avail < ac->limit)) { | 3574 | if (likely(ac->avail < ac->limit)) { |
| @@ -1877,9 +1877,16 @@ static struct kmem_cache_node * __init early_kmem_cache_node_alloc(gfp_t gfpflag | |||
| 1877 | 1877 | ||
| 1878 | BUG_ON(kmalloc_caches->size < sizeof(struct kmem_cache_node)); | 1878 | BUG_ON(kmalloc_caches->size < sizeof(struct kmem_cache_node)); |
| 1879 | 1879 | ||
| 1880 | page = new_slab(kmalloc_caches, gfpflags | GFP_THISNODE, node); | 1880 | page = new_slab(kmalloc_caches, gfpflags, node); |
| 1881 | 1881 | ||
| 1882 | BUG_ON(!page); | 1882 | BUG_ON(!page); |
| 1883 | if (page_to_nid(page) != node) { | ||
| 1884 | printk(KERN_ERR "SLUB: Unable to allocate memory from " | ||
| 1885 | "node %d\n", node); | ||
| 1886 | printk(KERN_ERR "SLUB: Allocating a useless per node structure " | ||
| 1887 | "in order to be able to continue\n"); | ||
| 1888 | } | ||
| 1889 | |||
| 1883 | n = page->freelist; | 1890 | n = page->freelist; |
| 1884 | BUG_ON(!n); | 1891 | BUG_ON(!n); |
| 1885 | page->freelist = get_freepointer(kmalloc_caches, n); | 1892 | page->freelist = get_freepointer(kmalloc_caches, n); |
| @@ -3112,7 +3119,7 @@ static int list_locations(struct kmem_cache *s, char *buf, | |||
| 3112 | unsigned long flags; | 3119 | unsigned long flags; |
| 3113 | struct page *page; | 3120 | struct page *page; |
| 3114 | 3121 | ||
| 3115 | if (!atomic_read(&n->nr_slabs)) | 3122 | if (!atomic_long_read(&n->nr_slabs)) |
| 3116 | continue; | 3123 | continue; |
| 3117 | 3124 | ||
| 3118 | spin_lock_irqsave(&n->list_lock, flags); | 3125 | spin_lock_irqsave(&n->list_lock, flags); |
| @@ -3247,7 +3254,7 @@ static unsigned long slab_objects(struct kmem_cache *s, | |||
| 3247 | } | 3254 | } |
| 3248 | 3255 | ||
| 3249 | if (flags & SO_FULL) { | 3256 | if (flags & SO_FULL) { |
| 3250 | int full_slabs = atomic_read(&n->nr_slabs) | 3257 | int full_slabs = atomic_long_read(&n->nr_slabs) |
| 3251 | - per_cpu[node] | 3258 | - per_cpu[node] |
| 3252 | - n->nr_partial; | 3259 | - n->nr_partial; |
| 3253 | 3260 | ||
| @@ -3283,7 +3290,7 @@ static int any_slab_objects(struct kmem_cache *s) | |||
| 3283 | for_each_node(node) { | 3290 | for_each_node(node) { |
| 3284 | struct kmem_cache_node *n = get_node(s, node); | 3291 | struct kmem_cache_node *n = get_node(s, node); |
| 3285 | 3292 | ||
| 3286 | if (n->nr_partial || atomic_read(&n->nr_slabs)) | 3293 | if (n->nr_partial || atomic_long_read(&n->nr_slabs)) |
| 3287 | return 1; | 3294 | return 1; |
| 3288 | } | 3295 | } |
| 3289 | return 0; | 3296 | return 0; |
diff --git a/mm/sparse.c b/mm/sparse.c index 3047bf06c1f3..239f5a720d38 100644 --- a/mm/sparse.c +++ b/mm/sparse.c | |||
| @@ -41,6 +41,15 @@ int page_to_nid(struct page *page) | |||
| 41 | return section_to_node_table[page_to_section(page)]; | 41 | return section_to_node_table[page_to_section(page)]; |
| 42 | } | 42 | } |
| 43 | EXPORT_SYMBOL(page_to_nid); | 43 | EXPORT_SYMBOL(page_to_nid); |
| 44 | |||
| 45 | static void set_section_nid(unsigned long section_nr, int nid) | ||
| 46 | { | ||
| 47 | section_to_node_table[section_nr] = nid; | ||
| 48 | } | ||
| 49 | #else /* !NODE_NOT_IN_PAGE_FLAGS */ | ||
| 50 | static inline void set_section_nid(unsigned long section_nr, int nid) | ||
| 51 | { | ||
| 52 | } | ||
| 44 | #endif | 53 | #endif |
| 45 | 54 | ||
| 46 | #ifdef CONFIG_SPARSEMEM_EXTREME | 55 | #ifdef CONFIG_SPARSEMEM_EXTREME |
| @@ -68,10 +77,6 @@ static int __meminit sparse_index_init(unsigned long section_nr, int nid) | |||
| 68 | struct mem_section *section; | 77 | struct mem_section *section; |
| 69 | int ret = 0; | 78 | int ret = 0; |
| 70 | 79 | ||
| 71 | #ifdef NODE_NOT_IN_PAGE_FLAGS | ||
| 72 | section_to_node_table[section_nr] = nid; | ||
| 73 | #endif | ||
| 74 | |||
| 75 | if (mem_section[root]) | 80 | if (mem_section[root]) |
| 76 | return -EEXIST; | 81 | return -EEXIST; |
| 77 | 82 | ||
| @@ -148,6 +153,7 @@ void __init memory_present(int nid, unsigned long start, unsigned long end) | |||
| 148 | struct mem_section *ms; | 153 | struct mem_section *ms; |
| 149 | 154 | ||
| 150 | sparse_index_init(section, nid); | 155 | sparse_index_init(section, nid); |
| 156 | set_section_nid(section, nid); | ||
| 151 | 157 | ||
| 152 | ms = __nr_to_section(section); | 158 | ms = __nr_to_section(section); |
| 153 | if (!ms->section_mem_map) | 159 | if (!ms->section_mem_map) |
diff --git a/mm/vmscan.c b/mm/vmscan.c index d419e10e3daa..a6e65d024995 100644 --- a/mm/vmscan.c +++ b/mm/vmscan.c | |||
| @@ -271,6 +271,12 @@ static void handle_write_error(struct address_space *mapping, | |||
| 271 | unlock_page(page); | 271 | unlock_page(page); |
| 272 | } | 272 | } |
| 273 | 273 | ||
| 274 | /* Request for sync pageout. */ | ||
| 275 | enum pageout_io { | ||
| 276 | PAGEOUT_IO_ASYNC, | ||
| 277 | PAGEOUT_IO_SYNC, | ||
| 278 | }; | ||
| 279 | |||
| 274 | /* possible outcome of pageout() */ | 280 | /* possible outcome of pageout() */ |
| 275 | typedef enum { | 281 | typedef enum { |
| 276 | /* failed to write page out, page is locked */ | 282 | /* failed to write page out, page is locked */ |
| @@ -287,7 +293,8 @@ typedef enum { | |||
| 287 | * pageout is called by shrink_page_list() for each dirty page. | 293 | * pageout is called by shrink_page_list() for each dirty page. |
| 288 | * Calls ->writepage(). | 294 | * Calls ->writepage(). |
| 289 | */ | 295 | */ |
| 290 | static pageout_t pageout(struct page *page, struct address_space *mapping) | 296 | static pageout_t pageout(struct page *page, struct address_space *mapping, |
| 297 | enum pageout_io sync_writeback) | ||
| 291 | { | 298 | { |
| 292 | /* | 299 | /* |
| 293 | * If the page is dirty, only perform writeback if that write | 300 | * If the page is dirty, only perform writeback if that write |
| @@ -346,6 +353,15 @@ static pageout_t pageout(struct page *page, struct address_space *mapping) | |||
| 346 | ClearPageReclaim(page); | 353 | ClearPageReclaim(page); |
| 347 | return PAGE_ACTIVATE; | 354 | return PAGE_ACTIVATE; |
| 348 | } | 355 | } |
| 356 | |||
| 357 | /* | ||
| 358 | * Wait on writeback if requested to. This happens when | ||
| 359 | * direct reclaiming a large contiguous area and the | ||
| 360 | * first attempt to free a range of pages fails. | ||
| 361 | */ | ||
| 362 | if (PageWriteback(page) && sync_writeback == PAGEOUT_IO_SYNC) | ||
| 363 | wait_on_page_writeback(page); | ||
| 364 | |||
| 349 | if (!PageWriteback(page)) { | 365 | if (!PageWriteback(page)) { |
| 350 | /* synchronous write or broken a_ops? */ | 366 | /* synchronous write or broken a_ops? */ |
| 351 | ClearPageReclaim(page); | 367 | ClearPageReclaim(page); |
| @@ -423,7 +439,8 @@ cannot_free: | |||
| 423 | * shrink_page_list() returns the number of reclaimed pages | 439 | * shrink_page_list() returns the number of reclaimed pages |
| 424 | */ | 440 | */ |
| 425 | static unsigned long shrink_page_list(struct list_head *page_list, | 441 | static unsigned long shrink_page_list(struct list_head *page_list, |
| 426 | struct scan_control *sc) | 442 | struct scan_control *sc, |
| 443 | enum pageout_io sync_writeback) | ||
| 427 | { | 444 | { |
| 428 | LIST_HEAD(ret_pages); | 445 | LIST_HEAD(ret_pages); |
| 429 | struct pagevec freed_pvec; | 446 | struct pagevec freed_pvec; |
| @@ -458,8 +475,23 @@ static unsigned long shrink_page_list(struct list_head *page_list, | |||
| 458 | if (page_mapped(page) || PageSwapCache(page)) | 475 | if (page_mapped(page) || PageSwapCache(page)) |
| 459 | sc->nr_scanned++; | 476 | sc->nr_scanned++; |
| 460 | 477 | ||
| 461 | if (PageWriteback(page)) | 478 | may_enter_fs = (sc->gfp_mask & __GFP_FS) || |
| 462 | goto keep_locked; | 479 | (PageSwapCache(page) && (sc->gfp_mask & __GFP_IO)); |
| 480 | |||
| 481 | if (PageWriteback(page)) { | ||
| 482 | /* | ||
| 483 | * Synchronous reclaim is performed in two passes, | ||
| 484 | * first an asynchronous pass over the list to | ||
| 485 | * start parallel writeback, and a second synchronous | ||
| 486 | * pass to wait for the IO to complete. Wait here | ||
| 487 | * for any page for which writeback has already | ||
| 488 | * started. | ||
| 489 | */ | ||
| 490 | if (sync_writeback == PAGEOUT_IO_SYNC && may_enter_fs) | ||
| 491 | wait_on_page_writeback(page); | ||
| 492 | else | ||
| 493 | goto keep_locked; | ||
| 494 | } | ||
| 463 | 495 | ||
| 464 | referenced = page_referenced(page, 1); | 496 | referenced = page_referenced(page, 1); |
| 465 | /* In active use or really unfreeable? Activate it. */ | 497 | /* In active use or really unfreeable? Activate it. */ |
| @@ -478,8 +510,6 @@ static unsigned long shrink_page_list(struct list_head *page_list, | |||
| 478 | #endif /* CONFIG_SWAP */ | 510 | #endif /* CONFIG_SWAP */ |
| 479 | 511 | ||
| 480 | mapping = page_mapping(page); | 512 | mapping = page_mapping(page); |
| 481 | may_enter_fs = (sc->gfp_mask & __GFP_FS) || | ||
| 482 | (PageSwapCache(page) && (sc->gfp_mask & __GFP_IO)); | ||
| 483 | 513 | ||
| 484 | /* | 514 | /* |
| 485 | * The page is mapped into the page tables of one or more | 515 | * The page is mapped into the page tables of one or more |
| @@ -505,7 +535,7 @@ static unsigned long shrink_page_list(struct list_head *page_list, | |||
| 505 | goto keep_locked; | 535 | goto keep_locked; |
| 506 | 536 | ||
| 507 | /* Page is dirty, try to write it out here */ | 537 | /* Page is dirty, try to write it out here */ |
| 508 | switch(pageout(page, mapping)) { | 538 | switch (pageout(page, mapping, sync_writeback)) { |
| 509 | case PAGE_KEEP: | 539 | case PAGE_KEEP: |
| 510 | goto keep_locked; | 540 | goto keep_locked; |
| 511 | case PAGE_ACTIVATE: | 541 | case PAGE_ACTIVATE: |
| @@ -777,6 +807,7 @@ static unsigned long shrink_inactive_list(unsigned long max_scan, | |||
| 777 | (sc->order > PAGE_ALLOC_COSTLY_ORDER)? | 807 | (sc->order > PAGE_ALLOC_COSTLY_ORDER)? |
| 778 | ISOLATE_BOTH : ISOLATE_INACTIVE); | 808 | ISOLATE_BOTH : ISOLATE_INACTIVE); |
| 779 | nr_active = clear_active_flags(&page_list); | 809 | nr_active = clear_active_flags(&page_list); |
| 810 | __count_vm_events(PGDEACTIVATE, nr_active); | ||
| 780 | 811 | ||
| 781 | __mod_zone_page_state(zone, NR_ACTIVE, -nr_active); | 812 | __mod_zone_page_state(zone, NR_ACTIVE, -nr_active); |
| 782 | __mod_zone_page_state(zone, NR_INACTIVE, | 813 | __mod_zone_page_state(zone, NR_INACTIVE, |
| @@ -785,7 +816,29 @@ static unsigned long shrink_inactive_list(unsigned long max_scan, | |||
| 785 | spin_unlock_irq(&zone->lru_lock); | 816 | spin_unlock_irq(&zone->lru_lock); |
| 786 | 817 | ||
| 787 | nr_scanned += nr_scan; | 818 | nr_scanned += nr_scan; |
| 788 | nr_freed = shrink_page_list(&page_list, sc); | 819 | nr_freed = shrink_page_list(&page_list, sc, PAGEOUT_IO_ASYNC); |
| 820 | |||
| 821 | /* | ||
| 822 | * If we are direct reclaiming for contiguous pages and we do | ||
| 823 | * not reclaim everything in the list, try again and wait | ||
| 824 | * for IO to complete. This will stall high-order allocations | ||
| 825 | * but that should be acceptable to the caller | ||
| 826 | */ | ||
| 827 | if (nr_freed < nr_taken && !current_is_kswapd() && | ||
| 828 | sc->order > PAGE_ALLOC_COSTLY_ORDER) { | ||
| 829 | congestion_wait(WRITE, HZ/10); | ||
| 830 | |||
| 831 | /* | ||
| 832 | * The attempt at page out may have made some | ||
| 833 | * of the pages active, mark them inactive again. | ||
| 834 | */ | ||
| 835 | nr_active = clear_active_flags(&page_list); | ||
| 836 | count_vm_events(PGDEACTIVATE, nr_active); | ||
| 837 | |||
| 838 | nr_freed += shrink_page_list(&page_list, sc, | ||
| 839 | PAGEOUT_IO_SYNC); | ||
| 840 | } | ||
| 841 | |||
| 789 | nr_reclaimed += nr_freed; | 842 | nr_reclaimed += nr_freed; |
| 790 | local_irq_disable(); | 843 | local_irq_disable(); |
| 791 | if (current_is_kswapd()) { | 844 | if (current_is_kswapd()) { |
diff --git a/net/802/psnap.c b/net/802/psnap.c index 04ee43e7538f..31128cb92a23 100644 --- a/net/802/psnap.c +++ b/net/802/psnap.c | |||
| @@ -55,6 +55,9 @@ static int snap_rcv(struct sk_buff *skb, struct net_device *dev, | |||
| 55 | .type = __constant_htons(ETH_P_SNAP), | 55 | .type = __constant_htons(ETH_P_SNAP), |
| 56 | }; | 56 | }; |
| 57 | 57 | ||
| 58 | if (unlikely(!pskb_may_pull(skb, 5))) | ||
| 59 | goto drop; | ||
| 60 | |||
| 58 | rcu_read_lock(); | 61 | rcu_read_lock(); |
| 59 | proto = find_snap_client(skb_transport_header(skb)); | 62 | proto = find_snap_client(skb_transport_header(skb)); |
| 60 | if (proto) { | 63 | if (proto) { |
| @@ -62,14 +65,18 @@ static int snap_rcv(struct sk_buff *skb, struct net_device *dev, | |||
| 62 | skb->transport_header += 5; | 65 | skb->transport_header += 5; |
| 63 | skb_pull_rcsum(skb, 5); | 66 | skb_pull_rcsum(skb, 5); |
| 64 | rc = proto->rcvfunc(skb, dev, &snap_packet_type, orig_dev); | 67 | rc = proto->rcvfunc(skb, dev, &snap_packet_type, orig_dev); |
| 65 | } else { | ||
| 66 | skb->sk = NULL; | ||
| 67 | kfree_skb(skb); | ||
| 68 | rc = 1; | ||
| 69 | } | 68 | } |
| 70 | |||
| 71 | rcu_read_unlock(); | 69 | rcu_read_unlock(); |
| 70 | |||
| 71 | if (unlikely(!proto)) | ||
| 72 | goto drop; | ||
| 73 | |||
| 74 | out: | ||
| 72 | return rc; | 75 | return rc; |
| 76 | |||
| 77 | drop: | ||
| 78 | kfree_skb(skb); | ||
| 79 | goto out; | ||
| 73 | } | 80 | } |
| 74 | 81 | ||
| 75 | /* | 82 | /* |
diff --git a/net/dccp/ccids/ccid2.c b/net/dccp/ccids/ccid2.c index 248d20f4c7c4..d29b88fe723c 100644 --- a/net/dccp/ccids/ccid2.c +++ b/net/dccp/ccids/ccid2.c | |||
| @@ -298,7 +298,7 @@ static void ccid2_hc_tx_packet_sent(struct sock *sk, int more, unsigned int len) | |||
| 298 | int rc; | 298 | int rc; |
| 299 | 299 | ||
| 300 | ccid2_pr_debug("allocating more space in history\n"); | 300 | ccid2_pr_debug("allocating more space in history\n"); |
| 301 | rc = ccid2_hc_tx_alloc_seq(hctx, CCID2_SEQBUF_LEN, GFP_KERNEL); | 301 | rc = ccid2_hc_tx_alloc_seq(hctx, CCID2_SEQBUF_LEN, gfp_any()); |
| 302 | BUG_ON(rc); /* XXX what do we do? */ | 302 | BUG_ON(rc); /* XXX what do we do? */ |
| 303 | 303 | ||
| 304 | next = hctx->ccid2hctx_seqh->ccid2s_next; | 304 | next = hctx->ccid2hctx_seqh->ccid2s_next; |
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c index 50d86e94d9ed..5dead399fe64 100644 --- a/net/ipv6/ip6_output.c +++ b/net/ipv6/ip6_output.c | |||
| @@ -794,7 +794,7 @@ slow_path: | |||
| 794 | /* | 794 | /* |
| 795 | * Copy a block of the IP datagram. | 795 | * Copy a block of the IP datagram. |
| 796 | */ | 796 | */ |
| 797 | if (skb_copy_bits(skb, ptr, skb_transport_header(skb), len)) | 797 | if (skb_copy_bits(skb, ptr, skb_transport_header(frag), len)) |
| 798 | BUG(); | 798 | BUG(); |
| 799 | left -= len; | 799 | left -= len; |
| 800 | 800 | ||
diff --git a/net/irda/irmod.c b/net/irda/irmod.c index 1900937b3328..8ba703da2797 100644 --- a/net/irda/irmod.c +++ b/net/irda/irmod.c | |||
| @@ -128,8 +128,8 @@ static int __init irda_init(void) | |||
| 128 | out_err_3: | 128 | out_err_3: |
| 129 | #ifdef CONFIG_SYSCTL | 129 | #ifdef CONFIG_SYSCTL |
| 130 | irda_sysctl_unregister(); | 130 | irda_sysctl_unregister(); |
| 131 | #endif | ||
| 132 | out_err_2: | 131 | out_err_2: |
| 132 | #endif | ||
| 133 | #ifdef CONFIG_PROC_FS | 133 | #ifdef CONFIG_PROC_FS |
| 134 | irda_proc_unregister(); | 134 | irda_proc_unregister(); |
| 135 | #endif | 135 | #endif |
diff --git a/net/irda/irnetlink.c b/net/irda/irnetlink.c index 694ea4d92fa8..1e429c929739 100644 --- a/net/irda/irnetlink.c +++ b/net/irda/irnetlink.c | |||
| @@ -106,7 +106,7 @@ static int irda_nl_get_mode(struct sk_buff *skb, struct genl_info *info) | |||
| 106 | } | 106 | } |
| 107 | 107 | ||
| 108 | if(nla_put_string(msg, IRDA_NL_ATTR_IFNAME, | 108 | if(nla_put_string(msg, IRDA_NL_ATTR_IFNAME, |
| 109 | dev->name)); | 109 | dev->name)) |
| 110 | goto err_out; | 110 | goto err_out; |
| 111 | 111 | ||
| 112 | if(nla_put_u32(msg, IRDA_NL_ATTR_MODE, irlap->mode)) | 112 | if(nla_put_u32(msg, IRDA_NL_ATTR_MODE, irlap->mode)) |
diff --git a/security/commoncap.c b/security/commoncap.c index 338606eb7238..7520361663e8 100644 --- a/security/commoncap.c +++ b/security/commoncap.c | |||
| @@ -315,13 +315,13 @@ int cap_syslog (int type) | |||
| 315 | return 0; | 315 | return 0; |
| 316 | } | 316 | } |
| 317 | 317 | ||
| 318 | int cap_vm_enough_memory(long pages) | 318 | int cap_vm_enough_memory(struct mm_struct *mm, long pages) |
| 319 | { | 319 | { |
| 320 | int cap_sys_admin = 0; | 320 | int cap_sys_admin = 0; |
| 321 | 321 | ||
| 322 | if (cap_capable(current, CAP_SYS_ADMIN) == 0) | 322 | if (cap_capable(current, CAP_SYS_ADMIN) == 0) |
| 323 | cap_sys_admin = 1; | 323 | cap_sys_admin = 1; |
| 324 | return __vm_enough_memory(pages, cap_sys_admin); | 324 | return __vm_enough_memory(mm, pages, cap_sys_admin); |
| 325 | } | 325 | } |
| 326 | 326 | ||
| 327 | EXPORT_SYMBOL(cap_capable); | 327 | EXPORT_SYMBOL(cap_capable); |
diff --git a/security/dummy.c b/security/dummy.c index 19d813d5e083..853ec2292798 100644 --- a/security/dummy.c +++ b/security/dummy.c | |||
| @@ -108,13 +108,13 @@ static int dummy_settime(struct timespec *ts, struct timezone *tz) | |||
| 108 | return 0; | 108 | return 0; |
| 109 | } | 109 | } |
| 110 | 110 | ||
| 111 | static int dummy_vm_enough_memory(long pages) | 111 | static int dummy_vm_enough_memory(struct mm_struct *mm, long pages) |
| 112 | { | 112 | { |
| 113 | int cap_sys_admin = 0; | 113 | int cap_sys_admin = 0; |
| 114 | 114 | ||
| 115 | if (dummy_capable(current, CAP_SYS_ADMIN) == 0) | 115 | if (dummy_capable(current, CAP_SYS_ADMIN) == 0) |
| 116 | cap_sys_admin = 1; | 116 | cap_sys_admin = 1; |
| 117 | return __vm_enough_memory(pages, cap_sys_admin); | 117 | return __vm_enough_memory(mm, pages, cap_sys_admin); |
| 118 | } | 118 | } |
| 119 | 119 | ||
| 120 | static int dummy_bprm_alloc_security (struct linux_binprm *bprm) | 120 | static int dummy_bprm_alloc_security (struct linux_binprm *bprm) |
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 6237933f7d82..d8bc4172819c 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c | |||
| @@ -1584,7 +1584,7 @@ static int selinux_syslog(int type) | |||
| 1584 | * Do not audit the selinux permission check, as this is applied to all | 1584 | * Do not audit the selinux permission check, as this is applied to all |
| 1585 | * processes that allocate mappings. | 1585 | * processes that allocate mappings. |
| 1586 | */ | 1586 | */ |
| 1587 | static int selinux_vm_enough_memory(long pages) | 1587 | static int selinux_vm_enough_memory(struct mm_struct *mm, long pages) |
| 1588 | { | 1588 | { |
| 1589 | int rc, cap_sys_admin = 0; | 1589 | int rc, cap_sys_admin = 0; |
| 1590 | struct task_security_struct *tsec = current->security; | 1590 | struct task_security_struct *tsec = current->security; |
| @@ -1600,7 +1600,7 @@ static int selinux_vm_enough_memory(long pages) | |||
| 1600 | if (rc == 0) | 1600 | if (rc == 0) |
| 1601 | cap_sys_admin = 1; | 1601 | cap_sys_admin = 1; |
| 1602 | 1602 | ||
| 1603 | return __vm_enough_memory(pages, cap_sys_admin); | 1603 | return __vm_enough_memory(mm, pages, cap_sys_admin); |
| 1604 | } | 1604 | } |
| 1605 | 1605 | ||
| 1606 | /* binprm security operations */ | 1606 | /* binprm security operations */ |
