diff options
66 files changed, 1009 insertions, 273 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/filesystems/9p.txt b/Documentation/filesystems/9p.txt index bbd8b28c13de..cda6905cbe49 100644 --- a/Documentation/filesystems/9p.txt +++ b/Documentation/filesystems/9p.txt | |||
@@ -6,12 +6,26 @@ ABOUT | |||
6 | 6 | ||
7 | v9fs is a Unix implementation of the Plan 9 9p remote filesystem protocol. | 7 | v9fs is a Unix implementation of the Plan 9 9p remote filesystem protocol. |
8 | 8 | ||
9 | This software was originally developed by Ron Minnich <rminnich@lanl.gov> | 9 | This software was originally developed by Ron Minnich <rminnich@sandia.gov> |
10 | and Maya Gokhale <maya@lanl.gov>. Additional development by Greg Watson | 10 | and Maya Gokhale. Additional development by Greg Watson |
11 | <gwatson@lanl.gov> and most recently Eric Van Hensbergen | 11 | <gwatson@lanl.gov> and most recently Eric Van Hensbergen |
12 | <ericvh@gmail.com>, Latchesar Ionkov <lucho@ionkov.net> and Russ Cox | 12 | <ericvh@gmail.com>, Latchesar Ionkov <lucho@ionkov.net> and Russ Cox |
13 | <rsc@swtch.com>. | 13 | <rsc@swtch.com>. |
14 | 14 | ||
15 | The best detailed explanation of the Linux implementation and applications of | ||
16 | the 9p client is available in the form of a USENIX paper: | ||
17 | http://www.usenix.org/events/usenix05/tech/freenix/hensbergen.html | ||
18 | |||
19 | Other applications are described in the following papers: | ||
20 | * XCPU & Clustering | ||
21 | http://www.xcpu.org/xcpu-talk.pdf | ||
22 | * KVMFS: control file system for KVM | ||
23 | http://www.xcpu.org/kvmfs.pdf | ||
24 | * CellFS: A New ProgrammingModel for the Cell BE | ||
25 | http://www.xcpu.org/cellfs-talk.pdf | ||
26 | * PROSE I/O: Using 9p to enable Application Partitions | ||
27 | http://plan9.escet.urjc.es/iwp9/cready/PROSE_iwp9_2006.pdf | ||
28 | |||
15 | USAGE | 29 | USAGE |
16 | ===== | 30 | ===== |
17 | 31 | ||
@@ -90,9 +104,9 @@ subset of the namespace by extending the path: '#U*'/tmp would just export | |||
90 | and export. | 104 | and export. |
91 | 105 | ||
92 | A Linux version of the 9p server is now maintained under the npfs project | 106 | A Linux version of the 9p server is now maintained under the npfs project |
93 | on sourceforge (http://sourceforge.net/projects/npfs). There is also a | 107 | on sourceforge (http://sourceforge.net/projects/npfs). The currently |
94 | more stable single-threaded version of the server (named spfs) available from | 108 | maintained version is the single-threaded version of the server (named spfs) |
95 | the same CVS repository. | 109 | available from the same CVS repository. |
96 | 110 | ||
97 | There are user and developer mailing lists available through the v9fs project | 111 | There are user and developer mailing lists available through the v9fs project |
98 | on sourceforge (http://sourceforge.net/projects/v9fs). | 112 | on sourceforge (http://sourceforge.net/projects/v9fs). |
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/MAINTAINERS b/MAINTAINERS index abe5fa7f9c33..10a6f57776b2 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
@@ -167,11 +167,11 @@ S: Maintained | |||
167 | P: Eric Van Hensbergen | 167 | P: Eric Van Hensbergen |
168 | M: ericvh@gmail.com | 168 | M: ericvh@gmail.com |
169 | P: Ron Minnich | 169 | P: Ron Minnich |
170 | M: rminnich@lanl.gov | 170 | M: rminnich@sandia.gov |
171 | P: Latchesar Ionkov | 171 | P: Latchesar Ionkov |
172 | M: lucho@ionkov.net | 172 | M: lucho@ionkov.net |
173 | L: v9fs-developer@lists.sourceforge.net | 173 | L: v9fs-developer@lists.sourceforge.net |
174 | W: http://v9fs.sf.net | 174 | W: http://swik.net/v9fs |
175 | T: git kernel.org:/pub/scm/linux/kernel/ericvh/v9fs.git | 175 | T: git kernel.org:/pub/scm/linux/kernel/ericvh/v9fs.git |
176 | S: Maintained | 176 | S: Maintained |
177 | 177 | ||
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/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/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/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/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/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/fs/9p/fid.c b/fs/9p/fid.c index 08fa320b7e6d..15e05a15b575 100644 --- a/fs/9p/fid.c +++ b/fs/9p/fid.c | |||
@@ -92,23 +92,6 @@ struct p9_fid *v9fs_fid_lookup(struct dentry *dentry) | |||
92 | return fid; | 92 | return fid; |
93 | } | 93 | } |
94 | 94 | ||
95 | struct p9_fid *v9fs_fid_lookup_remove(struct dentry *dentry) | ||
96 | { | ||
97 | struct p9_fid *fid; | ||
98 | struct v9fs_dentry *dent; | ||
99 | |||
100 | dent = dentry->d_fsdata; | ||
101 | fid = v9fs_fid_lookup(dentry); | ||
102 | if (!IS_ERR(fid)) { | ||
103 | spin_lock(&dent->lock); | ||
104 | list_del(&fid->dlist); | ||
105 | spin_unlock(&dent->lock); | ||
106 | } | ||
107 | |||
108 | return fid; | ||
109 | } | ||
110 | |||
111 | |||
112 | /** | 95 | /** |
113 | * v9fs_fid_clone - lookup the fid for a dentry, clone a private copy and | 96 | * v9fs_fid_clone - lookup the fid for a dentry, clone a private copy and |
114 | * release it | 97 | * release it |
diff --git a/fs/9p/fid.h b/fs/9p/fid.h index 47a0ba742872..26e07df783b9 100644 --- a/fs/9p/fid.h +++ b/fs/9p/fid.h | |||
@@ -28,6 +28,5 @@ struct v9fs_dentry { | |||
28 | }; | 28 | }; |
29 | 29 | ||
30 | struct p9_fid *v9fs_fid_lookup(struct dentry *dentry); | 30 | struct p9_fid *v9fs_fid_lookup(struct dentry *dentry); |
31 | struct p9_fid *v9fs_fid_lookup_remove(struct dentry *dentry); | ||
32 | struct p9_fid *v9fs_fid_clone(struct dentry *dentry); | 31 | struct p9_fid *v9fs_fid_clone(struct dentry *dentry); |
33 | int v9fs_fid_add(struct dentry *dentry, struct p9_fid *fid); | 32 | int v9fs_fid_add(struct dentry *dentry, struct p9_fid *fid); |
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-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/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/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 8938d59013c6..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 |
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/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/net/9p/conv.c b/net/9p/conv.c index f2a041cb508a..d979d958ea19 100644 --- a/net/9p/conv.c +++ b/net/9p/conv.c | |||
@@ -796,6 +796,7 @@ struct p9_fcall *p9_create_twrite_u(u32 fid, u64 offset, u32 count, | |||
796 | if (err) { | 796 | if (err) { |
797 | kfree(fc); | 797 | kfree(fc); |
798 | fc = ERR_PTR(err); | 798 | fc = ERR_PTR(err); |
799 | goto error; | ||
799 | } | 800 | } |
800 | 801 | ||
801 | if (buf_check_overflow(bufp)) { | 802 | if (buf_check_overflow(bufp)) { |
diff --git a/net/9p/mux.c b/net/9p/mux.c index acb038810f39..5d70558c4c61 100644 --- a/net/9p/mux.c +++ b/net/9p/mux.c | |||
@@ -288,9 +288,10 @@ struct p9_conn *p9_conn_create(struct p9_transport *trans, int msize, | |||
288 | m->extended = extended; | 288 | m->extended = extended; |
289 | m->trans = trans; | 289 | m->trans = trans; |
290 | m->tagpool = p9_idpool_create(); | 290 | m->tagpool = p9_idpool_create(); |
291 | if (!m->tagpool) { | 291 | if (IS_ERR(m->tagpool)) { |
292 | mtmp = ERR_PTR(-ENOMEM); | ||
292 | kfree(m); | 293 | kfree(m); |
293 | return ERR_PTR(PTR_ERR(m->tagpool)); | 294 | return mtmp; |
294 | } | 295 | } |
295 | 296 | ||
296 | m->err = 0; | 297 | m->err = 0; |
@@ -308,8 +309,10 @@ struct p9_conn *p9_conn_create(struct p9_transport *trans, int msize, | |||
308 | memset(&m->poll_waddr, 0, sizeof(m->poll_waddr)); | 309 | memset(&m->poll_waddr, 0, sizeof(m->poll_waddr)); |
309 | m->poll_task = NULL; | 310 | m->poll_task = NULL; |
310 | n = p9_mux_poll_start(m); | 311 | n = p9_mux_poll_start(m); |
311 | if (n) | 312 | if (n) { |
313 | kfree(m); | ||
312 | return ERR_PTR(n); | 314 | return ERR_PTR(n); |
315 | } | ||
313 | 316 | ||
314 | n = trans->poll(trans, &m->pt); | 317 | n = trans->poll(trans, &m->pt); |
315 | if (n & POLLIN) { | 318 | if (n & POLLIN) { |