diff options
273 files changed, 4638 insertions, 1579 deletions
diff --git a/.gitignore b/.gitignore index b93fb7eff942..946c7ec5c922 100644 --- a/.gitignore +++ b/.gitignore | |||
@@ -25,6 +25,7 @@ | |||
25 | *.elf | 25 | *.elf |
26 | *.bin | 26 | *.bin |
27 | *.gz | 27 | *.gz |
28 | *.bz2 | ||
28 | *.lzma | 29 | *.lzma |
29 | *.patch | 30 | *.patch |
30 | *.gcno | 31 | *.gcno |
diff --git a/Documentation/fb/framebuffer.txt b/Documentation/fb/framebuffer.txt index b3e3a0356839..fe79e3c8847d 100644 --- a/Documentation/fb/framebuffer.txt +++ b/Documentation/fb/framebuffer.txt | |||
@@ -312,10 +312,8 @@ and to the following documentation: | |||
312 | 8. Mailing list | 312 | 8. Mailing list |
313 | --------------- | 313 | --------------- |
314 | 314 | ||
315 | There are several frame buffer device related mailing lists at SourceForge: | 315 | There is a frame buffer device related mailing list at kernel.org: |
316 | - linux-fbdev-announce@lists.sourceforge.net, for announcements, | 316 | linux-fbdev@vger.kernel.org. |
317 | - linux-fbdev-user@lists.sourceforge.net, for generic user support, | ||
318 | - linux-fbdev-devel@lists.sourceforge.net, for project developers. | ||
319 | 317 | ||
320 | Point your web browser to http://sourceforge.net/projects/linux-fbdev/ for | 318 | Point your web browser to http://sourceforge.net/projects/linux-fbdev/ for |
321 | subscription information and archive browsing. | 319 | subscription information and archive browsing. |
diff --git a/Documentation/filesystems/caching/fscache.txt b/Documentation/filesystems/caching/fscache.txt index 9e94b9491d89..a91e2e2095b0 100644 --- a/Documentation/filesystems/caching/fscache.txt +++ b/Documentation/filesystems/caching/fscache.txt | |||
@@ -235,6 +235,7 @@ proc files. | |||
235 | neg=N Number of negative lookups made | 235 | neg=N Number of negative lookups made |
236 | pos=N Number of positive lookups made | 236 | pos=N Number of positive lookups made |
237 | crt=N Number of objects created by lookup | 237 | crt=N Number of objects created by lookup |
238 | tmo=N Number of lookups timed out and requeued | ||
238 | Updates n=N Number of update cookie requests seen | 239 | Updates n=N Number of update cookie requests seen |
239 | nul=N Number of upd reqs given a NULL parent | 240 | nul=N Number of upd reqs given a NULL parent |
240 | run=N Number of upd reqs granted CPU time | 241 | run=N Number of upd reqs granted CPU time |
@@ -250,8 +251,10 @@ proc files. | |||
250 | ok=N Number of successful alloc reqs | 251 | ok=N Number of successful alloc reqs |
251 | wt=N Number of alloc reqs that waited on lookup completion | 252 | wt=N Number of alloc reqs that waited on lookup completion |
252 | nbf=N Number of alloc reqs rejected -ENOBUFS | 253 | nbf=N Number of alloc reqs rejected -ENOBUFS |
254 | int=N Number of alloc reqs aborted -ERESTARTSYS | ||
253 | ops=N Number of alloc reqs submitted | 255 | ops=N Number of alloc reqs submitted |
254 | owt=N Number of alloc reqs waited for CPU time | 256 | owt=N Number of alloc reqs waited for CPU time |
257 | abt=N Number of alloc reqs aborted due to object death | ||
255 | Retrvls n=N Number of retrieval (read) requests seen | 258 | Retrvls n=N Number of retrieval (read) requests seen |
256 | ok=N Number of successful retr reqs | 259 | ok=N Number of successful retr reqs |
257 | wt=N Number of retr reqs that waited on lookup completion | 260 | wt=N Number of retr reqs that waited on lookup completion |
@@ -261,6 +264,7 @@ proc files. | |||
261 | oom=N Number of retr reqs failed -ENOMEM | 264 | oom=N Number of retr reqs failed -ENOMEM |
262 | ops=N Number of retr reqs submitted | 265 | ops=N Number of retr reqs submitted |
263 | owt=N Number of retr reqs waited for CPU time | 266 | owt=N Number of retr reqs waited for CPU time |
267 | abt=N Number of retr reqs aborted due to object death | ||
264 | Stores n=N Number of storage (write) requests seen | 268 | Stores n=N Number of storage (write) requests seen |
265 | ok=N Number of successful store reqs | 269 | ok=N Number of successful store reqs |
266 | agn=N Number of store reqs on a page already pending storage | 270 | agn=N Number of store reqs on a page already pending storage |
@@ -268,12 +272,37 @@ proc files. | |||
268 | oom=N Number of store reqs failed -ENOMEM | 272 | oom=N Number of store reqs failed -ENOMEM |
269 | ops=N Number of store reqs submitted | 273 | ops=N Number of store reqs submitted |
270 | run=N Number of store reqs granted CPU time | 274 | run=N Number of store reqs granted CPU time |
275 | pgs=N Number of pages given store req processing time | ||
276 | rxd=N Number of store reqs deleted from tracking tree | ||
277 | olm=N Number of store reqs over store limit | ||
278 | VmScan nos=N Number of release reqs against pages with no pending store | ||
279 | gon=N Number of release reqs against pages stored by time lock granted | ||
280 | bsy=N Number of release reqs ignored due to in-progress store | ||
281 | can=N Number of page stores cancelled due to release req | ||
271 | Ops pend=N Number of times async ops added to pending queues | 282 | Ops pend=N Number of times async ops added to pending queues |
272 | run=N Number of times async ops given CPU time | 283 | run=N Number of times async ops given CPU time |
273 | enq=N Number of times async ops queued for processing | 284 | enq=N Number of times async ops queued for processing |
285 | can=N Number of async ops cancelled | ||
286 | rej=N Number of async ops rejected due to object lookup/create failure | ||
274 | dfr=N Number of async ops queued for deferred release | 287 | dfr=N Number of async ops queued for deferred release |
275 | rel=N Number of async ops released | 288 | rel=N Number of async ops released |
276 | gc=N Number of deferred-release async ops garbage collected | 289 | gc=N Number of deferred-release async ops garbage collected |
290 | CacheOp alo=N Number of in-progress alloc_object() cache ops | ||
291 | luo=N Number of in-progress lookup_object() cache ops | ||
292 | luc=N Number of in-progress lookup_complete() cache ops | ||
293 | gro=N Number of in-progress grab_object() cache ops | ||
294 | upo=N Number of in-progress update_object() cache ops | ||
295 | dro=N Number of in-progress drop_object() cache ops | ||
296 | pto=N Number of in-progress put_object() cache ops | ||
297 | syn=N Number of in-progress sync_cache() cache ops | ||
298 | atc=N Number of in-progress attr_changed() cache ops | ||
299 | rap=N Number of in-progress read_or_alloc_page() cache ops | ||
300 | ras=N Number of in-progress read_or_alloc_pages() cache ops | ||
301 | alp=N Number of in-progress allocate_page() cache ops | ||
302 | als=N Number of in-progress allocate_pages() cache ops | ||
303 | wrp=N Number of in-progress write_page() cache ops | ||
304 | ucp=N Number of in-progress uncache_page() cache ops | ||
305 | dsp=N Number of in-progress dissociate_pages() cache ops | ||
277 | 306 | ||
278 | 307 | ||
279 | (*) /proc/fs/fscache/histogram | 308 | (*) /proc/fs/fscache/histogram |
@@ -299,6 +328,87 @@ proc files. | |||
299 | jiffy range covered, and the SECS field the equivalent number of seconds. | 328 | jiffy range covered, and the SECS field the equivalent number of seconds. |
300 | 329 | ||
301 | 330 | ||
331 | =========== | ||
332 | OBJECT LIST | ||
333 | =========== | ||
334 | |||
335 | If CONFIG_FSCACHE_OBJECT_LIST is enabled, the FS-Cache facility will maintain a | ||
336 | list of all the objects currently allocated and allow them to be viewed | ||
337 | through: | ||
338 | |||
339 | /proc/fs/fscache/objects | ||
340 | |||
341 | This will look something like: | ||
342 | |||
343 | [root@andromeda ~]# head /proc/fs/fscache/objects | ||
344 | OBJECT PARENT STAT CHLDN OPS OOP IPR EX READS EM EV F S | NETFS_COOKIE_DEF TY FL NETFS_DATA OBJECT_KEY, AUX_DATA | ||
345 | ======== ======== ==== ===== === === === == ===== == == = = | ================ == == ================ ================ | ||
346 | 17e4b 2 ACTV 0 0 0 0 0 0 7b 4 0 8 | NFS.fh DT 0 ffff88001dd82820 010006017edcf8bbc93b43298fdfbe71e50b57b13a172c0117f38472, e567634700000000000000000000000063f2404a000000000000000000000000c9030000000000000000000063f2404a | ||
347 | 1693a 2 ACTV 0 0 0 0 0 0 7b 4 0 8 | NFS.fh DT 0 ffff88002db23380 010006017edcf8bbc93b43298fdfbe71e50b57b1e0162c01a2df0ea6, 420ebc4a000000000000000000000000420ebc4a0000000000000000000000000e1801000000000000000000420ebc4a | ||
348 | |||
349 | where the first set of columns before the '|' describe the object: | ||
350 | |||
351 | COLUMN DESCRIPTION | ||
352 | ======= =============================================================== | ||
353 | OBJECT Object debugging ID (appears as OBJ%x in some debug messages) | ||
354 | PARENT Debugging ID of parent object | ||
355 | STAT Object state | ||
356 | CHLDN Number of child objects of this object | ||
357 | OPS Number of outstanding operations on this object | ||
358 | OOP Number of outstanding child object management operations | ||
359 | IPR | ||
360 | EX Number of outstanding exclusive operations | ||
361 | READS Number of outstanding read operations | ||
362 | EM Object's event mask | ||
363 | EV Events raised on this object | ||
364 | F Object flags | ||
365 | S Object slow-work work item flags | ||
366 | |||
367 | and the second set of columns describe the object's cookie, if present: | ||
368 | |||
369 | COLUMN DESCRIPTION | ||
370 | =============== ======================================================= | ||
371 | NETFS_COOKIE_DEF Name of netfs cookie definition | ||
372 | TY Cookie type (IX - index, DT - data, hex - special) | ||
373 | FL Cookie flags | ||
374 | NETFS_DATA Netfs private data stored in the cookie | ||
375 | OBJECT_KEY Object key } 1 column, with separating comma | ||
376 | AUX_DATA Object aux data } presence may be configured | ||
377 | |||
378 | The data shown may be filtered by attaching the a key to an appropriate keyring | ||
379 | before viewing the file. Something like: | ||
380 | |||
381 | keyctl add user fscache:objlist <restrictions> @s | ||
382 | |||
383 | where <restrictions> are a selection of the following letters: | ||
384 | |||
385 | K Show hexdump of object key (don't show if not given) | ||
386 | A Show hexdump of object aux data (don't show if not given) | ||
387 | |||
388 | and the following paired letters: | ||
389 | |||
390 | C Show objects that have a cookie | ||
391 | c Show objects that don't have a cookie | ||
392 | B Show objects that are busy | ||
393 | b Show objects that aren't busy | ||
394 | W Show objects that have pending writes | ||
395 | w Show objects that don't have pending writes | ||
396 | R Show objects that have outstanding reads | ||
397 | r Show objects that don't have outstanding reads | ||
398 | S Show objects that have slow work queued | ||
399 | s Show objects that don't have slow work queued | ||
400 | |||
401 | If neither side of a letter pair is given, then both are implied. For example: | ||
402 | |||
403 | keyctl add user fscache:objlist KB @s | ||
404 | |||
405 | shows objects that are busy, and lists their object keys, but does not dump | ||
406 | their auxiliary data. It also implies "CcWwRrSs", but as 'B' is given, 'b' is | ||
407 | not implied. | ||
408 | |||
409 | By default all objects and all fields will be shown. | ||
410 | |||
411 | |||
302 | ========= | 412 | ========= |
303 | DEBUGGING | 413 | DEBUGGING |
304 | ========= | 414 | ========= |
diff --git a/Documentation/filesystems/caching/netfs-api.txt b/Documentation/filesystems/caching/netfs-api.txt index 2666b1ed5e9e..1902c57b72ef 100644 --- a/Documentation/filesystems/caching/netfs-api.txt +++ b/Documentation/filesystems/caching/netfs-api.txt | |||
@@ -641,7 +641,7 @@ data file must be retired (see the relinquish cookie function below). | |||
641 | 641 | ||
642 | Furthermore, note that this does not cancel the asynchronous read or write | 642 | Furthermore, note that this does not cancel the asynchronous read or write |
643 | operation started by the read/alloc and write functions, so the page | 643 | operation started by the read/alloc and write functions, so the page |
644 | invalidation and release functions must use: | 644 | invalidation functions must use: |
645 | 645 | ||
646 | bool fscache_check_page_write(struct fscache_cookie *cookie, | 646 | bool fscache_check_page_write(struct fscache_cookie *cookie, |
647 | struct page *page); | 647 | struct page *page); |
@@ -654,6 +654,25 @@ to see if a page is being written to the cache, and: | |||
654 | to wait for it to finish if it is. | 654 | to wait for it to finish if it is. |
655 | 655 | ||
656 | 656 | ||
657 | When releasepage() is being implemented, a special FS-Cache function exists to | ||
658 | manage the heuristics of coping with vmscan trying to eject pages, which may | ||
659 | conflict with the cache trying to write pages to the cache (which may itself | ||
660 | need to allocate memory): | ||
661 | |||
662 | bool fscache_maybe_release_page(struct fscache_cookie *cookie, | ||
663 | struct page *page, | ||
664 | gfp_t gfp); | ||
665 | |||
666 | This takes the netfs cookie, and the page and gfp arguments as supplied to | ||
667 | releasepage(). It will return false if the page cannot be released yet for | ||
668 | some reason and if it returns true, the page has been uncached and can now be | ||
669 | released. | ||
670 | |||
671 | To make a page available for release, this function may wait for an outstanding | ||
672 | storage request to complete, or it may attempt to cancel the storage request - | ||
673 | in which case the page will not be stored in the cache this time. | ||
674 | |||
675 | |||
657 | ========================== | 676 | ========================== |
658 | INDEX AND DATA FILE UPDATE | 677 | INDEX AND DATA FILE UPDATE |
659 | ========================== | 678 | ========================== |
diff --git a/Documentation/filesystems/ocfs2.txt b/Documentation/filesystems/ocfs2.txt index c2a0871280a0..c58b9f5ba002 100644 --- a/Documentation/filesystems/ocfs2.txt +++ b/Documentation/filesystems/ocfs2.txt | |||
@@ -20,15 +20,16 @@ Lots of code taken from ext3 and other projects. | |||
20 | Authors in alphabetical order: | 20 | Authors in alphabetical order: |
21 | Joel Becker <joel.becker@oracle.com> | 21 | Joel Becker <joel.becker@oracle.com> |
22 | Zach Brown <zach.brown@oracle.com> | 22 | Zach Brown <zach.brown@oracle.com> |
23 | Mark Fasheh <mark.fasheh@oracle.com> | 23 | Mark Fasheh <mfasheh@suse.com> |
24 | Kurt Hackel <kurt.hackel@oracle.com> | 24 | Kurt Hackel <kurt.hackel@oracle.com> |
25 | Tao Ma <tao.ma@oracle.com> | ||
25 | Sunil Mushran <sunil.mushran@oracle.com> | 26 | Sunil Mushran <sunil.mushran@oracle.com> |
26 | Manish Singh <manish.singh@oracle.com> | 27 | Manish Singh <manish.singh@oracle.com> |
28 | Tiger Yang <tiger.yang@oracle.com> | ||
27 | 29 | ||
28 | Caveats | 30 | Caveats |
29 | ======= | 31 | ======= |
30 | Features which OCFS2 does not support yet: | 32 | Features which OCFS2 does not support yet: |
31 | - quotas | ||
32 | - Directory change notification (F_NOTIFY) | 33 | - Directory change notification (F_NOTIFY) |
33 | - Distributed Caching (F_SETLEASE/F_GETLEASE/break_lease) | 34 | - Distributed Caching (F_SETLEASE/F_GETLEASE/break_lease) |
34 | 35 | ||
@@ -70,7 +71,6 @@ commit=nrsec (*) Ocfs2 can be told to sync all its data and metadata | |||
70 | performance. | 71 | performance. |
71 | localalloc=8(*) Allows custom localalloc size in MB. If the value is too | 72 | localalloc=8(*) Allows custom localalloc size in MB. If the value is too |
72 | large, the fs will silently revert it to the default. | 73 | large, the fs will silently revert it to the default. |
73 | Localalloc is not enabled for local mounts. | ||
74 | localflocks This disables cluster aware flock. | 74 | localflocks This disables cluster aware flock. |
75 | inode64 Indicates that Ocfs2 is allowed to create inodes at | 75 | inode64 Indicates that Ocfs2 is allowed to create inodes at |
76 | any location in the filesystem, including those which | 76 | any location in the filesystem, including those which |
diff --git a/Documentation/slow-work.txt b/Documentation/slow-work.txt index ebc50f808ea4..52bc31433723 100644 --- a/Documentation/slow-work.txt +++ b/Documentation/slow-work.txt | |||
@@ -41,6 +41,13 @@ expand files, provided the time taken to do so isn't too long. | |||
41 | Operations of both types may sleep during execution, thus tying up the thread | 41 | Operations of both types may sleep during execution, thus tying up the thread |
42 | loaned to it. | 42 | loaned to it. |
43 | 43 | ||
44 | A further class of work item is available, based on the slow work item class: | ||
45 | |||
46 | (*) Delayed slow work items. | ||
47 | |||
48 | These are slow work items that have a timer to defer queueing of the item for | ||
49 | a while. | ||
50 | |||
44 | 51 | ||
45 | THREAD-TO-CLASS ALLOCATION | 52 | THREAD-TO-CLASS ALLOCATION |
46 | -------------------------- | 53 | -------------------------- |
@@ -64,9 +71,11 @@ USING SLOW WORK ITEMS | |||
64 | Firstly, a module or subsystem wanting to make use of slow work items must | 71 | Firstly, a module or subsystem wanting to make use of slow work items must |
65 | register its interest: | 72 | register its interest: |
66 | 73 | ||
67 | int ret = slow_work_register_user(); | 74 | int ret = slow_work_register_user(struct module *module); |
68 | 75 | ||
69 | This will return 0 if successful, or a -ve error upon failure. | 76 | This will return 0 if successful, or a -ve error upon failure. The module |
77 | pointer should be the module interested in using this facility (almost | ||
78 | certainly THIS_MODULE). | ||
70 | 79 | ||
71 | 80 | ||
72 | Slow work items may then be set up by: | 81 | Slow work items may then be set up by: |
@@ -93,6 +102,10 @@ Slow work items may then be set up by: | |||
93 | 102 | ||
94 | or: | 103 | or: |
95 | 104 | ||
105 | delayed_slow_work_init(&myitem, &myitem_ops); | ||
106 | |||
107 | or: | ||
108 | |||
96 | vslow_work_init(&myitem, &myitem_ops); | 109 | vslow_work_init(&myitem, &myitem_ops); |
97 | 110 | ||
98 | depending on its class. | 111 | depending on its class. |
@@ -102,15 +115,92 @@ A suitably set up work item can then be enqueued for processing: | |||
102 | int ret = slow_work_enqueue(&myitem); | 115 | int ret = slow_work_enqueue(&myitem); |
103 | 116 | ||
104 | This will return a -ve error if the thread pool is unable to gain a reference | 117 | This will return a -ve error if the thread pool is unable to gain a reference |
105 | on the item, 0 otherwise. | 118 | on the item, 0 otherwise, or (for delayed work): |
119 | |||
120 | int ret = delayed_slow_work_enqueue(&myitem, my_jiffy_delay); | ||
106 | 121 | ||
107 | 122 | ||
108 | The items are reference counted, so there ought to be no need for a flush | 123 | The items are reference counted, so there ought to be no need for a flush |
109 | operation. When all a module's slow work items have been processed, and the | 124 | operation. But as the reference counting is optional, means to cancel |
125 | existing work items are also included: | ||
126 | |||
127 | cancel_slow_work(&myitem); | ||
128 | cancel_delayed_slow_work(&myitem); | ||
129 | |||
130 | can be used to cancel pending work. The above cancel function waits for | ||
131 | existing work to have been executed (or prevent execution of them, depending | ||
132 | on timing). | ||
133 | |||
134 | |||
135 | When all a module's slow work items have been processed, and the | ||
110 | module has no further interest in the facility, it should unregister its | 136 | module has no further interest in the facility, it should unregister its |
111 | interest: | 137 | interest: |
112 | 138 | ||
113 | slow_work_unregister_user(); | 139 | slow_work_unregister_user(struct module *module); |
140 | |||
141 | The module pointer is used to wait for all outstanding work items for that | ||
142 | module before completing the unregistration. This prevents the put_ref() code | ||
143 | from being taken away before it completes. module should almost certainly be | ||
144 | THIS_MODULE. | ||
145 | |||
146 | |||
147 | ================ | ||
148 | HELPER FUNCTIONS | ||
149 | ================ | ||
150 | |||
151 | The slow-work facility provides a function by which it can be determined | ||
152 | whether or not an item is queued for later execution: | ||
153 | |||
154 | bool queued = slow_work_is_queued(struct slow_work *work); | ||
155 | |||
156 | If it returns false, then the item is not on the queue (it may be executing | ||
157 | with a requeue pending). This can be used to work out whether an item on which | ||
158 | another depends is on the queue, thus allowing a dependent item to be queued | ||
159 | after it. | ||
160 | |||
161 | If the above shows an item on which another depends not to be queued, then the | ||
162 | owner of the dependent item might need to wait. However, to avoid locking up | ||
163 | the threads unnecessarily be sleeping in them, it can make sense under some | ||
164 | circumstances to return the work item to the queue, thus deferring it until | ||
165 | some other items have had a chance to make use of the yielded thread. | ||
166 | |||
167 | To yield a thread and defer an item, the work function should simply enqueue | ||
168 | the work item again and return. However, this doesn't work if there's nothing | ||
169 | actually on the queue, as the thread just vacated will jump straight back into | ||
170 | the item's work function, thus busy waiting on a CPU. | ||
171 | |||
172 | Instead, the item should use the thread to wait for the dependency to go away, | ||
173 | but rather than using schedule() or schedule_timeout() to sleep, it should use | ||
174 | the following function: | ||
175 | |||
176 | bool requeue = slow_work_sleep_till_thread_needed( | ||
177 | struct slow_work *work, | ||
178 | signed long *_timeout); | ||
179 | |||
180 | This will add a second wait and then sleep, such that it will be woken up if | ||
181 | either something appears on the queue that could usefully make use of the | ||
182 | thread - and behind which this item can be queued, or if the event the caller | ||
183 | set up to wait for happens. True will be returned if something else appeared | ||
184 | on the queue and this work function should perhaps return, of false if | ||
185 | something else woke it up. The timeout is as for schedule_timeout(). | ||
186 | |||
187 | For example: | ||
188 | |||
189 | wq = bit_waitqueue(&my_flags, MY_BIT); | ||
190 | init_wait(&wait); | ||
191 | requeue = false; | ||
192 | do { | ||
193 | prepare_to_wait(wq, &wait, TASK_UNINTERRUPTIBLE); | ||
194 | if (!test_bit(MY_BIT, &my_flags)) | ||
195 | break; | ||
196 | requeue = slow_work_sleep_till_thread_needed(&my_work, | ||
197 | &timeout); | ||
198 | } while (timeout > 0 && !requeue); | ||
199 | finish_wait(wq, &wait); | ||
200 | if (!test_bit(MY_BIT, &my_flags) | ||
201 | goto do_my_thing; | ||
202 | if (requeue) | ||
203 | return; // to slow_work | ||
114 | 204 | ||
115 | 205 | ||
116 | =============== | 206 | =============== |
@@ -118,7 +208,8 @@ ITEM OPERATIONS | |||
118 | =============== | 208 | =============== |
119 | 209 | ||
120 | Each work item requires a table of operations of type struct slow_work_ops. | 210 | Each work item requires a table of operations of type struct slow_work_ops. |
121 | All members are required: | 211 | Only ->execute() is required; the getting and putting of a reference and the |
212 | describing of an item are all optional. | ||
122 | 213 | ||
123 | (*) Get a reference on an item: | 214 | (*) Get a reference on an item: |
124 | 215 | ||
@@ -148,6 +239,16 @@ All members are required: | |||
148 | This should perform the work required of the item. It may sleep, it may | 239 | This should perform the work required of the item. It may sleep, it may |
149 | perform disk I/O and it may wait for locks. | 240 | perform disk I/O and it may wait for locks. |
150 | 241 | ||
242 | (*) View an item through /proc: | ||
243 | |||
244 | void (*desc)(struct slow_work *work, struct seq_file *m); | ||
245 | |||
246 | If supplied, this should print to 'm' a small string describing the work | ||
247 | the item is to do. This should be no more than about 40 characters, and | ||
248 | shouldn't include a newline character. | ||
249 | |||
250 | See the 'Viewing executing and queued items' section below. | ||
251 | |||
151 | 252 | ||
152 | ================== | 253 | ================== |
153 | POOL CONFIGURATION | 254 | POOL CONFIGURATION |
@@ -172,3 +273,50 @@ The slow-work thread pool has a number of configurables: | |||
172 | is bounded to between 1 and one fewer than the number of active threads. | 273 | is bounded to between 1 and one fewer than the number of active threads. |
173 | This ensures there is always at least one thread that can process very | 274 | This ensures there is always at least one thread that can process very |
174 | slow work items, and always at least one thread that won't. | 275 | slow work items, and always at least one thread that won't. |
276 | |||
277 | |||
278 | ================================== | ||
279 | VIEWING EXECUTING AND QUEUED ITEMS | ||
280 | ================================== | ||
281 | |||
282 | If CONFIG_SLOW_WORK_PROC is enabled, a proc file is made available: | ||
283 | |||
284 | /proc/slow_work_rq | ||
285 | |||
286 | through which the list of work items being executed and the queues of items to | ||
287 | be executed may be viewed. The owner of a work item is given the chance to | ||
288 | add some information of its own. | ||
289 | |||
290 | The contents look something like the following: | ||
291 | |||
292 | THR PID ITEM ADDR FL MARK DESC | ||
293 | === ===== ================ == ===== ========== | ||
294 | 0 3005 ffff880023f52348 a 952ms FSC: OBJ17d3: LOOK | ||
295 | 1 3006 ffff880024e33668 2 160ms FSC: OBJ17e5 OP60d3b: Write1/Store fl=2 | ||
296 | 2 3165 ffff8800296dd180 a 424ms FSC: OBJ17e4: LOOK | ||
297 | 3 4089 ffff8800262c8d78 a 212ms FSC: OBJ17ea: CRTN | ||
298 | 4 4090 ffff88002792bed8 2 388ms FSC: OBJ17e8 OP60d36: Write1/Store fl=2 | ||
299 | 5 4092 ffff88002a0ef308 2 388ms FSC: OBJ17e7 OP60d2e: Write1/Store fl=2 | ||
300 | 6 4094 ffff88002abaf4b8 2 132ms FSC: OBJ17e2 OP60d4e: Write1/Store fl=2 | ||
301 | 7 4095 ffff88002bb188e0 a 388ms FSC: OBJ17e9: CRTN | ||
302 | vsq - ffff880023d99668 1 308ms FSC: OBJ17e0 OP60f91: Write1/EnQ fl=2 | ||
303 | vsq - ffff8800295d1740 1 212ms FSC: OBJ16be OP4d4b6: Write1/EnQ fl=2 | ||
304 | vsq - ffff880025ba3308 1 160ms FSC: OBJ179a OP58dec: Write1/EnQ fl=2 | ||
305 | vsq - ffff880024ec83e0 1 160ms FSC: OBJ17ae OP599f2: Write1/EnQ fl=2 | ||
306 | vsq - ffff880026618e00 1 160ms FSC: OBJ17e6 OP60d33: Write1/EnQ fl=2 | ||
307 | vsq - ffff880025a2a4b8 1 132ms FSC: OBJ16a2 OP4d583: Write1/EnQ fl=2 | ||
308 | vsq - ffff880023cbe6d8 9 212ms FSC: OBJ17eb: LOOK | ||
309 | vsq - ffff880024d37590 9 212ms FSC: OBJ17ec: LOOK | ||
310 | vsq - ffff880027746cb0 9 212ms FSC: OBJ17ed: LOOK | ||
311 | vsq - ffff880024d37ae8 9 212ms FSC: OBJ17ee: LOOK | ||
312 | vsq - ffff880024d37cb0 9 212ms FSC: OBJ17ef: LOOK | ||
313 | vsq - ffff880025036550 9 212ms FSC: OBJ17f0: LOOK | ||
314 | vsq - ffff8800250368e0 9 212ms FSC: OBJ17f1: LOOK | ||
315 | vsq - ffff880025036aa8 9 212ms FSC: OBJ17f2: LOOK | ||
316 | |||
317 | In the 'THR' column, executing items show the thread they're occupying and | ||
318 | queued threads indicate which queue they're on. 'PID' shows the process ID of | ||
319 | a slow-work thread that's executing something. 'FL' shows the work item flags. | ||
320 | 'MARK' indicates how long since an item was queued or began executing. Lastly, | ||
321 | the 'DESC' column permits the owner of an item to give some information. | ||
322 | |||
diff --git a/MAINTAINERS b/MAINTAINERS index 81d68d5b7eea..16129e67678a 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
@@ -512,10 +512,32 @@ W: http://www.arm.linux.org.uk/ | |||
512 | S: Maintained | 512 | S: Maintained |
513 | F: arch/arm/ | 513 | F: arch/arm/ |
514 | 514 | ||
515 | ARM PRIMECELL AACI PL041 DRIVER | ||
516 | M: Russell King <linux@arm.linux.org.uk> | ||
517 | S: Maintained | ||
518 | F: sound/arm/aaci.* | ||
519 | |||
520 | ARM PRIMECELL CLCD PL110 DRIVER | ||
521 | M: Russell King <linux@arm.linux.org.uk> | ||
522 | S: Maintained | ||
523 | F: drivers/video/amba-clcd.* | ||
524 | |||
525 | ARM PRIMECELL KMI PL050 DRIVER | ||
526 | M: Russell King <linux@arm.linux.org.uk> | ||
527 | S: Maintained | ||
528 | F: drivers/input/serio/ambakmi.* | ||
529 | F: include/linux/amba/kmi.h | ||
530 | |||
515 | ARM PRIMECELL MMCI PL180/1 DRIVER | 531 | ARM PRIMECELL MMCI PL180/1 DRIVER |
516 | S: Orphan | 532 | S: Orphan |
517 | F: drivers/mmc/host/mmci.* | 533 | F: drivers/mmc/host/mmci.* |
518 | 534 | ||
535 | ARM PRIMECELL BUS SUPPORT | ||
536 | M: Russell King <linux@arm.linux.org.uk> | ||
537 | S: Maintained | ||
538 | F: drivers/amba/ | ||
539 | F: include/linux/amba/bus.h | ||
540 | |||
519 | ARM/ADI ROADRUNNER MACHINE SUPPORT | 541 | ARM/ADI ROADRUNNER MACHINE SUPPORT |
520 | M: Lennert Buytenhek <kernel@wantstofly.org> | 542 | M: Lennert Buytenhek <kernel@wantstofly.org> |
521 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) | 543 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) |
@@ -1027,7 +1049,7 @@ F: drivers/serial/atmel_serial.c | |||
1027 | 1049 | ||
1028 | ATMEL LCDFB DRIVER | 1050 | ATMEL LCDFB DRIVER |
1029 | M: Nicolas Ferre <nicolas.ferre@atmel.com> | 1051 | M: Nicolas Ferre <nicolas.ferre@atmel.com> |
1030 | L: linux-fbdev-devel@lists.sourceforge.net (moderated for non-subscribers) | 1052 | L: linux-fbdev@vger.kernel.org |
1031 | S: Maintained | 1053 | S: Maintained |
1032 | F: drivers/video/atmel_lcdfb.c | 1054 | F: drivers/video/atmel_lcdfb.c |
1033 | F: include/video/atmel_lcdc.h | 1055 | F: include/video/atmel_lcdc.h |
@@ -2113,7 +2135,7 @@ F: drivers/net/wan/dlci.c | |||
2113 | F: drivers/net/wan/sdla.c | 2135 | F: drivers/net/wan/sdla.c |
2114 | 2136 | ||
2115 | FRAMEBUFFER LAYER | 2137 | FRAMEBUFFER LAYER |
2116 | L: linux-fbdev-devel@lists.sourceforge.net (moderated for non-subscribers) | 2138 | L: linux-fbdev@vger.kernel.org |
2117 | W: http://linux-fbdev.sourceforge.net/ | 2139 | W: http://linux-fbdev.sourceforge.net/ |
2118 | S: Orphan | 2140 | S: Orphan |
2119 | F: Documentation/fb/ | 2141 | F: Documentation/fb/ |
@@ -2136,7 +2158,7 @@ F: drivers/i2c/busses/i2c-cpm.c | |||
2136 | 2158 | ||
2137 | FREESCALE IMX / MXC FRAMEBUFFER DRIVER | 2159 | FREESCALE IMX / MXC FRAMEBUFFER DRIVER |
2138 | M: Sascha Hauer <kernel@pengutronix.de> | 2160 | M: Sascha Hauer <kernel@pengutronix.de> |
2139 | L: linux-fbdev-devel@lists.sourceforge.net (moderated for non-subscribers) | 2161 | L: linux-fbdev@vger.kernel.org |
2140 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) | 2162 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) |
2141 | S: Maintained | 2163 | S: Maintained |
2142 | F: arch/arm/plat-mxc/include/mach/imxfb.h | 2164 | F: arch/arm/plat-mxc/include/mach/imxfb.h |
@@ -2312,6 +2334,13 @@ T: git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6.git | |||
2312 | S: Maintained | 2334 | S: Maintained |
2313 | F: drivers/media/video/gspca/finepix.c | 2335 | F: drivers/media/video/gspca/finepix.c |
2314 | 2336 | ||
2337 | GSPCA GL860 SUBDRIVER | ||
2338 | M: Olivier Lorin <o.lorin@laposte.net> | ||
2339 | L: linux-media@vger.kernel.org | ||
2340 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6.git | ||
2341 | S: Maintained | ||
2342 | F: drivers/media/video/gspca/gl860/ | ||
2343 | |||
2315 | GSPCA M5602 SUBDRIVER | 2344 | GSPCA M5602 SUBDRIVER |
2316 | M: Erik Andren <erik.andren@gmail.com> | 2345 | M: Erik Andren <erik.andren@gmail.com> |
2317 | L: linux-media@vger.kernel.org | 2346 | L: linux-media@vger.kernel.org |
@@ -2533,8 +2562,7 @@ S: Maintained | |||
2533 | F: Documentation/i2c/ | 2562 | F: Documentation/i2c/ |
2534 | F: drivers/i2c/ | 2563 | F: drivers/i2c/ |
2535 | F: include/linux/i2c.h | 2564 | F: include/linux/i2c.h |
2536 | F: include/linux/i2c-dev.h | 2565 | F: include/linux/i2c-*.h |
2537 | F: include/linux/i2c-id.h | ||
2538 | 2566 | ||
2539 | I2C-TINY-USB DRIVER | 2567 | I2C-TINY-USB DRIVER |
2540 | M: Till Harbaum <till@harbaum.org> | 2568 | M: Till Harbaum <till@harbaum.org> |
@@ -2635,7 +2663,7 @@ S: Supported | |||
2635 | F: security/integrity/ima/ | 2663 | F: security/integrity/ima/ |
2636 | 2664 | ||
2637 | IMS TWINTURBO FRAMEBUFFER DRIVER | 2665 | IMS TWINTURBO FRAMEBUFFER DRIVER |
2638 | L: linux-fbdev-devel@lists.sourceforge.net (moderated for non-subscribers) | 2666 | L: linux-fbdev@vger.kernel.org |
2639 | S: Orphan | 2667 | S: Orphan |
2640 | F: drivers/video/imsttfb.c | 2668 | F: drivers/video/imsttfb.c |
2641 | 2669 | ||
@@ -2670,14 +2698,14 @@ F: drivers/input/ | |||
2670 | 2698 | ||
2671 | INTEL FRAMEBUFFER DRIVER (excluding 810 and 815) | 2699 | INTEL FRAMEBUFFER DRIVER (excluding 810 and 815) |
2672 | M: Sylvain Meyer <sylvain.meyer@worldonline.fr> | 2700 | M: Sylvain Meyer <sylvain.meyer@worldonline.fr> |
2673 | L: linux-fbdev-devel@lists.sourceforge.net (moderated for non-subscribers) | 2701 | L: linux-fbdev@vger.kernel.org |
2674 | S: Maintained | 2702 | S: Maintained |
2675 | F: Documentation/fb/intelfb.txt | 2703 | F: Documentation/fb/intelfb.txt |
2676 | F: drivers/video/intelfb/ | 2704 | F: drivers/video/intelfb/ |
2677 | 2705 | ||
2678 | INTEL 810/815 FRAMEBUFFER DRIVER | 2706 | INTEL 810/815 FRAMEBUFFER DRIVER |
2679 | M: Antonino Daplas <adaplas@gmail.com> | 2707 | M: Antonino Daplas <adaplas@gmail.com> |
2680 | L: linux-fbdev-devel@lists.sourceforge.net (moderated for non-subscribers) | 2708 | L: linux-fbdev@vger.kernel.org |
2681 | S: Maintained | 2709 | S: Maintained |
2682 | F: drivers/video/i810/ | 2710 | F: drivers/video/i810/ |
2683 | 2711 | ||
@@ -3084,9 +3112,13 @@ F: kernel/kgdb.c | |||
3084 | 3112 | ||
3085 | KMEMCHECK | 3113 | KMEMCHECK |
3086 | M: Vegard Nossum <vegardno@ifi.uio.no> | 3114 | M: Vegard Nossum <vegardno@ifi.uio.no> |
3087 | P Pekka Enberg | 3115 | M: Pekka Enberg <penberg@cs.helsinki.fi> |
3088 | M: penberg@cs.helsinki.fi | ||
3089 | S: Maintained | 3116 | S: Maintained |
3117 | F: Documentation/kmemcheck.txt | ||
3118 | F: arch/x86/include/asm/kmemcheck.h | ||
3119 | F: arch/x86/mm/kmemcheck/ | ||
3120 | F: include/linux/kmemcheck.h | ||
3121 | F: mm/kmemcheck.c | ||
3090 | 3122 | ||
3091 | KMEMLEAK | 3123 | KMEMLEAK |
3092 | M: Catalin Marinas <catalin.marinas@arm.com> | 3124 | M: Catalin Marinas <catalin.marinas@arm.com> |
@@ -3387,7 +3419,7 @@ S: Supported | |||
3387 | 3419 | ||
3388 | MATROX FRAMEBUFFER DRIVER | 3420 | MATROX FRAMEBUFFER DRIVER |
3389 | M: Petr Vandrovec <vandrove@vc.cvut.cz> | 3421 | M: Petr Vandrovec <vandrove@vc.cvut.cz> |
3390 | L: linux-fbdev-devel@lists.sourceforge.net (moderated for non-subscribers) | 3422 | L: linux-fbdev@vger.kernel.org |
3391 | S: Maintained | 3423 | S: Maintained |
3392 | F: drivers/video/matrox/matroxfb_* | 3424 | F: drivers/video/matrox/matroxfb_* |
3393 | F: include/linux/matroxfb.h | 3425 | F: include/linux/matroxfb.h |
@@ -3774,7 +3806,7 @@ F: fs/ntfs/ | |||
3774 | 3806 | ||
3775 | NVIDIA (rivafb and nvidiafb) FRAMEBUFFER DRIVER | 3807 | NVIDIA (rivafb and nvidiafb) FRAMEBUFFER DRIVER |
3776 | M: Antonino Daplas <adaplas@gmail.com> | 3808 | M: Antonino Daplas <adaplas@gmail.com> |
3777 | L: linux-fbdev-devel@lists.sourceforge.net (moderated for non-subscribers) | 3809 | L: linux-fbdev@vger.kernel.org |
3778 | S: Maintained | 3810 | S: Maintained |
3779 | F: drivers/video/riva/ | 3811 | F: drivers/video/riva/ |
3780 | F: drivers/video/nvidia/ | 3812 | F: drivers/video/nvidia/ |
@@ -3809,7 +3841,7 @@ F: sound/soc/omap/ | |||
3809 | 3841 | ||
3810 | OMAP FRAMEBUFFER SUPPORT | 3842 | OMAP FRAMEBUFFER SUPPORT |
3811 | M: Imre Deak <imre.deak@nokia.com> | 3843 | M: Imre Deak <imre.deak@nokia.com> |
3812 | L: linux-fbdev-devel@lists.sourceforge.net (moderated for non-subscribers) | 3844 | L: linux-fbdev@vger.kernel.org |
3813 | L: linux-omap@vger.kernel.org | 3845 | L: linux-omap@vger.kernel.org |
3814 | S: Maintained | 3846 | S: Maintained |
3815 | F: drivers/video/omap/ | 3847 | F: drivers/video/omap/ |
@@ -4315,19 +4347,21 @@ F: include/linux/qnxtypes.h | |||
4315 | 4347 | ||
4316 | RADEON FRAMEBUFFER DISPLAY DRIVER | 4348 | RADEON FRAMEBUFFER DISPLAY DRIVER |
4317 | M: Benjamin Herrenschmidt <benh@kernel.crashing.org> | 4349 | M: Benjamin Herrenschmidt <benh@kernel.crashing.org> |
4318 | L: linux-fbdev-devel@lists.sourceforge.net (moderated for non-subscribers) | 4350 | L: linux-fbdev@vger.kernel.org |
4319 | S: Maintained | 4351 | S: Maintained |
4320 | F: drivers/video/aty/radeon* | 4352 | F: drivers/video/aty/radeon* |
4321 | F: include/linux/radeonfb.h | 4353 | F: include/linux/radeonfb.h |
4322 | 4354 | ||
4323 | RAGE128 FRAMEBUFFER DISPLAY DRIVER | 4355 | RAGE128 FRAMEBUFFER DISPLAY DRIVER |
4324 | M: Paul Mackerras <paulus@samba.org> | 4356 | M: Paul Mackerras <paulus@samba.org> |
4325 | L: linux-fbdev-devel@lists.sourceforge.net (moderated for non-subscribers) | 4357 | L: linux-fbdev@vger.kernel.org |
4326 | S: Maintained | 4358 | S: Maintained |
4327 | F: drivers/video/aty/aty128fb.c | 4359 | F: drivers/video/aty/aty128fb.c |
4328 | 4360 | ||
4329 | RALINK RT2X00 WIRELESS LAN DRIVER | 4361 | RALINK RT2X00 WIRELESS LAN DRIVER |
4330 | P: rt2x00 project | 4362 | P: rt2x00 project |
4363 | M: Ivo van Doorn <IvDoorn@gmail.com> | ||
4364 | M: Gertjan van Wingerde <gwingerde@gmail.com> | ||
4331 | L: linux-wireless@vger.kernel.org | 4365 | L: linux-wireless@vger.kernel.org |
4332 | L: users@rt2x00.serialmonkey.com (moderated for non-subscribers) | 4366 | L: users@rt2x00.serialmonkey.com (moderated for non-subscribers) |
4333 | W: http://rt2x00.serialmonkey.com/ | 4367 | W: http://rt2x00.serialmonkey.com/ |
@@ -4415,7 +4449,7 @@ RFKILL | |||
4415 | M: Johannes Berg <johannes@sipsolutions.net> | 4449 | M: Johannes Berg <johannes@sipsolutions.net> |
4416 | L: linux-wireless@vger.kernel.org | 4450 | L: linux-wireless@vger.kernel.org |
4417 | S: Maintained | 4451 | S: Maintained |
4418 | F Documentation/rfkill.txt | 4452 | F: Documentation/rfkill.txt |
4419 | F: net/rfkill/ | 4453 | F: net/rfkill/ |
4420 | 4454 | ||
4421 | RISCOM8 DRIVER | 4455 | RISCOM8 DRIVER |
@@ -4459,7 +4493,7 @@ F: drivers/net/wireless/rtl818x/rtl8187* | |||
4459 | 4493 | ||
4460 | S3 SAVAGE FRAMEBUFFER DRIVER | 4494 | S3 SAVAGE FRAMEBUFFER DRIVER |
4461 | M: Antonino Daplas <adaplas@gmail.com> | 4495 | M: Antonino Daplas <adaplas@gmail.com> |
4462 | L: linux-fbdev-devel@lists.sourceforge.net (moderated for non-subscribers) | 4496 | L: linux-fbdev@vger.kernel.org |
4463 | S: Maintained | 4497 | S: Maintained |
4464 | F: drivers/video/savage/ | 4498 | F: drivers/video/savage/ |
4465 | 4499 | ||
@@ -5622,7 +5656,7 @@ S: Maintained | |||
5622 | 5656 | ||
5623 | UVESAFB DRIVER | 5657 | UVESAFB DRIVER |
5624 | M: Michal Januszewski <spock@gentoo.org> | 5658 | M: Michal Januszewski <spock@gentoo.org> |
5625 | L: linux-fbdev-devel@lists.sourceforge.net (moderated for non-subscribers) | 5659 | L: linux-fbdev@vger.kernel.org |
5626 | W: http://dev.gentoo.org/~spock/projects/uvesafb/ | 5660 | W: http://dev.gentoo.org/~spock/projects/uvesafb/ |
5627 | S: Maintained | 5661 | S: Maintained |
5628 | F: Documentation/fb/uvesafb.txt | 5662 | F: Documentation/fb/uvesafb.txt |
@@ -5655,7 +5689,7 @@ F: drivers/mmc/host/via-sdmmc.c | |||
5655 | VIA UNICHROME(PRO)/CHROME9 FRAMEBUFFER DRIVER | 5689 | VIA UNICHROME(PRO)/CHROME9 FRAMEBUFFER DRIVER |
5656 | M: Joseph Chan <JosephChan@via.com.tw> | 5690 | M: Joseph Chan <JosephChan@via.com.tw> |
5657 | M: Scott Fang <ScottFang@viatech.com.cn> | 5691 | M: Scott Fang <ScottFang@viatech.com.cn> |
5658 | L: linux-fbdev-devel@lists.sourceforge.net (moderated for non-subscribers) | 5692 | L: linux-fbdev@vger.kernel.org |
5659 | S: Maintained | 5693 | S: Maintained |
5660 | F: drivers/video/via/ | 5694 | F: drivers/video/via/ |
5661 | 5695 | ||
@@ -1,7 +1,7 @@ | |||
1 | VERSION = 2 | 1 | VERSION = 2 |
2 | PATCHLEVEL = 6 | 2 | PATCHLEVEL = 6 |
3 | SUBLEVEL = 32 | 3 | SUBLEVEL = 32 |
4 | EXTRAVERSION = -rc7 | 4 | EXTRAVERSION = -rc8 |
5 | NAME = Man-Eating Seals of Antiquity | 5 | NAME = Man-Eating Seals of Antiquity |
6 | 6 | ||
7 | # *DOCUMENTATION* | 7 | # *DOCUMENTATION* |
diff --git a/arch/arm/include/asm/kmap_types.h b/arch/arm/include/asm/kmap_types.h index d16ec97ec9a9..c019949a5189 100644 --- a/arch/arm/include/asm/kmap_types.h +++ b/arch/arm/include/asm/kmap_types.h | |||
@@ -22,4 +22,10 @@ enum km_type { | |||
22 | KM_TYPE_NR | 22 | KM_TYPE_NR |
23 | }; | 23 | }; |
24 | 24 | ||
25 | #ifdef CONFIG_DEBUG_HIGHMEM | ||
26 | #define KM_NMI (-1) | ||
27 | #define KM_NMI_PTE (-1) | ||
28 | #define KM_IRQ_PTE (-1) | ||
29 | #endif | ||
30 | |||
25 | #endif | 31 | #endif |
diff --git a/arch/arm/kernel/signal.c b/arch/arm/kernel/signal.c index 2a573d4fea24..e7714f367eb8 100644 --- a/arch/arm/kernel/signal.c +++ b/arch/arm/kernel/signal.c | |||
@@ -662,8 +662,12 @@ static void do_signal(struct pt_regs *regs, int syscall) | |||
662 | regs->ARM_sp -= 4; | 662 | regs->ARM_sp -= 4; |
663 | usp = (u32 __user *)regs->ARM_sp; | 663 | usp = (u32 __user *)regs->ARM_sp; |
664 | 664 | ||
665 | put_user(regs->ARM_pc, usp); | 665 | if (put_user(regs->ARM_pc, usp) == 0) { |
666 | regs->ARM_pc = KERN_RESTART_CODE; | 666 | regs->ARM_pc = KERN_RESTART_CODE; |
667 | } else { | ||
668 | regs->ARM_sp += 4; | ||
669 | force_sigsegv(0, current); | ||
670 | } | ||
667 | #endif | 671 | #endif |
668 | } | 672 | } |
669 | } | 673 | } |
diff --git a/arch/arm/mach-omap2/board-zoom2.c b/arch/arm/mach-omap2/board-zoom2.c index ea00486a5e53..51e0b3ba5f3a 100644 --- a/arch/arm/mach-omap2/board-zoom2.c +++ b/arch/arm/mach-omap2/board-zoom2.c | |||
@@ -30,57 +30,56 @@ | |||
30 | /* Zoom2 has Qwerty keyboard*/ | 30 | /* Zoom2 has Qwerty keyboard*/ |
31 | static int board_keymap[] = { | 31 | static int board_keymap[] = { |
32 | KEY(0, 0, KEY_E), | 32 | KEY(0, 0, KEY_E), |
33 | KEY(1, 0, KEY_R), | 33 | KEY(0, 1, KEY_R), |
34 | KEY(2, 0, KEY_T), | 34 | KEY(0, 2, KEY_T), |
35 | KEY(3, 0, KEY_HOME), | 35 | KEY(0, 3, KEY_HOME), |
36 | KEY(6, 0, KEY_I), | 36 | KEY(0, 6, KEY_I), |
37 | KEY(7, 0, KEY_LEFTSHIFT), | 37 | KEY(0, 7, KEY_LEFTSHIFT), |
38 | KEY(0, 1, KEY_D), | 38 | KEY(1, 0, KEY_D), |
39 | KEY(1, 1, KEY_F), | 39 | KEY(1, 1, KEY_F), |
40 | KEY(2, 1, KEY_G), | 40 | KEY(1, 2, KEY_G), |
41 | KEY(3, 1, KEY_SEND), | 41 | KEY(1, 3, KEY_SEND), |
42 | KEY(6, 1, KEY_K), | 42 | KEY(1, 6, KEY_K), |
43 | KEY(7, 1, KEY_ENTER), | 43 | KEY(1, 7, KEY_ENTER), |
44 | KEY(0, 2, KEY_X), | 44 | KEY(2, 0, KEY_X), |
45 | KEY(1, 2, KEY_C), | 45 | KEY(2, 1, KEY_C), |
46 | KEY(2, 2, KEY_V), | 46 | KEY(2, 2, KEY_V), |
47 | KEY(3, 2, KEY_END), | 47 | KEY(2, 3, KEY_END), |
48 | KEY(6, 2, KEY_DOT), | 48 | KEY(2, 6, KEY_DOT), |
49 | KEY(7, 2, KEY_CAPSLOCK), | 49 | KEY(2, 7, KEY_CAPSLOCK), |
50 | KEY(0, 3, KEY_Z), | 50 | KEY(3, 0, KEY_Z), |
51 | KEY(1, 3, KEY_KPPLUS), | 51 | KEY(3, 1, KEY_KPPLUS), |
52 | KEY(2, 3, KEY_B), | 52 | KEY(3, 2, KEY_B), |
53 | KEY(3, 3, KEY_F1), | 53 | KEY(3, 3, KEY_F1), |
54 | KEY(6, 3, KEY_O), | 54 | KEY(3, 6, KEY_O), |
55 | KEY(7, 3, KEY_SPACE), | 55 | KEY(3, 7, KEY_SPACE), |
56 | KEY(0, 4, KEY_W), | 56 | KEY(4, 0, KEY_W), |
57 | KEY(1, 4, KEY_Y), | 57 | KEY(4, 1, KEY_Y), |
58 | KEY(2, 4, KEY_U), | 58 | KEY(4, 2, KEY_U), |
59 | KEY(3, 4, KEY_F2), | 59 | KEY(4, 3, KEY_F2), |
60 | KEY(4, 4, KEY_VOLUMEUP), | 60 | KEY(4, 4, KEY_VOLUMEUP), |
61 | KEY(6, 4, KEY_L), | 61 | KEY(4, 6, KEY_L), |
62 | KEY(7, 4, KEY_LEFT), | 62 | KEY(4, 7, KEY_LEFT), |
63 | KEY(0, 5, KEY_S), | 63 | KEY(5, 0, KEY_S), |
64 | KEY(1, 5, KEY_H), | 64 | KEY(5, 1, KEY_H), |
65 | KEY(2, 5, KEY_J), | 65 | KEY(5, 2, KEY_J), |
66 | KEY(3, 5, KEY_F3), | 66 | KEY(5, 3, KEY_F3), |
67 | KEY(5, 5, KEY_VOLUMEDOWN), | 67 | KEY(5, 5, KEY_VOLUMEDOWN), |
68 | KEY(6, 5, KEY_M), | 68 | KEY(5, 6, KEY_M), |
69 | KEY(4, 5, KEY_ENTER), | 69 | KEY(5, 7, KEY_ENTER), |
70 | KEY(7, 5, KEY_RIGHT), | 70 | KEY(6, 0, KEY_Q), |
71 | KEY(0, 6, KEY_Q), | 71 | KEY(6, 1, KEY_A), |
72 | KEY(1, 6, KEY_A), | 72 | KEY(6, 2, KEY_N), |
73 | KEY(2, 6, KEY_N), | 73 | KEY(6, 3, KEY_BACKSPACE), |
74 | KEY(3, 6, KEY_BACKSPACE), | ||
75 | KEY(6, 6, KEY_P), | 74 | KEY(6, 6, KEY_P), |
76 | KEY(7, 6, KEY_UP), | ||
77 | KEY(6, 7, KEY_SELECT), | 75 | KEY(6, 7, KEY_SELECT), |
78 | KEY(7, 7, KEY_DOWN), | 76 | KEY(7, 0, KEY_PROG1), /*MACRO 1 <User defined> */ |
79 | KEY(0, 7, KEY_PROG1), /*MACRO 1 <User defined> */ | 77 | KEY(7, 1, KEY_PROG2), /*MACRO 2 <User defined> */ |
80 | KEY(1, 7, KEY_PROG2), /*MACRO 2 <User defined> */ | 78 | KEY(7, 2, KEY_PROG3), /*MACRO 3 <User defined> */ |
81 | KEY(2, 7, KEY_PROG3), /*MACRO 3 <User defined> */ | 79 | KEY(7, 3, KEY_PROG4), /*MACRO 4 <User defined> */ |
82 | KEY(3, 7, KEY_PROG4), /*MACRO 4 <User defined> */ | 80 | KEY(7, 5, KEY_RIGHT), |
83 | 0 | 81 | KEY(7, 6, KEY_UP), |
82 | KEY(7, 7, KEY_DOWN) | ||
84 | }; | 83 | }; |
85 | 84 | ||
86 | static struct matrix_keymap_data board_map_data = { | 85 | static struct matrix_keymap_data board_map_data = { |
diff --git a/arch/arm/mach-omap2/clock34xx.c b/arch/arm/mach-omap2/clock34xx.c index 489556eecbd1..7c5c00df3c70 100644 --- a/arch/arm/mach-omap2/clock34xx.c +++ b/arch/arm/mach-omap2/clock34xx.c | |||
@@ -473,7 +473,7 @@ static u16 _omap3_dpll_compute_freqsel(struct clk *clk, u8 n) | |||
473 | unsigned long fint; | 473 | unsigned long fint; |
474 | u16 f = 0; | 474 | u16 f = 0; |
475 | 475 | ||
476 | fint = clk->dpll_data->clk_ref->rate / (n + 1); | 476 | fint = clk->dpll_data->clk_ref->rate / n; |
477 | 477 | ||
478 | pr_debug("clock: fint is %lu\n", fint); | 478 | pr_debug("clock: fint is %lu\n", fint); |
479 | 479 | ||
diff --git a/arch/arm/mach-omap2/clock34xx.h b/arch/arm/mach-omap2/clock34xx.h index c8119781e00a..9565c05bebd2 100644 --- a/arch/arm/mach-omap2/clock34xx.h +++ b/arch/arm/mach-omap2/clock34xx.h | |||
@@ -489,9 +489,9 @@ static struct clk core_ck = { | |||
489 | static struct clk dpll3_m2x2_ck = { | 489 | static struct clk dpll3_m2x2_ck = { |
490 | .name = "dpll3_m2x2_ck", | 490 | .name = "dpll3_m2x2_ck", |
491 | .ops = &clkops_null, | 491 | .ops = &clkops_null, |
492 | .parent = &dpll3_x2_ck, | 492 | .parent = &dpll3_m2_ck, |
493 | .clkdm_name = "dpll3_clkdm", | 493 | .clkdm_name = "dpll3_clkdm", |
494 | .recalc = &followparent_recalc, | 494 | .recalc = &omap3_clkoutx2_recalc, |
495 | }; | 495 | }; |
496 | 496 | ||
497 | /* The PWRDN bit is apparently only available on 3430ES2 and above */ | 497 | /* The PWRDN bit is apparently only available on 3430ES2 and above */ |
diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c index f8657568b1ba..f3c992e29651 100644 --- a/arch/arm/mach-omap2/gpmc.c +++ b/arch/arm/mach-omap2/gpmc.c | |||
@@ -378,7 +378,7 @@ EXPORT_SYMBOL(gpmc_cs_request); | |||
378 | void gpmc_cs_free(int cs) | 378 | void gpmc_cs_free(int cs) |
379 | { | 379 | { |
380 | spin_lock(&gpmc_mem_lock); | 380 | spin_lock(&gpmc_mem_lock); |
381 | if (cs >= GPMC_CS_NUM || !gpmc_cs_reserved(cs)) { | 381 | if (cs >= GPMC_CS_NUM || cs < 0 || !gpmc_cs_reserved(cs)) { |
382 | printk(KERN_ERR "Trying to free non-reserved GPMC CS%d\n", cs); | 382 | printk(KERN_ERR "Trying to free non-reserved GPMC CS%d\n", cs); |
383 | BUG(); | 383 | BUG(); |
384 | spin_unlock(&gpmc_mem_lock); | 384 | spin_unlock(&gpmc_mem_lock); |
diff --git a/arch/arm/mach-pxa/cpufreq-pxa2xx.c b/arch/arm/mach-pxa/cpufreq-pxa2xx.c index 983cc8c20081..9e4d9816726a 100644 --- a/arch/arm/mach-pxa/cpufreq-pxa2xx.c +++ b/arch/arm/mach-pxa/cpufreq-pxa2xx.c | |||
@@ -447,6 +447,7 @@ static __init int pxa_cpufreq_init(struct cpufreq_policy *policy) | |||
447 | pxa27x_freq_table[i].frequency = freq; | 447 | pxa27x_freq_table[i].frequency = freq; |
448 | pxa27x_freq_table[i].index = i; | 448 | pxa27x_freq_table[i].index = i; |
449 | } | 449 | } |
450 | pxa27x_freq_table[i].index = i; | ||
450 | pxa27x_freq_table[i].frequency = CPUFREQ_TABLE_END; | 451 | pxa27x_freq_table[i].frequency = CPUFREQ_TABLE_END; |
451 | 452 | ||
452 | /* | 453 | /* |
diff --git a/arch/arm/mach-pxa/cpufreq-pxa3xx.c b/arch/arm/mach-pxa/cpufreq-pxa3xx.c index 67f34a8d8e60..149cdd9aee4d 100644 --- a/arch/arm/mach-pxa/cpufreq-pxa3xx.c +++ b/arch/arm/mach-pxa/cpufreq-pxa3xx.c | |||
@@ -102,7 +102,7 @@ static int setup_freqs_table(struct cpufreq_policy *policy, | |||
102 | table[i].index = i; | 102 | table[i].index = i; |
103 | table[i].frequency = freqs[i].cpufreq_mhz * 1000; | 103 | table[i].frequency = freqs[i].cpufreq_mhz * 1000; |
104 | } | 104 | } |
105 | table[num].frequency = i; | 105 | table[num].index = i; |
106 | table[num].frequency = CPUFREQ_TABLE_END; | 106 | table[num].frequency = CPUFREQ_TABLE_END; |
107 | 107 | ||
108 | pxa3xx_freqs = freqs; | 108 | pxa3xx_freqs = freqs; |
diff --git a/arch/arm/mach-pxa/spitz.c b/arch/arm/mach-pxa/spitz.c index 3da45d051743..d98023f55503 100644 --- a/arch/arm/mach-pxa/spitz.c +++ b/arch/arm/mach-pxa/spitz.c | |||
@@ -802,10 +802,12 @@ static void __init spitz_init(void) | |||
802 | { | 802 | { |
803 | spitz_ficp_platform_data.gpio_pwdown = SPITZ_GPIO_IR_ON; | 803 | spitz_ficp_platform_data.gpio_pwdown = SPITZ_GPIO_IR_ON; |
804 | 804 | ||
805 | #ifdef CONFIG_MACH_BORZOI | ||
805 | if (machine_is_borzoi()) { | 806 | if (machine_is_borzoi()) { |
806 | sharpsl_nand_platform_data.badblock_pattern = &sharpsl_akita_bbt; | 807 | sharpsl_nand_platform_data.badblock_pattern = &sharpsl_akita_bbt; |
807 | sharpsl_nand_platform_data.ecc_layout = &akita_oobinfo; | 808 | sharpsl_nand_platform_data.ecc_layout = &akita_oobinfo; |
808 | } | 809 | } |
810 | #endif | ||
809 | 811 | ||
810 | platform_scoop_config = &spitz_pcmcia_config; | 812 | platform_scoop_config = &spitz_pcmcia_config; |
811 | 813 | ||
diff --git a/arch/arm/plat-omap/gpio.c b/arch/arm/plat-omap/gpio.c index 71ebd7fcfea1..7c345b757df1 100644 --- a/arch/arm/plat-omap/gpio.c +++ b/arch/arm/plat-omap/gpio.c | |||
@@ -373,7 +373,7 @@ static inline int gpio_valid(int gpio) | |||
373 | 373 | ||
374 | static int check_gpio(int gpio) | 374 | static int check_gpio(int gpio) |
375 | { | 375 | { |
376 | if (unlikely(gpio_valid(gpio)) < 0) { | 376 | if (unlikely(gpio_valid(gpio) < 0)) { |
377 | printk(KERN_ERR "omap-gpio: invalid GPIO %d\n", gpio); | 377 | printk(KERN_ERR "omap-gpio: invalid GPIO %d\n", gpio); |
378 | dump_stack(); | 378 | dump_stack(); |
379 | return -1; | 379 | return -1; |
diff --git a/arch/arm/tools/mach-types b/arch/arm/tools/mach-types index 94be7bb6cb9a..07b976da6174 100644 --- a/arch/arm/tools/mach-types +++ b/arch/arm/tools/mach-types | |||
@@ -12,7 +12,7 @@ | |||
12 | # | 12 | # |
13 | # http://www.arm.linux.org.uk/developer/machines/?action=new | 13 | # http://www.arm.linux.org.uk/developer/machines/?action=new |
14 | # | 14 | # |
15 | # Last update: Fri Sep 18 21:42:00 2009 | 15 | # Last update: Wed Nov 25 22:14:58 2009 |
16 | # | 16 | # |
17 | # machine_is_xxx CONFIG_xxxx MACH_TYPE_xxx number | 17 | # machine_is_xxx CONFIG_xxxx MACH_TYPE_xxx number |
18 | # | 18 | # |
@@ -928,7 +928,7 @@ palmt5 MACH_PALMT5 PALMT5 917 | |||
928 | palmtc MACH_PALMTC PALMTC 918 | 928 | palmtc MACH_PALMTC PALMTC 918 |
929 | omap_apollon MACH_OMAP_APOLLON OMAP_APOLLON 919 | 929 | omap_apollon MACH_OMAP_APOLLON OMAP_APOLLON 919 |
930 | mxc30030evb MACH_MXC30030EVB MXC30030EVB 920 | 930 | mxc30030evb MACH_MXC30030EVB MXC30030EVB 920 |
931 | rea_2d MACH_REA_2D REA_2D 921 | 931 | rea_cpu2 MACH_REA_2D REA_2D 921 |
932 | eti3e524 MACH_TI3E524 TI3E524 922 | 932 | eti3e524 MACH_TI3E524 TI3E524 922 |
933 | ateb9200 MACH_ATEB9200 ATEB9200 923 | 933 | ateb9200 MACH_ATEB9200 ATEB9200 923 |
934 | auckland MACH_AUCKLAND AUCKLAND 924 | 934 | auckland MACH_AUCKLAND AUCKLAND 924 |
@@ -2421,3 +2421,118 @@ liberty MACH_LIBERTY LIBERTY 2434 | |||
2421 | mh355 MACH_MH355 MH355 2435 | 2421 | mh355 MACH_MH355 MH355 2435 |
2422 | pc7802 MACH_PC7802 PC7802 2436 | 2422 | pc7802 MACH_PC7802 PC7802 2436 |
2423 | gnet_sgc MACH_GNET_SGC GNET_SGC 2437 | 2423 | gnet_sgc MACH_GNET_SGC GNET_SGC 2437 |
2424 | einstein15 MACH_EINSTEIN15 EINSTEIN15 2438 | ||
2425 | cmpd MACH_CMPD CMPD 2439 | ||
2426 | davinci_hase1 MACH_DAVINCI_HASE1 DAVINCI_HASE1 2440 | ||
2427 | lgeincitephone MACH_LGEINCITEPHONE LGEINCITEPHONE 2441 | ||
2428 | ea313x MACH_EA313X EA313X 2442 | ||
2429 | fwbd_39064 MACH_FWBD_39064 FWBD_39064 2443 | ||
2430 | fwbd_390128 MACH_FWBD_390128 FWBD_390128 2444 | ||
2431 | pelco_moe MACH_PELCO_MOE PELCO_MOE 2445 | ||
2432 | minimix27 MACH_MINIMIX27 MINIMIX27 2446 | ||
2433 | omap3_thunder MACH_OMAP3_THUNDER OMAP3_THUNDER 2447 | ||
2434 | passionc MACH_PASSIONC PASSIONC 2448 | ||
2435 | mx27amata MACH_MX27AMATA MX27AMATA 2449 | ||
2436 | bgat1 MACH_BGAT1 BGAT1 2450 | ||
2437 | buzz MACH_BUZZ BUZZ 2451 | ||
2438 | mb9g20 MACH_MB9G20 MB9G20 2452 | ||
2439 | yushan MACH_YUSHAN YUSHAN 2453 | ||
2440 | lizard MACH_LIZARD LIZARD 2454 | ||
2441 | omap3polycom MACH_OMAP3POLYCOM OMAP3POLYCOM 2455 | ||
2442 | smdkv210 MACH_SMDKV210 SMDKV210 2456 | ||
2443 | bravo MACH_BRAVO BRAVO 2457 | ||
2444 | siogentoo1 MACH_SIOGENTOO1 SIOGENTOO1 2458 | ||
2445 | siogentoo2 MACH_SIOGENTOO2 SIOGENTOO2 2459 | ||
2446 | sm3k MACH_SM3K SM3K 2460 | ||
2447 | acer_tempo_f900 MACH_ACER_TEMPO_F900 ACER_TEMPO_F900 2461 | ||
2448 | sst61vc010_dev MACH_SST61VC010_DEV SST61VC010_DEV 2462 | ||
2449 | glittertind MACH_GLITTERTIND GLITTERTIND 2463 | ||
2450 | omap_zoom3 MACH_OMAP_ZOOM3 OMAP_ZOOM3 2464 | ||
2451 | omap_3630sdp MACH_OMAP_3630SDP OMAP_3630SDP 2465 | ||
2452 | cybook2440 MACH_CYBOOK2440 CYBOOK2440 2466 | ||
2453 | torino_s MACH_TORINO_S TORINO_S 2467 | ||
2454 | havana MACH_HAVANA HAVANA 2468 | ||
2455 | beaumont_11 MACH_BEAUMONT_11 BEAUMONT_11 2469 | ||
2456 | vanguard MACH_VANGUARD VANGUARD 2470 | ||
2457 | s5pc110_draco MACH_S5PC110_DRACO S5PC110_DRACO 2471 | ||
2458 | cartesio_two MACH_CARTESIO_TWO CARTESIO_TWO 2472 | ||
2459 | aster MACH_ASTER ASTER 2473 | ||
2460 | voguesv210 MACH_VOGUESV210 VOGUESV210 2474 | ||
2461 | acm500x MACH_ACM500X ACM500X 2475 | ||
2462 | km9260 MACH_KM9260 KM9260 2476 | ||
2463 | nideflexg1 MACH_NIDEFLEXG1 NIDEFLEXG1 2477 | ||
2464 | ctera_plug_io MACH_CTERA_PLUG_IO CTERA_PLUG_IO 2478 | ||
2465 | smartq7 MACH_SMARTQ7 SMARTQ7 2479 | ||
2466 | at91sam9g10ek2 MACH_AT91SAM9G10EK2 AT91SAM9G10EK2 2480 | ||
2467 | asusp527 MACH_ASUSP527 ASUSP527 2481 | ||
2468 | at91sam9g20mpm2 MACH_AT91SAM9G20MPM2 AT91SAM9G20MPM2 2482 | ||
2469 | topasa900 MACH_TOPASA900 TOPASA900 2483 | ||
2470 | electrum_100 MACH_ELECTRUM_100 ELECTRUM_100 2484 | ||
2471 | mx51grb MACH_MX51GRB MX51GRB 2485 | ||
2472 | xea300 MACH_XEA300 XEA300 2486 | ||
2473 | htcstartrek MACH_HTCSTARTREK HTCSTARTREK 2487 | ||
2474 | lima MACH_LIMA LIMA 2488 | ||
2475 | csb740 MACH_CSB740 CSB740 2489 | ||
2476 | usb_s8815 MACH_USB_S8815 USB_S8815 2490 | ||
2477 | watson_efm_plugin MACH_WATSON_EFM_PLUGIN WATSON_EFM_PLUGIN 2491 | ||
2478 | milkyway MACH_MILKYWAY MILKYWAY 2492 | ||
2479 | g4evm MACH_G4EVM G4EVM 2493 | ||
2480 | picomod6 MACH_PICOMOD6 PICOMOD6 2494 | ||
2481 | omapl138_hawkboard MACH_OMAPL138_HAWKBOARD OMAPL138_HAWKBOARD 2495 | ||
2482 | ip6000 MACH_IP6000 IP6000 2496 | ||
2483 | ip6010 MACH_IP6010 IP6010 2497 | ||
2484 | utm400 MACH_UTM400 UTM400 2498 | ||
2485 | omap3_zybex MACH_OMAP3_ZYBEX OMAP3_ZYBEX 2499 | ||
2486 | wireless_space MACH_WIRELESS_SPACE WIRELESS_SPACE 2500 | ||
2487 | sx560 MACH_SX560 SX560 2501 | ||
2488 | ts41x MACH_TS41X TS41X 2502 | ||
2489 | elphel10373 MACH_ELPHEL10373 ELPHEL10373 2503 | ||
2490 | rhobot MACH_RHOBOT RHOBOT 2504 | ||
2491 | mx51_refresh MACH_MX51_REFRESH MX51_REFRESH 2505 | ||
2492 | ls9260 MACH_LS9260 LS9260 2506 | ||
2493 | shank MACH_SHANK SHANK 2507 | ||
2494 | qsd8x50_st1 MACH_QSD8X50_ST1 QSD8X50_ST1 2508 | ||
2495 | at91sam9m10ekes MACH_AT91SAM9M10EKES AT91SAM9M10EKES 2509 | ||
2496 | hiram MACH_HIRAM HIRAM 2510 | ||
2497 | phy3250 MACH_PHY3250 PHY3250 2511 | ||
2498 | ea3250 MACH_EA3250 EA3250 2512 | ||
2499 | fdi3250 MACH_FDI3250 FDI3250 2513 | ||
2500 | whitestone MACH_WHITESTONE WHITESTONE 2514 | ||
2501 | at91sam9263nit MACH_AT91SAM9263NIT AT91SAM9263NIT 2515 | ||
2502 | ccmx51 MACH_CCMX51 CCMX51 2516 | ||
2503 | ccmx51js MACH_CCMX51JS CCMX51JS 2517 | ||
2504 | ccwmx51 MACH_CCWMX51 CCWMX51 2518 | ||
2505 | ccwmx51js MACH_CCWMX51JS CCWMX51JS 2519 | ||
2506 | mini6410 MACH_MINI6410 MINI6410 2520 | ||
2507 | tiny6410 MACH_TINY6410 TINY6410 2521 | ||
2508 | nano6410 MACH_NANO6410 NANO6410 2522 | ||
2509 | at572d940hfnldb MACH_AT572D940HFNLDB AT572D940HFNLDB 2523 | ||
2510 | htcleo MACH_HTCLEO HTCLEO 2524 | ||
2511 | avp13 MACH_AVP13 AVP13 2525 | ||
2512 | xxsvideod MACH_XXSVIDEOD XXSVIDEOD 2526 | ||
2513 | vpnext MACH_VPNEXT VPNEXT 2527 | ||
2514 | swarco_itc3 MACH_SWARCO_ITC3 SWARCO_ITC3 2528 | ||
2515 | tx51 MACH_TX51 TX51 2529 | ||
2516 | dolby_cat1021 MACH_DOLBY_CAT1021 DOLBY_CAT1021 2530 | ||
2517 | mx28evk MACH_MX28EVK MX28EVK 2531 | ||
2518 | phoenix260 MACH_PHOENIX260 PHOENIX260 2532 | ||
2519 | uvaca_stork MACH_UVACA_STORK UVACA_STORK 2533 | ||
2520 | smartq5 MACH_SMARTQ5 SMARTQ5 2534 | ||
2521 | all3078 MACH_ALL3078 ALL3078 2535 | ||
2522 | ctera_2bay_ds MACH_CTERA_2BAY_DS CTERA_2BAY_DS 2536 | ||
2523 | siogentoo3 MACH_SIOGENTOO3 SIOGENTOO3 2537 | ||
2524 | epb5000 MACH_EPB5000 EPB5000 2538 | ||
2525 | hy9263 MACH_HY9263 HY9263 2539 | ||
2526 | acer_tempo_m900 MACH_ACER_TEMPO_M900 ACER_TEMPO_M900 2540 | ||
2527 | acer_tempo_dx650 MACH_ACER_TEMPO_DX900 ACER_TEMPO_DX900 2541 | ||
2528 | acer_tempo_x960 MACH_ACER_TEMPO_X960 ACER_TEMPO_X960 2542 | ||
2529 | acer_eten_v900 MACH_ACER_ETEN_V900 ACER_ETEN_V900 2543 | ||
2530 | acer_eten_x900 MACH_ACER_ETEN_X900 ACER_ETEN_X900 2544 | ||
2531 | bonnell MACH_BONNELL BONNELL 2545 | ||
2532 | oht_mx27 MACH_OHT_MX27 OHT_MX27 2546 | ||
2533 | htcquartz MACH_HTCQUARTZ HTCQUARTZ 2547 | ||
2534 | davinci_dm6467tevm MACH_DAVINCI_DM6467TEVM DAVINCI_DM6467TEVM 2548 | ||
2535 | c3ax03 MACH_C3AX03 C3AX03 2549 | ||
2536 | mxt_td60 MACH_MXT_TD60 MXT_TD60 2550 | ||
2537 | esyx MACH_ESYX ESYX 2551 | ||
2538 | bulldog MACH_BULLDOG BULLDOG 2553 | ||
diff --git a/arch/parisc/kernel/unwind.c b/arch/parisc/kernel/unwind.c index 69dad5a850a8..a36799e85693 100644 --- a/arch/parisc/kernel/unwind.c +++ b/arch/parisc/kernel/unwind.c | |||
@@ -28,7 +28,7 @@ | |||
28 | #define dbg(x...) | 28 | #define dbg(x...) |
29 | #endif | 29 | #endif |
30 | 30 | ||
31 | #define KERNEL_START (KERNEL_BINARY_TEXT_START - 0x1000) | 31 | #define KERNEL_START (KERNEL_BINARY_TEXT_START) |
32 | 32 | ||
33 | extern struct unwind_table_entry __start___unwind[]; | 33 | extern struct unwind_table_entry __start___unwind[]; |
34 | extern struct unwind_table_entry __stop___unwind[]; | 34 | extern struct unwind_table_entry __stop___unwind[]; |
diff --git a/arch/parisc/kernel/vmlinux.lds.S b/arch/parisc/kernel/vmlinux.lds.S index fda4baa059b5..9dab4a4e09f7 100644 --- a/arch/parisc/kernel/vmlinux.lds.S +++ b/arch/parisc/kernel/vmlinux.lds.S | |||
@@ -78,9 +78,6 @@ SECTIONS | |||
78 | */ | 78 | */ |
79 | . = ALIGN(PAGE_SIZE); | 79 | . = ALIGN(PAGE_SIZE); |
80 | data_start = .; | 80 | data_start = .; |
81 | EXCEPTION_TABLE(16) | ||
82 | |||
83 | NOTES | ||
84 | 81 | ||
85 | /* unwind info */ | 82 | /* unwind info */ |
86 | .PARISC.unwind : { | 83 | .PARISC.unwind : { |
@@ -89,6 +86,9 @@ SECTIONS | |||
89 | __stop___unwind = .; | 86 | __stop___unwind = .; |
90 | } | 87 | } |
91 | 88 | ||
89 | EXCEPTION_TABLE(16) | ||
90 | NOTES | ||
91 | |||
92 | /* Data */ | 92 | /* Data */ |
93 | RW_DATA_SECTION(L1_CACHE_BYTES, PAGE_SIZE, THREAD_SIZE) | 93 | RW_DATA_SECTION(L1_CACHE_BYTES, PAGE_SIZE, THREAD_SIZE) |
94 | 94 | ||
diff --git a/arch/powerpc/include/asm/kmap_types.h b/arch/powerpc/include/asm/kmap_types.h index b6bac6f61c16..916369575c97 100644 --- a/arch/powerpc/include/asm/kmap_types.h +++ b/arch/powerpc/include/asm/kmap_types.h | |||
@@ -29,5 +29,16 @@ enum km_type { | |||
29 | KM_TYPE_NR | 29 | KM_TYPE_NR |
30 | }; | 30 | }; |
31 | 31 | ||
32 | /* | ||
33 | * This is a temporary build fix that (so they say on lkml....) should no longer | ||
34 | * be required after 2.6.33, because of changes planned to the kmap code. | ||
35 | * Let's try to remove this cruft then. | ||
36 | */ | ||
37 | #ifdef CONFIG_DEBUG_HIGHMEM | ||
38 | #define KM_NMI (-1) | ||
39 | #define KM_NMI_PTE (-1) | ||
40 | #define KM_IRQ_PTE (-1) | ||
41 | #endif | ||
42 | |||
32 | #endif /* __KERNEL__ */ | 43 | #endif /* __KERNEL__ */ |
33 | #endif /* _ASM_POWERPC_KMAP_TYPES_H */ | 44 | #endif /* _ASM_POWERPC_KMAP_TYPES_H */ |
diff --git a/arch/sh/kernel/cpu/irq/imask.c b/arch/sh/kernel/cpu/irq/imask.c index 6b5d191eec3a..a351ed84eec5 100644 --- a/arch/sh/kernel/cpu/irq/imask.c +++ b/arch/sh/kernel/cpu/irq/imask.c | |||
@@ -68,7 +68,7 @@ static void unmask_imask_irq(unsigned int irq) | |||
68 | } | 68 | } |
69 | 69 | ||
70 | static struct irq_chip imask_irq_chip = { | 70 | static struct irq_chip imask_irq_chip = { |
71 | .typename = "SR.IMASK", | 71 | .name = "SR.IMASK", |
72 | .mask = mask_imask_irq, | 72 | .mask = mask_imask_irq, |
73 | .unmask = unmask_imask_irq, | 73 | .unmask = unmask_imask_irq, |
74 | .mask_ack = mask_imask_irq, | 74 | .mask_ack = mask_imask_irq, |
diff --git a/arch/sh/kernel/cpu/irq/intc-sh5.c b/arch/sh/kernel/cpu/irq/intc-sh5.c index 6c092f1f5557..06e7e2959b54 100644 --- a/arch/sh/kernel/cpu/irq/intc-sh5.c +++ b/arch/sh/kernel/cpu/irq/intc-sh5.c | |||
@@ -85,7 +85,7 @@ static void mask_and_ack_intc(unsigned int); | |||
85 | static void end_intc_irq(unsigned int irq); | 85 | static void end_intc_irq(unsigned int irq); |
86 | 86 | ||
87 | static struct irq_chip intc_irq_type = { | 87 | static struct irq_chip intc_irq_type = { |
88 | .typename = "INTC", | 88 | .name = "INTC", |
89 | .startup = startup_intc_irq, | 89 | .startup = startup_intc_irq, |
90 | .shutdown = shutdown_intc_irq, | 90 | .shutdown = shutdown_intc_irq, |
91 | .enable = enable_intc_irq, | 91 | .enable = enable_intc_irq, |
diff --git a/arch/sparc/mm/init_64.h b/arch/sparc/mm/init_64.h index c2f772dbd556..77d1b313e344 100644 --- a/arch/sparc/mm/init_64.h +++ b/arch/sparc/mm/init_64.h | |||
@@ -45,7 +45,7 @@ extern void free_initmem(void); | |||
45 | #define VMEMMAP_ALIGN(x) (((x)+VMEMMAP_CHUNK-1UL)&VMEMMAP_CHUNK_MASK) | 45 | #define VMEMMAP_ALIGN(x) (((x)+VMEMMAP_CHUNK-1UL)&VMEMMAP_CHUNK_MASK) |
46 | 46 | ||
47 | #define VMEMMAP_SIZE ((((1UL << MAX_PHYSADDR_BITS) >> PAGE_SHIFT) * \ | 47 | #define VMEMMAP_SIZE ((((1UL << MAX_PHYSADDR_BITS) >> PAGE_SHIFT) * \ |
48 | sizeof(struct page *)) >> VMEMMAP_CHUNK_SHIFT) | 48 | sizeof(struct page)) >> VMEMMAP_CHUNK_SHIFT) |
49 | extern unsigned long vmemmap_table[VMEMMAP_SIZE]; | 49 | extern unsigned long vmemmap_table[VMEMMAP_SIZE]; |
50 | #endif | 50 | #endif |
51 | 51 | ||
diff --git a/arch/x86/kernel/acpi/processor.c b/arch/x86/kernel/acpi/processor.c index d296f4a195c9..d85d1b2432ba 100644 --- a/arch/x86/kernel/acpi/processor.c +++ b/arch/x86/kernel/acpi/processor.c | |||
@@ -79,7 +79,8 @@ void arch_acpi_processor_init_pdc(struct acpi_processor *pr) | |||
79 | struct cpuinfo_x86 *c = &cpu_data(pr->id); | 79 | struct cpuinfo_x86 *c = &cpu_data(pr->id); |
80 | 80 | ||
81 | pr->pdc = NULL; | 81 | pr->pdc = NULL; |
82 | if (c->x86_vendor == X86_VENDOR_INTEL) | 82 | if (c->x86_vendor == X86_VENDOR_INTEL || |
83 | c->x86_vendor == X86_VENDOR_CENTAUR) | ||
83 | init_intel_pdc(pr, c); | 84 | init_intel_pdc(pr, c); |
84 | 85 | ||
85 | return; | 86 | return; |
diff --git a/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c b/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c index 7d5c3b0ea8da..8b581d3905cb 100644 --- a/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c +++ b/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c | |||
@@ -526,15 +526,21 @@ static const struct dmi_system_id sw_any_bug_dmi_table[] = { | |||
526 | 526 | ||
527 | static int acpi_cpufreq_blacklist(struct cpuinfo_x86 *c) | 527 | static int acpi_cpufreq_blacklist(struct cpuinfo_x86 *c) |
528 | { | 528 | { |
529 | /* http://www.intel.com/Assets/PDF/specupdate/314554.pdf | 529 | /* Intel Xeon Processor 7100 Series Specification Update |
530 | * http://www.intel.com/Assets/PDF/specupdate/314554.pdf | ||
530 | * AL30: A Machine Check Exception (MCE) Occurring during an | 531 | * AL30: A Machine Check Exception (MCE) Occurring during an |
531 | * Enhanced Intel SpeedStep Technology Ratio Change May Cause | 532 | * Enhanced Intel SpeedStep Technology Ratio Change May Cause |
532 | * Both Processor Cores to Lock Up when HT is enabled*/ | 533 | * Both Processor Cores to Lock Up. */ |
533 | if (c->x86_vendor == X86_VENDOR_INTEL) { | 534 | if (c->x86_vendor == X86_VENDOR_INTEL) { |
534 | if ((c->x86 == 15) && | 535 | if ((c->x86 == 15) && |
535 | (c->x86_model == 6) && | 536 | (c->x86_model == 6) && |
536 | (c->x86_mask == 8) && smt_capable()) | 537 | (c->x86_mask == 8)) { |
538 | printk(KERN_INFO "acpi-cpufreq: Intel(R) " | ||
539 | "Xeon(R) 7100 Errata AL30, processors may " | ||
540 | "lock up on frequency changes: disabling " | ||
541 | "acpi-cpufreq.\n"); | ||
537 | return -ENODEV; | 542 | return -ENODEV; |
543 | } | ||
538 | } | 544 | } |
539 | return 0; | 545 | return 0; |
540 | } | 546 | } |
@@ -549,13 +555,18 @@ static int acpi_cpufreq_cpu_init(struct cpufreq_policy *policy) | |||
549 | unsigned int result = 0; | 555 | unsigned int result = 0; |
550 | struct cpuinfo_x86 *c = &cpu_data(policy->cpu); | 556 | struct cpuinfo_x86 *c = &cpu_data(policy->cpu); |
551 | struct acpi_processor_performance *perf; | 557 | struct acpi_processor_performance *perf; |
558 | #ifdef CONFIG_SMP | ||
559 | static int blacklisted; | ||
560 | #endif | ||
552 | 561 | ||
553 | dprintk("acpi_cpufreq_cpu_init\n"); | 562 | dprintk("acpi_cpufreq_cpu_init\n"); |
554 | 563 | ||
555 | #ifdef CONFIG_SMP | 564 | #ifdef CONFIG_SMP |
556 | result = acpi_cpufreq_blacklist(c); | 565 | if (blacklisted) |
557 | if (result) | 566 | return blacklisted; |
558 | return result; | 567 | blacklisted = acpi_cpufreq_blacklist(c); |
568 | if (blacklisted) | ||
569 | return blacklisted; | ||
559 | #endif | 570 | #endif |
560 | 571 | ||
561 | data = kzalloc(sizeof(struct acpi_cpufreq_data), GFP_KERNEL); | 572 | data = kzalloc(sizeof(struct acpi_cpufreq_data), GFP_KERNEL); |
diff --git a/arch/x86/kernel/cpu/cpufreq/longhaul.c b/arch/x86/kernel/cpu/cpufreq/longhaul.c index ce2ed3e4aad9..cabd2fa3fc93 100644 --- a/arch/x86/kernel/cpu/cpufreq/longhaul.c +++ b/arch/x86/kernel/cpu/cpufreq/longhaul.c | |||
@@ -813,7 +813,7 @@ static int __init longhaul_cpu_init(struct cpufreq_policy *policy) | |||
813 | memcpy(eblcr, samuel2_eblcr, sizeof(samuel2_eblcr)); | 813 | memcpy(eblcr, samuel2_eblcr, sizeof(samuel2_eblcr)); |
814 | break; | 814 | break; |
815 | case 1 ... 15: | 815 | case 1 ... 15: |
816 | longhaul_version = TYPE_LONGHAUL_V1; | 816 | longhaul_version = TYPE_LONGHAUL_V2; |
817 | if (c->x86_mask < 8) { | 817 | if (c->x86_mask < 8) { |
818 | cpu_model = CPU_SAMUEL2; | 818 | cpu_model = CPU_SAMUEL2; |
819 | cpuname = "C3 'Samuel 2' [C5B]"; | 819 | cpuname = "C3 'Samuel 2' [C5B]"; |
diff --git a/arch/x86/kernel/cpu/cpufreq/powernow-k8.c b/arch/x86/kernel/cpu/cpufreq/powernow-k8.c index 6394aa5c7985..3f12dabeab52 100644 --- a/arch/x86/kernel/cpu/cpufreq/powernow-k8.c +++ b/arch/x86/kernel/cpu/cpufreq/powernow-k8.c | |||
@@ -1022,7 +1022,7 @@ static int get_transition_latency(struct powernow_k8_data *data) | |||
1022 | * set it to 1 to avoid problems in the future. | 1022 | * set it to 1 to avoid problems in the future. |
1023 | * For all others it's a BIOS bug. | 1023 | * For all others it's a BIOS bug. |
1024 | */ | 1024 | */ |
1025 | if (!boot_cpu_data.x86 == 0x11) | 1025 | if (boot_cpu_data.x86 != 0x11) |
1026 | printk(KERN_ERR FW_WARN PFX "Invalid zero transition " | 1026 | printk(KERN_ERR FW_WARN PFX "Invalid zero transition " |
1027 | "latency\n"); | 1027 | "latency\n"); |
1028 | max_latency = 1; | 1028 | max_latency = 1; |
diff --git a/arch/x86/kernel/cpu/cpufreq/speedstep-ich.c b/arch/x86/kernel/cpu/cpufreq/speedstep-ich.c index 6911e91fb4f6..3ae5a7a3a500 100644 --- a/arch/x86/kernel/cpu/cpufreq/speedstep-ich.c +++ b/arch/x86/kernel/cpu/cpufreq/speedstep-ich.c | |||
@@ -232,28 +232,23 @@ static unsigned int speedstep_detect_chipset(void) | |||
232 | return 0; | 232 | return 0; |
233 | } | 233 | } |
234 | 234 | ||
235 | struct get_freq_data { | 235 | static void get_freq_data(void *_speed) |
236 | unsigned int speed; | ||
237 | unsigned int processor; | ||
238 | }; | ||
239 | |||
240 | static void get_freq_data(void *_data) | ||
241 | { | 236 | { |
242 | struct get_freq_data *data = _data; | 237 | unsigned int *speed = _speed; |
243 | 238 | ||
244 | data->speed = speedstep_get_frequency(data->processor); | 239 | *speed = speedstep_get_frequency(speedstep_processor); |
245 | } | 240 | } |
246 | 241 | ||
247 | static unsigned int speedstep_get(unsigned int cpu) | 242 | static unsigned int speedstep_get(unsigned int cpu) |
248 | { | 243 | { |
249 | struct get_freq_data data = { .processor = cpu }; | 244 | unsigned int speed; |
250 | 245 | ||
251 | /* You're supposed to ensure CPU is online. */ | 246 | /* You're supposed to ensure CPU is online. */ |
252 | if (smp_call_function_single(cpu, get_freq_data, &data, 1) != 0) | 247 | if (smp_call_function_single(cpu, get_freq_data, &speed, 1) != 0) |
253 | BUG(); | 248 | BUG(); |
254 | 249 | ||
255 | dprintk("detected %u kHz as current frequency\n", data.speed); | 250 | dprintk("detected %u kHz as current frequency\n", speed); |
256 | return data.speed; | 251 | return speed; |
257 | } | 252 | } |
258 | 253 | ||
259 | /** | 254 | /** |
diff --git a/crypto/async_tx/Kconfig b/crypto/async_tx/Kconfig index e5aeb2b79e6f..e28e276ac611 100644 --- a/crypto/async_tx/Kconfig +++ b/crypto/async_tx/Kconfig | |||
@@ -23,3 +23,8 @@ config ASYNC_RAID6_RECOV | |||
23 | select ASYNC_CORE | 23 | select ASYNC_CORE |
24 | select ASYNC_PQ | 24 | select ASYNC_PQ |
25 | 25 | ||
26 | config ASYNC_TX_DISABLE_PQ_VAL_DMA | ||
27 | bool | ||
28 | |||
29 | config ASYNC_TX_DISABLE_XOR_VAL_DMA | ||
30 | bool | ||
diff --git a/crypto/async_tx/async_pq.c b/crypto/async_tx/async_pq.c index 6b5cc4fba59f..ec87f53d5059 100644 --- a/crypto/async_tx/async_pq.c +++ b/crypto/async_tx/async_pq.c | |||
@@ -240,6 +240,16 @@ async_gen_syndrome(struct page **blocks, unsigned int offset, int disks, | |||
240 | } | 240 | } |
241 | EXPORT_SYMBOL_GPL(async_gen_syndrome); | 241 | EXPORT_SYMBOL_GPL(async_gen_syndrome); |
242 | 242 | ||
243 | static inline struct dma_chan * | ||
244 | pq_val_chan(struct async_submit_ctl *submit, struct page **blocks, int disks, size_t len) | ||
245 | { | ||
246 | #ifdef CONFIG_ASYNC_TX_DISABLE_PQ_VAL_DMA | ||
247 | return NULL; | ||
248 | #endif | ||
249 | return async_tx_find_channel(submit, DMA_PQ_VAL, NULL, 0, blocks, | ||
250 | disks, len); | ||
251 | } | ||
252 | |||
243 | /** | 253 | /** |
244 | * async_syndrome_val - asynchronously validate a raid6 syndrome | 254 | * async_syndrome_val - asynchronously validate a raid6 syndrome |
245 | * @blocks: source blocks from idx 0..disks-3, P @ disks-2 and Q @ disks-1 | 255 | * @blocks: source blocks from idx 0..disks-3, P @ disks-2 and Q @ disks-1 |
@@ -260,9 +270,7 @@ async_syndrome_val(struct page **blocks, unsigned int offset, int disks, | |||
260 | size_t len, enum sum_check_flags *pqres, struct page *spare, | 270 | size_t len, enum sum_check_flags *pqres, struct page *spare, |
261 | struct async_submit_ctl *submit) | 271 | struct async_submit_ctl *submit) |
262 | { | 272 | { |
263 | struct dma_chan *chan = async_tx_find_channel(submit, DMA_PQ_VAL, | 273 | struct dma_chan *chan = pq_val_chan(submit, blocks, disks, len); |
264 | NULL, 0, blocks, disks, | ||
265 | len); | ||
266 | struct dma_device *device = chan ? chan->device : NULL; | 274 | struct dma_device *device = chan ? chan->device : NULL; |
267 | struct dma_async_tx_descriptor *tx; | 275 | struct dma_async_tx_descriptor *tx; |
268 | unsigned char coefs[disks-2]; | 276 | unsigned char coefs[disks-2]; |
diff --git a/crypto/async_tx/async_xor.c b/crypto/async_tx/async_xor.c index 79182dcb91b7..079ae8ca590b 100644 --- a/crypto/async_tx/async_xor.c +++ b/crypto/async_tx/async_xor.c | |||
@@ -234,6 +234,17 @@ static int page_is_zero(struct page *p, unsigned int offset, size_t len) | |||
234 | memcmp(a, a + 4, len - 4) == 0); | 234 | memcmp(a, a + 4, len - 4) == 0); |
235 | } | 235 | } |
236 | 236 | ||
237 | static inline struct dma_chan * | ||
238 | xor_val_chan(struct async_submit_ctl *submit, struct page *dest, | ||
239 | struct page **src_list, int src_cnt, size_t len) | ||
240 | { | ||
241 | #ifdef CONFIG_ASYNC_TX_DISABLE_XOR_VAL_DMA | ||
242 | return NULL; | ||
243 | #endif | ||
244 | return async_tx_find_channel(submit, DMA_XOR_VAL, &dest, 1, src_list, | ||
245 | src_cnt, len); | ||
246 | } | ||
247 | |||
237 | /** | 248 | /** |
238 | * async_xor_val - attempt a xor parity check with a dma engine. | 249 | * async_xor_val - attempt a xor parity check with a dma engine. |
239 | * @dest: destination page used if the xor is performed synchronously | 250 | * @dest: destination page used if the xor is performed synchronously |
@@ -255,9 +266,7 @@ async_xor_val(struct page *dest, struct page **src_list, unsigned int offset, | |||
255 | int src_cnt, size_t len, enum sum_check_flags *result, | 266 | int src_cnt, size_t len, enum sum_check_flags *result, |
256 | struct async_submit_ctl *submit) | 267 | struct async_submit_ctl *submit) |
257 | { | 268 | { |
258 | struct dma_chan *chan = async_tx_find_channel(submit, DMA_XOR_VAL, | 269 | struct dma_chan *chan = xor_val_chan(submit, dest, src_list, src_cnt, len); |
259 | &dest, 1, src_list, | ||
260 | src_cnt, len); | ||
261 | struct dma_device *device = chan ? chan->device : NULL; | 270 | struct dma_device *device = chan ? chan->device : NULL; |
262 | struct dma_async_tx_descriptor *tx = NULL; | 271 | struct dma_async_tx_descriptor *tx = NULL; |
263 | dma_addr_t *dma_src = NULL; | 272 | dma_addr_t *dma_src = NULL; |
diff --git a/drivers/acpi/acpica/acpredef.h b/drivers/acpi/acpica/acpredef.h index cd80d1dd1950..57bdaf6ffab1 100644 --- a/drivers/acpi/acpica/acpredef.h +++ b/drivers/acpi/acpica/acpredef.h | |||
@@ -203,8 +203,9 @@ static const union acpi_predefined_info predefined_names[] = | |||
203 | {{"_BCT", 1, ACPI_RTYPE_INTEGER}}, | 203 | {{"_BCT", 1, ACPI_RTYPE_INTEGER}}, |
204 | {{"_BDN", 0, ACPI_RTYPE_INTEGER}}, | 204 | {{"_BDN", 0, ACPI_RTYPE_INTEGER}}, |
205 | {{"_BFS", 1, 0}}, | 205 | {{"_BFS", 1, 0}}, |
206 | {{"_BIF", 0, ACPI_RTYPE_PACKAGE}}, /* Fixed-length (9 Int),(4 Str) */ | 206 | {{"_BIF", 0, ACPI_RTYPE_PACKAGE} }, /* Fixed-length (9 Int),(4 Str/Buf) */ |
207 | {{{ACPI_PTYPE1_FIXED, ACPI_RTYPE_INTEGER, 9, ACPI_RTYPE_STRING}, 4,0}}, | 207 | {{{ACPI_PTYPE1_FIXED, ACPI_RTYPE_INTEGER, 9, |
208 | ACPI_RTYPE_STRING | ACPI_RTYPE_BUFFER}, 4, 0} }, | ||
208 | 209 | ||
209 | {{"_BIX", 0, ACPI_RTYPE_PACKAGE}}, /* Fixed-length (16 Int),(4 Str) */ | 210 | {{"_BIX", 0, ACPI_RTYPE_PACKAGE}}, /* Fixed-length (16 Int),(4 Str) */ |
210 | {{{ACPI_PTYPE1_FIXED, ACPI_RTYPE_INTEGER, 16, ACPI_RTYPE_STRING}, 4, | 211 | {{{ACPI_PTYPE1_FIXED, ACPI_RTYPE_INTEGER, 16, ACPI_RTYPE_STRING}, 4, |
diff --git a/drivers/acpi/blacklist.c b/drivers/acpi/blacklist.c index e56b2a7b53db..23e5a0519af5 100644 --- a/drivers/acpi/blacklist.c +++ b/drivers/acpi/blacklist.c | |||
@@ -224,6 +224,7 @@ static struct dmi_system_id acpi_osi_dmi_table[] __initdata = { | |||
224 | * _OSI(Linux) helps sound | 224 | * _OSI(Linux) helps sound |
225 | * DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad R61"), | 225 | * DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad R61"), |
226 | * DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad T61"), | 226 | * DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad T61"), |
227 | * T400, T500 | ||
227 | * _OSI(Linux) has Linux specific hooks | 228 | * _OSI(Linux) has Linux specific hooks |
228 | * DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad X61"), | 229 | * DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad X61"), |
229 | * _OSI(Linux) is a NOP: | 230 | * _OSI(Linux) is a NOP: |
@@ -254,6 +255,22 @@ static struct dmi_system_id acpi_osi_dmi_table[] __initdata = { | |||
254 | DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad X61"), | 255 | DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad X61"), |
255 | }, | 256 | }, |
256 | }, | 257 | }, |
258 | { | ||
259 | .callback = dmi_enable_osi_linux, | ||
260 | .ident = "Lenovo ThinkPad T400", | ||
261 | .matches = { | ||
262 | DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), | ||
263 | DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad T400"), | ||
264 | }, | ||
265 | }, | ||
266 | { | ||
267 | .callback = dmi_enable_osi_linux, | ||
268 | .ident = "Lenovo ThinkPad T500", | ||
269 | .matches = { | ||
270 | DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), | ||
271 | DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad T500"), | ||
272 | }, | ||
273 | }, | ||
257 | {} | 274 | {} |
258 | }; | 275 | }; |
259 | 276 | ||
diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c index 4cc1b8116e76..5f2c379ab7bf 100644 --- a/drivers/acpi/sleep.c +++ b/drivers/acpi/sleep.c | |||
@@ -430,6 +430,14 @@ static struct dmi_system_id __initdata acpisleep_dmi_table[] = { | |||
430 | }, | 430 | }, |
431 | { | 431 | { |
432 | .callback = init_set_sci_en_on_resume, | 432 | .callback = init_set_sci_en_on_resume, |
433 | .ident = "Hewlett-Packard Compaq Presario C700 Notebook PC", | ||
434 | .matches = { | ||
435 | DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), | ||
436 | DMI_MATCH(DMI_PRODUCT_NAME, "Compaq Presario C700 Notebook PC"), | ||
437 | }, | ||
438 | }, | ||
439 | { | ||
440 | .callback = init_set_sci_en_on_resume, | ||
433 | .ident = "Hewlett-Packard Compaq Presario CQ40 Notebook PC", | 441 | .ident = "Hewlett-Packard Compaq Presario CQ40 Notebook PC", |
434 | .matches = { | 442 | .matches = { |
435 | DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), | 443 | DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), |
diff --git a/drivers/ata/sata_fsl.c b/drivers/ata/sata_fsl.c index d344db42a002..172b57e6543f 100644 --- a/drivers/ata/sata_fsl.c +++ b/drivers/ata/sata_fsl.c | |||
@@ -707,34 +707,17 @@ static unsigned int sata_fsl_dev_classify(struct ata_port *ap) | |||
707 | return ata_dev_classify(&tf); | 707 | return ata_dev_classify(&tf); |
708 | } | 708 | } |
709 | 709 | ||
710 | static int sata_fsl_prereset(struct ata_link *link, unsigned long deadline) | 710 | static int sata_fsl_hardreset(struct ata_link *link, unsigned int *class, |
711 | { | ||
712 | /* FIXME: Never skip softreset, sata_fsl_softreset() is | ||
713 | * combination of soft and hard resets. sata_fsl_softreset() | ||
714 | * needs to be splitted into soft and hard resets. | ||
715 | */ | ||
716 | return 0; | ||
717 | } | ||
718 | |||
719 | static int sata_fsl_softreset(struct ata_link *link, unsigned int *class, | ||
720 | unsigned long deadline) | 711 | unsigned long deadline) |
721 | { | 712 | { |
722 | struct ata_port *ap = link->ap; | 713 | struct ata_port *ap = link->ap; |
723 | struct sata_fsl_port_priv *pp = ap->private_data; | ||
724 | struct sata_fsl_host_priv *host_priv = ap->host->private_data; | 714 | struct sata_fsl_host_priv *host_priv = ap->host->private_data; |
725 | void __iomem *hcr_base = host_priv->hcr_base; | 715 | void __iomem *hcr_base = host_priv->hcr_base; |
726 | int pmp = sata_srst_pmp(link); | ||
727 | u32 temp; | 716 | u32 temp; |
728 | struct ata_taskfile tf; | ||
729 | u8 *cfis; | ||
730 | u32 Serror; | ||
731 | int i = 0; | 717 | int i = 0; |
732 | unsigned long start_jiffies; | 718 | unsigned long start_jiffies; |
733 | 719 | ||
734 | DPRINTK("in xx_softreset\n"); | 720 | DPRINTK("in xx_hardreset\n"); |
735 | |||
736 | if (pmp != SATA_PMP_CTRL_PORT) | ||
737 | goto issue_srst; | ||
738 | 721 | ||
739 | try_offline_again: | 722 | try_offline_again: |
740 | /* | 723 | /* |
@@ -749,7 +732,7 @@ try_offline_again: | |||
749 | 732 | ||
750 | if (temp & ONLINE) { | 733 | if (temp & ONLINE) { |
751 | ata_port_printk(ap, KERN_ERR, | 734 | ata_port_printk(ap, KERN_ERR, |
752 | "Softreset failed, not off-lined %d\n", i); | 735 | "Hardreset failed, not off-lined %d\n", i); |
753 | 736 | ||
754 | /* | 737 | /* |
755 | * Try to offline controller atleast twice | 738 | * Try to offline controller atleast twice |
@@ -761,7 +744,7 @@ try_offline_again: | |||
761 | goto try_offline_again; | 744 | goto try_offline_again; |
762 | } | 745 | } |
763 | 746 | ||
764 | DPRINTK("softreset, controller off-lined\n"); | 747 | DPRINTK("hardreset, controller off-lined\n"); |
765 | VPRINTK("HStatus = 0x%x\n", ioread32(hcr_base + HSTATUS)); | 748 | VPRINTK("HStatus = 0x%x\n", ioread32(hcr_base + HSTATUS)); |
766 | VPRINTK("HControl = 0x%x\n", ioread32(hcr_base + HCONTROL)); | 749 | VPRINTK("HControl = 0x%x\n", ioread32(hcr_base + HCONTROL)); |
767 | 750 | ||
@@ -786,11 +769,11 @@ try_offline_again: | |||
786 | 769 | ||
787 | if (!(temp & ONLINE)) { | 770 | if (!(temp & ONLINE)) { |
788 | ata_port_printk(ap, KERN_ERR, | 771 | ata_port_printk(ap, KERN_ERR, |
789 | "Softreset failed, not on-lined\n"); | 772 | "Hardreset failed, not on-lined\n"); |
790 | goto err; | 773 | goto err; |
791 | } | 774 | } |
792 | 775 | ||
793 | DPRINTK("softreset, controller off-lined & on-lined\n"); | 776 | DPRINTK("hardreset, controller off-lined & on-lined\n"); |
794 | VPRINTK("HStatus = 0x%x\n", ioread32(hcr_base + HSTATUS)); | 777 | VPRINTK("HStatus = 0x%x\n", ioread32(hcr_base + HSTATUS)); |
795 | VPRINTK("HControl = 0x%x\n", ioread32(hcr_base + HCONTROL)); | 778 | VPRINTK("HControl = 0x%x\n", ioread32(hcr_base + HCONTROL)); |
796 | 779 | ||
@@ -806,7 +789,7 @@ try_offline_again: | |||
806 | "No Device OR PHYRDY change,Hstatus = 0x%x\n", | 789 | "No Device OR PHYRDY change,Hstatus = 0x%x\n", |
807 | ioread32(hcr_base + HSTATUS)); | 790 | ioread32(hcr_base + HSTATUS)); |
808 | *class = ATA_DEV_NONE; | 791 | *class = ATA_DEV_NONE; |
809 | goto out; | 792 | return 0; |
810 | } | 793 | } |
811 | 794 | ||
812 | /* | 795 | /* |
@@ -819,11 +802,44 @@ try_offline_again: | |||
819 | if ((temp & 0xFF) != 0x18) { | 802 | if ((temp & 0xFF) != 0x18) { |
820 | ata_port_printk(ap, KERN_WARNING, "No Signature Update\n"); | 803 | ata_port_printk(ap, KERN_WARNING, "No Signature Update\n"); |
821 | *class = ATA_DEV_NONE; | 804 | *class = ATA_DEV_NONE; |
822 | goto out; | 805 | goto do_followup_srst; |
823 | } else { | 806 | } else { |
824 | ata_port_printk(ap, KERN_INFO, | 807 | ata_port_printk(ap, KERN_INFO, |
825 | "Signature Update detected @ %d msecs\n", | 808 | "Signature Update detected @ %d msecs\n", |
826 | jiffies_to_msecs(jiffies - start_jiffies)); | 809 | jiffies_to_msecs(jiffies - start_jiffies)); |
810 | *class = sata_fsl_dev_classify(ap); | ||
811 | return 0; | ||
812 | } | ||
813 | |||
814 | do_followup_srst: | ||
815 | /* | ||
816 | * request libATA to perform follow-up softreset | ||
817 | */ | ||
818 | return -EAGAIN; | ||
819 | |||
820 | err: | ||
821 | return -EIO; | ||
822 | } | ||
823 | |||
824 | static int sata_fsl_softreset(struct ata_link *link, unsigned int *class, | ||
825 | unsigned long deadline) | ||
826 | { | ||
827 | struct ata_port *ap = link->ap; | ||
828 | struct sata_fsl_port_priv *pp = ap->private_data; | ||
829 | struct sata_fsl_host_priv *host_priv = ap->host->private_data; | ||
830 | void __iomem *hcr_base = host_priv->hcr_base; | ||
831 | int pmp = sata_srst_pmp(link); | ||
832 | u32 temp; | ||
833 | struct ata_taskfile tf; | ||
834 | u8 *cfis; | ||
835 | u32 Serror; | ||
836 | |||
837 | DPRINTK("in xx_softreset\n"); | ||
838 | |||
839 | if (ata_link_offline(link)) { | ||
840 | DPRINTK("PHY reports no device\n"); | ||
841 | *class = ATA_DEV_NONE; | ||
842 | return 0; | ||
827 | } | 843 | } |
828 | 844 | ||
829 | /* | 845 | /* |
@@ -834,7 +850,6 @@ try_offline_again: | |||
834 | * reached here, we can send a command to the target device | 850 | * reached here, we can send a command to the target device |
835 | */ | 851 | */ |
836 | 852 | ||
837 | issue_srst: | ||
838 | DPRINTK("Sending SRST/device reset\n"); | 853 | DPRINTK("Sending SRST/device reset\n"); |
839 | 854 | ||
840 | ata_tf_init(link->device, &tf); | 855 | ata_tf_init(link->device, &tf); |
@@ -860,6 +875,8 @@ issue_srst: | |||
860 | ioread32(CA + hcr_base), ioread32(CC + hcr_base)); | 875 | ioread32(CA + hcr_base), ioread32(CC + hcr_base)); |
861 | 876 | ||
862 | iowrite32(0xFFFF, CC + hcr_base); | 877 | iowrite32(0xFFFF, CC + hcr_base); |
878 | if (pmp != SATA_PMP_CTRL_PORT) | ||
879 | iowrite32(pmp, CQPMP + hcr_base); | ||
863 | iowrite32(1, CQ + hcr_base); | 880 | iowrite32(1, CQ + hcr_base); |
864 | 881 | ||
865 | temp = ata_wait_register(CQ + hcr_base, 0x1, 0x1, 1, 5000); | 882 | temp = ata_wait_register(CQ + hcr_base, 0x1, 0x1, 1, 5000); |
@@ -926,7 +943,6 @@ issue_srst: | |||
926 | VPRINTK("cereg = 0x%x\n", ioread32(hcr_base + CE)); | 943 | VPRINTK("cereg = 0x%x\n", ioread32(hcr_base + CE)); |
927 | } | 944 | } |
928 | 945 | ||
929 | out: | ||
930 | return 0; | 946 | return 0; |
931 | 947 | ||
932 | err: | 948 | err: |
@@ -988,18 +1004,6 @@ static void sata_fsl_error_intr(struct ata_port *ap) | |||
988 | ehi->err_mask |= AC_ERR_ATA_BUS; | 1004 | ehi->err_mask |= AC_ERR_ATA_BUS; |
989 | ehi->action |= ATA_EH_SOFTRESET; | 1005 | ehi->action |= ATA_EH_SOFTRESET; |
990 | 1006 | ||
991 | /* | ||
992 | * Ignore serror in case of fatal errors as we always want | ||
993 | * to do a soft-reset of the FSL SATA controller. Analyzing | ||
994 | * serror may cause libata to schedule a hard-reset action, | ||
995 | * and hard-reset currently does not do controller | ||
996 | * offline/online, causing command timeouts and leads to an | ||
997 | * un-recoverable state, hence make libATA ignore | ||
998 | * autopsy in case of fatal errors. | ||
999 | */ | ||
1000 | |||
1001 | ehi->flags |= ATA_EHI_NO_AUTOPSY; | ||
1002 | |||
1003 | freeze = 1; | 1007 | freeze = 1; |
1004 | } | 1008 | } |
1005 | 1009 | ||
@@ -1267,8 +1271,8 @@ static struct ata_port_operations sata_fsl_ops = { | |||
1267 | 1271 | ||
1268 | .freeze = sata_fsl_freeze, | 1272 | .freeze = sata_fsl_freeze, |
1269 | .thaw = sata_fsl_thaw, | 1273 | .thaw = sata_fsl_thaw, |
1270 | .prereset = sata_fsl_prereset, | ||
1271 | .softreset = sata_fsl_softreset, | 1274 | .softreset = sata_fsl_softreset, |
1275 | .hardreset = sata_fsl_hardreset, | ||
1272 | .pmp_softreset = sata_fsl_softreset, | 1276 | .pmp_softreset = sata_fsl_softreset, |
1273 | .error_handler = sata_fsl_error_handler, | 1277 | .error_handler = sata_fsl_error_handler, |
1274 | .post_internal_cmd = sata_fsl_post_internal_cmd, | 1278 | .post_internal_cmd = sata_fsl_post_internal_cmd, |
diff --git a/drivers/base/power/runtime.c b/drivers/base/power/runtime.c index a770498a74ec..846d89e3d122 100644 --- a/drivers/base/power/runtime.c +++ b/drivers/base/power/runtime.c | |||
@@ -328,11 +328,11 @@ int __pm_runtime_resume(struct device *dev, bool from_wq) | |||
328 | * necessary. | 328 | * necessary. |
329 | */ | 329 | */ |
330 | parent = dev->parent; | 330 | parent = dev->parent; |
331 | spin_unlock_irq(&dev->power.lock); | 331 | spin_unlock(&dev->power.lock); |
332 | 332 | ||
333 | pm_runtime_get_noresume(parent); | 333 | pm_runtime_get_noresume(parent); |
334 | 334 | ||
335 | spin_lock_irq(&parent->power.lock); | 335 | spin_lock(&parent->power.lock); |
336 | /* | 336 | /* |
337 | * We can resume if the parent's run-time PM is disabled or it | 337 | * We can resume if the parent's run-time PM is disabled or it |
338 | * is set to ignore children. | 338 | * is set to ignore children. |
@@ -343,9 +343,9 @@ int __pm_runtime_resume(struct device *dev, bool from_wq) | |||
343 | if (parent->power.runtime_status != RPM_ACTIVE) | 343 | if (parent->power.runtime_status != RPM_ACTIVE) |
344 | retval = -EBUSY; | 344 | retval = -EBUSY; |
345 | } | 345 | } |
346 | spin_unlock_irq(&parent->power.lock); | 346 | spin_unlock(&parent->power.lock); |
347 | 347 | ||
348 | spin_lock_irq(&dev->power.lock); | 348 | spin_lock(&dev->power.lock); |
349 | if (retval) | 349 | if (retval) |
350 | goto out; | 350 | goto out; |
351 | goto repeat; | 351 | goto repeat; |
@@ -777,7 +777,7 @@ int __pm_runtime_set_status(struct device *dev, unsigned int status) | |||
777 | } | 777 | } |
778 | 778 | ||
779 | if (parent) { | 779 | if (parent) { |
780 | spin_lock_irq(&parent->power.lock); | 780 | spin_lock(&parent->power.lock); |
781 | 781 | ||
782 | /* | 782 | /* |
783 | * It is invalid to put an active child under a parent that is | 783 | * It is invalid to put an active child under a parent that is |
@@ -793,7 +793,7 @@ int __pm_runtime_set_status(struct device *dev, unsigned int status) | |||
793 | atomic_inc(&parent->power.child_count); | 793 | atomic_inc(&parent->power.child_count); |
794 | } | 794 | } |
795 | 795 | ||
796 | spin_unlock_irq(&parent->power.lock); | 796 | spin_unlock(&parent->power.lock); |
797 | 797 | ||
798 | if (error) | 798 | if (error) |
799 | goto out; | 799 | goto out; |
diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c index 6399e5090df4..92b126394fa1 100644 --- a/drivers/block/cciss.c +++ b/drivers/block/cciss.c | |||
@@ -482,7 +482,7 @@ static ssize_t host_store_rescan(struct device *dev, | |||
482 | 482 | ||
483 | return count; | 483 | return count; |
484 | } | 484 | } |
485 | DEVICE_ATTR(rescan, S_IWUSR, NULL, host_store_rescan); | 485 | static DEVICE_ATTR(rescan, S_IWUSR, NULL, host_store_rescan); |
486 | 486 | ||
487 | static ssize_t dev_show_unique_id(struct device *dev, | 487 | static ssize_t dev_show_unique_id(struct device *dev, |
488 | struct device_attribute *attr, | 488 | struct device_attribute *attr, |
@@ -512,7 +512,7 @@ static ssize_t dev_show_unique_id(struct device *dev, | |||
512 | sn[8], sn[9], sn[10], sn[11], | 512 | sn[8], sn[9], sn[10], sn[11], |
513 | sn[12], sn[13], sn[14], sn[15]); | 513 | sn[12], sn[13], sn[14], sn[15]); |
514 | } | 514 | } |
515 | DEVICE_ATTR(unique_id, S_IRUGO, dev_show_unique_id, NULL); | 515 | static DEVICE_ATTR(unique_id, S_IRUGO, dev_show_unique_id, NULL); |
516 | 516 | ||
517 | static ssize_t dev_show_vendor(struct device *dev, | 517 | static ssize_t dev_show_vendor(struct device *dev, |
518 | struct device_attribute *attr, | 518 | struct device_attribute *attr, |
@@ -536,7 +536,7 @@ static ssize_t dev_show_vendor(struct device *dev, | |||
536 | else | 536 | else |
537 | return snprintf(buf, sizeof(vendor) + 1, "%s\n", drv->vendor); | 537 | return snprintf(buf, sizeof(vendor) + 1, "%s\n", drv->vendor); |
538 | } | 538 | } |
539 | DEVICE_ATTR(vendor, S_IRUGO, dev_show_vendor, NULL); | 539 | static DEVICE_ATTR(vendor, S_IRUGO, dev_show_vendor, NULL); |
540 | 540 | ||
541 | static ssize_t dev_show_model(struct device *dev, | 541 | static ssize_t dev_show_model(struct device *dev, |
542 | struct device_attribute *attr, | 542 | struct device_attribute *attr, |
@@ -560,7 +560,7 @@ static ssize_t dev_show_model(struct device *dev, | |||
560 | else | 560 | else |
561 | return snprintf(buf, sizeof(model) + 1, "%s\n", drv->model); | 561 | return snprintf(buf, sizeof(model) + 1, "%s\n", drv->model); |
562 | } | 562 | } |
563 | DEVICE_ATTR(model, S_IRUGO, dev_show_model, NULL); | 563 | static DEVICE_ATTR(model, S_IRUGO, dev_show_model, NULL); |
564 | 564 | ||
565 | static ssize_t dev_show_rev(struct device *dev, | 565 | static ssize_t dev_show_rev(struct device *dev, |
566 | struct device_attribute *attr, | 566 | struct device_attribute *attr, |
@@ -584,7 +584,7 @@ static ssize_t dev_show_rev(struct device *dev, | |||
584 | else | 584 | else |
585 | return snprintf(buf, sizeof(rev) + 1, "%s\n", drv->rev); | 585 | return snprintf(buf, sizeof(rev) + 1, "%s\n", drv->rev); |
586 | } | 586 | } |
587 | DEVICE_ATTR(rev, S_IRUGO, dev_show_rev, NULL); | 587 | static DEVICE_ATTR(rev, S_IRUGO, dev_show_rev, NULL); |
588 | 588 | ||
589 | static ssize_t cciss_show_lunid(struct device *dev, | 589 | static ssize_t cciss_show_lunid(struct device *dev, |
590 | struct device_attribute *attr, char *buf) | 590 | struct device_attribute *attr, char *buf) |
@@ -609,7 +609,7 @@ static ssize_t cciss_show_lunid(struct device *dev, | |||
609 | lunid[0], lunid[1], lunid[2], lunid[3], | 609 | lunid[0], lunid[1], lunid[2], lunid[3], |
610 | lunid[4], lunid[5], lunid[6], lunid[7]); | 610 | lunid[4], lunid[5], lunid[6], lunid[7]); |
611 | } | 611 | } |
612 | DEVICE_ATTR(lunid, S_IRUGO, cciss_show_lunid, NULL); | 612 | static DEVICE_ATTR(lunid, S_IRUGO, cciss_show_lunid, NULL); |
613 | 613 | ||
614 | static ssize_t cciss_show_raid_level(struct device *dev, | 614 | static ssize_t cciss_show_raid_level(struct device *dev, |
615 | struct device_attribute *attr, char *buf) | 615 | struct device_attribute *attr, char *buf) |
@@ -632,7 +632,7 @@ static ssize_t cciss_show_raid_level(struct device *dev, | |||
632 | return snprintf(buf, strlen(raid_label[raid]) + 7, "RAID %s\n", | 632 | return snprintf(buf, strlen(raid_label[raid]) + 7, "RAID %s\n", |
633 | raid_label[raid]); | 633 | raid_label[raid]); |
634 | } | 634 | } |
635 | DEVICE_ATTR(raid_level, S_IRUGO, cciss_show_raid_level, NULL); | 635 | static DEVICE_ATTR(raid_level, S_IRUGO, cciss_show_raid_level, NULL); |
636 | 636 | ||
637 | static ssize_t cciss_show_usage_count(struct device *dev, | 637 | static ssize_t cciss_show_usage_count(struct device *dev, |
638 | struct device_attribute *attr, char *buf) | 638 | struct device_attribute *attr, char *buf) |
@@ -651,7 +651,7 @@ static ssize_t cciss_show_usage_count(struct device *dev, | |||
651 | spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags); | 651 | spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags); |
652 | return snprintf(buf, 20, "%d\n", count); | 652 | return snprintf(buf, 20, "%d\n", count); |
653 | } | 653 | } |
654 | DEVICE_ATTR(usage_count, S_IRUGO, cciss_show_usage_count, NULL); | 654 | static DEVICE_ATTR(usage_count, S_IRUGO, cciss_show_usage_count, NULL); |
655 | 655 | ||
656 | static struct attribute *cciss_host_attrs[] = { | 656 | static struct attribute *cciss_host_attrs[] = { |
657 | &dev_attr_rescan.attr, | 657 | &dev_attr_rescan.attr, |
diff --git a/drivers/char/agp/intel-agp.c b/drivers/char/agp/intel-agp.c index 4068467ce7b9..3cb56a049e24 100644 --- a/drivers/char/agp/intel-agp.c +++ b/drivers/char/agp/intel-agp.c | |||
@@ -62,6 +62,7 @@ | |||
62 | #define PCI_DEVICE_ID_INTEL_IGDNG_D_IG 0x0042 | 62 | #define PCI_DEVICE_ID_INTEL_IGDNG_D_IG 0x0042 |
63 | #define PCI_DEVICE_ID_INTEL_IGDNG_M_HB 0x0044 | 63 | #define PCI_DEVICE_ID_INTEL_IGDNG_M_HB 0x0044 |
64 | #define PCI_DEVICE_ID_INTEL_IGDNG_MA_HB 0x0062 | 64 | #define PCI_DEVICE_ID_INTEL_IGDNG_MA_HB 0x0062 |
65 | #define PCI_DEVICE_ID_INTEL_IGDNG_MC2_HB 0x006a | ||
65 | #define PCI_DEVICE_ID_INTEL_IGDNG_M_IG 0x0046 | 66 | #define PCI_DEVICE_ID_INTEL_IGDNG_M_IG 0x0046 |
66 | 67 | ||
67 | /* cover 915 and 945 variants */ | 68 | /* cover 915 and 945 variants */ |
@@ -96,7 +97,8 @@ | |||
96 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_B43_HB || \ | 97 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_B43_HB || \ |
97 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IGDNG_D_HB || \ | 98 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IGDNG_D_HB || \ |
98 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IGDNG_M_HB || \ | 99 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IGDNG_M_HB || \ |
99 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IGDNG_MA_HB) | 100 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IGDNG_MA_HB || \ |
101 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IGDNG_MC2_HB) | ||
100 | 102 | ||
101 | extern int agp_memory_reserved; | 103 | extern int agp_memory_reserved; |
102 | 104 | ||
@@ -1161,12 +1163,6 @@ static int intel_i915_configure(void) | |||
1161 | 1163 | ||
1162 | intel_i9xx_setup_flush(); | 1164 | intel_i9xx_setup_flush(); |
1163 | 1165 | ||
1164 | #ifdef USE_PCI_DMA_API | ||
1165 | if (pci_set_dma_mask(intel_private.pcidev, DMA_BIT_MASK(36))) | ||
1166 | dev_err(&intel_private.pcidev->dev, | ||
1167 | "set gfx device dma mask 36bit failed!\n"); | ||
1168 | #endif | ||
1169 | |||
1170 | return 0; | 1166 | return 0; |
1171 | } | 1167 | } |
1172 | 1168 | ||
@@ -1364,6 +1360,7 @@ static void intel_i965_get_gtt_range(int *gtt_offset, int *gtt_size) | |||
1364 | case PCI_DEVICE_ID_INTEL_IGDNG_D_HB: | 1360 | case PCI_DEVICE_ID_INTEL_IGDNG_D_HB: |
1365 | case PCI_DEVICE_ID_INTEL_IGDNG_M_HB: | 1361 | case PCI_DEVICE_ID_INTEL_IGDNG_M_HB: |
1366 | case PCI_DEVICE_ID_INTEL_IGDNG_MA_HB: | 1362 | case PCI_DEVICE_ID_INTEL_IGDNG_MA_HB: |
1363 | case PCI_DEVICE_ID_INTEL_IGDNG_MC2_HB: | ||
1367 | *gtt_offset = *gtt_size = MB(2); | 1364 | *gtt_offset = *gtt_size = MB(2); |
1368 | break; | 1365 | break; |
1369 | default: | 1366 | default: |
@@ -2365,6 +2362,8 @@ static const struct intel_driver_description { | |||
2365 | "IGDNG/M", NULL, &intel_i965_driver }, | 2362 | "IGDNG/M", NULL, &intel_i965_driver }, |
2366 | { PCI_DEVICE_ID_INTEL_IGDNG_MA_HB, PCI_DEVICE_ID_INTEL_IGDNG_M_IG, 0, | 2363 | { PCI_DEVICE_ID_INTEL_IGDNG_MA_HB, PCI_DEVICE_ID_INTEL_IGDNG_M_IG, 0, |
2367 | "IGDNG/MA", NULL, &intel_i965_driver }, | 2364 | "IGDNG/MA", NULL, &intel_i965_driver }, |
2365 | { PCI_DEVICE_ID_INTEL_IGDNG_MC2_HB, PCI_DEVICE_ID_INTEL_IGDNG_M_IG, 0, | ||
2366 | "IGDNG/MC2", NULL, &intel_i965_driver }, | ||
2368 | { 0, 0, 0, NULL, NULL, NULL } | 2367 | { 0, 0, 0, NULL, NULL, NULL } |
2369 | }; | 2368 | }; |
2370 | 2369 | ||
@@ -2456,6 +2455,11 @@ static int __devinit agp_intel_probe(struct pci_dev *pdev, | |||
2456 | &bridge->mode); | 2455 | &bridge->mode); |
2457 | } | 2456 | } |
2458 | 2457 | ||
2458 | if (bridge->driver->mask_memory == intel_i965_mask_memory) | ||
2459 | if (pci_set_dma_mask(intel_private.pcidev, DMA_BIT_MASK(36))) | ||
2460 | dev_err(&intel_private.pcidev->dev, | ||
2461 | "set gfx device dma mask 36bit failed!\n"); | ||
2462 | |||
2459 | pci_set_drvdata(pdev, bridge); | 2463 | pci_set_drvdata(pdev, bridge); |
2460 | return agp_add_bridge(bridge); | 2464 | return agp_add_bridge(bridge); |
2461 | } | 2465 | } |
@@ -2561,6 +2565,7 @@ static struct pci_device_id agp_intel_pci_table[] = { | |||
2561 | ID(PCI_DEVICE_ID_INTEL_IGDNG_D_HB), | 2565 | ID(PCI_DEVICE_ID_INTEL_IGDNG_D_HB), |
2562 | ID(PCI_DEVICE_ID_INTEL_IGDNG_M_HB), | 2566 | ID(PCI_DEVICE_ID_INTEL_IGDNG_M_HB), |
2563 | ID(PCI_DEVICE_ID_INTEL_IGDNG_MA_HB), | 2567 | ID(PCI_DEVICE_ID_INTEL_IGDNG_MA_HB), |
2568 | ID(PCI_DEVICE_ID_INTEL_IGDNG_MC2_HB), | ||
2564 | { } | 2569 | { } |
2565 | }; | 2570 | }; |
2566 | 2571 | ||
diff --git a/drivers/char/keyboard.c b/drivers/char/keyboard.c index 737be953cc58..950837cf9e9c 100644 --- a/drivers/char/keyboard.c +++ b/drivers/char/keyboard.c | |||
@@ -1249,7 +1249,7 @@ static void kbd_keycode(unsigned int keycode, int down, int hw_raw) | |||
1249 | 1249 | ||
1250 | if (keycode >= NR_KEYS) | 1250 | if (keycode >= NR_KEYS) |
1251 | if (keycode >= KEY_BRL_DOT1 && keycode <= KEY_BRL_DOT8) | 1251 | if (keycode >= KEY_BRL_DOT1 && keycode <= KEY_BRL_DOT8) |
1252 | keysym = K(KT_BRL, keycode - KEY_BRL_DOT1 + 1); | 1252 | keysym = U(K(KT_BRL, keycode - KEY_BRL_DOT1 + 1)); |
1253 | else | 1253 | else |
1254 | return; | 1254 | return; |
1255 | else | 1255 | else |
diff --git a/drivers/char/tty_port.c b/drivers/char/tty_port.c index a4bbb28f10be..2e8552dc5eda 100644 --- a/drivers/char/tty_port.c +++ b/drivers/char/tty_port.c | |||
@@ -221,6 +221,9 @@ int tty_port_block_til_ready(struct tty_port *port, | |||
221 | the port has just hung up or is in another error state */ | 221 | the port has just hung up or is in another error state */ |
222 | if ((filp->f_flags & O_NONBLOCK) || | 222 | if ((filp->f_flags & O_NONBLOCK) || |
223 | (tty->flags & (1 << TTY_IO_ERROR))) { | 223 | (tty->flags & (1 << TTY_IO_ERROR))) { |
224 | /* Indicate we are open */ | ||
225 | if (tty->termios->c_cflag & CBAUD) | ||
226 | tty_port_raise_dtr_rts(port); | ||
224 | port->flags |= ASYNC_NORMAL_ACTIVE; | 227 | port->flags |= ASYNC_NORMAL_ACTIVE; |
225 | return 0; | 228 | return 0; |
226 | } | 229 | } |
diff --git a/drivers/char/vt_ioctl.c b/drivers/char/vt_ioctl.c index ed86d3bf249a..6aa10284104a 100644 --- a/drivers/char/vt_ioctl.c +++ b/drivers/char/vt_ioctl.c | |||
@@ -103,8 +103,8 @@ void vt_event_post(unsigned int event, unsigned int old, unsigned int new) | |||
103 | ve->event.event = event; | 103 | ve->event.event = event; |
104 | /* kernel view is consoles 0..n-1, user space view is | 104 | /* kernel view is consoles 0..n-1, user space view is |
105 | console 1..n with 0 meaning current, so we must bias */ | 105 | console 1..n with 0 meaning current, so we must bias */ |
106 | ve->event.old = old + 1; | 106 | ve->event.oldev = old + 1; |
107 | ve->event.new = new + 1; | 107 | ve->event.newev = new + 1; |
108 | wake = 1; | 108 | wake = 1; |
109 | ve->done = 1; | 109 | ve->done = 1; |
110 | } | 110 | } |
@@ -186,7 +186,7 @@ int vt_waitactive(int n) | |||
186 | vt_event_wait(&vw); | 186 | vt_event_wait(&vw); |
187 | if (vw.done == 0) | 187 | if (vw.done == 0) |
188 | return -EINTR; | 188 | return -EINTR; |
189 | } while (vw.event.new != n); | 189 | } while (vw.event.newev != n); |
190 | return 0; | 190 | return 0; |
191 | } | 191 | } |
192 | 192 | ||
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index 3938c7817095..ff57c40e9b8b 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c | |||
@@ -41,7 +41,7 @@ static struct cpufreq_driver *cpufreq_driver; | |||
41 | static DEFINE_PER_CPU(struct cpufreq_policy *, cpufreq_cpu_data); | 41 | static DEFINE_PER_CPU(struct cpufreq_policy *, cpufreq_cpu_data); |
42 | #ifdef CONFIG_HOTPLUG_CPU | 42 | #ifdef CONFIG_HOTPLUG_CPU |
43 | /* This one keeps track of the previously set governor of a removed CPU */ | 43 | /* This one keeps track of the previously set governor of a removed CPU */ |
44 | static DEFINE_PER_CPU(struct cpufreq_governor *, cpufreq_cpu_governor); | 44 | static DEFINE_PER_CPU(char[CPUFREQ_NAME_LEN], cpufreq_cpu_governor); |
45 | #endif | 45 | #endif |
46 | static DEFINE_SPINLOCK(cpufreq_driver_lock); | 46 | static DEFINE_SPINLOCK(cpufreq_driver_lock); |
47 | 47 | ||
@@ -774,10 +774,12 @@ int cpufreq_add_dev_policy(unsigned int cpu, struct cpufreq_policy *policy, | |||
774 | #ifdef CONFIG_SMP | 774 | #ifdef CONFIG_SMP |
775 | unsigned long flags; | 775 | unsigned long flags; |
776 | unsigned int j; | 776 | unsigned int j; |
777 | |||
778 | #ifdef CONFIG_HOTPLUG_CPU | 777 | #ifdef CONFIG_HOTPLUG_CPU |
779 | if (per_cpu(cpufreq_cpu_governor, cpu)) { | 778 | struct cpufreq_governor *gov; |
780 | policy->governor = per_cpu(cpufreq_cpu_governor, cpu); | 779 | |
780 | gov = __find_governor(per_cpu(cpufreq_cpu_governor, cpu)); | ||
781 | if (gov) { | ||
782 | policy->governor = gov; | ||
781 | dprintk("Restoring governor %s for cpu %d\n", | 783 | dprintk("Restoring governor %s for cpu %d\n", |
782 | policy->governor->name, cpu); | 784 | policy->governor->name, cpu); |
783 | } | 785 | } |
@@ -949,10 +951,13 @@ err_out_kobj_put: | |||
949 | static int cpufreq_add_dev(struct sys_device *sys_dev) | 951 | static int cpufreq_add_dev(struct sys_device *sys_dev) |
950 | { | 952 | { |
951 | unsigned int cpu = sys_dev->id; | 953 | unsigned int cpu = sys_dev->id; |
952 | int ret = 0; | 954 | int ret = 0, found = 0; |
953 | struct cpufreq_policy *policy; | 955 | struct cpufreq_policy *policy; |
954 | unsigned long flags; | 956 | unsigned long flags; |
955 | unsigned int j; | 957 | unsigned int j; |
958 | #ifdef CONFIG_HOTPLUG_CPU | ||
959 | int sibling; | ||
960 | #endif | ||
956 | 961 | ||
957 | if (cpu_is_offline(cpu)) | 962 | if (cpu_is_offline(cpu)) |
958 | return 0; | 963 | return 0; |
@@ -999,7 +1004,19 @@ static int cpufreq_add_dev(struct sys_device *sys_dev) | |||
999 | INIT_WORK(&policy->update, handle_update); | 1004 | INIT_WORK(&policy->update, handle_update); |
1000 | 1005 | ||
1001 | /* Set governor before ->init, so that driver could check it */ | 1006 | /* Set governor before ->init, so that driver could check it */ |
1002 | policy->governor = CPUFREQ_DEFAULT_GOVERNOR; | 1007 | #ifdef CONFIG_HOTPLUG_CPU |
1008 | for_each_online_cpu(sibling) { | ||
1009 | struct cpufreq_policy *cp = per_cpu(cpufreq_cpu_data, sibling); | ||
1010 | if (cp && cp->governor && | ||
1011 | (cpumask_test_cpu(cpu, cp->related_cpus))) { | ||
1012 | policy->governor = cp->governor; | ||
1013 | found = 1; | ||
1014 | break; | ||
1015 | } | ||
1016 | } | ||
1017 | #endif | ||
1018 | if (!found) | ||
1019 | policy->governor = CPUFREQ_DEFAULT_GOVERNOR; | ||
1003 | /* call driver. From then on the cpufreq must be able | 1020 | /* call driver. From then on the cpufreq must be able |
1004 | * to accept all calls to ->verify and ->setpolicy for this CPU | 1021 | * to accept all calls to ->verify and ->setpolicy for this CPU |
1005 | */ | 1022 | */ |
@@ -1111,7 +1128,8 @@ static int __cpufreq_remove_dev(struct sys_device *sys_dev) | |||
1111 | #ifdef CONFIG_SMP | 1128 | #ifdef CONFIG_SMP |
1112 | 1129 | ||
1113 | #ifdef CONFIG_HOTPLUG_CPU | 1130 | #ifdef CONFIG_HOTPLUG_CPU |
1114 | per_cpu(cpufreq_cpu_governor, cpu) = data->governor; | 1131 | strncpy(per_cpu(cpufreq_cpu_governor, cpu), data->governor->name, |
1132 | CPUFREQ_NAME_LEN); | ||
1115 | #endif | 1133 | #endif |
1116 | 1134 | ||
1117 | /* if we have other CPUs still registered, we need to unlink them, | 1135 | /* if we have other CPUs still registered, we need to unlink them, |
@@ -1135,7 +1153,8 @@ static int __cpufreq_remove_dev(struct sys_device *sys_dev) | |||
1135 | continue; | 1153 | continue; |
1136 | dprintk("removing link for cpu %u\n", j); | 1154 | dprintk("removing link for cpu %u\n", j); |
1137 | #ifdef CONFIG_HOTPLUG_CPU | 1155 | #ifdef CONFIG_HOTPLUG_CPU |
1138 | per_cpu(cpufreq_cpu_governor, j) = data->governor; | 1156 | strncpy(per_cpu(cpufreq_cpu_governor, j), |
1157 | data->governor->name, CPUFREQ_NAME_LEN); | ||
1139 | #endif | 1158 | #endif |
1140 | cpu_sys_dev = get_cpu_sysdev(j); | 1159 | cpu_sys_dev = get_cpu_sysdev(j); |
1141 | sysfs_remove_link(&cpu_sys_dev->kobj, "cpufreq"); | 1160 | sysfs_remove_link(&cpu_sys_dev->kobj, "cpufreq"); |
@@ -1606,9 +1625,22 @@ EXPORT_SYMBOL_GPL(cpufreq_register_governor); | |||
1606 | 1625 | ||
1607 | void cpufreq_unregister_governor(struct cpufreq_governor *governor) | 1626 | void cpufreq_unregister_governor(struct cpufreq_governor *governor) |
1608 | { | 1627 | { |
1628 | #ifdef CONFIG_HOTPLUG_CPU | ||
1629 | int cpu; | ||
1630 | #endif | ||
1631 | |||
1609 | if (!governor) | 1632 | if (!governor) |
1610 | return; | 1633 | return; |
1611 | 1634 | ||
1635 | #ifdef CONFIG_HOTPLUG_CPU | ||
1636 | for_each_present_cpu(cpu) { | ||
1637 | if (cpu_online(cpu)) | ||
1638 | continue; | ||
1639 | if (!strcmp(per_cpu(cpufreq_cpu_governor, cpu), governor->name)) | ||
1640 | strcpy(per_cpu(cpufreq_cpu_governor, cpu), "\0"); | ||
1641 | } | ||
1642 | #endif | ||
1643 | |||
1612 | mutex_lock(&cpufreq_governor_mutex); | 1644 | mutex_lock(&cpufreq_governor_mutex); |
1613 | list_del(&governor->governor_list); | 1645 | list_del(&governor->governor_list); |
1614 | mutex_unlock(&cpufreq_governor_mutex); | 1646 | mutex_unlock(&cpufreq_governor_mutex); |
diff --git a/drivers/cpufreq/cpufreq_conservative.c b/drivers/cpufreq/cpufreq_conservative.c index bc33ddc9c97c..c7b081b839ff 100644 --- a/drivers/cpufreq/cpufreq_conservative.c +++ b/drivers/cpufreq/cpufreq_conservative.c | |||
@@ -116,9 +116,9 @@ static inline cputime64_t get_cpu_idle_time_jiffy(unsigned int cpu, | |||
116 | 116 | ||
117 | idle_time = cputime64_sub(cur_wall_time, busy_time); | 117 | idle_time = cputime64_sub(cur_wall_time, busy_time); |
118 | if (wall) | 118 | if (wall) |
119 | *wall = cur_wall_time; | 119 | *wall = (cputime64_t)jiffies_to_usecs(cur_wall_time); |
120 | 120 | ||
121 | return idle_time; | 121 | return (cputime64_t)jiffies_to_usecs(idle_time);; |
122 | } | 122 | } |
123 | 123 | ||
124 | static inline cputime64_t get_cpu_idle_time(unsigned int cpu, cputime64_t *wall) | 124 | static inline cputime64_t get_cpu_idle_time(unsigned int cpu, cputime64_t *wall) |
diff --git a/drivers/cpufreq/cpufreq_ondemand.c b/drivers/cpufreq/cpufreq_ondemand.c index 071699de50ee..4b34ade2332b 100644 --- a/drivers/cpufreq/cpufreq_ondemand.c +++ b/drivers/cpufreq/cpufreq_ondemand.c | |||
@@ -133,9 +133,9 @@ static inline cputime64_t get_cpu_idle_time_jiffy(unsigned int cpu, | |||
133 | 133 | ||
134 | idle_time = cputime64_sub(cur_wall_time, busy_time); | 134 | idle_time = cputime64_sub(cur_wall_time, busy_time); |
135 | if (wall) | 135 | if (wall) |
136 | *wall = cur_wall_time; | 136 | *wall = (cputime64_t)jiffies_to_usecs(cur_wall_time); |
137 | 137 | ||
138 | return idle_time; | 138 | return (cputime64_t)jiffies_to_usecs(idle_time); |
139 | } | 139 | } |
140 | 140 | ||
141 | static inline cputime64_t get_cpu_idle_time(unsigned int cpu, cputime64_t *wall) | 141 | static inline cputime64_t get_cpu_idle_time(unsigned int cpu, cputime64_t *wall) |
diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig index 5903a88351bf..b401dadad4a8 100644 --- a/drivers/dma/Kconfig +++ b/drivers/dma/Kconfig | |||
@@ -26,6 +26,8 @@ config INTEL_IOATDMA | |||
26 | select DMA_ENGINE | 26 | select DMA_ENGINE |
27 | select DCA | 27 | select DCA |
28 | select ASYNC_TX_DISABLE_CHANNEL_SWITCH | 28 | select ASYNC_TX_DISABLE_CHANNEL_SWITCH |
29 | select ASYNC_TX_DISABLE_PQ_VAL_DMA | ||
30 | select ASYNC_TX_DISABLE_XOR_VAL_DMA | ||
29 | help | 31 | help |
30 | Enable support for the Intel(R) I/OAT DMA engine present | 32 | Enable support for the Intel(R) I/OAT DMA engine present |
31 | in recent Intel Xeon chipsets. | 33 | in recent Intel Xeon chipsets. |
diff --git a/drivers/dma/dmaengine.c b/drivers/dma/dmaengine.c index bd0b248de2cf..8f99354082ce 100644 --- a/drivers/dma/dmaengine.c +++ b/drivers/dma/dmaengine.c | |||
@@ -632,11 +632,21 @@ static bool device_has_all_tx_types(struct dma_device *device) | |||
632 | #if defined(CONFIG_ASYNC_XOR) || defined(CONFIG_ASYNC_XOR_MODULE) | 632 | #if defined(CONFIG_ASYNC_XOR) || defined(CONFIG_ASYNC_XOR_MODULE) |
633 | if (!dma_has_cap(DMA_XOR, device->cap_mask)) | 633 | if (!dma_has_cap(DMA_XOR, device->cap_mask)) |
634 | return false; | 634 | return false; |
635 | |||
636 | #ifndef CONFIG_ASYNC_TX_DISABLE_XOR_VAL_DMA | ||
637 | if (!dma_has_cap(DMA_XOR_VAL, device->cap_mask)) | ||
638 | return false; | ||
639 | #endif | ||
635 | #endif | 640 | #endif |
636 | 641 | ||
637 | #if defined(CONFIG_ASYNC_PQ) || defined(CONFIG_ASYNC_PQ_MODULE) | 642 | #if defined(CONFIG_ASYNC_PQ) || defined(CONFIG_ASYNC_PQ_MODULE) |
638 | if (!dma_has_cap(DMA_PQ, device->cap_mask)) | 643 | if (!dma_has_cap(DMA_PQ, device->cap_mask)) |
639 | return false; | 644 | return false; |
645 | |||
646 | #ifndef CONFIG_ASYNC_TX_DISABLE_PQ_VAL_DMA | ||
647 | if (!dma_has_cap(DMA_PQ_VAL, device->cap_mask)) | ||
648 | return false; | ||
649 | #endif | ||
640 | #endif | 650 | #endif |
641 | 651 | ||
642 | return true; | 652 | return true; |
diff --git a/drivers/dma/ioat/dca.c b/drivers/dma/ioat/dca.c index 69d02615c4d6..abd9038e06b1 100644 --- a/drivers/dma/ioat/dca.c +++ b/drivers/dma/ioat/dca.c | |||
@@ -98,17 +98,17 @@ static int dca_enabled_in_bios(struct pci_dev *pdev) | |||
98 | cpuid_level_9 = cpuid_eax(9); | 98 | cpuid_level_9 = cpuid_eax(9); |
99 | res = test_bit(0, &cpuid_level_9); | 99 | res = test_bit(0, &cpuid_level_9); |
100 | if (!res) | 100 | if (!res) |
101 | dev_err(&pdev->dev, "DCA is disabled in BIOS\n"); | 101 | dev_dbg(&pdev->dev, "DCA is disabled in BIOS\n"); |
102 | 102 | ||
103 | return res; | 103 | return res; |
104 | } | 104 | } |
105 | 105 | ||
106 | static int system_has_dca_enabled(struct pci_dev *pdev) | 106 | int system_has_dca_enabled(struct pci_dev *pdev) |
107 | { | 107 | { |
108 | if (boot_cpu_has(X86_FEATURE_DCA)) | 108 | if (boot_cpu_has(X86_FEATURE_DCA)) |
109 | return dca_enabled_in_bios(pdev); | 109 | return dca_enabled_in_bios(pdev); |
110 | 110 | ||
111 | dev_err(&pdev->dev, "boot cpu doesn't have X86_FEATURE_DCA\n"); | 111 | dev_dbg(&pdev->dev, "boot cpu doesn't have X86_FEATURE_DCA\n"); |
112 | return 0; | 112 | return 0; |
113 | } | 113 | } |
114 | 114 | ||
diff --git a/drivers/dma/ioat/dma.h b/drivers/dma/ioat/dma.h index c14fdfeb7f33..45edde996480 100644 --- a/drivers/dma/ioat/dma.h +++ b/drivers/dma/ioat/dma.h | |||
@@ -297,9 +297,7 @@ static inline bool is_ioat_suspended(unsigned long status) | |||
297 | /* channel was fatally programmed */ | 297 | /* channel was fatally programmed */ |
298 | static inline bool is_ioat_bug(unsigned long err) | 298 | static inline bool is_ioat_bug(unsigned long err) |
299 | { | 299 | { |
300 | return !!(err & (IOAT_CHANERR_SRC_ADDR_ERR|IOAT_CHANERR_DEST_ADDR_ERR| | 300 | return !!err; |
301 | IOAT_CHANERR_NEXT_ADDR_ERR|IOAT_CHANERR_CONTROL_ERR| | ||
302 | IOAT_CHANERR_LENGTH_ERR)); | ||
303 | } | 301 | } |
304 | 302 | ||
305 | static inline void ioat_unmap(struct pci_dev *pdev, dma_addr_t addr, size_t len, | 303 | static inline void ioat_unmap(struct pci_dev *pdev, dma_addr_t addr, size_t len, |
diff --git a/drivers/dma/ioat/dma_v2.c b/drivers/dma/ioat/dma_v2.c index 96ffab7d37a7..8f1f7f05deaa 100644 --- a/drivers/dma/ioat/dma_v2.c +++ b/drivers/dma/ioat/dma_v2.c | |||
@@ -279,6 +279,8 @@ void ioat2_timer_event(unsigned long data) | |||
279 | u32 chanerr; | 279 | u32 chanerr; |
280 | 280 | ||
281 | chanerr = readl(chan->reg_base + IOAT_CHANERR_OFFSET); | 281 | chanerr = readl(chan->reg_base + IOAT_CHANERR_OFFSET); |
282 | dev_err(to_dev(chan), "%s: Channel halted (%x)\n", | ||
283 | __func__, chanerr); | ||
282 | BUG_ON(is_ioat_bug(chanerr)); | 284 | BUG_ON(is_ioat_bug(chanerr)); |
283 | } | 285 | } |
284 | 286 | ||
diff --git a/drivers/dma/ioat/dma_v3.c b/drivers/dma/ioat/dma_v3.c index 35d1e33afd5b..42f6f10fb0cc 100644 --- a/drivers/dma/ioat/dma_v3.c +++ b/drivers/dma/ioat/dma_v3.c | |||
@@ -378,6 +378,8 @@ static void ioat3_timer_event(unsigned long data) | |||
378 | u32 chanerr; | 378 | u32 chanerr; |
379 | 379 | ||
380 | chanerr = readl(chan->reg_base + IOAT_CHANERR_OFFSET); | 380 | chanerr = readl(chan->reg_base + IOAT_CHANERR_OFFSET); |
381 | dev_err(to_dev(chan), "%s: Channel halted (%x)\n", | ||
382 | __func__, chanerr); | ||
381 | BUG_ON(is_ioat_bug(chanerr)); | 383 | BUG_ON(is_ioat_bug(chanerr)); |
382 | } | 384 | } |
383 | 385 | ||
@@ -569,7 +571,7 @@ __ioat3_prep_xor_lock(struct dma_chan *c, enum sum_check_flags *result, | |||
569 | dump_desc_dbg(ioat, compl_desc); | 571 | dump_desc_dbg(ioat, compl_desc); |
570 | 572 | ||
571 | /* we leave the channel locked to ensure in order submission */ | 573 | /* we leave the channel locked to ensure in order submission */ |
572 | return &desc->txd; | 574 | return &compl_desc->txd; |
573 | } | 575 | } |
574 | 576 | ||
575 | static struct dma_async_tx_descriptor * | 577 | static struct dma_async_tx_descriptor * |
@@ -728,7 +730,7 @@ __ioat3_prep_pq_lock(struct dma_chan *c, enum sum_check_flags *result, | |||
728 | dump_desc_dbg(ioat, compl_desc); | 730 | dump_desc_dbg(ioat, compl_desc); |
729 | 731 | ||
730 | /* we leave the channel locked to ensure in order submission */ | 732 | /* we leave the channel locked to ensure in order submission */ |
731 | return &desc->txd; | 733 | return &compl_desc->txd; |
732 | } | 734 | } |
733 | 735 | ||
734 | static struct dma_async_tx_descriptor * | 736 | static struct dma_async_tx_descriptor * |
@@ -736,10 +738,16 @@ ioat3_prep_pq(struct dma_chan *chan, dma_addr_t *dst, dma_addr_t *src, | |||
736 | unsigned int src_cnt, const unsigned char *scf, size_t len, | 738 | unsigned int src_cnt, const unsigned char *scf, size_t len, |
737 | unsigned long flags) | 739 | unsigned long flags) |
738 | { | 740 | { |
741 | /* specify valid address for disabled result */ | ||
742 | if (flags & DMA_PREP_PQ_DISABLE_P) | ||
743 | dst[0] = dst[1]; | ||
744 | if (flags & DMA_PREP_PQ_DISABLE_Q) | ||
745 | dst[1] = dst[0]; | ||
746 | |||
739 | /* handle the single source multiply case from the raid6 | 747 | /* handle the single source multiply case from the raid6 |
740 | * recovery path | 748 | * recovery path |
741 | */ | 749 | */ |
742 | if (unlikely((flags & DMA_PREP_PQ_DISABLE_P) && src_cnt == 1)) { | 750 | if ((flags & DMA_PREP_PQ_DISABLE_P) && src_cnt == 1) { |
743 | dma_addr_t single_source[2]; | 751 | dma_addr_t single_source[2]; |
744 | unsigned char single_source_coef[2]; | 752 | unsigned char single_source_coef[2]; |
745 | 753 | ||
@@ -761,6 +769,12 @@ ioat3_prep_pq_val(struct dma_chan *chan, dma_addr_t *pq, dma_addr_t *src, | |||
761 | unsigned int src_cnt, const unsigned char *scf, size_t len, | 769 | unsigned int src_cnt, const unsigned char *scf, size_t len, |
762 | enum sum_check_flags *pqres, unsigned long flags) | 770 | enum sum_check_flags *pqres, unsigned long flags) |
763 | { | 771 | { |
772 | /* specify valid address for disabled result */ | ||
773 | if (flags & DMA_PREP_PQ_DISABLE_P) | ||
774 | pq[0] = pq[1]; | ||
775 | if (flags & DMA_PREP_PQ_DISABLE_Q) | ||
776 | pq[1] = pq[0]; | ||
777 | |||
764 | /* the cleanup routine only sets bits on validate failure, it | 778 | /* the cleanup routine only sets bits on validate failure, it |
765 | * does not clear bits on validate success... so clear it here | 779 | * does not clear bits on validate success... so clear it here |
766 | */ | 780 | */ |
@@ -778,9 +792,9 @@ ioat3_prep_pqxor(struct dma_chan *chan, dma_addr_t dst, dma_addr_t *src, | |||
778 | dma_addr_t pq[2]; | 792 | dma_addr_t pq[2]; |
779 | 793 | ||
780 | memset(scf, 0, src_cnt); | 794 | memset(scf, 0, src_cnt); |
781 | flags |= DMA_PREP_PQ_DISABLE_Q; | ||
782 | pq[0] = dst; | 795 | pq[0] = dst; |
783 | pq[1] = ~0; | 796 | flags |= DMA_PREP_PQ_DISABLE_Q; |
797 | pq[1] = dst; /* specify valid address for disabled result */ | ||
784 | 798 | ||
785 | return __ioat3_prep_pq_lock(chan, NULL, pq, src, src_cnt, scf, len, | 799 | return __ioat3_prep_pq_lock(chan, NULL, pq, src, src_cnt, scf, len, |
786 | flags); | 800 | flags); |
@@ -800,9 +814,9 @@ ioat3_prep_pqxor_val(struct dma_chan *chan, dma_addr_t *src, | |||
800 | *result = 0; | 814 | *result = 0; |
801 | 815 | ||
802 | memset(scf, 0, src_cnt); | 816 | memset(scf, 0, src_cnt); |
803 | flags |= DMA_PREP_PQ_DISABLE_Q; | ||
804 | pq[0] = src[0]; | 817 | pq[0] = src[0]; |
805 | pq[1] = ~0; | 818 | flags |= DMA_PREP_PQ_DISABLE_Q; |
819 | pq[1] = pq[0]; /* specify valid address for disabled result */ | ||
806 | 820 | ||
807 | return __ioat3_prep_pq_lock(chan, result, pq, &src[1], src_cnt - 1, scf, | 821 | return __ioat3_prep_pq_lock(chan, result, pq, &src[1], src_cnt - 1, scf, |
808 | len, flags); | 822 | len, flags); |
@@ -1117,6 +1131,7 @@ static int __devinit ioat3_dma_self_test(struct ioatdma_device *device) | |||
1117 | int __devinit ioat3_dma_probe(struct ioatdma_device *device, int dca) | 1131 | int __devinit ioat3_dma_probe(struct ioatdma_device *device, int dca) |
1118 | { | 1132 | { |
1119 | struct pci_dev *pdev = device->pdev; | 1133 | struct pci_dev *pdev = device->pdev; |
1134 | int dca_en = system_has_dca_enabled(pdev); | ||
1120 | struct dma_device *dma; | 1135 | struct dma_device *dma; |
1121 | struct dma_chan *c; | 1136 | struct dma_chan *c; |
1122 | struct ioat_chan_common *chan; | 1137 | struct ioat_chan_common *chan; |
@@ -1137,6 +1152,11 @@ int __devinit ioat3_dma_probe(struct ioatdma_device *device, int dca) | |||
1137 | dma->device_prep_dma_interrupt = ioat3_prep_interrupt_lock; | 1152 | dma->device_prep_dma_interrupt = ioat3_prep_interrupt_lock; |
1138 | 1153 | ||
1139 | cap = readl(device->reg_base + IOAT_DMA_CAP_OFFSET); | 1154 | cap = readl(device->reg_base + IOAT_DMA_CAP_OFFSET); |
1155 | |||
1156 | /* dca is incompatible with raid operations */ | ||
1157 | if (dca_en && (cap & (IOAT_CAP_XOR|IOAT_CAP_PQ))) | ||
1158 | cap &= ~(IOAT_CAP_XOR|IOAT_CAP_PQ); | ||
1159 | |||
1140 | if (cap & IOAT_CAP_XOR) { | 1160 | if (cap & IOAT_CAP_XOR) { |
1141 | is_raid_device = true; | 1161 | is_raid_device = true; |
1142 | dma->max_xor = 8; | 1162 | dma->max_xor = 8; |
@@ -1186,6 +1206,16 @@ int __devinit ioat3_dma_probe(struct ioatdma_device *device, int dca) | |||
1186 | device->timer_fn = ioat2_timer_event; | 1206 | device->timer_fn = ioat2_timer_event; |
1187 | } | 1207 | } |
1188 | 1208 | ||
1209 | #ifdef CONFIG_ASYNC_TX_DISABLE_PQ_VAL_DMA | ||
1210 | dma_cap_clear(DMA_PQ_VAL, dma->cap_mask); | ||
1211 | dma->device_prep_dma_pq_val = NULL; | ||
1212 | #endif | ||
1213 | |||
1214 | #ifdef CONFIG_ASYNC_TX_DISABLE_XOR_VAL_DMA | ||
1215 | dma_cap_clear(DMA_XOR_VAL, dma->cap_mask); | ||
1216 | dma->device_prep_dma_xor_val = NULL; | ||
1217 | #endif | ||
1218 | |||
1189 | /* -= IOAT ver.3 workarounds =- */ | 1219 | /* -= IOAT ver.3 workarounds =- */ |
1190 | /* Write CHANERRMSK_INT with 3E07h to mask out the errors | 1220 | /* Write CHANERRMSK_INT with 3E07h to mask out the errors |
1191 | * that can cause stability issues for IOAT ver.3 | 1221 | * that can cause stability issues for IOAT ver.3 |
diff --git a/drivers/dma/ioat/hw.h b/drivers/dma/ioat/hw.h index 99afb12bd409..60e675455b6a 100644 --- a/drivers/dma/ioat/hw.h +++ b/drivers/dma/ioat/hw.h | |||
@@ -39,6 +39,8 @@ | |||
39 | #define IOAT_VER_3_0 0x30 /* Version 3.0 */ | 39 | #define IOAT_VER_3_0 0x30 /* Version 3.0 */ |
40 | #define IOAT_VER_3_2 0x32 /* Version 3.2 */ | 40 | #define IOAT_VER_3_2 0x32 /* Version 3.2 */ |
41 | 41 | ||
42 | int system_has_dca_enabled(struct pci_dev *pdev); | ||
43 | |||
42 | struct ioat_dma_descriptor { | 44 | struct ioat_dma_descriptor { |
43 | uint32_t size; | 45 | uint32_t size; |
44 | union { | 46 | union { |
diff --git a/drivers/dma/ioat/registers.h b/drivers/dma/ioat/registers.h index 63038e18ab03..f015ec196700 100644 --- a/drivers/dma/ioat/registers.h +++ b/drivers/dma/ioat/registers.h | |||
@@ -92,9 +92,7 @@ | |||
92 | #define IOAT_CHANCTRL_ERR_COMPLETION_EN 0x0004 | 92 | #define IOAT_CHANCTRL_ERR_COMPLETION_EN 0x0004 |
93 | #define IOAT_CHANCTRL_INT_REARM 0x0001 | 93 | #define IOAT_CHANCTRL_INT_REARM 0x0001 |
94 | #define IOAT_CHANCTRL_RUN (IOAT_CHANCTRL_INT_REARM |\ | 94 | #define IOAT_CHANCTRL_RUN (IOAT_CHANCTRL_INT_REARM |\ |
95 | IOAT_CHANCTRL_ERR_COMPLETION_EN |\ | 95 | IOAT_CHANCTRL_ANY_ERR_ABORT_EN) |
96 | IOAT_CHANCTRL_ANY_ERR_ABORT_EN |\ | ||
97 | IOAT_CHANCTRL_ERR_INT_EN) | ||
98 | 96 | ||
99 | #define IOAT_DMA_COMP_OFFSET 0x02 /* 16-bit DMA channel compatibility */ | 97 | #define IOAT_DMA_COMP_OFFSET 0x02 /* 16-bit DMA channel compatibility */ |
100 | #define IOAT_DMA_COMP_V1 0x0001 /* Compatibility with DMA version 1 */ | 98 | #define IOAT_DMA_COMP_V1 0x0001 /* Compatibility with DMA version 1 */ |
diff --git a/drivers/dma/shdma.c b/drivers/dma/shdma.c index b3b065c4e5c1..034ecf0ace03 100644 --- a/drivers/dma/shdma.c +++ b/drivers/dma/shdma.c | |||
@@ -640,17 +640,16 @@ static int __init sh_dmae_probe(struct platform_device *pdev) | |||
640 | #endif | 640 | #endif |
641 | struct sh_dmae_device *shdev; | 641 | struct sh_dmae_device *shdev; |
642 | 642 | ||
643 | /* get platform data */ | ||
644 | if (!pdev->dev.platform_data) | ||
645 | return -ENODEV; | ||
646 | |||
643 | shdev = kzalloc(sizeof(struct sh_dmae_device), GFP_KERNEL); | 647 | shdev = kzalloc(sizeof(struct sh_dmae_device), GFP_KERNEL); |
644 | if (!shdev) { | 648 | if (!shdev) { |
645 | dev_err(&pdev->dev, "No enough memory\n"); | 649 | dev_err(&pdev->dev, "No enough memory\n"); |
646 | err = -ENOMEM; | 650 | return -ENOMEM; |
647 | goto shdev_err; | ||
648 | } | 651 | } |
649 | 652 | ||
650 | /* get platform data */ | ||
651 | if (!pdev->dev.platform_data) | ||
652 | goto shdev_err; | ||
653 | |||
654 | /* platform data */ | 653 | /* platform data */ |
655 | memcpy(&shdev->pdata, pdev->dev.platform_data, | 654 | memcpy(&shdev->pdata, pdev->dev.platform_data, |
656 | sizeof(struct sh_dmae_pdata)); | 655 | sizeof(struct sh_dmae_pdata)); |
@@ -722,7 +721,6 @@ eirq_err: | |||
722 | rst_err: | 721 | rst_err: |
723 | kfree(shdev); | 722 | kfree(shdev); |
724 | 723 | ||
725 | shdev_err: | ||
726 | return err; | 724 | return err; |
727 | } | 725 | } |
728 | 726 | ||
diff --git a/drivers/firewire/ohci.c b/drivers/firewire/ohci.c index 5d524254499e..94260aa76aa3 100644 --- a/drivers/firewire/ohci.c +++ b/drivers/firewire/ohci.c | |||
@@ -275,7 +275,7 @@ static void log_irqs(u32 evt) | |||
275 | !(evt & OHCI1394_busReset)) | 275 | !(evt & OHCI1394_busReset)) |
276 | return; | 276 | return; |
277 | 277 | ||
278 | fw_notify("IRQ %08x%s%s%s%s%s%s%s%s%s%s%s%s%s\n", evt, | 278 | fw_notify("IRQ %08x%s%s%s%s%s%s%s%s%s%s%s%s%s%s\n", evt, |
279 | evt & OHCI1394_selfIDComplete ? " selfID" : "", | 279 | evt & OHCI1394_selfIDComplete ? " selfID" : "", |
280 | evt & OHCI1394_RQPkt ? " AR_req" : "", | 280 | evt & OHCI1394_RQPkt ? " AR_req" : "", |
281 | evt & OHCI1394_RSPkt ? " AR_resp" : "", | 281 | evt & OHCI1394_RSPkt ? " AR_resp" : "", |
@@ -286,6 +286,7 @@ static void log_irqs(u32 evt) | |||
286 | evt & OHCI1394_postedWriteErr ? " postedWriteErr" : "", | 286 | evt & OHCI1394_postedWriteErr ? " postedWriteErr" : "", |
287 | evt & OHCI1394_cycleTooLong ? " cycleTooLong" : "", | 287 | evt & OHCI1394_cycleTooLong ? " cycleTooLong" : "", |
288 | evt & OHCI1394_cycle64Seconds ? " cycle64Seconds" : "", | 288 | evt & OHCI1394_cycle64Seconds ? " cycle64Seconds" : "", |
289 | evt & OHCI1394_cycleInconsistent ? " cycleInconsistent" : "", | ||
289 | evt & OHCI1394_regAccessFail ? " regAccessFail" : "", | 290 | evt & OHCI1394_regAccessFail ? " regAccessFail" : "", |
290 | evt & OHCI1394_busReset ? " busReset" : "", | 291 | evt & OHCI1394_busReset ? " busReset" : "", |
291 | evt & ~(OHCI1394_selfIDComplete | OHCI1394_RQPkt | | 292 | evt & ~(OHCI1394_selfIDComplete | OHCI1394_RQPkt | |
@@ -293,6 +294,7 @@ static void log_irqs(u32 evt) | |||
293 | OHCI1394_respTxComplete | OHCI1394_isochRx | | 294 | OHCI1394_respTxComplete | OHCI1394_isochRx | |
294 | OHCI1394_isochTx | OHCI1394_postedWriteErr | | 295 | OHCI1394_isochTx | OHCI1394_postedWriteErr | |
295 | OHCI1394_cycleTooLong | OHCI1394_cycle64Seconds | | 296 | OHCI1394_cycleTooLong | OHCI1394_cycle64Seconds | |
297 | OHCI1394_cycleInconsistent | | ||
296 | OHCI1394_regAccessFail | OHCI1394_busReset) | 298 | OHCI1394_regAccessFail | OHCI1394_busReset) |
297 | ? " ?" : ""); | 299 | ? " ?" : ""); |
298 | } | 300 | } |
@@ -1439,6 +1441,17 @@ static irqreturn_t irq_handler(int irq, void *data) | |||
1439 | OHCI1394_LinkControl_cycleMaster); | 1441 | OHCI1394_LinkControl_cycleMaster); |
1440 | } | 1442 | } |
1441 | 1443 | ||
1444 | if (unlikely(event & OHCI1394_cycleInconsistent)) { | ||
1445 | /* | ||
1446 | * We need to clear this event bit in order to make | ||
1447 | * cycleMatch isochronous I/O work. In theory we should | ||
1448 | * stop active cycleMatch iso contexts now and restart | ||
1449 | * them at least two cycles later. (FIXME?) | ||
1450 | */ | ||
1451 | if (printk_ratelimit()) | ||
1452 | fw_notify("isochronous cycle inconsistent\n"); | ||
1453 | } | ||
1454 | |||
1442 | if (event & OHCI1394_cycle64Seconds) { | 1455 | if (event & OHCI1394_cycle64Seconds) { |
1443 | cycle_time = reg_read(ohci, OHCI1394_IsochronousCycleTimer); | 1456 | cycle_time = reg_read(ohci, OHCI1394_IsochronousCycleTimer); |
1444 | if ((cycle_time & 0x80000000) == 0) | 1457 | if ((cycle_time & 0x80000000) == 0) |
@@ -1528,6 +1541,7 @@ static int ohci_enable(struct fw_card *card, u32 *config_rom, size_t length) | |||
1528 | OHCI1394_reqTxComplete | OHCI1394_respTxComplete | | 1541 | OHCI1394_reqTxComplete | OHCI1394_respTxComplete | |
1529 | OHCI1394_isochRx | OHCI1394_isochTx | | 1542 | OHCI1394_isochRx | OHCI1394_isochTx | |
1530 | OHCI1394_postedWriteErr | OHCI1394_cycleTooLong | | 1543 | OHCI1394_postedWriteErr | OHCI1394_cycleTooLong | |
1544 | OHCI1394_cycleInconsistent | | ||
1531 | OHCI1394_cycle64Seconds | OHCI1394_regAccessFail | | 1545 | OHCI1394_cycle64Seconds | OHCI1394_regAccessFail | |
1532 | OHCI1394_masterIntEnable); | 1546 | OHCI1394_masterIntEnable); |
1533 | if (param_debug & OHCI_PARAM_DEBUG_BUSRESETS) | 1547 | if (param_debug & OHCI_PARAM_DEBUG_BUSRESETS) |
@@ -1890,15 +1904,30 @@ static int handle_it_packet(struct context *context, | |||
1890 | { | 1904 | { |
1891 | struct iso_context *ctx = | 1905 | struct iso_context *ctx = |
1892 | container_of(context, struct iso_context, context); | 1906 | container_of(context, struct iso_context, context); |
1907 | int i; | ||
1908 | struct descriptor *pd; | ||
1893 | 1909 | ||
1894 | if (last->transfer_status == 0) | 1910 | for (pd = d; pd <= last; pd++) |
1895 | /* This descriptor isn't done yet, stop iteration. */ | 1911 | if (pd->transfer_status) |
1912 | break; | ||
1913 | if (pd > last) | ||
1914 | /* Descriptor(s) not done yet, stop iteration */ | ||
1896 | return 0; | 1915 | return 0; |
1897 | 1916 | ||
1898 | if (le16_to_cpu(last->control) & DESCRIPTOR_IRQ_ALWAYS) | 1917 | i = ctx->header_length; |
1918 | if (i + 4 < PAGE_SIZE) { | ||
1919 | /* Present this value as big-endian to match the receive code */ | ||
1920 | *(__be32 *)(ctx->header + i) = cpu_to_be32( | ||
1921 | ((u32)le16_to_cpu(pd->transfer_status) << 16) | | ||
1922 | le16_to_cpu(pd->res_count)); | ||
1923 | ctx->header_length += 4; | ||
1924 | } | ||
1925 | if (le16_to_cpu(last->control) & DESCRIPTOR_IRQ_ALWAYS) { | ||
1899 | ctx->base.callback(&ctx->base, le16_to_cpu(last->res_count), | 1926 | ctx->base.callback(&ctx->base, le16_to_cpu(last->res_count), |
1900 | 0, NULL, ctx->base.callback_data); | 1927 | ctx->header_length, ctx->header, |
1901 | 1928 | ctx->base.callback_data); | |
1929 | ctx->header_length = 0; | ||
1930 | } | ||
1902 | return 1; | 1931 | return 1; |
1903 | } | 1932 | } |
1904 | 1933 | ||
diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig index f831ea159291..96eddd17e050 100644 --- a/drivers/gpu/drm/Kconfig +++ b/drivers/gpu/drm/Kconfig | |||
@@ -92,6 +92,7 @@ config DRM_I830 | |||
92 | config DRM_I915 | 92 | config DRM_I915 |
93 | tristate "i915 driver" | 93 | tristate "i915 driver" |
94 | depends on AGP_INTEL | 94 | depends on AGP_INTEL |
95 | select SHMEM | ||
95 | select DRM_KMS_HELPER | 96 | select DRM_KMS_HELPER |
96 | select FB_CFB_FILLRECT | 97 | select FB_CFB_FILLRECT |
97 | select FB_CFB_COPYAREA | 98 | select FB_CFB_COPYAREA |
diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c index cea665d86dd3..b54ba63d506e 100644 --- a/drivers/gpu/drm/drm_edid.c +++ b/drivers/gpu/drm/drm_edid.c | |||
@@ -662,6 +662,12 @@ static struct drm_display_mode *drm_mode_detailed(struct drm_device *dev, | |||
662 | return NULL; | 662 | return NULL; |
663 | } | 663 | } |
664 | 664 | ||
665 | /* Some EDIDs have bogus h/vtotal values */ | ||
666 | if (mode->hsync_end > mode->htotal) | ||
667 | mode->htotal = mode->hsync_end + 1; | ||
668 | if (mode->vsync_end > mode->vtotal) | ||
669 | mode->vtotal = mode->vsync_end + 1; | ||
670 | |||
665 | drm_mode_set_name(mode); | 671 | drm_mode_set_name(mode); |
666 | 672 | ||
667 | if (pt->misc & DRM_EDID_PT_INTERLACED) | 673 | if (pt->misc & DRM_EDID_PT_INTERLACED) |
diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c index dc8e374a0b55..65ef011fa8ba 100644 --- a/drivers/gpu/drm/drm_fb_helper.c +++ b/drivers/gpu/drm/drm_fb_helper.c | |||
@@ -599,7 +599,7 @@ int drm_fb_helper_check_var(struct fb_var_screeninfo *var, | |||
599 | struct drm_framebuffer *fb = fb_helper->fb; | 599 | struct drm_framebuffer *fb = fb_helper->fb; |
600 | int depth; | 600 | int depth; |
601 | 601 | ||
602 | if (var->pixclock == -1 || !var->pixclock) | 602 | if (var->pixclock != 0) |
603 | return -EINVAL; | 603 | return -EINVAL; |
604 | 604 | ||
605 | /* Need to resize the fb object !!! */ | 605 | /* Need to resize the fb object !!! */ |
@@ -691,7 +691,7 @@ int drm_fb_helper_set_par(struct fb_info *info) | |||
691 | int ret; | 691 | int ret; |
692 | int i; | 692 | int i; |
693 | 693 | ||
694 | if (var->pixclock != -1) { | 694 | if (var->pixclock != 0) { |
695 | DRM_ERROR("PIXEL CLCOK SET\n"); | 695 | DRM_ERROR("PIXEL CLCOK SET\n"); |
696 | return -EINVAL; | 696 | return -EINVAL; |
697 | } | 697 | } |
@@ -904,7 +904,7 @@ int drm_fb_helper_single_fb_probe(struct drm_device *dev, | |||
904 | fb_helper->fb = fb; | 904 | fb_helper->fb = fb; |
905 | 905 | ||
906 | if (new_fb) { | 906 | if (new_fb) { |
907 | info->var.pixclock = -1; | 907 | info->var.pixclock = 0; |
908 | if (register_framebuffer(info) < 0) | 908 | if (register_framebuffer(info) < 0) |
909 | return -EINVAL; | 909 | return -EINVAL; |
910 | } else { | 910 | } else { |
diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c index 80391995bdec..e9dbb481c469 100644 --- a/drivers/gpu/drm/drm_gem.c +++ b/drivers/gpu/drm/drm_gem.c | |||
@@ -552,7 +552,7 @@ int drm_gem_mmap(struct file *filp, struct vm_area_struct *vma) | |||
552 | vma->vm_flags |= VM_RESERVED | VM_IO | VM_PFNMAP | VM_DONTEXPAND; | 552 | vma->vm_flags |= VM_RESERVED | VM_IO | VM_PFNMAP | VM_DONTEXPAND; |
553 | vma->vm_ops = obj->dev->driver->gem_vm_ops; | 553 | vma->vm_ops = obj->dev->driver->gem_vm_ops; |
554 | vma->vm_private_data = map->handle; | 554 | vma->vm_private_data = map->handle; |
555 | vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot); | 555 | vma->vm_page_prot = pgprot_writecombine(vm_get_page_prot(vma->vm_flags)); |
556 | 556 | ||
557 | /* Take a ref for this mapping of the object, so that the fault | 557 | /* Take a ref for this mapping of the object, so that the fault |
558 | * handler can dereference the mmap offset's pointer to the object. | 558 | * handler can dereference the mmap offset's pointer to the object. |
diff --git a/drivers/gpu/drm/drm_mm.c b/drivers/gpu/drm/drm_mm.c index c861d80fd779..97dc5a4f0de4 100644 --- a/drivers/gpu/drm/drm_mm.c +++ b/drivers/gpu/drm/drm_mm.c | |||
@@ -103,6 +103,11 @@ static struct drm_mm_node *drm_mm_kmalloc(struct drm_mm *mm, int atomic) | |||
103 | return child; | 103 | return child; |
104 | } | 104 | } |
105 | 105 | ||
106 | /* drm_mm_pre_get() - pre allocate drm_mm_node structure | ||
107 | * drm_mm: memory manager struct we are pre-allocating for | ||
108 | * | ||
109 | * Returns 0 on success or -ENOMEM if allocation fails. | ||
110 | */ | ||
106 | int drm_mm_pre_get(struct drm_mm *mm) | 111 | int drm_mm_pre_get(struct drm_mm *mm) |
107 | { | 112 | { |
108 | struct drm_mm_node *node; | 113 | struct drm_mm_node *node; |
@@ -253,12 +258,14 @@ void drm_mm_put_block(struct drm_mm_node *cur) | |||
253 | prev_node->size += next_node->size; | 258 | prev_node->size += next_node->size; |
254 | list_del(&next_node->ml_entry); | 259 | list_del(&next_node->ml_entry); |
255 | list_del(&next_node->fl_entry); | 260 | list_del(&next_node->fl_entry); |
261 | spin_lock(&mm->unused_lock); | ||
256 | if (mm->num_unused < MM_UNUSED_TARGET) { | 262 | if (mm->num_unused < MM_UNUSED_TARGET) { |
257 | list_add(&next_node->fl_entry, | 263 | list_add(&next_node->fl_entry, |
258 | &mm->unused_nodes); | 264 | &mm->unused_nodes); |
259 | ++mm->num_unused; | 265 | ++mm->num_unused; |
260 | } else | 266 | } else |
261 | kfree(next_node); | 267 | kfree(next_node); |
268 | spin_unlock(&mm->unused_lock); | ||
262 | } else { | 269 | } else { |
263 | next_node->size += cur->size; | 270 | next_node->size += cur->size; |
264 | next_node->start = cur->start; | 271 | next_node->start = cur->start; |
@@ -271,11 +278,13 @@ void drm_mm_put_block(struct drm_mm_node *cur) | |||
271 | list_add(&cur->fl_entry, &mm->fl_entry); | 278 | list_add(&cur->fl_entry, &mm->fl_entry); |
272 | } else { | 279 | } else { |
273 | list_del(&cur->ml_entry); | 280 | list_del(&cur->ml_entry); |
281 | spin_lock(&mm->unused_lock); | ||
274 | if (mm->num_unused < MM_UNUSED_TARGET) { | 282 | if (mm->num_unused < MM_UNUSED_TARGET) { |
275 | list_add(&cur->fl_entry, &mm->unused_nodes); | 283 | list_add(&cur->fl_entry, &mm->unused_nodes); |
276 | ++mm->num_unused; | 284 | ++mm->num_unused; |
277 | } else | 285 | } else |
278 | kfree(cur); | 286 | kfree(cur); |
287 | spin_unlock(&mm->unused_lock); | ||
279 | } | 288 | } |
280 | } | 289 | } |
281 | 290 | ||
diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index f8ce9a3a420d..26bf0552b3cb 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c | |||
@@ -267,10 +267,10 @@ static void i915_dump_pages(struct seq_file *m, struct page **pages, int page_co | |||
267 | uint32_t *mem; | 267 | uint32_t *mem; |
268 | 268 | ||
269 | for (page = 0; page < page_count; page++) { | 269 | for (page = 0; page < page_count; page++) { |
270 | mem = kmap(pages[page]); | 270 | mem = kmap_atomic(pages[page], KM_USER0); |
271 | for (i = 0; i < PAGE_SIZE; i += 4) | 271 | for (i = 0; i < PAGE_SIZE; i += 4) |
272 | seq_printf(m, "%08x : %08x\n", i, mem[i / 4]); | 272 | seq_printf(m, "%08x : %08x\n", i, mem[i / 4]); |
273 | kunmap(pages[page]); | 273 | kunmap_atomic(pages[page], KM_USER0); |
274 | } | 274 | } |
275 | } | 275 | } |
276 | 276 | ||
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 57204e298975..a725f6591192 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h | |||
@@ -296,6 +296,7 @@ typedef struct drm_i915_private { | |||
296 | u32 saveVBLANK_A; | 296 | u32 saveVBLANK_A; |
297 | u32 saveVSYNC_A; | 297 | u32 saveVSYNC_A; |
298 | u32 saveBCLRPAT_A; | 298 | u32 saveBCLRPAT_A; |
299 | u32 saveTRANSACONF; | ||
299 | u32 saveTRANS_HTOTAL_A; | 300 | u32 saveTRANS_HTOTAL_A; |
300 | u32 saveTRANS_HBLANK_A; | 301 | u32 saveTRANS_HBLANK_A; |
301 | u32 saveTRANS_HSYNC_A; | 302 | u32 saveTRANS_HSYNC_A; |
@@ -326,6 +327,7 @@ typedef struct drm_i915_private { | |||
326 | u32 saveVBLANK_B; | 327 | u32 saveVBLANK_B; |
327 | u32 saveVSYNC_B; | 328 | u32 saveVSYNC_B; |
328 | u32 saveBCLRPAT_B; | 329 | u32 saveBCLRPAT_B; |
330 | u32 saveTRANSBCONF; | ||
329 | u32 saveTRANS_HTOTAL_B; | 331 | u32 saveTRANS_HTOTAL_B; |
330 | u32 saveTRANS_HBLANK_B; | 332 | u32 saveTRANS_HBLANK_B; |
331 | u32 saveTRANS_HSYNC_B; | 333 | u32 saveTRANS_HSYNC_B; |
@@ -414,6 +416,16 @@ typedef struct drm_i915_private { | |||
414 | u32 savePFB_WIN_SZ; | 416 | u32 savePFB_WIN_SZ; |
415 | u32 savePFA_WIN_POS; | 417 | u32 savePFA_WIN_POS; |
416 | u32 savePFB_WIN_POS; | 418 | u32 savePFB_WIN_POS; |
419 | u32 savePCH_DREF_CONTROL; | ||
420 | u32 saveDISP_ARB_CTL; | ||
421 | u32 savePIPEA_DATA_M1; | ||
422 | u32 savePIPEA_DATA_N1; | ||
423 | u32 savePIPEA_LINK_M1; | ||
424 | u32 savePIPEA_LINK_N1; | ||
425 | u32 savePIPEB_DATA_M1; | ||
426 | u32 savePIPEB_DATA_N1; | ||
427 | u32 savePIPEB_LINK_M1; | ||
428 | u32 savePIPEB_LINK_N1; | ||
417 | 429 | ||
418 | struct { | 430 | struct { |
419 | struct drm_mm gtt_space; | 431 | struct drm_mm gtt_space; |
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index c3ceffa46ea0..aa7fd82aa6eb 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c | |||
@@ -254,10 +254,15 @@ irqreturn_t igdng_irq_handler(struct drm_device *dev) | |||
254 | { | 254 | { |
255 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; | 255 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; |
256 | int ret = IRQ_NONE; | 256 | int ret = IRQ_NONE; |
257 | u32 de_iir, gt_iir; | 257 | u32 de_iir, gt_iir, de_ier; |
258 | u32 new_de_iir, new_gt_iir; | 258 | u32 new_de_iir, new_gt_iir; |
259 | struct drm_i915_master_private *master_priv; | 259 | struct drm_i915_master_private *master_priv; |
260 | 260 | ||
261 | /* disable master interrupt before clearing iir */ | ||
262 | de_ier = I915_READ(DEIER); | ||
263 | I915_WRITE(DEIER, de_ier & ~DE_MASTER_IRQ_CONTROL); | ||
264 | (void)I915_READ(DEIER); | ||
265 | |||
261 | de_iir = I915_READ(DEIIR); | 266 | de_iir = I915_READ(DEIIR); |
262 | gt_iir = I915_READ(GTIIR); | 267 | gt_iir = I915_READ(GTIIR); |
263 | 268 | ||
@@ -290,6 +295,9 @@ irqreturn_t igdng_irq_handler(struct drm_device *dev) | |||
290 | gt_iir = new_gt_iir; | 295 | gt_iir = new_gt_iir; |
291 | } | 296 | } |
292 | 297 | ||
298 | I915_WRITE(DEIER, de_ier); | ||
299 | (void)I915_READ(DEIER); | ||
300 | |||
293 | return ret; | 301 | return ret; |
294 | } | 302 | } |
295 | 303 | ||
diff --git a/drivers/gpu/drm/i915/i915_suspend.c b/drivers/gpu/drm/i915/i915_suspend.c index 992d5617e798..6eec8171a44e 100644 --- a/drivers/gpu/drm/i915/i915_suspend.c +++ b/drivers/gpu/drm/i915/i915_suspend.c | |||
@@ -239,6 +239,11 @@ static void i915_save_modeset_reg(struct drm_device *dev) | |||
239 | if (drm_core_check_feature(dev, DRIVER_MODESET)) | 239 | if (drm_core_check_feature(dev, DRIVER_MODESET)) |
240 | return; | 240 | return; |
241 | 241 | ||
242 | if (IS_IGDNG(dev)) { | ||
243 | dev_priv->savePCH_DREF_CONTROL = I915_READ(PCH_DREF_CONTROL); | ||
244 | dev_priv->saveDISP_ARB_CTL = I915_READ(DISP_ARB_CTL); | ||
245 | } | ||
246 | |||
242 | /* Pipe & plane A info */ | 247 | /* Pipe & plane A info */ |
243 | dev_priv->savePIPEACONF = I915_READ(PIPEACONF); | 248 | dev_priv->savePIPEACONF = I915_READ(PIPEACONF); |
244 | dev_priv->savePIPEASRC = I915_READ(PIPEASRC); | 249 | dev_priv->savePIPEASRC = I915_READ(PIPEASRC); |
@@ -263,6 +268,11 @@ static void i915_save_modeset_reg(struct drm_device *dev) | |||
263 | dev_priv->saveBCLRPAT_A = I915_READ(BCLRPAT_A); | 268 | dev_priv->saveBCLRPAT_A = I915_READ(BCLRPAT_A); |
264 | 269 | ||
265 | if (IS_IGDNG(dev)) { | 270 | if (IS_IGDNG(dev)) { |
271 | dev_priv->savePIPEA_DATA_M1 = I915_READ(PIPEA_DATA_M1); | ||
272 | dev_priv->savePIPEA_DATA_N1 = I915_READ(PIPEA_DATA_N1); | ||
273 | dev_priv->savePIPEA_LINK_M1 = I915_READ(PIPEA_LINK_M1); | ||
274 | dev_priv->savePIPEA_LINK_N1 = I915_READ(PIPEA_LINK_N1); | ||
275 | |||
266 | dev_priv->saveFDI_TXA_CTL = I915_READ(FDI_TXA_CTL); | 276 | dev_priv->saveFDI_TXA_CTL = I915_READ(FDI_TXA_CTL); |
267 | dev_priv->saveFDI_RXA_CTL = I915_READ(FDI_RXA_CTL); | 277 | dev_priv->saveFDI_RXA_CTL = I915_READ(FDI_RXA_CTL); |
268 | 278 | ||
@@ -270,6 +280,7 @@ static void i915_save_modeset_reg(struct drm_device *dev) | |||
270 | dev_priv->savePFA_WIN_SZ = I915_READ(PFA_WIN_SZ); | 280 | dev_priv->savePFA_WIN_SZ = I915_READ(PFA_WIN_SZ); |
271 | dev_priv->savePFA_WIN_POS = I915_READ(PFA_WIN_POS); | 281 | dev_priv->savePFA_WIN_POS = I915_READ(PFA_WIN_POS); |
272 | 282 | ||
283 | dev_priv->saveTRANSACONF = I915_READ(TRANSACONF); | ||
273 | dev_priv->saveTRANS_HTOTAL_A = I915_READ(TRANS_HTOTAL_A); | 284 | dev_priv->saveTRANS_HTOTAL_A = I915_READ(TRANS_HTOTAL_A); |
274 | dev_priv->saveTRANS_HBLANK_A = I915_READ(TRANS_HBLANK_A); | 285 | dev_priv->saveTRANS_HBLANK_A = I915_READ(TRANS_HBLANK_A); |
275 | dev_priv->saveTRANS_HSYNC_A = I915_READ(TRANS_HSYNC_A); | 286 | dev_priv->saveTRANS_HSYNC_A = I915_READ(TRANS_HSYNC_A); |
@@ -314,6 +325,11 @@ static void i915_save_modeset_reg(struct drm_device *dev) | |||
314 | dev_priv->saveBCLRPAT_B = I915_READ(BCLRPAT_B); | 325 | dev_priv->saveBCLRPAT_B = I915_READ(BCLRPAT_B); |
315 | 326 | ||
316 | if (IS_IGDNG(dev)) { | 327 | if (IS_IGDNG(dev)) { |
328 | dev_priv->savePIPEB_DATA_M1 = I915_READ(PIPEB_DATA_M1); | ||
329 | dev_priv->savePIPEB_DATA_N1 = I915_READ(PIPEB_DATA_N1); | ||
330 | dev_priv->savePIPEB_LINK_M1 = I915_READ(PIPEB_LINK_M1); | ||
331 | dev_priv->savePIPEB_LINK_N1 = I915_READ(PIPEB_LINK_N1); | ||
332 | |||
317 | dev_priv->saveFDI_TXB_CTL = I915_READ(FDI_TXB_CTL); | 333 | dev_priv->saveFDI_TXB_CTL = I915_READ(FDI_TXB_CTL); |
318 | dev_priv->saveFDI_RXB_CTL = I915_READ(FDI_RXB_CTL); | 334 | dev_priv->saveFDI_RXB_CTL = I915_READ(FDI_RXB_CTL); |
319 | 335 | ||
@@ -321,6 +337,7 @@ static void i915_save_modeset_reg(struct drm_device *dev) | |||
321 | dev_priv->savePFB_WIN_SZ = I915_READ(PFB_WIN_SZ); | 337 | dev_priv->savePFB_WIN_SZ = I915_READ(PFB_WIN_SZ); |
322 | dev_priv->savePFB_WIN_POS = I915_READ(PFB_WIN_POS); | 338 | dev_priv->savePFB_WIN_POS = I915_READ(PFB_WIN_POS); |
323 | 339 | ||
340 | dev_priv->saveTRANSBCONF = I915_READ(TRANSBCONF); | ||
324 | dev_priv->saveTRANS_HTOTAL_B = I915_READ(TRANS_HTOTAL_B); | 341 | dev_priv->saveTRANS_HTOTAL_B = I915_READ(TRANS_HTOTAL_B); |
325 | dev_priv->saveTRANS_HBLANK_B = I915_READ(TRANS_HBLANK_B); | 342 | dev_priv->saveTRANS_HBLANK_B = I915_READ(TRANS_HBLANK_B); |
326 | dev_priv->saveTRANS_HSYNC_B = I915_READ(TRANS_HSYNC_B); | 343 | dev_priv->saveTRANS_HSYNC_B = I915_READ(TRANS_HSYNC_B); |
@@ -368,6 +385,11 @@ static void i915_restore_modeset_reg(struct drm_device *dev) | |||
368 | fpb1_reg = FPB1; | 385 | fpb1_reg = FPB1; |
369 | } | 386 | } |
370 | 387 | ||
388 | if (IS_IGDNG(dev)) { | ||
389 | I915_WRITE(PCH_DREF_CONTROL, dev_priv->savePCH_DREF_CONTROL); | ||
390 | I915_WRITE(DISP_ARB_CTL, dev_priv->saveDISP_ARB_CTL); | ||
391 | } | ||
392 | |||
371 | /* Pipe & plane A info */ | 393 | /* Pipe & plane A info */ |
372 | /* Prime the clock */ | 394 | /* Prime the clock */ |
373 | if (dev_priv->saveDPLL_A & DPLL_VCO_ENABLE) { | 395 | if (dev_priv->saveDPLL_A & DPLL_VCO_ENABLE) { |
@@ -395,6 +417,11 @@ static void i915_restore_modeset_reg(struct drm_device *dev) | |||
395 | I915_WRITE(BCLRPAT_A, dev_priv->saveBCLRPAT_A); | 417 | I915_WRITE(BCLRPAT_A, dev_priv->saveBCLRPAT_A); |
396 | 418 | ||
397 | if (IS_IGDNG(dev)) { | 419 | if (IS_IGDNG(dev)) { |
420 | I915_WRITE(PIPEA_DATA_M1, dev_priv->savePIPEA_DATA_M1); | ||
421 | I915_WRITE(PIPEA_DATA_N1, dev_priv->savePIPEA_DATA_N1); | ||
422 | I915_WRITE(PIPEA_LINK_M1, dev_priv->savePIPEA_LINK_M1); | ||
423 | I915_WRITE(PIPEA_LINK_N1, dev_priv->savePIPEA_LINK_N1); | ||
424 | |||
398 | I915_WRITE(FDI_RXA_CTL, dev_priv->saveFDI_RXA_CTL); | 425 | I915_WRITE(FDI_RXA_CTL, dev_priv->saveFDI_RXA_CTL); |
399 | I915_WRITE(FDI_TXA_CTL, dev_priv->saveFDI_TXA_CTL); | 426 | I915_WRITE(FDI_TXA_CTL, dev_priv->saveFDI_TXA_CTL); |
400 | 427 | ||
@@ -402,6 +429,7 @@ static void i915_restore_modeset_reg(struct drm_device *dev) | |||
402 | I915_WRITE(PFA_WIN_SZ, dev_priv->savePFA_WIN_SZ); | 429 | I915_WRITE(PFA_WIN_SZ, dev_priv->savePFA_WIN_SZ); |
403 | I915_WRITE(PFA_WIN_POS, dev_priv->savePFA_WIN_POS); | 430 | I915_WRITE(PFA_WIN_POS, dev_priv->savePFA_WIN_POS); |
404 | 431 | ||
432 | I915_WRITE(TRANSACONF, dev_priv->saveTRANSACONF); | ||
405 | I915_WRITE(TRANS_HTOTAL_A, dev_priv->saveTRANS_HTOTAL_A); | 433 | I915_WRITE(TRANS_HTOTAL_A, dev_priv->saveTRANS_HTOTAL_A); |
406 | I915_WRITE(TRANS_HBLANK_A, dev_priv->saveTRANS_HBLANK_A); | 434 | I915_WRITE(TRANS_HBLANK_A, dev_priv->saveTRANS_HBLANK_A); |
407 | I915_WRITE(TRANS_HSYNC_A, dev_priv->saveTRANS_HSYNC_A); | 435 | I915_WRITE(TRANS_HSYNC_A, dev_priv->saveTRANS_HSYNC_A); |
@@ -439,7 +467,7 @@ static void i915_restore_modeset_reg(struct drm_device *dev) | |||
439 | /* Actually enable it */ | 467 | /* Actually enable it */ |
440 | I915_WRITE(dpll_b_reg, dev_priv->saveDPLL_B); | 468 | I915_WRITE(dpll_b_reg, dev_priv->saveDPLL_B); |
441 | DRM_UDELAY(150); | 469 | DRM_UDELAY(150); |
442 | if (IS_I965G(dev)) | 470 | if (IS_I965G(dev) && !IS_IGDNG(dev)) |
443 | I915_WRITE(DPLL_B_MD, dev_priv->saveDPLL_B_MD); | 471 | I915_WRITE(DPLL_B_MD, dev_priv->saveDPLL_B_MD); |
444 | DRM_UDELAY(150); | 472 | DRM_UDELAY(150); |
445 | 473 | ||
@@ -454,6 +482,11 @@ static void i915_restore_modeset_reg(struct drm_device *dev) | |||
454 | I915_WRITE(BCLRPAT_B, dev_priv->saveBCLRPAT_B); | 482 | I915_WRITE(BCLRPAT_B, dev_priv->saveBCLRPAT_B); |
455 | 483 | ||
456 | if (IS_IGDNG(dev)) { | 484 | if (IS_IGDNG(dev)) { |
485 | I915_WRITE(PIPEB_DATA_M1, dev_priv->savePIPEB_DATA_M1); | ||
486 | I915_WRITE(PIPEB_DATA_N1, dev_priv->savePIPEB_DATA_N1); | ||
487 | I915_WRITE(PIPEB_LINK_M1, dev_priv->savePIPEB_LINK_M1); | ||
488 | I915_WRITE(PIPEB_LINK_N1, dev_priv->savePIPEB_LINK_N1); | ||
489 | |||
457 | I915_WRITE(FDI_RXB_CTL, dev_priv->saveFDI_RXB_CTL); | 490 | I915_WRITE(FDI_RXB_CTL, dev_priv->saveFDI_RXB_CTL); |
458 | I915_WRITE(FDI_TXB_CTL, dev_priv->saveFDI_TXB_CTL); | 491 | I915_WRITE(FDI_TXB_CTL, dev_priv->saveFDI_TXB_CTL); |
459 | 492 | ||
@@ -461,6 +494,7 @@ static void i915_restore_modeset_reg(struct drm_device *dev) | |||
461 | I915_WRITE(PFB_WIN_SZ, dev_priv->savePFB_WIN_SZ); | 494 | I915_WRITE(PFB_WIN_SZ, dev_priv->savePFB_WIN_SZ); |
462 | I915_WRITE(PFB_WIN_POS, dev_priv->savePFB_WIN_POS); | 495 | I915_WRITE(PFB_WIN_POS, dev_priv->savePFB_WIN_POS); |
463 | 496 | ||
497 | I915_WRITE(TRANSBCONF, dev_priv->saveTRANSBCONF); | ||
464 | I915_WRITE(TRANS_HTOTAL_B, dev_priv->saveTRANS_HTOTAL_B); | 498 | I915_WRITE(TRANS_HTOTAL_B, dev_priv->saveTRANS_HTOTAL_B); |
465 | I915_WRITE(TRANS_HBLANK_B, dev_priv->saveTRANS_HBLANK_B); | 499 | I915_WRITE(TRANS_HBLANK_B, dev_priv->saveTRANS_HBLANK_B); |
466 | I915_WRITE(TRANS_HSYNC_B, dev_priv->saveTRANS_HSYNC_B); | 500 | I915_WRITE(TRANS_HSYNC_B, dev_priv->saveTRANS_HSYNC_B); |
diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c index 212e22740fc1..e5051446c48e 100644 --- a/drivers/gpu/drm/i915/intel_crt.c +++ b/drivers/gpu/drm/i915/intel_crt.c | |||
@@ -262,8 +262,8 @@ static bool intel_crt_detect_hotplug(struct drm_connector *connector) | |||
262 | } while (time_after(timeout, jiffies)); | 262 | } while (time_after(timeout, jiffies)); |
263 | } | 263 | } |
264 | 264 | ||
265 | if ((I915_READ(PORT_HOTPLUG_STAT) & CRT_HOTPLUG_MONITOR_MASK) == | 265 | if ((I915_READ(PORT_HOTPLUG_STAT) & CRT_HOTPLUG_MONITOR_MASK) != |
266 | CRT_HOTPLUG_MONITOR_COLOR) | 266 | CRT_HOTPLUG_MONITOR_NONE) |
267 | return true; | 267 | return true; |
268 | 268 | ||
269 | return false; | 269 | return false; |
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 3ba6546b7c7f..099f420de57a 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c | |||
@@ -863,10 +863,8 @@ intel_igdng_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, | |||
863 | struct drm_device *dev = crtc->dev; | 863 | struct drm_device *dev = crtc->dev; |
864 | struct drm_i915_private *dev_priv = dev->dev_private; | 864 | struct drm_i915_private *dev_priv = dev->dev_private; |
865 | intel_clock_t clock; | 865 | intel_clock_t clock; |
866 | int max_n; | ||
867 | bool found; | ||
868 | int err_most = 47; | 866 | int err_most = 47; |
869 | found = false; | 867 | int err_min = 10000; |
870 | 868 | ||
871 | /* eDP has only 2 clock choice, no n/m/p setting */ | 869 | /* eDP has only 2 clock choice, no n/m/p setting */ |
872 | if (HAS_eDP) | 870 | if (HAS_eDP) |
@@ -890,10 +888,9 @@ intel_igdng_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, | |||
890 | } | 888 | } |
891 | 889 | ||
892 | memset(best_clock, 0, sizeof(*best_clock)); | 890 | memset(best_clock, 0, sizeof(*best_clock)); |
893 | max_n = limit->n.max; | ||
894 | for (clock.p1 = limit->p1.max; clock.p1 >= limit->p1.min; clock.p1--) { | 891 | for (clock.p1 = limit->p1.max; clock.p1 >= limit->p1.min; clock.p1--) { |
895 | /* based on hardware requriment prefer smaller n to precision */ | 892 | /* based on hardware requriment prefer smaller n to precision */ |
896 | for (clock.n = limit->n.min; clock.n <= max_n; clock.n++) { | 893 | for (clock.n = limit->n.min; clock.n <= limit->n.max; clock.n++) { |
897 | /* based on hardware requirment prefere larger m1,m2 */ | 894 | /* based on hardware requirment prefere larger m1,m2 */ |
898 | for (clock.m1 = limit->m1.max; | 895 | for (clock.m1 = limit->m1.max; |
899 | clock.m1 >= limit->m1.min; clock.m1--) { | 896 | clock.m1 >= limit->m1.min; clock.m1--) { |
@@ -907,18 +904,18 @@ intel_igdng_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, | |||
907 | this_err = abs((10000 - (target*10000/clock.dot))); | 904 | this_err = abs((10000 - (target*10000/clock.dot))); |
908 | if (this_err < err_most) { | 905 | if (this_err < err_most) { |
909 | *best_clock = clock; | 906 | *best_clock = clock; |
910 | err_most = this_err; | ||
911 | max_n = clock.n; | ||
912 | found = true; | ||
913 | /* found on first matching */ | 907 | /* found on first matching */ |
914 | goto out; | 908 | goto out; |
909 | } else if (this_err < err_min) { | ||
910 | *best_clock = clock; | ||
911 | err_min = this_err; | ||
915 | } | 912 | } |
916 | } | 913 | } |
917 | } | 914 | } |
918 | } | 915 | } |
919 | } | 916 | } |
920 | out: | 917 | out: |
921 | return found; | 918 | return true; |
922 | } | 919 | } |
923 | 920 | ||
924 | /* DisplayPort has only two frequencies, 162MHz and 270MHz */ | 921 | /* DisplayPort has only two frequencies, 162MHz and 270MHz */ |
diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c index 663ab6de0b58..c33451aec1bd 100644 --- a/drivers/gpu/drm/i915/intel_hdmi.c +++ b/drivers/gpu/drm/i915/intel_hdmi.c | |||
@@ -77,14 +77,32 @@ static void intel_hdmi_dpms(struct drm_encoder *encoder, int mode) | |||
77 | struct intel_hdmi_priv *hdmi_priv = intel_output->dev_priv; | 77 | struct intel_hdmi_priv *hdmi_priv = intel_output->dev_priv; |
78 | u32 temp; | 78 | u32 temp; |
79 | 79 | ||
80 | if (mode != DRM_MODE_DPMS_ON) { | 80 | temp = I915_READ(hdmi_priv->sdvox_reg); |
81 | temp = I915_READ(hdmi_priv->sdvox_reg); | 81 | |
82 | /* HW workaround, need to toggle enable bit off and on for 12bpc, but | ||
83 | * we do this anyway which shows more stable in testing. | ||
84 | */ | ||
85 | if (IS_IGDNG(dev)) { | ||
82 | I915_WRITE(hdmi_priv->sdvox_reg, temp & ~SDVO_ENABLE); | 86 | I915_WRITE(hdmi_priv->sdvox_reg, temp & ~SDVO_ENABLE); |
87 | POSTING_READ(hdmi_priv->sdvox_reg); | ||
88 | } | ||
89 | |||
90 | if (mode != DRM_MODE_DPMS_ON) { | ||
91 | temp &= ~SDVO_ENABLE; | ||
83 | } else { | 92 | } else { |
84 | temp = I915_READ(hdmi_priv->sdvox_reg); | 93 | temp |= SDVO_ENABLE; |
85 | I915_WRITE(hdmi_priv->sdvox_reg, temp | SDVO_ENABLE); | ||
86 | } | 94 | } |
95 | |||
96 | I915_WRITE(hdmi_priv->sdvox_reg, temp); | ||
87 | POSTING_READ(hdmi_priv->sdvox_reg); | 97 | POSTING_READ(hdmi_priv->sdvox_reg); |
98 | |||
99 | /* HW workaround, need to write this twice for issue that may result | ||
100 | * in first write getting masked. | ||
101 | */ | ||
102 | if (IS_IGDNG(dev)) { | ||
103 | I915_WRITE(hdmi_priv->sdvox_reg, temp); | ||
104 | POSTING_READ(hdmi_priv->sdvox_reg); | ||
105 | } | ||
88 | } | 106 | } |
89 | 107 | ||
90 | static void intel_hdmi_save(struct drm_connector *connector) | 108 | static void intel_hdmi_save(struct drm_connector *connector) |
diff --git a/drivers/gpu/drm/radeon/atom.c b/drivers/gpu/drm/radeon/atom.c index 901befe03da2..d67c42555ab9 100644 --- a/drivers/gpu/drm/radeon/atom.c +++ b/drivers/gpu/drm/radeon/atom.c | |||
@@ -107,6 +107,7 @@ static uint32_t atom_iio_execute(struct atom_context *ctx, int base, | |||
107 | base += 3; | 107 | base += 3; |
108 | break; | 108 | break; |
109 | case ATOM_IIO_WRITE: | 109 | case ATOM_IIO_WRITE: |
110 | (void)ctx->card->reg_read(ctx->card, CU16(base + 1)); | ||
110 | ctx->card->reg_write(ctx->card, CU16(base + 1), temp); | 111 | ctx->card->reg_write(ctx->card, CU16(base + 1), temp); |
111 | base += 3; | 112 | base += 3; |
112 | break; | 113 | break; |
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index 757f5cd37744..224506a2f7b1 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h | |||
@@ -519,6 +519,7 @@ typedef int (*radeon_packet3_check_t)(struct radeon_cs_parser *p, | |||
519 | * AGP | 519 | * AGP |
520 | */ | 520 | */ |
521 | int radeon_agp_init(struct radeon_device *rdev); | 521 | int radeon_agp_init(struct radeon_device *rdev); |
522 | void radeon_agp_resume(struct radeon_device *rdev); | ||
522 | void radeon_agp_fini(struct radeon_device *rdev); | 523 | void radeon_agp_fini(struct radeon_device *rdev); |
523 | 524 | ||
524 | 525 | ||
diff --git a/drivers/gpu/drm/radeon/radeon_agp.c b/drivers/gpu/drm/radeon/radeon_agp.c index 23ea9955ac59..54bf49a6d676 100644 --- a/drivers/gpu/drm/radeon/radeon_agp.c +++ b/drivers/gpu/drm/radeon/radeon_agp.c | |||
@@ -237,6 +237,18 @@ int radeon_agp_init(struct radeon_device *rdev) | |||
237 | #endif | 237 | #endif |
238 | } | 238 | } |
239 | 239 | ||
240 | void radeon_agp_resume(struct radeon_device *rdev) | ||
241 | { | ||
242 | #if __OS_HAS_AGP | ||
243 | int r; | ||
244 | if (rdev->flags & RADEON_IS_AGP) { | ||
245 | r = radeon_agp_init(rdev); | ||
246 | if (r) | ||
247 | dev_warn(rdev->dev, "radeon AGP reinit failed\n"); | ||
248 | } | ||
249 | #endif | ||
250 | } | ||
251 | |||
240 | void radeon_agp_fini(struct radeon_device *rdev) | 252 | void radeon_agp_fini(struct radeon_device *rdev) |
241 | { | 253 | { |
242 | #if __OS_HAS_AGP | 254 | #if __OS_HAS_AGP |
diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c index fce4c4087fda..29763ceae3af 100644 --- a/drivers/gpu/drm/radeon/radeon_connectors.c +++ b/drivers/gpu/drm/radeon/radeon_connectors.c | |||
@@ -566,8 +566,9 @@ static enum drm_connector_status radeon_vga_detect(struct drm_connector *connect | |||
566 | radeon_i2c_do_lock(radeon_connector, 0); | 566 | radeon_i2c_do_lock(radeon_connector, 0); |
567 | 567 | ||
568 | if (!radeon_connector->edid) { | 568 | if (!radeon_connector->edid) { |
569 | DRM_ERROR("DDC responded but not EDID found for %s\n", | 569 | DRM_ERROR("%s: probed a monitor but no|invalid EDID\n", |
570 | drm_get_connector_name(connector)); | 570 | drm_get_connector_name(connector)); |
571 | ret = connector_status_connected; | ||
571 | } else { | 572 | } else { |
572 | radeon_connector->use_digital = !!(radeon_connector->edid->input & DRM_EDID_INPUT_DIGITAL); | 573 | radeon_connector->use_digital = !!(radeon_connector->edid->input & DRM_EDID_INPUT_DIGITAL); |
573 | 574 | ||
@@ -720,8 +721,8 @@ static enum drm_connector_status radeon_dvi_detect(struct drm_connector *connect | |||
720 | radeon_i2c_do_lock(radeon_connector, 0); | 721 | radeon_i2c_do_lock(radeon_connector, 0); |
721 | 722 | ||
722 | if (!radeon_connector->edid) { | 723 | if (!radeon_connector->edid) { |
723 | DRM_ERROR("DDC responded but not EDID found for %s\n", | 724 | DRM_ERROR("%s: probed a monitor but no|invalid EDID\n", |
724 | drm_get_connector_name(connector)); | 725 | drm_get_connector_name(connector)); |
725 | } else { | 726 | } else { |
726 | radeon_connector->use_digital = !!(radeon_connector->edid->input & DRM_EDID_INPUT_DIGITAL); | 727 | radeon_connector->use_digital = !!(radeon_connector->edid->input & DRM_EDID_INPUT_DIGITAL); |
727 | 728 | ||
@@ -1149,6 +1150,13 @@ radeon_add_legacy_connector(struct drm_device *dev, | |||
1149 | if (ret) | 1150 | if (ret) |
1150 | goto failed; | 1151 | goto failed; |
1151 | radeon_connector->dac_load_detect = true; | 1152 | radeon_connector->dac_load_detect = true; |
1153 | /* RS400,RC410,RS480 chipset seems to report a lot | ||
1154 | * of false positive on load detect, we haven't yet | ||
1155 | * found a way to make load detect reliable on those | ||
1156 | * chipset, thus just disable it for TV. | ||
1157 | */ | ||
1158 | if (rdev->family == CHIP_RS400 || rdev->family == CHIP_RS480) | ||
1159 | radeon_connector->dac_load_detect = false; | ||
1152 | drm_connector_attach_property(&radeon_connector->base, | 1160 | drm_connector_attach_property(&radeon_connector->base, |
1153 | rdev->mode_info.load_detect_property, | 1161 | rdev->mode_info.load_detect_property, |
1154 | 1); | 1162 | 1); |
diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c index e3f9edfa40fe..41bb76fbe734 100644 --- a/drivers/gpu/drm/radeon/radeon_device.c +++ b/drivers/gpu/drm/radeon/radeon_device.c | |||
@@ -688,6 +688,8 @@ int radeon_resume_kms(struct drm_device *dev) | |||
688 | return -1; | 688 | return -1; |
689 | } | 689 | } |
690 | pci_set_master(dev->pdev); | 690 | pci_set_master(dev->pdev); |
691 | /* resume AGP if in use */ | ||
692 | radeon_agp_resume(rdev); | ||
691 | radeon_resume(rdev); | 693 | radeon_resume(rdev); |
692 | radeon_restore_bios_scratch_regs(rdev); | 694 | radeon_restore_bios_scratch_regs(rdev); |
693 | fb_set_suspend(rdev->fbdev_info, 0); | 695 | fb_set_suspend(rdev->fbdev_info, 0); |
diff --git a/drivers/gpu/drm/radeon/rv515.c b/drivers/gpu/drm/radeon/rv515.c index 7935f793bf62..ba68c9fe90a1 100644 --- a/drivers/gpu/drm/radeon/rv515.c +++ b/drivers/gpu/drm/radeon/rv515.c | |||
@@ -137,8 +137,6 @@ int rv515_mc_wait_for_idle(struct radeon_device *rdev) | |||
137 | 137 | ||
138 | void rv515_vga_render_disable(struct radeon_device *rdev) | 138 | void rv515_vga_render_disable(struct radeon_device *rdev) |
139 | { | 139 | { |
140 | WREG32(R_000330_D1VGA_CONTROL, 0); | ||
141 | WREG32(R_000338_D2VGA_CONTROL, 0); | ||
142 | WREG32(R_000300_VGA_RENDER_CONTROL, | 140 | WREG32(R_000300_VGA_RENDER_CONTROL, |
143 | RREG32(R_000300_VGA_RENDER_CONTROL) & C_000300_VGA_VSTATUS_CNTL); | 141 | RREG32(R_000300_VGA_RENDER_CONTROL) & C_000300_VGA_VSTATUS_CNTL); |
144 | } | 142 | } |
@@ -382,7 +380,6 @@ void rv515_mc_stop(struct radeon_device *rdev, struct rv515_mc_save *save) | |||
382 | save->d2crtc_control = RREG32(R_006880_D2CRTC_CONTROL); | 380 | save->d2crtc_control = RREG32(R_006880_D2CRTC_CONTROL); |
383 | 381 | ||
384 | /* Stop all video */ | 382 | /* Stop all video */ |
385 | WREG32(R_000330_D1VGA_CONTROL, 0); | ||
386 | WREG32(R_0068E8_D2CRTC_UPDATE_LOCK, 0); | 383 | WREG32(R_0068E8_D2CRTC_UPDATE_LOCK, 0); |
387 | WREG32(R_000300_VGA_RENDER_CONTROL, 0); | 384 | WREG32(R_000300_VGA_RENDER_CONTROL, 0); |
388 | WREG32(R_0060E8_D1CRTC_UPDATE_LOCK, 1); | 385 | WREG32(R_0060E8_D1CRTC_UPDATE_LOCK, 1); |
@@ -391,6 +388,8 @@ void rv515_mc_stop(struct radeon_device *rdev, struct rv515_mc_save *save) | |||
391 | WREG32(R_006880_D2CRTC_CONTROL, 0); | 388 | WREG32(R_006880_D2CRTC_CONTROL, 0); |
392 | WREG32(R_0060E8_D1CRTC_UPDATE_LOCK, 0); | 389 | WREG32(R_0060E8_D1CRTC_UPDATE_LOCK, 0); |
393 | WREG32(R_0068E8_D2CRTC_UPDATE_LOCK, 0); | 390 | WREG32(R_0068E8_D2CRTC_UPDATE_LOCK, 0); |
391 | WREG32(R_000330_D1VGA_CONTROL, 0); | ||
392 | WREG32(R_000338_D2VGA_CONTROL, 0); | ||
394 | } | 393 | } |
395 | 394 | ||
396 | void rv515_mc_resume(struct radeon_device *rdev, struct rv515_mc_save *save) | 395 | void rv515_mc_resume(struct radeon_device *rdev, struct rv515_mc_save *save) |
@@ -404,14 +403,14 @@ void rv515_mc_resume(struct radeon_device *rdev, struct rv515_mc_save *save) | |||
404 | WREG32(R_000328_VGA_HDP_CONTROL, save->vga_hdp_control); | 403 | WREG32(R_000328_VGA_HDP_CONTROL, save->vga_hdp_control); |
405 | mdelay(1); | 404 | mdelay(1); |
406 | /* Restore video state */ | 405 | /* Restore video state */ |
406 | WREG32(R_000330_D1VGA_CONTROL, save->d1vga_control); | ||
407 | WREG32(R_000338_D2VGA_CONTROL, save->d2vga_control); | ||
407 | WREG32(R_0060E8_D1CRTC_UPDATE_LOCK, 1); | 408 | WREG32(R_0060E8_D1CRTC_UPDATE_LOCK, 1); |
408 | WREG32(R_0068E8_D2CRTC_UPDATE_LOCK, 1); | 409 | WREG32(R_0068E8_D2CRTC_UPDATE_LOCK, 1); |
409 | WREG32(R_006080_D1CRTC_CONTROL, save->d1crtc_control); | 410 | WREG32(R_006080_D1CRTC_CONTROL, save->d1crtc_control); |
410 | WREG32(R_006880_D2CRTC_CONTROL, save->d2crtc_control); | 411 | WREG32(R_006880_D2CRTC_CONTROL, save->d2crtc_control); |
411 | WREG32(R_0060E8_D1CRTC_UPDATE_LOCK, 0); | 412 | WREG32(R_0060E8_D1CRTC_UPDATE_LOCK, 0); |
412 | WREG32(R_0068E8_D2CRTC_UPDATE_LOCK, 0); | 413 | WREG32(R_0068E8_D2CRTC_UPDATE_LOCK, 0); |
413 | WREG32(R_000330_D1VGA_CONTROL, save->d1vga_control); | ||
414 | WREG32(R_000338_D2VGA_CONTROL, save->d2vga_control); | ||
415 | WREG32(R_000300_VGA_RENDER_CONTROL, save->vga_render_control); | 414 | WREG32(R_000300_VGA_RENDER_CONTROL, save->vga_render_control); |
416 | } | 415 | } |
417 | 416 | ||
diff --git a/drivers/i2c/busses/i2c-pnx.c b/drivers/i2c/busses/i2c-pnx.c index 6ff6c20f1e78..fbab6846ae64 100644 --- a/drivers/i2c/busses/i2c-pnx.c +++ b/drivers/i2c/busses/i2c-pnx.c | |||
@@ -19,7 +19,9 @@ | |||
19 | #include <linux/completion.h> | 19 | #include <linux/completion.h> |
20 | #include <linux/platform_device.h> | 20 | #include <linux/platform_device.h> |
21 | #include <linux/i2c-pnx.h> | 21 | #include <linux/i2c-pnx.h> |
22 | #include <linux/io.h> | ||
22 | #include <mach/hardware.h> | 23 | #include <mach/hardware.h> |
24 | #include <mach/i2c.h> | ||
23 | #include <asm/irq.h> | 25 | #include <asm/irq.h> |
24 | #include <asm/uaccess.h> | 26 | #include <asm/uaccess.h> |
25 | 27 | ||
@@ -54,6 +56,9 @@ static inline void i2c_pnx_arm_timer(struct i2c_adapter *adap) | |||
54 | struct timer_list *timer = &data->mif.timer; | 56 | struct timer_list *timer = &data->mif.timer; |
55 | int expires = I2C_PNX_TIMEOUT / (1000 / HZ); | 57 | int expires = I2C_PNX_TIMEOUT / (1000 / HZ); |
56 | 58 | ||
59 | if (expires <= 1) | ||
60 | expires = 2; | ||
61 | |||
57 | del_timer_sync(timer); | 62 | del_timer_sync(timer); |
58 | 63 | ||
59 | dev_dbg(&adap->dev, "Timer armed at %lu plus %u jiffies.\n", | 64 | dev_dbg(&adap->dev, "Timer armed at %lu plus %u jiffies.\n", |
@@ -645,7 +650,7 @@ static int __devinit i2c_pnx_probe(struct platform_device *pdev) | |||
645 | return 0; | 650 | return 0; |
646 | 651 | ||
647 | out_irq: | 652 | out_irq: |
648 | free_irq(alg_data->irq, alg_data); | 653 | free_irq(alg_data->irq, i2c_pnx->adapter); |
649 | out_clock: | 654 | out_clock: |
650 | i2c_pnx->set_clock_stop(pdev); | 655 | i2c_pnx->set_clock_stop(pdev); |
651 | out_unmap: | 656 | out_unmap: |
@@ -664,7 +669,7 @@ static int __devexit i2c_pnx_remove(struct platform_device *pdev) | |||
664 | struct i2c_adapter *adap = i2c_pnx->adapter; | 669 | struct i2c_adapter *adap = i2c_pnx->adapter; |
665 | struct i2c_pnx_algo_data *alg_data = adap->algo_data; | 670 | struct i2c_pnx_algo_data *alg_data = adap->algo_data; |
666 | 671 | ||
667 | free_irq(alg_data->irq, alg_data); | 672 | free_irq(alg_data->irq, i2c_pnx->adapter); |
668 | i2c_del_adapter(adap); | 673 | i2c_del_adapter(adap); |
669 | i2c_pnx->set_clock_stop(pdev); | 674 | i2c_pnx->set_clock_stop(pdev); |
670 | iounmap((void *)alg_data->ioaddr); | 675 | iounmap((void *)alg_data->ioaddr); |
diff --git a/drivers/i2c/chips/tsl2550.c b/drivers/i2c/chips/tsl2550.c index aa96bd2d27ea..a0702f36a72f 100644 --- a/drivers/i2c/chips/tsl2550.c +++ b/drivers/i2c/chips/tsl2550.c | |||
@@ -257,6 +257,7 @@ static DEVICE_ATTR(operating_mode, S_IWUSR | S_IRUGO, | |||
257 | 257 | ||
258 | static ssize_t __tsl2550_show_lux(struct i2c_client *client, char *buf) | 258 | static ssize_t __tsl2550_show_lux(struct i2c_client *client, char *buf) |
259 | { | 259 | { |
260 | struct tsl2550_data *data = i2c_get_clientdata(client); | ||
260 | u8 ch0, ch1; | 261 | u8 ch0, ch1; |
261 | int ret; | 262 | int ret; |
262 | 263 | ||
@@ -274,6 +275,8 @@ static ssize_t __tsl2550_show_lux(struct i2c_client *client, char *buf) | |||
274 | ret = tsl2550_calculate_lux(ch0, ch1); | 275 | ret = tsl2550_calculate_lux(ch0, ch1); |
275 | if (ret < 0) | 276 | if (ret < 0) |
276 | return ret; | 277 | return ret; |
278 | if (data->operating_mode == 1) | ||
279 | ret *= 5; | ||
277 | 280 | ||
278 | return sprintf(buf, "%d\n", ret); | 281 | return sprintf(buf, "%d\n", ret); |
279 | } | 282 | } |
diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c index 8d80fceca6a4..296504355142 100644 --- a/drivers/i2c/i2c-core.c +++ b/drivers/i2c/i2c-core.c | |||
@@ -762,6 +762,7 @@ int i2c_del_adapter(struct i2c_adapter *adap) | |||
762 | { | 762 | { |
763 | int res = 0; | 763 | int res = 0; |
764 | struct i2c_adapter *found; | 764 | struct i2c_adapter *found; |
765 | struct i2c_client *client, *next; | ||
765 | 766 | ||
766 | /* First make sure that this adapter was ever added */ | 767 | /* First make sure that this adapter was ever added */ |
767 | mutex_lock(&core_lock); | 768 | mutex_lock(&core_lock); |
@@ -781,6 +782,16 @@ int i2c_del_adapter(struct i2c_adapter *adap) | |||
781 | if (res) | 782 | if (res) |
782 | return res; | 783 | return res; |
783 | 784 | ||
785 | /* Remove devices instantiated from sysfs */ | ||
786 | list_for_each_entry_safe(client, next, &userspace_devices, detected) { | ||
787 | if (client->adapter == adap) { | ||
788 | dev_dbg(&adap->dev, "Removing %s at 0x%x\n", | ||
789 | client->name, client->addr); | ||
790 | list_del(&client->detected); | ||
791 | i2c_unregister_device(client); | ||
792 | } | ||
793 | } | ||
794 | |||
784 | /* Detach any active clients. This can't fail, thus we do not | 795 | /* Detach any active clients. This can't fail, thus we do not |
785 | checking the returned value. */ | 796 | checking the returned value. */ |
786 | res = device_for_each_child(&adap->dev, NULL, __unregister_client); | 797 | res = device_for_each_child(&adap->dev, NULL, __unregister_client); |
diff --git a/drivers/ide/ide-ioctls.c b/drivers/ide/ide-ioctls.c index d3440b5010a5..6e7ae2b6cfc6 100644 --- a/drivers/ide/ide-ioctls.c +++ b/drivers/ide/ide-ioctls.c | |||
@@ -162,7 +162,7 @@ static int ide_cmd_ioctl(ide_drive_t *drive, unsigned long arg) | |||
162 | if (tf->command == ATA_CMD_SET_FEATURES && | 162 | if (tf->command == ATA_CMD_SET_FEATURES && |
163 | tf->feature == SETFEATURES_XFER && | 163 | tf->feature == SETFEATURES_XFER && |
164 | tf->nsect >= XFER_SW_DMA_0) { | 164 | tf->nsect >= XFER_SW_DMA_0) { |
165 | xfer_rate = ide_find_dma_mode(drive, XFER_UDMA_6); | 165 | xfer_rate = ide_find_dma_mode(drive, tf->nsect); |
166 | if (xfer_rate != tf->nsect) { | 166 | if (xfer_rate != tf->nsect) { |
167 | err = -EINVAL; | 167 | err = -EINVAL; |
168 | goto abort; | 168 | goto abort; |
diff --git a/drivers/ieee802154/fakehard.c b/drivers/ieee802154/fakehard.c index 96a2959ce877..7c544f7c74c4 100644 --- a/drivers/ieee802154/fakehard.c +++ b/drivers/ieee802154/fakehard.c | |||
@@ -260,15 +260,12 @@ static int ieee802154_fake_close(struct net_device *dev) | |||
260 | static netdev_tx_t ieee802154_fake_xmit(struct sk_buff *skb, | 260 | static netdev_tx_t ieee802154_fake_xmit(struct sk_buff *skb, |
261 | struct net_device *dev) | 261 | struct net_device *dev) |
262 | { | 262 | { |
263 | skb->iif = dev->ifindex; | ||
264 | skb->dev = dev; | ||
265 | dev->stats.tx_packets++; | 263 | dev->stats.tx_packets++; |
266 | dev->stats.tx_bytes += skb->len; | 264 | dev->stats.tx_bytes += skb->len; |
267 | 265 | ||
268 | dev->trans_start = jiffies; | ||
269 | |||
270 | /* FIXME: do hardware work here ... */ | 266 | /* FIXME: do hardware work here ... */ |
271 | 267 | ||
268 | dev_kfree_skb(skb); | ||
272 | return NETDEV_TX_OK; | 269 | return NETDEV_TX_OK; |
273 | } | 270 | } |
274 | 271 | ||
diff --git a/drivers/isdn/hardware/mISDN/hfcmulti.c b/drivers/isdn/hardware/mISDN/hfcmulti.c index faed794cf75a..a6624ad252c5 100644 --- a/drivers/isdn/hardware/mISDN/hfcmulti.c +++ b/drivers/isdn/hardware/mISDN/hfcmulti.c | |||
@@ -5481,7 +5481,7 @@ HFCmulti_init(void) | |||
5481 | if (err) { | 5481 | if (err) { |
5482 | printk(KERN_ERR "error registering embedded driver: " | 5482 | printk(KERN_ERR "error registering embedded driver: " |
5483 | "%x\n", err); | 5483 | "%x\n", err); |
5484 | return -err; | 5484 | return err; |
5485 | } | 5485 | } |
5486 | HFC_cnt++; | 5486 | HFC_cnt++; |
5487 | printk(KERN_INFO "%d devices registered\n", HFC_cnt); | 5487 | printk(KERN_INFO "%d devices registered\n", HFC_cnt); |
diff --git a/drivers/isdn/i4l/isdn_ppp.c b/drivers/isdn/i4l/isdn_ppp.c index 2d14b64202a3..642d5aaf53ce 100644 --- a/drivers/isdn/i4l/isdn_ppp.c +++ b/drivers/isdn/i4l/isdn_ppp.c | |||
@@ -1535,10 +1535,8 @@ static int isdn_ppp_mp_bundle_array_init(void) | |||
1535 | int sz = ISDN_MAX_CHANNELS*sizeof(ippp_bundle); | 1535 | int sz = ISDN_MAX_CHANNELS*sizeof(ippp_bundle); |
1536 | if( (isdn_ppp_bundle_arr = kzalloc(sz, GFP_KERNEL)) == NULL ) | 1536 | if( (isdn_ppp_bundle_arr = kzalloc(sz, GFP_KERNEL)) == NULL ) |
1537 | return -ENOMEM; | 1537 | return -ENOMEM; |
1538 | for (i = 0; i < ISDN_MAX_CHANNELS; i++) { | 1538 | for( i = 0; i < ISDN_MAX_CHANNELS; i++ ) |
1539 | spin_lock_init(&isdn_ppp_bundle_arr[i].lock); | 1539 | spin_lock_init(&isdn_ppp_bundle_arr[i].lock); |
1540 | skb_queue_head_init(&isdn_ppp_bundle_arr[i].frags); | ||
1541 | } | ||
1542 | return 0; | 1540 | return 0; |
1543 | } | 1541 | } |
1544 | 1542 | ||
@@ -1571,7 +1569,7 @@ static int isdn_ppp_mp_init( isdn_net_local * lp, ippp_bundle * add_to ) | |||
1571 | if ((lp->netdev->pb = isdn_ppp_mp_bundle_alloc()) == NULL) | 1569 | if ((lp->netdev->pb = isdn_ppp_mp_bundle_alloc()) == NULL) |
1572 | return -ENOMEM; | 1570 | return -ENOMEM; |
1573 | lp->next = lp->last = lp; /* nobody else in a queue */ | 1571 | lp->next = lp->last = lp; /* nobody else in a queue */ |
1574 | skb_queue_head_init(&lp->netdev->pb->frags); | 1572 | lp->netdev->pb->frags = NULL; |
1575 | lp->netdev->pb->frames = 0; | 1573 | lp->netdev->pb->frames = 0; |
1576 | lp->netdev->pb->seq = UINT_MAX; | 1574 | lp->netdev->pb->seq = UINT_MAX; |
1577 | } | 1575 | } |
@@ -1583,29 +1581,28 @@ static int isdn_ppp_mp_init( isdn_net_local * lp, ippp_bundle * add_to ) | |||
1583 | 1581 | ||
1584 | static u32 isdn_ppp_mp_get_seq( int short_seq, | 1582 | static u32 isdn_ppp_mp_get_seq( int short_seq, |
1585 | struct sk_buff * skb, u32 last_seq ); | 1583 | struct sk_buff * skb, u32 last_seq ); |
1586 | static void isdn_ppp_mp_discard(ippp_bundle *mp, struct sk_buff *from, | 1584 | static struct sk_buff * isdn_ppp_mp_discard( ippp_bundle * mp, |
1587 | struct sk_buff *to); | 1585 | struct sk_buff * from, struct sk_buff * to ); |
1588 | static void isdn_ppp_mp_reassembly(isdn_net_dev *net_dev, isdn_net_local *lp, | 1586 | static void isdn_ppp_mp_reassembly( isdn_net_dev * net_dev, isdn_net_local * lp, |
1589 | struct sk_buff *from, struct sk_buff *to, | 1587 | struct sk_buff * from, struct sk_buff * to ); |
1590 | u32 lastseq); | 1588 | static void isdn_ppp_mp_free_skb( ippp_bundle * mp, struct sk_buff * skb ); |
1591 | static void isdn_ppp_mp_free_skb(ippp_bundle *mp, struct sk_buff *skb); | ||
1592 | static void isdn_ppp_mp_print_recv_pkt( int slot, struct sk_buff * skb ); | 1589 | static void isdn_ppp_mp_print_recv_pkt( int slot, struct sk_buff * skb ); |
1593 | 1590 | ||
1594 | static void isdn_ppp_mp_receive(isdn_net_dev * net_dev, isdn_net_local * lp, | 1591 | static void isdn_ppp_mp_receive(isdn_net_dev * net_dev, isdn_net_local * lp, |
1595 | struct sk_buff *skb) | 1592 | struct sk_buff *skb) |
1596 | { | 1593 | { |
1597 | struct sk_buff *newfrag, *frag, *start, *nextf; | ||
1598 | u32 newseq, minseq, thisseq; | ||
1599 | isdn_mppp_stats *stats; | ||
1600 | struct ippp_struct *is; | 1594 | struct ippp_struct *is; |
1595 | isdn_net_local * lpq; | ||
1596 | ippp_bundle * mp; | ||
1597 | isdn_mppp_stats * stats; | ||
1598 | struct sk_buff * newfrag, * frag, * start, *nextf; | ||
1599 | u32 newseq, minseq, thisseq; | ||
1601 | unsigned long flags; | 1600 | unsigned long flags; |
1602 | isdn_net_local *lpq; | ||
1603 | ippp_bundle *mp; | ||
1604 | int slot; | 1601 | int slot; |
1605 | 1602 | ||
1606 | spin_lock_irqsave(&net_dev->pb->lock, flags); | 1603 | spin_lock_irqsave(&net_dev->pb->lock, flags); |
1607 | mp = net_dev->pb; | 1604 | mp = net_dev->pb; |
1608 | stats = &mp->stats; | 1605 | stats = &mp->stats; |
1609 | slot = lp->ppp_slot; | 1606 | slot = lp->ppp_slot; |
1610 | if (slot < 0 || slot >= ISDN_MAX_CHANNELS) { | 1607 | if (slot < 0 || slot >= ISDN_MAX_CHANNELS) { |
1611 | printk(KERN_ERR "%s: lp->ppp_slot(%d)\n", | 1608 | printk(KERN_ERR "%s: lp->ppp_slot(%d)\n", |
@@ -1616,19 +1613,20 @@ static void isdn_ppp_mp_receive(isdn_net_dev * net_dev, isdn_net_local * lp, | |||
1616 | return; | 1613 | return; |
1617 | } | 1614 | } |
1618 | is = ippp_table[slot]; | 1615 | is = ippp_table[slot]; |
1619 | if (++mp->frames > stats->max_queue_len) | 1616 | if( ++mp->frames > stats->max_queue_len ) |
1620 | stats->max_queue_len = mp->frames; | 1617 | stats->max_queue_len = mp->frames; |
1621 | 1618 | ||
1622 | if (is->debug & 0x8) | 1619 | if (is->debug & 0x8) |
1623 | isdn_ppp_mp_print_recv_pkt(lp->ppp_slot, skb); | 1620 | isdn_ppp_mp_print_recv_pkt(lp->ppp_slot, skb); |
1624 | 1621 | ||
1625 | newseq = isdn_ppp_mp_get_seq(is->mpppcfg & SC_IN_SHORT_SEQ, | 1622 | newseq = isdn_ppp_mp_get_seq(is->mpppcfg & SC_IN_SHORT_SEQ, |
1626 | skb, is->last_link_seqno); | 1623 | skb, is->last_link_seqno); |
1624 | |||
1627 | 1625 | ||
1628 | /* if this packet seq # is less than last already processed one, | 1626 | /* if this packet seq # is less than last already processed one, |
1629 | * toss it right away, but check for sequence start case first | 1627 | * toss it right away, but check for sequence start case first |
1630 | */ | 1628 | */ |
1631 | if (mp->seq > MP_LONGSEQ_MAX && (newseq & MP_LONGSEQ_MAXBIT)) { | 1629 | if( mp->seq > MP_LONGSEQ_MAX && (newseq & MP_LONGSEQ_MAXBIT) ) { |
1632 | mp->seq = newseq; /* the first packet: required for | 1630 | mp->seq = newseq; /* the first packet: required for |
1633 | * rfc1990 non-compliant clients -- | 1631 | * rfc1990 non-compliant clients -- |
1634 | * prevents constant packet toss */ | 1632 | * prevents constant packet toss */ |
@@ -1638,7 +1636,7 @@ static void isdn_ppp_mp_receive(isdn_net_dev * net_dev, isdn_net_local * lp, | |||
1638 | spin_unlock_irqrestore(&mp->lock, flags); | 1636 | spin_unlock_irqrestore(&mp->lock, flags); |
1639 | return; | 1637 | return; |
1640 | } | 1638 | } |
1641 | 1639 | ||
1642 | /* find the minimum received sequence number over all links */ | 1640 | /* find the minimum received sequence number over all links */ |
1643 | is->last_link_seqno = minseq = newseq; | 1641 | is->last_link_seqno = minseq = newseq; |
1644 | for (lpq = net_dev->queue;;) { | 1642 | for (lpq = net_dev->queue;;) { |
@@ -1659,31 +1657,22 @@ static void isdn_ppp_mp_receive(isdn_net_dev * net_dev, isdn_net_local * lp, | |||
1659 | * packets */ | 1657 | * packets */ |
1660 | newfrag = skb; | 1658 | newfrag = skb; |
1661 | 1659 | ||
1662 | /* Insert new fragment into the proper sequence slot. */ | 1660 | /* if this new fragment is before the first one, then enqueue it now. */ |
1663 | skb_queue_walk(&mp->frags, frag) { | 1661 | if ((frag = mp->frags) == NULL || MP_LT(newseq, MP_SEQ(frag))) { |
1664 | if (MP_SEQ(frag) == newseq) { | 1662 | newfrag->next = frag; |
1665 | isdn_ppp_mp_free_skb(mp, newfrag); | 1663 | mp->frags = frag = newfrag; |
1666 | newfrag = NULL; | 1664 | newfrag = NULL; |
1667 | break; | 1665 | } |
1668 | } | ||
1669 | if (MP_LT(newseq, MP_SEQ(frag))) { | ||
1670 | __skb_queue_before(&mp->frags, frag, newfrag); | ||
1671 | newfrag = NULL; | ||
1672 | break; | ||
1673 | } | ||
1674 | } | ||
1675 | if (newfrag) | ||
1676 | __skb_queue_tail(&mp->frags, newfrag); | ||
1677 | 1666 | ||
1678 | frag = skb_peek(&mp->frags); | 1667 | start = MP_FLAGS(frag) & MP_BEGIN_FRAG && |
1679 | start = ((MP_FLAGS(frag) & MP_BEGIN_FRAG) && | 1668 | MP_SEQ(frag) == mp->seq ? frag : NULL; |
1680 | (MP_SEQ(frag) == mp->seq)) ? frag : NULL; | ||
1681 | if (!start) | ||
1682 | goto check_overflow; | ||
1683 | 1669 | ||
1684 | /* main fragment traversing loop | 1670 | /* |
1671 | * main fragment traversing loop | ||
1685 | * | 1672 | * |
1686 | * try to accomplish several tasks: | 1673 | * try to accomplish several tasks: |
1674 | * - insert new fragment into the proper sequence slot (once that's done | ||
1675 | * newfrag will be set to NULL) | ||
1687 | * - reassemble any complete fragment sequence (non-null 'start' | 1676 | * - reassemble any complete fragment sequence (non-null 'start' |
1688 | * indicates there is a continguous sequence present) | 1677 | * indicates there is a continguous sequence present) |
1689 | * - discard any incomplete sequences that are below minseq -- due | 1678 | * - discard any incomplete sequences that are below minseq -- due |
@@ -1692,46 +1681,71 @@ static void isdn_ppp_mp_receive(isdn_net_dev * net_dev, isdn_net_local * lp, | |||
1692 | * come to complete such sequence and it should be discarded | 1681 | * come to complete such sequence and it should be discarded |
1693 | * | 1682 | * |
1694 | * loop completes when we accomplished the following tasks: | 1683 | * loop completes when we accomplished the following tasks: |
1684 | * - new fragment is inserted in the proper sequence ('newfrag' is | ||
1685 | * set to NULL) | ||
1695 | * - we hit a gap in the sequence, so no reassembly/processing is | 1686 | * - we hit a gap in the sequence, so no reassembly/processing is |
1696 | * possible ('start' would be set to NULL) | 1687 | * possible ('start' would be set to NULL) |
1697 | * | 1688 | * |
1698 | * algorithm for this code is derived from code in the book | 1689 | * algorithm for this code is derived from code in the book |
1699 | * 'PPP Design And Debugging' by James Carlson (Addison-Wesley) | 1690 | * 'PPP Design And Debugging' by James Carlson (Addison-Wesley) |
1700 | */ | 1691 | */ |
1701 | skb_queue_walk_safe(&mp->frags, frag, nextf) { | 1692 | while (start != NULL || newfrag != NULL) { |
1702 | thisseq = MP_SEQ(frag); | 1693 | |
1703 | 1694 | thisseq = MP_SEQ(frag); | |
1704 | /* check for misplaced start */ | 1695 | nextf = frag->next; |
1705 | if (start != frag && (MP_FLAGS(frag) & MP_BEGIN_FRAG)) { | 1696 | |
1706 | printk(KERN_WARNING"isdn_mppp(seq %d): new " | 1697 | /* drop any duplicate fragments */ |
1707 | "BEGIN flag with no prior END", thisseq); | 1698 | if (newfrag != NULL && thisseq == newseq) { |
1708 | stats->seqerrs++; | 1699 | isdn_ppp_mp_free_skb(mp, newfrag); |
1709 | stats->frame_drops++; | 1700 | newfrag = NULL; |
1710 | isdn_ppp_mp_discard(mp, start, frag); | 1701 | } |
1711 | start = frag; | 1702 | |
1712 | } else if (MP_LE(thisseq, minseq)) { | 1703 | /* insert new fragment before next element if possible. */ |
1713 | if (MP_FLAGS(frag) & MP_BEGIN_FRAG) | 1704 | if (newfrag != NULL && (nextf == NULL || |
1705 | MP_LT(newseq, MP_SEQ(nextf)))) { | ||
1706 | newfrag->next = nextf; | ||
1707 | frag->next = nextf = newfrag; | ||
1708 | newfrag = NULL; | ||
1709 | } | ||
1710 | |||
1711 | if (start != NULL) { | ||
1712 | /* check for misplaced start */ | ||
1713 | if (start != frag && (MP_FLAGS(frag) & MP_BEGIN_FRAG)) { | ||
1714 | printk(KERN_WARNING"isdn_mppp(seq %d): new " | ||
1715 | "BEGIN flag with no prior END", thisseq); | ||
1716 | stats->seqerrs++; | ||
1717 | stats->frame_drops++; | ||
1718 | start = isdn_ppp_mp_discard(mp, start,frag); | ||
1719 | nextf = frag->next; | ||
1720 | } | ||
1721 | } else if (MP_LE(thisseq, minseq)) { | ||
1722 | if (MP_FLAGS(frag) & MP_BEGIN_FRAG) | ||
1714 | start = frag; | 1723 | start = frag; |
1715 | else { | 1724 | else { |
1716 | if (MP_FLAGS(frag) & MP_END_FRAG) | 1725 | if (MP_FLAGS(frag) & MP_END_FRAG) |
1717 | stats->frame_drops++; | 1726 | stats->frame_drops++; |
1718 | __skb_unlink(skb, &mp->frags); | 1727 | if( mp->frags == frag ) |
1728 | mp->frags = nextf; | ||
1719 | isdn_ppp_mp_free_skb(mp, frag); | 1729 | isdn_ppp_mp_free_skb(mp, frag); |
1730 | frag = nextf; | ||
1720 | continue; | 1731 | continue; |
1721 | } | 1732 | } |
1722 | } | 1733 | } |
1723 | 1734 | ||
1724 | /* if we have end fragment, then we have full reassembly | 1735 | /* if start is non-null and we have end fragment, then |
1725 | * sequence -- reassemble and process packet now | 1736 | * we have full reassembly sequence -- reassemble |
1737 | * and process packet now | ||
1726 | */ | 1738 | */ |
1727 | if (MP_FLAGS(frag) & MP_END_FRAG) { | 1739 | if (start != NULL && (MP_FLAGS(frag) & MP_END_FRAG)) { |
1728 | minseq = mp->seq = (thisseq+1) & MP_LONGSEQ_MASK; | 1740 | minseq = mp->seq = (thisseq+1) & MP_LONGSEQ_MASK; |
1729 | /* Reassemble the packet then dispatch it */ | 1741 | /* Reassemble the packet then dispatch it */ |
1730 | isdn_ppp_mp_reassembly(net_dev, lp, start, frag, thisseq); | 1742 | isdn_ppp_mp_reassembly(net_dev, lp, start, nextf); |
1743 | |||
1744 | start = NULL; | ||
1745 | frag = NULL; | ||
1731 | 1746 | ||
1732 | start = NULL; | 1747 | mp->frags = nextf; |
1733 | frag = NULL; | 1748 | } |
1734 | } | ||
1735 | 1749 | ||
1736 | /* check if need to update start pointer: if we just | 1750 | /* check if need to update start pointer: if we just |
1737 | * reassembled the packet and sequence is contiguous | 1751 | * reassembled the packet and sequence is contiguous |
@@ -1742,25 +1756,26 @@ static void isdn_ppp_mp_receive(isdn_net_dev * net_dev, isdn_net_local * lp, | |||
1742 | * below low watermark and set start to the next frag or | 1756 | * below low watermark and set start to the next frag or |
1743 | * clear start ptr. | 1757 | * clear start ptr. |
1744 | */ | 1758 | */ |
1745 | if (nextf != (struct sk_buff *)&mp->frags && | 1759 | if (nextf != NULL && |
1746 | ((thisseq+1) & MP_LONGSEQ_MASK) == MP_SEQ(nextf)) { | 1760 | ((thisseq+1) & MP_LONGSEQ_MASK) == MP_SEQ(nextf)) { |
1747 | /* if we just reassembled and the next one is here, | 1761 | /* if we just reassembled and the next one is here, |
1748 | * then start another reassembly. | 1762 | * then start another reassembly. */ |
1749 | */ | 1763 | |
1750 | if (frag == NULL) { | 1764 | if (frag == NULL) { |
1751 | if (MP_FLAGS(nextf) & MP_BEGIN_FRAG) | 1765 | if (MP_FLAGS(nextf) & MP_BEGIN_FRAG) |
1752 | start = nextf; | 1766 | start = nextf; |
1753 | else { | 1767 | else |
1754 | printk(KERN_WARNING"isdn_mppp(seq %d):" | 1768 | { |
1755 | " END flag with no following " | 1769 | printk(KERN_WARNING"isdn_mppp(seq %d):" |
1756 | "BEGIN", thisseq); | 1770 | " END flag with no following " |
1771 | "BEGIN", thisseq); | ||
1757 | stats->seqerrs++; | 1772 | stats->seqerrs++; |
1758 | } | 1773 | } |
1759 | } | 1774 | } |
1760 | } else { | 1775 | |
1761 | if (nextf != (struct sk_buff *)&mp->frags && | 1776 | } else { |
1762 | frag != NULL && | 1777 | if ( nextf != NULL && frag != NULL && |
1763 | MP_LT(thisseq, minseq)) { | 1778 | MP_LT(thisseq, minseq)) { |
1764 | /* we've got a break in the sequence | 1779 | /* we've got a break in the sequence |
1765 | * and we not at the end yet | 1780 | * and we not at the end yet |
1766 | * and we did not just reassembled | 1781 | * and we did not just reassembled |
@@ -1769,39 +1784,41 @@ static void isdn_ppp_mp_receive(isdn_net_dev * net_dev, isdn_net_local * lp, | |||
1769 | * discard all the frames below low watermark | 1784 | * discard all the frames below low watermark |
1770 | * and start over */ | 1785 | * and start over */ |
1771 | stats->frame_drops++; | 1786 | stats->frame_drops++; |
1772 | isdn_ppp_mp_discard(mp, start, nextf); | 1787 | mp->frags = isdn_ppp_mp_discard(mp,start,nextf); |
1773 | } | 1788 | } |
1774 | /* break in the sequence, no reassembly */ | 1789 | /* break in the sequence, no reassembly */ |
1775 | start = NULL; | 1790 | start = NULL; |
1776 | } | 1791 | } |
1777 | if (!start) | 1792 | |
1778 | break; | 1793 | frag = nextf; |
1779 | } | 1794 | } /* while -- main loop */ |
1780 | 1795 | ||
1781 | check_overflow: | 1796 | if (mp->frags == NULL) |
1797 | mp->frags = frag; | ||
1798 | |||
1782 | /* rather straighforward way to deal with (not very) possible | 1799 | /* rather straighforward way to deal with (not very) possible |
1783 | * queue overflow | 1800 | * queue overflow */ |
1784 | */ | ||
1785 | if (mp->frames > MP_MAX_QUEUE_LEN) { | 1801 | if (mp->frames > MP_MAX_QUEUE_LEN) { |
1786 | stats->overflows++; | 1802 | stats->overflows++; |
1787 | skb_queue_walk_safe(&mp->frags, frag, nextf) { | 1803 | while (mp->frames > MP_MAX_QUEUE_LEN) { |
1788 | if (mp->frames <= MP_MAX_QUEUE_LEN) | 1804 | frag = mp->frags->next; |
1789 | break; | 1805 | isdn_ppp_mp_free_skb(mp, mp->frags); |
1790 | __skb_unlink(frag, &mp->frags); | 1806 | mp->frags = frag; |
1791 | isdn_ppp_mp_free_skb(mp, frag); | ||
1792 | } | 1807 | } |
1793 | } | 1808 | } |
1794 | spin_unlock_irqrestore(&mp->lock, flags); | 1809 | spin_unlock_irqrestore(&mp->lock, flags); |
1795 | } | 1810 | } |
1796 | 1811 | ||
1797 | static void isdn_ppp_mp_cleanup(isdn_net_local *lp) | 1812 | static void isdn_ppp_mp_cleanup( isdn_net_local * lp ) |
1798 | { | 1813 | { |
1799 | struct sk_buff *skb, *tmp; | 1814 | struct sk_buff * frag = lp->netdev->pb->frags; |
1800 | 1815 | struct sk_buff * nextfrag; | |
1801 | skb_queue_walk_safe(&lp->netdev->pb->frags, skb, tmp) { | 1816 | while( frag ) { |
1802 | __skb_unlink(skb, &lp->netdev->pb->frags); | 1817 | nextfrag = frag->next; |
1803 | isdn_ppp_mp_free_skb(lp->netdev->pb, skb); | 1818 | isdn_ppp_mp_free_skb(lp->netdev->pb, frag); |
1804 | } | 1819 | frag = nextfrag; |
1820 | } | ||
1821 | lp->netdev->pb->frags = NULL; | ||
1805 | } | 1822 | } |
1806 | 1823 | ||
1807 | static u32 isdn_ppp_mp_get_seq( int short_seq, | 1824 | static u32 isdn_ppp_mp_get_seq( int short_seq, |
@@ -1838,115 +1855,72 @@ static u32 isdn_ppp_mp_get_seq( int short_seq, | |||
1838 | return seq; | 1855 | return seq; |
1839 | } | 1856 | } |
1840 | 1857 | ||
1841 | static void isdn_ppp_mp_discard(ippp_bundle *mp, struct sk_buff *from, | 1858 | struct sk_buff * isdn_ppp_mp_discard( ippp_bundle * mp, |
1842 | struct sk_buff *to) | 1859 | struct sk_buff * from, struct sk_buff * to ) |
1843 | { | 1860 | { |
1844 | if (from) { | 1861 | if( from ) |
1845 | struct sk_buff *skb, *tmp; | 1862 | while (from != to) { |
1846 | int freeing = 0; | 1863 | struct sk_buff * next = from->next; |
1847 | 1864 | isdn_ppp_mp_free_skb(mp, from); | |
1848 | skb_queue_walk_safe(&mp->frags, skb, tmp) { | 1865 | from = next; |
1849 | if (skb == to) | ||
1850 | break; | ||
1851 | if (skb == from) | ||
1852 | freeing = 1; | ||
1853 | if (!freeing) | ||
1854 | continue; | ||
1855 | __skb_unlink(skb, &mp->frags); | ||
1856 | isdn_ppp_mp_free_skb(mp, skb); | ||
1857 | } | 1866 | } |
1858 | } | 1867 | return from; |
1859 | } | ||
1860 | |||
1861 | static unsigned int calc_tot_len(struct sk_buff_head *queue, | ||
1862 | struct sk_buff *from, struct sk_buff *to) | ||
1863 | { | ||
1864 | unsigned int tot_len = 0; | ||
1865 | struct sk_buff *skb; | ||
1866 | int found_start = 0; | ||
1867 | |||
1868 | skb_queue_walk(queue, skb) { | ||
1869 | if (skb == from) | ||
1870 | found_start = 1; | ||
1871 | if (!found_start) | ||
1872 | continue; | ||
1873 | tot_len += skb->len - MP_HEADER_LEN; | ||
1874 | if (skb == to) | ||
1875 | break; | ||
1876 | } | ||
1877 | return tot_len; | ||
1878 | } | 1868 | } |
1879 | 1869 | ||
1880 | /* Reassemble packet using fragments in the reassembly queue from | 1870 | void isdn_ppp_mp_reassembly( isdn_net_dev * net_dev, isdn_net_local * lp, |
1881 | * 'from' until 'to', inclusive. | 1871 | struct sk_buff * from, struct sk_buff * to ) |
1882 | */ | ||
1883 | static void isdn_ppp_mp_reassembly(isdn_net_dev *net_dev, isdn_net_local *lp, | ||
1884 | struct sk_buff *from, struct sk_buff *to, | ||
1885 | u32 lastseq) | ||
1886 | { | 1872 | { |
1887 | ippp_bundle *mp = net_dev->pb; | 1873 | ippp_bundle * mp = net_dev->pb; |
1888 | unsigned int tot_len; | ||
1889 | struct sk_buff *skb; | ||
1890 | int proto; | 1874 | int proto; |
1875 | struct sk_buff * skb; | ||
1876 | unsigned int tot_len; | ||
1891 | 1877 | ||
1892 | if (lp->ppp_slot < 0 || lp->ppp_slot >= ISDN_MAX_CHANNELS) { | 1878 | if (lp->ppp_slot < 0 || lp->ppp_slot >= ISDN_MAX_CHANNELS) { |
1893 | printk(KERN_ERR "%s: lp->ppp_slot(%d) out of range\n", | 1879 | printk(KERN_ERR "%s: lp->ppp_slot(%d) out of range\n", |
1894 | __func__, lp->ppp_slot); | 1880 | __func__, lp->ppp_slot); |
1895 | return; | 1881 | return; |
1896 | } | 1882 | } |
1897 | 1883 | if( MP_FLAGS(from) == (MP_BEGIN_FRAG | MP_END_FRAG) ) { | |
1898 | tot_len = calc_tot_len(&mp->frags, from, to); | 1884 | if( ippp_table[lp->ppp_slot]->debug & 0x40 ) |
1899 | |||
1900 | if (MP_FLAGS(from) == (MP_BEGIN_FRAG | MP_END_FRAG)) { | ||
1901 | if (ippp_table[lp->ppp_slot]->debug & 0x40) | ||
1902 | printk(KERN_DEBUG "isdn_mppp: reassembly: frame %d, " | 1885 | printk(KERN_DEBUG "isdn_mppp: reassembly: frame %d, " |
1903 | "len %d\n", MP_SEQ(from), from->len); | 1886 | "len %d\n", MP_SEQ(from), from->len ); |
1904 | skb = from; | 1887 | skb = from; |
1905 | skb_pull(skb, MP_HEADER_LEN); | 1888 | skb_pull(skb, MP_HEADER_LEN); |
1906 | __skb_unlink(skb, &mp->frags); | ||
1907 | mp->frames--; | 1889 | mp->frames--; |
1908 | } else { | 1890 | } else { |
1909 | struct sk_buff *walk, *tmp; | 1891 | struct sk_buff * frag; |
1910 | int found_start = 0; | 1892 | int n; |
1911 | 1893 | ||
1912 | if (ippp_table[lp->ppp_slot]->debug & 0x40) | 1894 | for(tot_len=n=0, frag=from; frag != to; frag=frag->next, n++) |
1913 | printk(KERN_DEBUG"isdn_mppp: reassembling frames %d " | 1895 | tot_len += frag->len - MP_HEADER_LEN; |
1914 | "to %d, len %d\n", MP_SEQ(from), lastseq, | ||
1915 | tot_len); | ||
1916 | 1896 | ||
1917 | skb = dev_alloc_skb(tot_len); | 1897 | if( ippp_table[lp->ppp_slot]->debug & 0x40 ) |
1918 | if (!skb) | 1898 | printk(KERN_DEBUG"isdn_mppp: reassembling frames %d " |
1899 | "to %d, len %d\n", MP_SEQ(from), | ||
1900 | (MP_SEQ(from)+n-1) & MP_LONGSEQ_MASK, tot_len ); | ||
1901 | if( (skb = dev_alloc_skb(tot_len)) == NULL ) { | ||
1919 | printk(KERN_ERR "isdn_mppp: cannot allocate sk buff " | 1902 | printk(KERN_ERR "isdn_mppp: cannot allocate sk buff " |
1920 | "of size %d\n", tot_len); | 1903 | "of size %d\n", tot_len); |
1921 | 1904 | isdn_ppp_mp_discard(mp, from, to); | |
1922 | found_start = 0; | 1905 | return; |
1923 | skb_queue_walk_safe(&mp->frags, walk, tmp) { | 1906 | } |
1924 | if (walk == from) | ||
1925 | found_start = 1; | ||
1926 | if (!found_start) | ||
1927 | continue; | ||
1928 | 1907 | ||
1929 | if (skb) { | 1908 | while( from != to ) { |
1930 | unsigned int len = walk->len - MP_HEADER_LEN; | 1909 | unsigned int len = from->len - MP_HEADER_LEN; |
1931 | skb_copy_from_linear_data_offset(walk, MP_HEADER_LEN, | ||
1932 | skb_put(skb, len), | ||
1933 | len); | ||
1934 | } | ||
1935 | __skb_unlink(walk, &mp->frags); | ||
1936 | isdn_ppp_mp_free_skb(mp, walk); | ||
1937 | 1910 | ||
1938 | if (walk == to) | 1911 | skb_copy_from_linear_data_offset(from, MP_HEADER_LEN, |
1939 | break; | 1912 | skb_put(skb,len), |
1913 | len); | ||
1914 | frag = from->next; | ||
1915 | isdn_ppp_mp_free_skb(mp, from); | ||
1916 | from = frag; | ||
1940 | } | 1917 | } |
1941 | } | 1918 | } |
1942 | if (!skb) | ||
1943 | return; | ||
1944 | |||
1945 | proto = isdn_ppp_strip_proto(skb); | 1919 | proto = isdn_ppp_strip_proto(skb); |
1946 | isdn_ppp_push_higher(net_dev, lp, skb, proto); | 1920 | isdn_ppp_push_higher(net_dev, lp, skb, proto); |
1947 | } | 1921 | } |
1948 | 1922 | ||
1949 | static void isdn_ppp_mp_free_skb(ippp_bundle *mp, struct sk_buff *skb) | 1923 | static void isdn_ppp_mp_free_skb(ippp_bundle * mp, struct sk_buff * skb) |
1950 | { | 1924 | { |
1951 | dev_kfree_skb(skb); | 1925 | dev_kfree_skb(skb); |
1952 | mp->frames--; | 1926 | mp->frames--; |
diff --git a/drivers/media/common/ir-functions.c b/drivers/media/common/ir-functions.c index 655474b29e21..abd4791acb0e 100644 --- a/drivers/media/common/ir-functions.c +++ b/drivers/media/common/ir-functions.c | |||
@@ -64,7 +64,7 @@ void ir_input_init(struct input_dev *dev, struct ir_input_state *ir, | |||
64 | 64 | ||
65 | ir->ir_type = ir_type; | 65 | ir->ir_type = ir_type; |
66 | 66 | ||
67 | memset(ir->ir_codes, sizeof(ir->ir_codes), 0); | 67 | memset(ir->ir_codes, 0, sizeof(ir->ir_codes)); |
68 | 68 | ||
69 | /* | 69 | /* |
70 | * FIXME: This is a temporary workaround to use the new IR tables | 70 | * FIXME: This is a temporary workaround to use the new IR tables |
diff --git a/drivers/media/dvb/dvb-usb/cxusb.c b/drivers/media/dvb/dvb-usb/cxusb.c index f65591fb7cec..2a53dd096eef 100644 --- a/drivers/media/dvb/dvb-usb/cxusb.c +++ b/drivers/media/dvb/dvb-usb/cxusb.c | |||
@@ -663,6 +663,14 @@ static struct zl10353_config cxusb_zl10353_xc3028_config = { | |||
663 | .parallel_ts = 1, | 663 | .parallel_ts = 1, |
664 | }; | 664 | }; |
665 | 665 | ||
666 | static struct zl10353_config cxusb_zl10353_xc3028_config_no_i2c_gate = { | ||
667 | .demod_address = 0x0f, | ||
668 | .if2 = 45600, | ||
669 | .no_tuner = 1, | ||
670 | .parallel_ts = 1, | ||
671 | .disable_i2c_gate_ctrl = 1, | ||
672 | }; | ||
673 | |||
666 | static struct mt352_config cxusb_mt352_xc3028_config = { | 674 | static struct mt352_config cxusb_mt352_xc3028_config = { |
667 | .demod_address = 0x0f, | 675 | .demod_address = 0x0f, |
668 | .if2 = 4560, | 676 | .if2 = 4560, |
@@ -894,7 +902,7 @@ static int cxusb_dualdig4_frontend_attach(struct dvb_usb_adapter *adap) | |||
894 | cxusb_bluebird_gpio_pulse(adap->dev, 0x02, 1); | 902 | cxusb_bluebird_gpio_pulse(adap->dev, 0x02, 1); |
895 | 903 | ||
896 | if ((adap->fe = dvb_attach(zl10353_attach, | 904 | if ((adap->fe = dvb_attach(zl10353_attach, |
897 | &cxusb_zl10353_xc3028_config, | 905 | &cxusb_zl10353_xc3028_config_no_i2c_gate, |
898 | &adap->dev->i2c_adap)) == NULL) | 906 | &adap->dev->i2c_adap)) == NULL) |
899 | return -EIO; | 907 | return -EIO; |
900 | 908 | ||
diff --git a/drivers/media/dvb/siano/Kconfig b/drivers/media/dvb/siano/Kconfig index 8c1aed77ea30..85a222c4eaa0 100644 --- a/drivers/media/dvb/siano/Kconfig +++ b/drivers/media/dvb/siano/Kconfig | |||
@@ -4,7 +4,7 @@ | |||
4 | 4 | ||
5 | config SMS_SIANO_MDTV | 5 | config SMS_SIANO_MDTV |
6 | tristate "Siano SMS1xxx based MDTV receiver" | 6 | tristate "Siano SMS1xxx based MDTV receiver" |
7 | depends on DVB_CORE && INPUT | 7 | depends on DVB_CORE && INPUT && HAS_DMA |
8 | ---help--- | 8 | ---help--- |
9 | Choose Y or M here if you have MDTV receiver with a Siano chipset. | 9 | Choose Y or M here if you have MDTV receiver with a Siano chipset. |
10 | 10 | ||
diff --git a/drivers/media/radio/radio-gemtek-pci.c b/drivers/media/radio/radio-gemtek-pci.c index c3f579de6e71..c6cf11661868 100644 --- a/drivers/media/radio/radio-gemtek-pci.c +++ b/drivers/media/radio/radio-gemtek-pci.c | |||
@@ -181,12 +181,10 @@ static void gemtek_pci_mute(struct gemtek_pci *card) | |||
181 | 181 | ||
182 | static void gemtek_pci_unmute(struct gemtek_pci *card) | 182 | static void gemtek_pci_unmute(struct gemtek_pci *card) |
183 | { | 183 | { |
184 | mutex_lock(&card->lock); | ||
185 | if (card->mute) { | 184 | if (card->mute) { |
186 | gemtek_pci_setfrequency(card, card->current_frequency); | 185 | gemtek_pci_setfrequency(card, card->current_frequency); |
187 | card->mute = false; | 186 | card->mute = false; |
188 | } | 187 | } |
189 | mutex_unlock(&card->lock); | ||
190 | } | 188 | } |
191 | 189 | ||
192 | static int gemtek_pci_getsignal(struct gemtek_pci *card) | 190 | static int gemtek_pci_getsignal(struct gemtek_pci *card) |
diff --git a/drivers/media/video/davinci/vpif_display.c b/drivers/media/video/davinci/vpif_display.c index c015da813dda..d14cfb200ed0 100644 --- a/drivers/media/video/davinci/vpif_display.c +++ b/drivers/media/video/davinci/vpif_display.c | |||
@@ -1426,7 +1426,6 @@ static __init int vpif_probe(struct platform_device *pdev) | |||
1426 | struct vpif_display_config *config; | 1426 | struct vpif_display_config *config; |
1427 | int i, j = 0, k, q, m, err = 0; | 1427 | int i, j = 0, k, q, m, err = 0; |
1428 | struct i2c_adapter *i2c_adap; | 1428 | struct i2c_adapter *i2c_adap; |
1429 | struct vpif_config *config; | ||
1430 | struct common_obj *common; | 1429 | struct common_obj *common; |
1431 | struct channel_obj *ch; | 1430 | struct channel_obj *ch; |
1432 | struct video_device *vfd; | 1431 | struct video_device *vfd; |
diff --git a/drivers/media/video/em28xx/em28xx-cards.c b/drivers/media/video/em28xx/em28xx-cards.c index bdb249bd9d5d..c0fd5c6feeac 100644 --- a/drivers/media/video/em28xx/em28xx-cards.c +++ b/drivers/media/video/em28xx/em28xx-cards.c | |||
@@ -1584,8 +1584,8 @@ struct em28xx_board em28xx_boards[] = { | |||
1584 | [EM2870_BOARD_REDDO_DVB_C_USB_BOX] = { | 1584 | [EM2870_BOARD_REDDO_DVB_C_USB_BOX] = { |
1585 | .name = "Reddo DVB-C USB TV Box", | 1585 | .name = "Reddo DVB-C USB TV Box", |
1586 | .tuner_type = TUNER_ABSENT, | 1586 | .tuner_type = TUNER_ABSENT, |
1587 | .tuner_gpio = reddo_dvb_c_usb_box, | ||
1587 | .has_dvb = 1, | 1588 | .has_dvb = 1, |
1588 | .dvb_gpio = reddo_dvb_c_usb_box, | ||
1589 | }, | 1589 | }, |
1590 | }; | 1590 | }; |
1591 | const unsigned int em28xx_bcount = ARRAY_SIZE(em28xx_boards); | 1591 | const unsigned int em28xx_bcount = ARRAY_SIZE(em28xx_boards); |
diff --git a/drivers/media/video/mx1_camera.c b/drivers/media/video/mx1_camera.c index 5f37952c75cf..72802291e812 100644 --- a/drivers/media/video/mx1_camera.c +++ b/drivers/media/video/mx1_camera.c | |||
@@ -28,6 +28,7 @@ | |||
28 | #include <linux/moduleparam.h> | 28 | #include <linux/moduleparam.h> |
29 | #include <linux/mutex.h> | 29 | #include <linux/mutex.h> |
30 | #include <linux/platform_device.h> | 30 | #include <linux/platform_device.h> |
31 | #include <linux/sched.h> | ||
31 | #include <linux/time.h> | 32 | #include <linux/time.h> |
32 | #include <linux/version.h> | 33 | #include <linux/version.h> |
33 | #include <linux/videodev2.h> | 34 | #include <linux/videodev2.h> |
diff --git a/drivers/media/video/mx3_camera.c b/drivers/media/video/mx3_camera.c index dff2e5e2d8c6..7db82bdf6f31 100644 --- a/drivers/media/video/mx3_camera.c +++ b/drivers/media/video/mx3_camera.c | |||
@@ -17,6 +17,7 @@ | |||
17 | #include <linux/clk.h> | 17 | #include <linux/clk.h> |
18 | #include <linux/vmalloc.h> | 18 | #include <linux/vmalloc.h> |
19 | #include <linux/interrupt.h> | 19 | #include <linux/interrupt.h> |
20 | #include <linux/sched.h> | ||
20 | 21 | ||
21 | #include <media/v4l2-common.h> | 22 | #include <media/v4l2-common.h> |
22 | #include <media/v4l2-dev.h> | 23 | #include <media/v4l2-dev.h> |
diff --git a/drivers/media/video/sh_mobile_ceu_camera.c b/drivers/media/video/sh_mobile_ceu_camera.c index 2f78b4f263f5..9c8b7c7b89ee 100644 --- a/drivers/media/video/sh_mobile_ceu_camera.c +++ b/drivers/media/video/sh_mobile_ceu_camera.c | |||
@@ -31,6 +31,7 @@ | |||
31 | #include <linux/platform_device.h> | 31 | #include <linux/platform_device.h> |
32 | #include <linux/videodev2.h> | 32 | #include <linux/videodev2.h> |
33 | #include <linux/pm_runtime.h> | 33 | #include <linux/pm_runtime.h> |
34 | #include <linux/sched.h> | ||
34 | 35 | ||
35 | #include <media/v4l2-common.h> | 36 | #include <media/v4l2-common.h> |
36 | #include <media/v4l2-dev.h> | 37 | #include <media/v4l2-dev.h> |
@@ -1723,11 +1724,12 @@ static int __devinit sh_mobile_ceu_probe(struct platform_device *pdev) | |||
1723 | 1724 | ||
1724 | err = soc_camera_host_register(&pcdev->ici); | 1725 | err = soc_camera_host_register(&pcdev->ici); |
1725 | if (err) | 1726 | if (err) |
1726 | goto exit_free_irq; | 1727 | goto exit_free_clk; |
1727 | 1728 | ||
1728 | return 0; | 1729 | return 0; |
1729 | 1730 | ||
1730 | exit_free_irq: | 1731 | exit_free_clk: |
1732 | pm_runtime_disable(&pdev->dev); | ||
1731 | free_irq(pcdev->irq, pcdev); | 1733 | free_irq(pcdev->irq, pcdev); |
1732 | exit_release_mem: | 1734 | exit_release_mem: |
1733 | if (platform_get_resource(pdev, IORESOURCE_MEM, 1)) | 1735 | if (platform_get_resource(pdev, IORESOURCE_MEM, 1)) |
@@ -1747,6 +1749,7 @@ static int __devexit sh_mobile_ceu_remove(struct platform_device *pdev) | |||
1747 | struct sh_mobile_ceu_dev, ici); | 1749 | struct sh_mobile_ceu_dev, ici); |
1748 | 1750 | ||
1749 | soc_camera_host_unregister(soc_host); | 1751 | soc_camera_host_unregister(soc_host); |
1752 | pm_runtime_disable(&pdev->dev); | ||
1750 | free_irq(pcdev->irq, pcdev); | 1753 | free_irq(pcdev->irq, pcdev); |
1751 | if (platform_get_resource(pdev, IORESOURCE_MEM, 1)) | 1754 | if (platform_get_resource(pdev, IORESOURCE_MEM, 1)) |
1752 | dma_release_declared_memory(&pdev->dev); | 1755 | dma_release_declared_memory(&pdev->dev); |
diff --git a/drivers/media/video/soc_camera.c b/drivers/media/video/soc_camera.c index 36e617bd13c7..95fdeb23c2c1 100644 --- a/drivers/media/video/soc_camera.c +++ b/drivers/media/video/soc_camera.c | |||
@@ -1097,6 +1097,13 @@ static int default_s_crop(struct soc_camera_device *icd, struct v4l2_crop *a) | |||
1097 | return v4l2_subdev_call(sd, video, s_crop, a); | 1097 | return v4l2_subdev_call(sd, video, s_crop, a); |
1098 | } | 1098 | } |
1099 | 1099 | ||
1100 | static void soc_camera_device_init(struct device *dev, void *pdata) | ||
1101 | { | ||
1102 | dev->platform_data = pdata; | ||
1103 | dev->bus = &soc_camera_bus_type; | ||
1104 | dev->release = dummy_release; | ||
1105 | } | ||
1106 | |||
1100 | int soc_camera_host_register(struct soc_camera_host *ici) | 1107 | int soc_camera_host_register(struct soc_camera_host *ici) |
1101 | { | 1108 | { |
1102 | struct soc_camera_host *ix; | 1109 | struct soc_camera_host *ix; |
@@ -1158,6 +1165,7 @@ void soc_camera_host_unregister(struct soc_camera_host *ici) | |||
1158 | 1165 | ||
1159 | list_for_each_entry(icd, &devices, list) { | 1166 | list_for_each_entry(icd, &devices, list) { |
1160 | if (icd->iface == ici->nr) { | 1167 | if (icd->iface == ici->nr) { |
1168 | void *pdata = icd->dev.platform_data; | ||
1161 | /* The bus->remove will be called */ | 1169 | /* The bus->remove will be called */ |
1162 | device_unregister(&icd->dev); | 1170 | device_unregister(&icd->dev); |
1163 | /* | 1171 | /* |
@@ -1169,6 +1177,7 @@ void soc_camera_host_unregister(struct soc_camera_host *ici) | |||
1169 | * device private data. | 1177 | * device private data. |
1170 | */ | 1178 | */ |
1171 | memset(&icd->dev, 0, sizeof(icd->dev)); | 1179 | memset(&icd->dev, 0, sizeof(icd->dev)); |
1180 | soc_camera_device_init(&icd->dev, pdata); | ||
1172 | } | 1181 | } |
1173 | } | 1182 | } |
1174 | 1183 | ||
@@ -1200,10 +1209,7 @@ static int soc_camera_device_register(struct soc_camera_device *icd) | |||
1200 | * man, stay reasonable... */ | 1209 | * man, stay reasonable... */ |
1201 | return -ENOMEM; | 1210 | return -ENOMEM; |
1202 | 1211 | ||
1203 | icd->devnum = num; | 1212 | icd->devnum = num; |
1204 | icd->dev.bus = &soc_camera_bus_type; | ||
1205 | |||
1206 | icd->dev.release = dummy_release; | ||
1207 | icd->use_count = 0; | 1213 | icd->use_count = 0; |
1208 | icd->host_priv = NULL; | 1214 | icd->host_priv = NULL; |
1209 | mutex_init(&icd->video_lock); | 1215 | mutex_init(&icd->video_lock); |
@@ -1311,12 +1317,13 @@ static int __devinit soc_camera_pdrv_probe(struct platform_device *pdev) | |||
1311 | icd->iface = icl->bus_id; | 1317 | icd->iface = icl->bus_id; |
1312 | icd->pdev = &pdev->dev; | 1318 | icd->pdev = &pdev->dev; |
1313 | platform_set_drvdata(pdev, icd); | 1319 | platform_set_drvdata(pdev, icd); |
1314 | icd->dev.platform_data = icl; | ||
1315 | 1320 | ||
1316 | ret = soc_camera_device_register(icd); | 1321 | ret = soc_camera_device_register(icd); |
1317 | if (ret < 0) | 1322 | if (ret < 0) |
1318 | goto escdevreg; | 1323 | goto escdevreg; |
1319 | 1324 | ||
1325 | soc_camera_device_init(&icd->dev, icl); | ||
1326 | |||
1320 | icd->user_width = DEFAULT_WIDTH; | 1327 | icd->user_width = DEFAULT_WIDTH; |
1321 | icd->user_height = DEFAULT_HEIGHT; | 1328 | icd->user_height = DEFAULT_HEIGHT; |
1322 | 1329 | ||
diff --git a/drivers/media/video/videobuf-dma-contig.c b/drivers/media/video/videobuf-dma-contig.c index 635ffc7b0391..c3065c4bcba9 100644 --- a/drivers/media/video/videobuf-dma-contig.c +++ b/drivers/media/video/videobuf-dma-contig.c | |||
@@ -19,6 +19,7 @@ | |||
19 | #include <linux/mm.h> | 19 | #include <linux/mm.h> |
20 | #include <linux/pagemap.h> | 20 | #include <linux/pagemap.h> |
21 | #include <linux/dma-mapping.h> | 21 | #include <linux/dma-mapping.h> |
22 | #include <linux/sched.h> | ||
22 | #include <media/videobuf-dma-contig.h> | 23 | #include <media/videobuf-dma-contig.h> |
23 | 24 | ||
24 | struct videobuf_dma_contig_memory { | 25 | struct videobuf_dma_contig_memory { |
diff --git a/drivers/misc/eeprom/at24.c b/drivers/misc/eeprom/at24.c index db39f4a52f53..2cb2736d65aa 100644 --- a/drivers/misc/eeprom/at24.c +++ b/drivers/misc/eeprom/at24.c | |||
@@ -158,6 +158,7 @@ static ssize_t at24_eeprom_read(struct at24_data *at24, char *buf, | |||
158 | struct i2c_msg msg[2]; | 158 | struct i2c_msg msg[2]; |
159 | u8 msgbuf[2]; | 159 | u8 msgbuf[2]; |
160 | struct i2c_client *client; | 160 | struct i2c_client *client; |
161 | unsigned long timeout, read_time; | ||
161 | int status, i; | 162 | int status, i; |
162 | 163 | ||
163 | memset(msg, 0, sizeof(msg)); | 164 | memset(msg, 0, sizeof(msg)); |
@@ -183,47 +184,60 @@ static ssize_t at24_eeprom_read(struct at24_data *at24, char *buf, | |||
183 | if (count > io_limit) | 184 | if (count > io_limit) |
184 | count = io_limit; | 185 | count = io_limit; |
185 | 186 | ||
186 | /* Smaller eeproms can work given some SMBus extension calls */ | ||
187 | if (at24->use_smbus) { | 187 | if (at24->use_smbus) { |
188 | /* Smaller eeproms can work given some SMBus extension calls */ | ||
188 | if (count > I2C_SMBUS_BLOCK_MAX) | 189 | if (count > I2C_SMBUS_BLOCK_MAX) |
189 | count = I2C_SMBUS_BLOCK_MAX; | 190 | count = I2C_SMBUS_BLOCK_MAX; |
190 | status = i2c_smbus_read_i2c_block_data(client, offset, | 191 | } else { |
191 | count, buf); | 192 | /* |
192 | dev_dbg(&client->dev, "smbus read %zu@%d --> %d\n", | 193 | * When we have a better choice than SMBus calls, use a |
193 | count, offset, status); | 194 | * combined I2C message. Write address; then read up to |
194 | return (status < 0) ? -EIO : status; | 195 | * io_limit data bytes. Note that read page rollover helps us |
196 | * here (unlike writes). msgbuf is u8 and will cast to our | ||
197 | * needs. | ||
198 | */ | ||
199 | i = 0; | ||
200 | if (at24->chip.flags & AT24_FLAG_ADDR16) | ||
201 | msgbuf[i++] = offset >> 8; | ||
202 | msgbuf[i++] = offset; | ||
203 | |||
204 | msg[0].addr = client->addr; | ||
205 | msg[0].buf = msgbuf; | ||
206 | msg[0].len = i; | ||
207 | |||
208 | msg[1].addr = client->addr; | ||
209 | msg[1].flags = I2C_M_RD; | ||
210 | msg[1].buf = buf; | ||
211 | msg[1].len = count; | ||
195 | } | 212 | } |
196 | 213 | ||
197 | /* | 214 | /* |
198 | * When we have a better choice than SMBus calls, use a combined | 215 | * Reads fail if the previous write didn't complete yet. We may |
199 | * I2C message. Write address; then read up to io_limit data bytes. | 216 | * loop a few times until this one succeeds, waiting at least |
200 | * Note that read page rollover helps us here (unlike writes). | 217 | * long enough for one entire page write to work. |
201 | * msgbuf is u8 and will cast to our needs. | ||
202 | */ | 218 | */ |
203 | i = 0; | 219 | timeout = jiffies + msecs_to_jiffies(write_timeout); |
204 | if (at24->chip.flags & AT24_FLAG_ADDR16) | 220 | do { |
205 | msgbuf[i++] = offset >> 8; | 221 | read_time = jiffies; |
206 | msgbuf[i++] = offset; | 222 | if (at24->use_smbus) { |
207 | 223 | status = i2c_smbus_read_i2c_block_data(client, offset, | |
208 | msg[0].addr = client->addr; | 224 | count, buf); |
209 | msg[0].buf = msgbuf; | 225 | } else { |
210 | msg[0].len = i; | 226 | status = i2c_transfer(client->adapter, msg, 2); |
227 | if (status == 2) | ||
228 | status = count; | ||
229 | } | ||
230 | dev_dbg(&client->dev, "read %zu@%d --> %d (%ld)\n", | ||
231 | count, offset, status, jiffies); | ||
211 | 232 | ||
212 | msg[1].addr = client->addr; | 233 | if (status == count) |
213 | msg[1].flags = I2C_M_RD; | 234 | return count; |
214 | msg[1].buf = buf; | ||
215 | msg[1].len = count; | ||
216 | 235 | ||
217 | status = i2c_transfer(client->adapter, msg, 2); | 236 | /* REVISIT: at HZ=100, this is sloooow */ |
218 | dev_dbg(&client->dev, "i2c read %zu@%d --> %d\n", | 237 | msleep(1); |
219 | count, offset, status); | 238 | } while (time_before(read_time, timeout)); |
220 | 239 | ||
221 | if (status == 2) | 240 | return -ETIMEDOUT; |
222 | return count; | ||
223 | else if (status >= 0) | ||
224 | return -EIO; | ||
225 | else | ||
226 | return status; | ||
227 | } | 241 | } |
228 | 242 | ||
229 | static ssize_t at24_read(struct at24_data *at24, | 243 | static ssize_t at24_read(struct at24_data *at24, |
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index e19ca4bb7510..b2f71f79baaf 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig | |||
@@ -975,7 +975,7 @@ config ENC28J60_WRITEVERIFY | |||
975 | 975 | ||
976 | config ETHOC | 976 | config ETHOC |
977 | tristate "OpenCores 10/100 Mbps Ethernet MAC support" | 977 | tristate "OpenCores 10/100 Mbps Ethernet MAC support" |
978 | depends on NET_ETHERNET && HAS_IOMEM | 978 | depends on NET_ETHERNET && HAS_IOMEM && HAS_DMA |
979 | select MII | 979 | select MII |
980 | select PHYLIB | 980 | select PHYLIB |
981 | select CRC32 | 981 | select CRC32 |
diff --git a/drivers/net/arm/ep93xx_eth.c b/drivers/net/arm/ep93xx_eth.c index 2be49c817995..b25467ac895c 100644 --- a/drivers/net/arm/ep93xx_eth.c +++ b/drivers/net/arm/ep93xx_eth.c | |||
@@ -628,15 +628,6 @@ static int ep93xx_open(struct net_device *dev) | |||
628 | if (ep93xx_alloc_buffers(ep)) | 628 | if (ep93xx_alloc_buffers(ep)) |
629 | return -ENOMEM; | 629 | return -ENOMEM; |
630 | 630 | ||
631 | if (is_zero_ether_addr(dev->dev_addr)) { | ||
632 | random_ether_addr(dev->dev_addr); | ||
633 | printk(KERN_INFO "%s: generated random MAC address " | ||
634 | "%.2x:%.2x:%.2x:%.2x:%.2x:%.2x.\n", dev->name, | ||
635 | dev->dev_addr[0], dev->dev_addr[1], | ||
636 | dev->dev_addr[2], dev->dev_addr[3], | ||
637 | dev->dev_addr[4], dev->dev_addr[5]); | ||
638 | } | ||
639 | |||
640 | napi_enable(&ep->napi); | 631 | napi_enable(&ep->napi); |
641 | 632 | ||
642 | if (ep93xx_start_hw(dev)) { | 633 | if (ep93xx_start_hw(dev)) { |
@@ -877,6 +868,9 @@ static int ep93xx_eth_probe(struct platform_device *pdev) | |||
877 | ep->mii.mdio_write = ep93xx_mdio_write; | 868 | ep->mii.mdio_write = ep93xx_mdio_write; |
878 | ep->mdc_divisor = 40; /* Max HCLK 100 MHz, min MDIO clk 2.5 MHz. */ | 869 | ep->mdc_divisor = 40; /* Max HCLK 100 MHz, min MDIO clk 2.5 MHz. */ |
879 | 870 | ||
871 | if (is_zero_ether_addr(dev->dev_addr)) | ||
872 | random_ether_addr(dev->dev_addr); | ||
873 | |||
880 | err = register_netdev(dev); | 874 | err = register_netdev(dev); |
881 | if (err) { | 875 | if (err) { |
882 | dev_err(&pdev->dev, "Failed to register netdev\n"); | 876 | dev_err(&pdev->dev, "Failed to register netdev\n"); |
diff --git a/drivers/net/au1000_eth.c b/drivers/net/au1000_eth.c index ce6f1ac25df8..3f4b4300f533 100644 --- a/drivers/net/au1000_eth.c +++ b/drivers/net/au1000_eth.c | |||
@@ -1088,7 +1088,14 @@ static struct net_device * au1000_probe(int port_num) | |||
1088 | return NULL; | 1088 | return NULL; |
1089 | } | 1089 | } |
1090 | 1090 | ||
1091 | if ((err = register_netdev(dev)) != 0) { | 1091 | dev->base_addr = base; |
1092 | dev->irq = irq; | ||
1093 | dev->netdev_ops = &au1000_netdev_ops; | ||
1094 | SET_ETHTOOL_OPS(dev, &au1000_ethtool_ops); | ||
1095 | dev->watchdog_timeo = ETH_TX_TIMEOUT; | ||
1096 | |||
1097 | err = register_netdev(dev); | ||
1098 | if (err != 0) { | ||
1092 | printk(KERN_ERR "%s: Cannot register net device, error %d\n", | 1099 | printk(KERN_ERR "%s: Cannot register net device, error %d\n", |
1093 | DRV_NAME, err); | 1100 | DRV_NAME, err); |
1094 | free_netdev(dev); | 1101 | free_netdev(dev); |
@@ -1209,12 +1216,6 @@ static struct net_device * au1000_probe(int port_num) | |||
1209 | aup->tx_db_inuse[i] = pDB; | 1216 | aup->tx_db_inuse[i] = pDB; |
1210 | } | 1217 | } |
1211 | 1218 | ||
1212 | dev->base_addr = base; | ||
1213 | dev->irq = irq; | ||
1214 | dev->netdev_ops = &au1000_netdev_ops; | ||
1215 | SET_ETHTOOL_OPS(dev, &au1000_ethtool_ops); | ||
1216 | dev->watchdog_timeo = ETH_TX_TIMEOUT; | ||
1217 | |||
1218 | /* | 1219 | /* |
1219 | * The boot code uses the ethernet controller, so reset it to start | 1220 | * The boot code uses the ethernet controller, so reset it to start |
1220 | * fresh. au1000_init() expects that the device is in reset state. | 1221 | * fresh. au1000_init() expects that the device is in reset state. |
diff --git a/drivers/net/b44.c b/drivers/net/b44.c index e046943ef29d..2a9132343b66 100644 --- a/drivers/net/b44.c +++ b/drivers/net/b44.c | |||
@@ -912,9 +912,6 @@ static irqreturn_t b44_interrupt(int irq, void *dev_id) | |||
912 | bp->istat = istat; | 912 | bp->istat = istat; |
913 | __b44_disable_ints(bp); | 913 | __b44_disable_ints(bp); |
914 | __napi_schedule(&bp->napi); | 914 | __napi_schedule(&bp->napi); |
915 | } else { | ||
916 | printk(KERN_ERR PFX "%s: Error, poll already scheduled\n", | ||
917 | dev->name); | ||
918 | } | 915 | } |
919 | 916 | ||
920 | irq_ack: | 917 | irq_ack: |
diff --git a/drivers/net/can/Kconfig b/drivers/net/can/Kconfig index df32c109b7ac..772f6d2489ce 100644 --- a/drivers/net/can/Kconfig +++ b/drivers/net/can/Kconfig | |||
@@ -35,66 +35,16 @@ config CAN_CALC_BITTIMING | |||
35 | arguments "tq", "prop_seg", "phase_seg1", "phase_seg2" and "sjw". | 35 | arguments "tq", "prop_seg", "phase_seg1", "phase_seg2" and "sjw". |
36 | If unsure, say Y. | 36 | If unsure, say Y. |
37 | 37 | ||
38 | config CAN_SJA1000 | ||
39 | depends on CAN_DEV && HAS_IOMEM | ||
40 | tristate "Philips SJA1000" | ||
41 | ---help--- | ||
42 | Driver for the SJA1000 CAN controllers from Philips or NXP | ||
43 | |||
44 | config CAN_SJA1000_ISA | ||
45 | depends on CAN_SJA1000 && ISA | ||
46 | tristate "ISA Bus based legacy SJA1000 driver" | ||
47 | ---help--- | ||
48 | This driver adds legacy support for SJA1000 chips connected to | ||
49 | the ISA bus using I/O port, memory mapped or indirect access. | ||
50 | |||
51 | config CAN_SJA1000_PLATFORM | ||
52 | depends on CAN_SJA1000 | ||
53 | tristate "Generic Platform Bus based SJA1000 driver" | ||
54 | ---help--- | ||
55 | This driver adds support for the SJA1000 chips connected to | ||
56 | the "platform bus" (Linux abstraction for directly to the | ||
57 | processor attached devices). Which can be found on various | ||
58 | boards from Phytec (http://www.phytec.de) like the PCM027, | ||
59 | PCM038. | ||
60 | |||
61 | config CAN_SJA1000_OF_PLATFORM | ||
62 | depends on CAN_SJA1000 && PPC_OF | ||
63 | tristate "Generic OF Platform Bus based SJA1000 driver" | ||
64 | ---help--- | ||
65 | This driver adds support for the SJA1000 chips connected to | ||
66 | the OpenFirmware "platform bus" found on embedded systems with | ||
67 | OpenFirmware bindings, e.g. if you have a PowerPC based system | ||
68 | you may want to enable this option. | ||
69 | |||
70 | config CAN_EMS_PCI | ||
71 | tristate "EMS CPC-PCI, CPC-PCIe and CPC-104P Card" | ||
72 | depends on PCI && CAN_SJA1000 | ||
73 | ---help--- | ||
74 | This driver is for the one, two or four channel CPC-PCI, | ||
75 | CPC-PCIe and CPC-104P cards from EMS Dr. Thomas Wuensche | ||
76 | (http://www.ems-wuensche.de). | ||
77 | |||
78 | config CAN_EMS_USB | ||
79 | tristate "EMS CPC-USB/ARM7 CAN/USB interface" | ||
80 | depends on USB && CAN_DEV | ||
81 | ---help--- | ||
82 | This driver is for the one channel CPC-USB/ARM7 CAN/USB interface | ||
83 | from from EMS Dr. Thomas Wuensche (http://www.ems-wuensche.de). | ||
84 | |||
85 | config CAN_KVASER_PCI | ||
86 | tristate "Kvaser PCIcanx and Kvaser PCIcan PCI Cards" | ||
87 | depends on PCI && CAN_SJA1000 | ||
88 | ---help--- | ||
89 | This driver is for the the PCIcanx and PCIcan cards (1, 2 or | ||
90 | 4 channel) from Kvaser (http://www.kvaser.com). | ||
91 | |||
92 | config CAN_AT91 | 38 | config CAN_AT91 |
93 | tristate "Atmel AT91 onchip CAN controller" | 39 | tristate "Atmel AT91 onchip CAN controller" |
94 | depends on CAN && CAN_DEV && ARCH_AT91SAM9263 | 40 | depends on CAN_DEV && ARCH_AT91SAM9263 |
95 | ---help--- | 41 | ---help--- |
96 | This is a driver for the SoC CAN controller in Atmel's AT91SAM9263. | 42 | This is a driver for the SoC CAN controller in Atmel's AT91SAM9263. |
97 | 43 | ||
44 | source "drivers/net/can/sja1000/Kconfig" | ||
45 | |||
46 | source "drivers/net/can/usb/Kconfig" | ||
47 | |||
98 | config CAN_DEBUG_DEVICES | 48 | config CAN_DEBUG_DEVICES |
99 | bool "CAN devices debugging messages" | 49 | bool "CAN devices debugging messages" |
100 | depends on CAN | 50 | depends on CAN |
diff --git a/drivers/net/can/dev.c b/drivers/net/can/dev.c index 564e31c9fee4..2868fe842a41 100644 --- a/drivers/net/can/dev.c +++ b/drivers/net/can/dev.c | |||
@@ -629,6 +629,11 @@ nla_put_failure: | |||
629 | return -EMSGSIZE; | 629 | return -EMSGSIZE; |
630 | } | 630 | } |
631 | 631 | ||
632 | static size_t can_get_xstats_size(const struct net_device *dev) | ||
633 | { | ||
634 | return sizeof(struct can_device_stats); | ||
635 | } | ||
636 | |||
632 | static int can_fill_xstats(struct sk_buff *skb, const struct net_device *dev) | 637 | static int can_fill_xstats(struct sk_buff *skb, const struct net_device *dev) |
633 | { | 638 | { |
634 | struct can_priv *priv = netdev_priv(dev); | 639 | struct can_priv *priv = netdev_priv(dev); |
@@ -657,6 +662,7 @@ static struct rtnl_link_ops can_link_ops __read_mostly = { | |||
657 | .changelink = can_changelink, | 662 | .changelink = can_changelink, |
658 | .get_size = can_get_size, | 663 | .get_size = can_get_size, |
659 | .fill_info = can_fill_info, | 664 | .fill_info = can_fill_info, |
665 | .get_xstats_size = can_get_xstats_size, | ||
660 | .fill_xstats = can_fill_xstats, | 666 | .fill_xstats = can_fill_xstats, |
661 | }; | 667 | }; |
662 | 668 | ||
diff --git a/drivers/net/can/sja1000/Kconfig b/drivers/net/can/sja1000/Kconfig new file mode 100644 index 000000000000..4c674927f247 --- /dev/null +++ b/drivers/net/can/sja1000/Kconfig | |||
@@ -0,0 +1,47 @@ | |||
1 | menuconfig CAN_SJA1000 | ||
2 | tristate "Philips/NXP SJA1000 devices" | ||
3 | depends on CAN_DEV && HAS_IOMEM | ||
4 | |||
5 | if CAN_SJA1000 | ||
6 | |||
7 | config CAN_SJA1000_ISA | ||
8 | tristate "ISA Bus based legacy SJA1000 driver" | ||
9 | depends on ISA | ||
10 | ---help--- | ||
11 | This driver adds legacy support for SJA1000 chips connected to | ||
12 | the ISA bus using I/O port, memory mapped or indirect access. | ||
13 | |||
14 | config CAN_SJA1000_PLATFORM | ||
15 | tristate "Generic Platform Bus based SJA1000 driver" | ||
16 | ---help--- | ||
17 | This driver adds support for the SJA1000 chips connected to | ||
18 | the "platform bus" (Linux abstraction for directly to the | ||
19 | processor attached devices). Which can be found on various | ||
20 | boards from Phytec (http://www.phytec.de) like the PCM027, | ||
21 | PCM038. | ||
22 | |||
23 | config CAN_SJA1000_OF_PLATFORM | ||
24 | tristate "Generic OF Platform Bus based SJA1000 driver" | ||
25 | depends on PPC_OF | ||
26 | ---help--- | ||
27 | This driver adds support for the SJA1000 chips connected to | ||
28 | the OpenFirmware "platform bus" found on embedded systems with | ||
29 | OpenFirmware bindings, e.g. if you have a PowerPC based system | ||
30 | you may want to enable this option. | ||
31 | |||
32 | config CAN_EMS_PCI | ||
33 | tristate "EMS CPC-PCI, CPC-PCIe and CPC-104P Card" | ||
34 | depends on PCI | ||
35 | ---help--- | ||
36 | This driver is for the one, two or four channel CPC-PCI, | ||
37 | CPC-PCIe and CPC-104P cards from EMS Dr. Thomas Wuensche | ||
38 | (http://www.ems-wuensche.de). | ||
39 | |||
40 | config CAN_KVASER_PCI | ||
41 | tristate "Kvaser PCIcanx and Kvaser PCIcan PCI Cards" | ||
42 | depends on PCI | ||
43 | ---help--- | ||
44 | This driver is for the the PCIcanx and PCIcan cards (1, 2 or | ||
45 | 4 channel) from Kvaser (http://www.kvaser.com). | ||
46 | |||
47 | endif | ||
diff --git a/drivers/net/can/usb/Kconfig b/drivers/net/can/usb/Kconfig new file mode 100644 index 000000000000..bbc78e0b8a15 --- /dev/null +++ b/drivers/net/can/usb/Kconfig | |||
@@ -0,0 +1,10 @@ | |||
1 | menu "CAN USB interfaces" | ||
2 | depends on USB && CAN_DEV | ||
3 | |||
4 | config CAN_EMS_USB | ||
5 | tristate "EMS CPC-USB/ARM7 CAN/USB interface" | ||
6 | ---help--- | ||
7 | This driver is for the one channel CPC-USB/ARM7 CAN/USB interface | ||
8 | from from EMS Dr. Thomas Wuensche (http://www.ems-wuensche.de). | ||
9 | |||
10 | endmenu | ||
diff --git a/drivers/net/can/usb/Makefile b/drivers/net/can/usb/Makefile index c3f75ba701b1..0afd51d4c7a5 100644 --- a/drivers/net/can/usb/Makefile +++ b/drivers/net/can/usb/Makefile | |||
@@ -3,3 +3,5 @@ | |||
3 | # | 3 | # |
4 | 4 | ||
5 | obj-$(CONFIG_CAN_EMS_USB) += ems_usb.o | 5 | obj-$(CONFIG_CAN_EMS_USB) += ems_usb.o |
6 | |||
7 | ccflags-$(CONFIG_CAN_DEBUG_DEVICES) := -DDEBUG | ||
diff --git a/drivers/net/cxgb3/sge.c b/drivers/net/cxgb3/sge.c index f86612857a73..6366061712f4 100644 --- a/drivers/net/cxgb3/sge.c +++ b/drivers/net/cxgb3/sge.c | |||
@@ -879,7 +879,7 @@ recycle: | |||
879 | pci_dma_sync_single_for_cpu(adap->pdev, dma_addr, len, | 879 | pci_dma_sync_single_for_cpu(adap->pdev, dma_addr, len, |
880 | PCI_DMA_FROMDEVICE); | 880 | PCI_DMA_FROMDEVICE); |
881 | (*sd->pg_chunk.p_cnt)--; | 881 | (*sd->pg_chunk.p_cnt)--; |
882 | if (!*sd->pg_chunk.p_cnt) | 882 | if (!*sd->pg_chunk.p_cnt && sd->pg_chunk.page != fl->pg_chunk.page) |
883 | pci_unmap_page(adap->pdev, | 883 | pci_unmap_page(adap->pdev, |
884 | sd->pg_chunk.mapping, | 884 | sd->pg_chunk.mapping, |
885 | fl->alloc_size, | 885 | fl->alloc_size, |
@@ -2088,7 +2088,7 @@ static void lro_add_page(struct adapter *adap, struct sge_qset *qs, | |||
2088 | PCI_DMA_FROMDEVICE); | 2088 | PCI_DMA_FROMDEVICE); |
2089 | 2089 | ||
2090 | (*sd->pg_chunk.p_cnt)--; | 2090 | (*sd->pg_chunk.p_cnt)--; |
2091 | if (!*sd->pg_chunk.p_cnt) | 2091 | if (!*sd->pg_chunk.p_cnt && sd->pg_chunk.page != fl->pg_chunk.page) |
2092 | pci_unmap_page(adap->pdev, | 2092 | pci_unmap_page(adap->pdev, |
2093 | sd->pg_chunk.mapping, | 2093 | sd->pg_chunk.mapping, |
2094 | fl->alloc_size, | 2094 | fl->alloc_size, |
diff --git a/drivers/net/davinci_emac.c b/drivers/net/davinci_emac.c index 3179521aee90..e3478314c002 100644 --- a/drivers/net/davinci_emac.c +++ b/drivers/net/davinci_emac.c | |||
@@ -164,16 +164,14 @@ static const char emac_version_string[] = "TI DaVinci EMAC Linux v6.1"; | |||
164 | # define EMAC_MBP_MCASTCHAN(ch) ((ch) & 0x7) | 164 | # define EMAC_MBP_MCASTCHAN(ch) ((ch) & 0x7) |
165 | 165 | ||
166 | /* EMAC mac_control register */ | 166 | /* EMAC mac_control register */ |
167 | #define EMAC_MACCONTROL_TXPTYPE (0x200) | 167 | #define EMAC_MACCONTROL_TXPTYPE BIT(9) |
168 | #define EMAC_MACCONTROL_TXPACEEN (0x40) | 168 | #define EMAC_MACCONTROL_TXPACEEN BIT(6) |
169 | #define EMAC_MACCONTROL_MIIEN (0x20) | 169 | #define EMAC_MACCONTROL_GMIIEN BIT(5) |
170 | #define EMAC_MACCONTROL_GIGABITEN (0x80) | 170 | #define EMAC_MACCONTROL_GIGABITEN BIT(7) |
171 | #define EMAC_MACCONTROL_GIGABITEN_SHIFT (7) | 171 | #define EMAC_MACCONTROL_FULLDUPLEXEN BIT(0) |
172 | #define EMAC_MACCONTROL_FULLDUPLEXEN (0x1) | ||
173 | #define EMAC_MACCONTROL_RMIISPEED_MASK BIT(15) | 172 | #define EMAC_MACCONTROL_RMIISPEED_MASK BIT(15) |
174 | 173 | ||
175 | /* GIGABIT MODE related bits */ | 174 | /* GIGABIT MODE related bits */ |
176 | #define EMAC_DM646X_MACCONTORL_GMIIEN BIT(5) | ||
177 | #define EMAC_DM646X_MACCONTORL_GIG BIT(7) | 175 | #define EMAC_DM646X_MACCONTORL_GIG BIT(7) |
178 | #define EMAC_DM646X_MACCONTORL_GIGFORCE BIT(17) | 176 | #define EMAC_DM646X_MACCONTORL_GIGFORCE BIT(17) |
179 | 177 | ||
@@ -192,10 +190,10 @@ static const char emac_version_string[] = "TI DaVinci EMAC Linux v6.1"; | |||
192 | #define EMAC_RX_BUFFER_OFFSET_MASK (0xFFFF) | 190 | #define EMAC_RX_BUFFER_OFFSET_MASK (0xFFFF) |
193 | 191 | ||
194 | /* MAC_IN_VECTOR (0x180) register bit fields */ | 192 | /* MAC_IN_VECTOR (0x180) register bit fields */ |
195 | #define EMAC_DM644X_MAC_IN_VECTOR_HOST_INT (0x20000) | 193 | #define EMAC_DM644X_MAC_IN_VECTOR_HOST_INT BIT(17) |
196 | #define EMAC_DM644X_MAC_IN_VECTOR_STATPEND_INT (0x10000) | 194 | #define EMAC_DM644X_MAC_IN_VECTOR_STATPEND_INT BIT(16) |
197 | #define EMAC_DM644X_MAC_IN_VECTOR_RX_INT_VEC (0x0100) | 195 | #define EMAC_DM644X_MAC_IN_VECTOR_RX_INT_VEC BIT(8) |
198 | #define EMAC_DM644X_MAC_IN_VECTOR_TX_INT_VEC (0x01) | 196 | #define EMAC_DM644X_MAC_IN_VECTOR_TX_INT_VEC BIT(0) |
199 | 197 | ||
200 | /** NOTE:: For DM646x the IN_VECTOR has changed */ | 198 | /** NOTE:: For DM646x the IN_VECTOR has changed */ |
201 | #define EMAC_DM646X_MAC_IN_VECTOR_RX_INT_VEC BIT(EMAC_DEF_RX_CH) | 199 | #define EMAC_DM646X_MAC_IN_VECTOR_RX_INT_VEC BIT(EMAC_DEF_RX_CH) |
@@ -203,7 +201,6 @@ static const char emac_version_string[] = "TI DaVinci EMAC Linux v6.1"; | |||
203 | #define EMAC_DM646X_MAC_IN_VECTOR_HOST_INT BIT(26) | 201 | #define EMAC_DM646X_MAC_IN_VECTOR_HOST_INT BIT(26) |
204 | #define EMAC_DM646X_MAC_IN_VECTOR_STATPEND_INT BIT(27) | 202 | #define EMAC_DM646X_MAC_IN_VECTOR_STATPEND_INT BIT(27) |
205 | 203 | ||
206 | |||
207 | /* CPPI bit positions */ | 204 | /* CPPI bit positions */ |
208 | #define EMAC_CPPI_SOP_BIT BIT(31) | 205 | #define EMAC_CPPI_SOP_BIT BIT(31) |
209 | #define EMAC_CPPI_EOP_BIT BIT(30) | 206 | #define EMAC_CPPI_EOP_BIT BIT(30) |
@@ -750,8 +747,7 @@ static void emac_update_phystatus(struct emac_priv *priv) | |||
750 | 747 | ||
751 | if (priv->speed == SPEED_1000 && (priv->version == EMAC_VERSION_2)) { | 748 | if (priv->speed == SPEED_1000 && (priv->version == EMAC_VERSION_2)) { |
752 | mac_control = emac_read(EMAC_MACCONTROL); | 749 | mac_control = emac_read(EMAC_MACCONTROL); |
753 | mac_control |= (EMAC_DM646X_MACCONTORL_GMIIEN | | 750 | mac_control |= (EMAC_DM646X_MACCONTORL_GIG | |
754 | EMAC_DM646X_MACCONTORL_GIG | | ||
755 | EMAC_DM646X_MACCONTORL_GIGFORCE); | 751 | EMAC_DM646X_MACCONTORL_GIGFORCE); |
756 | } else { | 752 | } else { |
757 | /* Clear the GIG bit and GIGFORCE bit */ | 753 | /* Clear the GIG bit and GIGFORCE bit */ |
@@ -2108,7 +2104,7 @@ static int emac_hw_enable(struct emac_priv *priv) | |||
2108 | 2104 | ||
2109 | /* Enable MII */ | 2105 | /* Enable MII */ |
2110 | val = emac_read(EMAC_MACCONTROL); | 2106 | val = emac_read(EMAC_MACCONTROL); |
2111 | val |= (EMAC_MACCONTROL_MIIEN); | 2107 | val |= (EMAC_MACCONTROL_GMIIEN); |
2112 | emac_write(EMAC_MACCONTROL, val); | 2108 | emac_write(EMAC_MACCONTROL, val); |
2113 | 2109 | ||
2114 | /* Enable NAPI and interrupts */ | 2110 | /* Enable NAPI and interrupts */ |
@@ -2140,9 +2136,6 @@ static int emac_poll(struct napi_struct *napi, int budget) | |||
2140 | u32 status = 0; | 2136 | u32 status = 0; |
2141 | u32 num_pkts = 0; | 2137 | u32 num_pkts = 0; |
2142 | 2138 | ||
2143 | if (!netif_running(ndev)) | ||
2144 | return 0; | ||
2145 | |||
2146 | /* Check interrupt vectors and call packet processing */ | 2139 | /* Check interrupt vectors and call packet processing */ |
2147 | status = emac_read(EMAC_MACINVECTOR); | 2140 | status = emac_read(EMAC_MACINVECTOR); |
2148 | 2141 | ||
diff --git a/drivers/net/e100.c b/drivers/net/e100.c index 3c29a20b751e..d269a68ce354 100644 --- a/drivers/net/e100.c +++ b/drivers/net/e100.c | |||
@@ -157,6 +157,7 @@ | |||
157 | #include <linux/init.h> | 157 | #include <linux/init.h> |
158 | #include <linux/pci.h> | 158 | #include <linux/pci.h> |
159 | #include <linux/dma-mapping.h> | 159 | #include <linux/dma-mapping.h> |
160 | #include <linux/dmapool.h> | ||
160 | #include <linux/netdevice.h> | 161 | #include <linux/netdevice.h> |
161 | #include <linux/etherdevice.h> | 162 | #include <linux/etherdevice.h> |
162 | #include <linux/mii.h> | 163 | #include <linux/mii.h> |
@@ -602,6 +603,7 @@ struct nic { | |||
602 | struct mem *mem; | 603 | struct mem *mem; |
603 | dma_addr_t dma_addr; | 604 | dma_addr_t dma_addr; |
604 | 605 | ||
606 | struct pci_pool *cbs_pool; | ||
605 | dma_addr_t cbs_dma_addr; | 607 | dma_addr_t cbs_dma_addr; |
606 | u8 adaptive_ifs; | 608 | u8 adaptive_ifs; |
607 | u8 tx_threshold; | 609 | u8 tx_threshold; |
@@ -1793,9 +1795,7 @@ static void e100_clean_cbs(struct nic *nic) | |||
1793 | nic->cb_to_clean = nic->cb_to_clean->next; | 1795 | nic->cb_to_clean = nic->cb_to_clean->next; |
1794 | nic->cbs_avail++; | 1796 | nic->cbs_avail++; |
1795 | } | 1797 | } |
1796 | pci_free_consistent(nic->pdev, | 1798 | pci_pool_free(nic->cbs_pool, nic->cbs, nic->cbs_dma_addr); |
1797 | sizeof(struct cb) * nic->params.cbs.count, | ||
1798 | nic->cbs, nic->cbs_dma_addr); | ||
1799 | nic->cbs = NULL; | 1799 | nic->cbs = NULL; |
1800 | nic->cbs_avail = 0; | 1800 | nic->cbs_avail = 0; |
1801 | } | 1801 | } |
@@ -1813,8 +1813,8 @@ static int e100_alloc_cbs(struct nic *nic) | |||
1813 | nic->cb_to_use = nic->cb_to_send = nic->cb_to_clean = NULL; | 1813 | nic->cb_to_use = nic->cb_to_send = nic->cb_to_clean = NULL; |
1814 | nic->cbs_avail = 0; | 1814 | nic->cbs_avail = 0; |
1815 | 1815 | ||
1816 | nic->cbs = pci_alloc_consistent(nic->pdev, | 1816 | nic->cbs = pci_pool_alloc(nic->cbs_pool, GFP_KERNEL, |
1817 | sizeof(struct cb) * count, &nic->cbs_dma_addr); | 1817 | &nic->cbs_dma_addr); |
1818 | if (!nic->cbs) | 1818 | if (!nic->cbs) |
1819 | return -ENOMEM; | 1819 | return -ENOMEM; |
1820 | 1820 | ||
@@ -2841,7 +2841,11 @@ static int __devinit e100_probe(struct pci_dev *pdev, | |||
2841 | DPRINTK(PROBE, ERR, "Cannot register net device, aborting.\n"); | 2841 | DPRINTK(PROBE, ERR, "Cannot register net device, aborting.\n"); |
2842 | goto err_out_free; | 2842 | goto err_out_free; |
2843 | } | 2843 | } |
2844 | 2844 | nic->cbs_pool = pci_pool_create(netdev->name, | |
2845 | nic->pdev, | ||
2846 | nic->params.cbs.count * sizeof(struct cb), | ||
2847 | sizeof(u32), | ||
2848 | 0); | ||
2845 | DPRINTK(PROBE, INFO, "addr 0x%llx, irq %d, MAC addr %pM\n", | 2849 | DPRINTK(PROBE, INFO, "addr 0x%llx, irq %d, MAC addr %pM\n", |
2846 | (unsigned long long)pci_resource_start(pdev, use_io ? 1 : 0), | 2850 | (unsigned long long)pci_resource_start(pdev, use_io ? 1 : 0), |
2847 | pdev->irq, netdev->dev_addr); | 2851 | pdev->irq, netdev->dev_addr); |
@@ -2871,6 +2875,7 @@ static void __devexit e100_remove(struct pci_dev *pdev) | |||
2871 | unregister_netdev(netdev); | 2875 | unregister_netdev(netdev); |
2872 | e100_free(nic); | 2876 | e100_free(nic); |
2873 | pci_iounmap(pdev, nic->csr); | 2877 | pci_iounmap(pdev, nic->csr); |
2878 | pci_pool_destroy(nic->cbs_pool); | ||
2874 | free_netdev(netdev); | 2879 | free_netdev(netdev); |
2875 | pci_release_regions(pdev); | 2880 | pci_release_regions(pdev); |
2876 | pci_disable_device(pdev); | 2881 | pci_disable_device(pdev); |
diff --git a/drivers/net/e1000e/e1000.h b/drivers/net/e1000e/e1000.h index 189dfa2d6c76..3e187b0e4203 100644 --- a/drivers/net/e1000e/e1000.h +++ b/drivers/net/e1000e/e1000.h | |||
@@ -141,6 +141,8 @@ struct e1000_info; | |||
141 | #define HV_TNCRS_UPPER PHY_REG(778, 29) /* Transmit with no CRS */ | 141 | #define HV_TNCRS_UPPER PHY_REG(778, 29) /* Transmit with no CRS */ |
142 | #define HV_TNCRS_LOWER PHY_REG(778, 30) | 142 | #define HV_TNCRS_LOWER PHY_REG(778, 30) |
143 | 143 | ||
144 | #define E1000_FCRTV_PCH 0x05F40 /* PCH Flow Control Refresh Timer Value */ | ||
145 | |||
144 | /* BM PHY Copper Specific Status */ | 146 | /* BM PHY Copper Specific Status */ |
145 | #define BM_CS_STATUS 17 | 147 | #define BM_CS_STATUS 17 |
146 | #define BM_CS_STATUS_LINK_UP 0x0400 | 148 | #define BM_CS_STATUS_LINK_UP 0x0400 |
diff --git a/drivers/net/e1000e/ethtool.c b/drivers/net/e1000e/ethtool.c index 1bf4d2a5d34f..e82638ecae88 100644 --- a/drivers/net/e1000e/ethtool.c +++ b/drivers/net/e1000e/ethtool.c | |||
@@ -327,10 +327,18 @@ static int e1000_set_pauseparam(struct net_device *netdev, | |||
327 | 327 | ||
328 | hw->fc.current_mode = hw->fc.requested_mode; | 328 | hw->fc.current_mode = hw->fc.requested_mode; |
329 | 329 | ||
330 | retval = ((hw->phy.media_type == e1000_media_type_fiber) ? | 330 | if (hw->phy.media_type == e1000_media_type_fiber) { |
331 | hw->mac.ops.setup_link(hw) : e1000e_force_mac_fc(hw)); | 331 | retval = hw->mac.ops.setup_link(hw); |
332 | /* implicit goto out */ | ||
333 | } else { | ||
334 | retval = e1000e_force_mac_fc(hw); | ||
335 | if (retval) | ||
336 | goto out; | ||
337 | e1000e_set_fc_watermarks(hw); | ||
338 | } | ||
332 | } | 339 | } |
333 | 340 | ||
341 | out: | ||
334 | clear_bit(__E1000_RESETTING, &adapter->state); | 342 | clear_bit(__E1000_RESETTING, &adapter->state); |
335 | return retval; | 343 | return retval; |
336 | } | 344 | } |
diff --git a/drivers/net/e1000e/ich8lan.c b/drivers/net/e1000e/ich8lan.c index 51ddb04ab195..eff3f4783655 100644 --- a/drivers/net/e1000e/ich8lan.c +++ b/drivers/net/e1000e/ich8lan.c | |||
@@ -1118,7 +1118,8 @@ static s32 e1000_oem_bits_config_ich8lan(struct e1000_hw *hw, bool d0_state) | |||
1118 | oem_reg |= HV_OEM_BITS_LPLU; | 1118 | oem_reg |= HV_OEM_BITS_LPLU; |
1119 | } | 1119 | } |
1120 | /* Restart auto-neg to activate the bits */ | 1120 | /* Restart auto-neg to activate the bits */ |
1121 | oem_reg |= HV_OEM_BITS_RESTART_AN; | 1121 | if (!e1000_check_reset_block(hw)) |
1122 | oem_reg |= HV_OEM_BITS_RESTART_AN; | ||
1122 | ret_val = hw->phy.ops.write_phy_reg_locked(hw, HV_OEM_BITS, oem_reg); | 1123 | ret_val = hw->phy.ops.write_phy_reg_locked(hw, HV_OEM_BITS, oem_reg); |
1123 | 1124 | ||
1124 | out: | 1125 | out: |
@@ -3558,6 +3559,7 @@ struct e1000_info e1000_pch_info = { | |||
3558 | | FLAG_HAS_AMT | 3559 | | FLAG_HAS_AMT |
3559 | | FLAG_HAS_FLASH | 3560 | | FLAG_HAS_FLASH |
3560 | | FLAG_HAS_JUMBO_FRAMES | 3561 | | FLAG_HAS_JUMBO_FRAMES |
3562 | | FLAG_DISABLE_FC_PAUSE_TIME /* errata */ | ||
3561 | | FLAG_APME_IN_WUC, | 3563 | | FLAG_APME_IN_WUC, |
3562 | .pba = 26, | 3564 | .pba = 26, |
3563 | .max_hw_frame_size = 4096, | 3565 | .max_hw_frame_size = 4096, |
diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c index 0687c6aa4e46..fad8f9ea0043 100644 --- a/drivers/net/e1000e/netdev.c +++ b/drivers/net/e1000e/netdev.c | |||
@@ -2769,25 +2769,38 @@ void e1000e_reset(struct e1000_adapter *adapter) | |||
2769 | /* | 2769 | /* |
2770 | * flow control settings | 2770 | * flow control settings |
2771 | * | 2771 | * |
2772 | * The high water mark must be low enough to fit two full frame | 2772 | * The high water mark must be low enough to fit one full frame |
2773 | * (or the size used for early receive) above it in the Rx FIFO. | 2773 | * (or the size used for early receive) above it in the Rx FIFO. |
2774 | * Set it to the lower of: | 2774 | * Set it to the lower of: |
2775 | * - 90% of the Rx FIFO size, and | 2775 | * - 90% of the Rx FIFO size, and |
2776 | * - the full Rx FIFO size minus the early receive size (for parts | 2776 | * - the full Rx FIFO size minus the early receive size (for parts |
2777 | * with ERT support assuming ERT set to E1000_ERT_2048), or | 2777 | * with ERT support assuming ERT set to E1000_ERT_2048), or |
2778 | * - the full Rx FIFO size minus two full frames | 2778 | * - the full Rx FIFO size minus one full frame |
2779 | */ | 2779 | */ |
2780 | if ((adapter->flags & FLAG_HAS_ERT) && | 2780 | if (hw->mac.type == e1000_pchlan) { |
2781 | (adapter->netdev->mtu > ETH_DATA_LEN)) | 2781 | /* |
2782 | hwm = min(((pba << 10) * 9 / 10), | 2782 | * Workaround PCH LOM adapter hangs with certain network |
2783 | ((pba << 10) - (E1000_ERT_2048 << 3))); | 2783 | * loads. If hangs persist, try disabling Tx flow control. |
2784 | else | 2784 | */ |
2785 | hwm = min(((pba << 10) * 9 / 10), | 2785 | if (adapter->netdev->mtu > ETH_DATA_LEN) { |
2786 | ((pba << 10) - (2 * adapter->max_frame_size))); | 2786 | fc->high_water = 0x3500; |
2787 | fc->low_water = 0x1500; | ||
2788 | } else { | ||
2789 | fc->high_water = 0x5000; | ||
2790 | fc->low_water = 0x3000; | ||
2791 | } | ||
2792 | } else { | ||
2793 | if ((adapter->flags & FLAG_HAS_ERT) && | ||
2794 | (adapter->netdev->mtu > ETH_DATA_LEN)) | ||
2795 | hwm = min(((pba << 10) * 9 / 10), | ||
2796 | ((pba << 10) - (E1000_ERT_2048 << 3))); | ||
2797 | else | ||
2798 | hwm = min(((pba << 10) * 9 / 10), | ||
2799 | ((pba << 10) - adapter->max_frame_size)); | ||
2787 | 2800 | ||
2788 | fc->high_water = hwm & E1000_FCRTH_RTH; /* 8-byte granularity */ | 2801 | fc->high_water = hwm & E1000_FCRTH_RTH; /* 8-byte granularity */ |
2789 | fc->low_water = (fc->high_water - (2 * adapter->max_frame_size)); | 2802 | fc->low_water = fc->high_water - 8; |
2790 | fc->low_water &= E1000_FCRTL_RTL; /* 8-byte granularity */ | 2803 | } |
2791 | 2804 | ||
2792 | if (adapter->flags & FLAG_DISABLE_FC_PAUSE_TIME) | 2805 | if (adapter->flags & FLAG_DISABLE_FC_PAUSE_TIME) |
2793 | fc->pause_time = 0xFFFF; | 2806 | fc->pause_time = 0xFFFF; |
@@ -2813,6 +2826,10 @@ void e1000e_reset(struct e1000_adapter *adapter) | |||
2813 | if (mac->ops.init_hw(hw)) | 2826 | if (mac->ops.init_hw(hw)) |
2814 | e_err("Hardware Error\n"); | 2827 | e_err("Hardware Error\n"); |
2815 | 2828 | ||
2829 | /* additional part of the flow-control workaround above */ | ||
2830 | if (hw->mac.type == e1000_pchlan) | ||
2831 | ew32(FCRTV_PCH, 0x1000); | ||
2832 | |||
2816 | e1000_update_mng_vlan(adapter); | 2833 | e1000_update_mng_vlan(adapter); |
2817 | 2834 | ||
2818 | /* Enable h/w to recognize an 802.1Q VLAN Ethernet packet */ | 2835 | /* Enable h/w to recognize an 802.1Q VLAN Ethernet packet */ |
@@ -3610,7 +3627,7 @@ static void e1000_watchdog_task(struct work_struct *work) | |||
3610 | case SPEED_100: | 3627 | case SPEED_100: |
3611 | txb2b = 0; | 3628 | txb2b = 0; |
3612 | netdev->tx_queue_len = 100; | 3629 | netdev->tx_queue_len = 100; |
3613 | /* maybe add some timeout factor ? */ | 3630 | adapter->tx_timeout_factor = 10; |
3614 | break; | 3631 | break; |
3615 | } | 3632 | } |
3616 | 3633 | ||
@@ -4288,8 +4305,10 @@ static int e1000_change_mtu(struct net_device *netdev, int new_mtu) | |||
4288 | 4305 | ||
4289 | while (test_and_set_bit(__E1000_RESETTING, &adapter->state)) | 4306 | while (test_and_set_bit(__E1000_RESETTING, &adapter->state)) |
4290 | msleep(1); | 4307 | msleep(1); |
4291 | /* e1000e_down has a dependency on max_frame_size */ | 4308 | /* e1000e_down -> e1000e_reset dependent on max_frame_size & mtu */ |
4292 | adapter->max_frame_size = max_frame; | 4309 | adapter->max_frame_size = max_frame; |
4310 | e_info("changing MTU from %d to %d\n", netdev->mtu, new_mtu); | ||
4311 | netdev->mtu = new_mtu; | ||
4293 | if (netif_running(netdev)) | 4312 | if (netif_running(netdev)) |
4294 | e1000e_down(adapter); | 4313 | e1000e_down(adapter); |
4295 | 4314 | ||
@@ -4319,9 +4338,6 @@ static int e1000_change_mtu(struct net_device *netdev, int new_mtu) | |||
4319 | adapter->rx_buffer_len = ETH_FRAME_LEN + VLAN_HLEN | 4338 | adapter->rx_buffer_len = ETH_FRAME_LEN + VLAN_HLEN |
4320 | + ETH_FCS_LEN; | 4339 | + ETH_FCS_LEN; |
4321 | 4340 | ||
4322 | e_info("changing MTU from %d to %d\n", netdev->mtu, new_mtu); | ||
4323 | netdev->mtu = new_mtu; | ||
4324 | |||
4325 | if (netif_running(netdev)) | 4341 | if (netif_running(netdev)) |
4326 | e1000e_up(adapter); | 4342 | e1000e_up(adapter); |
4327 | else | 4343 | else |
diff --git a/drivers/net/e1000e/phy.c b/drivers/net/e1000e/phy.c index 03175b3a2c9e..85f955f70417 100644 --- a/drivers/net/e1000e/phy.c +++ b/drivers/net/e1000e/phy.c | |||
@@ -71,7 +71,6 @@ static const u16 e1000_igp_2_cable_length_table[] = | |||
71 | #define I82577_CFG_ASSERT_CRS_ON_TX (1 << 15) | 71 | #define I82577_CFG_ASSERT_CRS_ON_TX (1 << 15) |
72 | #define I82577_CFG_ENABLE_DOWNSHIFT (3 << 10) /* auto downshift 100/10 */ | 72 | #define I82577_CFG_ENABLE_DOWNSHIFT (3 << 10) /* auto downshift 100/10 */ |
73 | #define I82577_CTRL_REG 23 | 73 | #define I82577_CTRL_REG 23 |
74 | #define I82577_CTRL_DOWNSHIFT_MASK (7 << 10) | ||
75 | 74 | ||
76 | /* 82577 specific PHY registers */ | 75 | /* 82577 specific PHY registers */ |
77 | #define I82577_PHY_CTRL_2 18 | 76 | #define I82577_PHY_CTRL_2 18 |
@@ -660,15 +659,6 @@ s32 e1000_copper_link_setup_82577(struct e1000_hw *hw) | |||
660 | phy_data |= I82577_CFG_ENABLE_DOWNSHIFT; | 659 | phy_data |= I82577_CFG_ENABLE_DOWNSHIFT; |
661 | 660 | ||
662 | ret_val = phy->ops.write_phy_reg(hw, I82577_CFG_REG, phy_data); | 661 | ret_val = phy->ops.write_phy_reg(hw, I82577_CFG_REG, phy_data); |
663 | if (ret_val) | ||
664 | goto out; | ||
665 | |||
666 | /* Set number of link attempts before downshift */ | ||
667 | ret_val = phy->ops.read_phy_reg(hw, I82577_CTRL_REG, &phy_data); | ||
668 | if (ret_val) | ||
669 | goto out; | ||
670 | phy_data &= ~I82577_CTRL_DOWNSHIFT_MASK; | ||
671 | ret_val = phy->ops.write_phy_reg(hw, I82577_CTRL_REG, phy_data); | ||
672 | 662 | ||
673 | out: | 663 | out: |
674 | return ret_val; | 664 | return ret_val; |
@@ -2658,19 +2648,18 @@ static s32 __e1000_read_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 *data, | |||
2658 | page = 0; | 2648 | page = 0; |
2659 | 2649 | ||
2660 | if (reg > MAX_PHY_MULTI_PAGE_REG) { | 2650 | if (reg > MAX_PHY_MULTI_PAGE_REG) { |
2661 | if ((hw->phy.type != e1000_phy_82578) || | 2651 | u32 phy_addr = hw->phy.addr; |
2662 | ((reg != I82578_ADDR_REG) && | ||
2663 | (reg != I82578_ADDR_REG + 1))) { | ||
2664 | u32 phy_addr = hw->phy.addr; | ||
2665 | 2652 | ||
2666 | hw->phy.addr = 1; | 2653 | hw->phy.addr = 1; |
2667 | 2654 | ||
2668 | /* Page is shifted left, PHY expects (page x 32) */ | 2655 | /* Page is shifted left, PHY expects (page x 32) */ |
2669 | ret_val = e1000e_write_phy_reg_mdic(hw, | 2656 | ret_val = e1000e_write_phy_reg_mdic(hw, |
2670 | IGP01E1000_PHY_PAGE_SELECT, | 2657 | IGP01E1000_PHY_PAGE_SELECT, |
2671 | (page << IGP_PAGE_SHIFT)); | 2658 | (page << IGP_PAGE_SHIFT)); |
2672 | hw->phy.addr = phy_addr; | 2659 | hw->phy.addr = phy_addr; |
2673 | } | 2660 | |
2661 | if (ret_val) | ||
2662 | goto out; | ||
2674 | } | 2663 | } |
2675 | 2664 | ||
2676 | ret_val = e1000e_read_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & reg, | 2665 | ret_val = e1000e_read_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & reg, |
@@ -2678,7 +2667,7 @@ static s32 __e1000_read_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 *data, | |||
2678 | out: | 2667 | out: |
2679 | /* Revert to MDIO fast mode, if applicable */ | 2668 | /* Revert to MDIO fast mode, if applicable */ |
2680 | if ((hw->phy.type == e1000_phy_82577) && in_slow_mode) | 2669 | if ((hw->phy.type == e1000_phy_82577) && in_slow_mode) |
2681 | ret_val = e1000_set_mdio_slow_mode_hv(hw, false); | 2670 | ret_val |= e1000_set_mdio_slow_mode_hv(hw, false); |
2682 | 2671 | ||
2683 | if (!locked) | 2672 | if (!locked) |
2684 | hw->phy.ops.release_phy(hw); | 2673 | hw->phy.ops.release_phy(hw); |
@@ -2784,19 +2773,18 @@ static s32 __e1000_write_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 data, | |||
2784 | } | 2773 | } |
2785 | 2774 | ||
2786 | if (reg > MAX_PHY_MULTI_PAGE_REG) { | 2775 | if (reg > MAX_PHY_MULTI_PAGE_REG) { |
2787 | if ((hw->phy.type != e1000_phy_82578) || | 2776 | u32 phy_addr = hw->phy.addr; |
2788 | ((reg != I82578_ADDR_REG) && | ||
2789 | (reg != I82578_ADDR_REG + 1))) { | ||
2790 | u32 phy_addr = hw->phy.addr; | ||
2791 | 2777 | ||
2792 | hw->phy.addr = 1; | 2778 | hw->phy.addr = 1; |
2793 | 2779 | ||
2794 | /* Page is shifted left, PHY expects (page x 32) */ | 2780 | /* Page is shifted left, PHY expects (page x 32) */ |
2795 | ret_val = e1000e_write_phy_reg_mdic(hw, | 2781 | ret_val = e1000e_write_phy_reg_mdic(hw, |
2796 | IGP01E1000_PHY_PAGE_SELECT, | 2782 | IGP01E1000_PHY_PAGE_SELECT, |
2797 | (page << IGP_PAGE_SHIFT)); | 2783 | (page << IGP_PAGE_SHIFT)); |
2798 | hw->phy.addr = phy_addr; | 2784 | hw->phy.addr = phy_addr; |
2799 | } | 2785 | |
2786 | if (ret_val) | ||
2787 | goto out; | ||
2800 | } | 2788 | } |
2801 | 2789 | ||
2802 | ret_val = e1000e_write_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & reg, | 2790 | ret_val = e1000e_write_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & reg, |
@@ -2805,7 +2793,7 @@ static s32 __e1000_write_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 data, | |||
2805 | out: | 2793 | out: |
2806 | /* Revert to MDIO fast mode, if applicable */ | 2794 | /* Revert to MDIO fast mode, if applicable */ |
2807 | if ((hw->phy.type == e1000_phy_82577) && in_slow_mode) | 2795 | if ((hw->phy.type == e1000_phy_82577) && in_slow_mode) |
2808 | ret_val = e1000_set_mdio_slow_mode_hv(hw, false); | 2796 | ret_val |= e1000_set_mdio_slow_mode_hv(hw, false); |
2809 | 2797 | ||
2810 | if (!locked) | 2798 | if (!locked) |
2811 | hw->phy.ops.release_phy(hw); | 2799 | hw->phy.ops.release_phy(hw); |
diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c index e1da4666f204..3116601dbfea 100644 --- a/drivers/net/forcedeth.c +++ b/drivers/net/forcedeth.c | |||
@@ -5821,10 +5821,7 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i | |||
5821 | dev->dev_addr); | 5821 | dev->dev_addr); |
5822 | dev_printk(KERN_ERR, &pci_dev->dev, | 5822 | dev_printk(KERN_ERR, &pci_dev->dev, |
5823 | "Please complain to your hardware vendor. Switching to a random MAC.\n"); | 5823 | "Please complain to your hardware vendor. Switching to a random MAC.\n"); |
5824 | dev->dev_addr[0] = 0x00; | 5824 | random_ether_addr(dev->dev_addr); |
5825 | dev->dev_addr[1] = 0x00; | ||
5826 | dev->dev_addr[2] = 0x6c; | ||
5827 | get_random_bytes(&dev->dev_addr[3], 3); | ||
5828 | } | 5825 | } |
5829 | 5826 | ||
5830 | dprintk(KERN_DEBUG "%s: MAC Address %pM\n", | 5827 | dprintk(KERN_DEBUG "%s: MAC Address %pM\n", |
diff --git a/drivers/net/ibm_newemac/emac.h b/drivers/net/ibm_newemac/emac.h index d34adf99fc6a..8a61b597a169 100644 --- a/drivers/net/ibm_newemac/emac.h +++ b/drivers/net/ibm_newemac/emac.h | |||
@@ -263,8 +263,8 @@ struct emac_regs { | |||
263 | 263 | ||
264 | 264 | ||
265 | /* EMACx_TRTR */ | 265 | /* EMACx_TRTR */ |
266 | #define EMAC_TRTR_SHIFT_EMAC4 27 | 266 | #define EMAC_TRTR_SHIFT_EMAC4 24 |
267 | #define EMAC_TRTR_SHIFT 24 | 267 | #define EMAC_TRTR_SHIFT 27 |
268 | 268 | ||
269 | /* EMAC specific TX descriptor control fields (write access) */ | 269 | /* EMAC specific TX descriptor control fields (write access) */ |
270 | #define EMAC_TX_CTRL_GFCS 0x0200 | 270 | #define EMAC_TX_CTRL_GFCS 0x0200 |
diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index 5bd9e6bf6f2f..a456578b8578 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c | |||
@@ -240,11 +240,11 @@ static void ixgbe_unmap_and_free_tx_resource(struct ixgbe_adapter *adapter, | |||
240 | static inline bool ixgbe_tx_is_paused(struct ixgbe_adapter *adapter, | 240 | static inline bool ixgbe_tx_is_paused(struct ixgbe_adapter *adapter, |
241 | struct ixgbe_ring *tx_ring) | 241 | struct ixgbe_ring *tx_ring) |
242 | { | 242 | { |
243 | int tc; | ||
244 | u32 txoff = IXGBE_TFCS_TXOFF; | 243 | u32 txoff = IXGBE_TFCS_TXOFF; |
245 | 244 | ||
246 | #ifdef CONFIG_IXGBE_DCB | 245 | #ifdef CONFIG_IXGBE_DCB |
247 | if (adapter->flags & IXGBE_FLAG_DCB_ENABLED) { | 246 | if (adapter->flags & IXGBE_FLAG_DCB_ENABLED) { |
247 | int tc; | ||
248 | int reg_idx = tx_ring->reg_idx; | 248 | int reg_idx = tx_ring->reg_idx; |
249 | int dcb_i = adapter->ring_feature[RING_F_DCB].indices; | 249 | int dcb_i = adapter->ring_feature[RING_F_DCB].indices; |
250 | 250 | ||
@@ -5994,6 +5994,7 @@ static pci_ers_result_t ixgbe_io_slot_reset(struct pci_dev *pdev) | |||
5994 | } else { | 5994 | } else { |
5995 | pci_set_master(pdev); | 5995 | pci_set_master(pdev); |
5996 | pci_restore_state(pdev); | 5996 | pci_restore_state(pdev); |
5997 | pci_save_state(pdev); | ||
5997 | 5998 | ||
5998 | pci_wake_from_d3(pdev, false); | 5999 | pci_wake_from_d3(pdev, false); |
5999 | 6000 | ||
diff --git a/drivers/net/ks8851_mll.c b/drivers/net/ks8851_mll.c index 0be14d702beb..c146304d8d6c 100644 --- a/drivers/net/ks8851_mll.c +++ b/drivers/net/ks8851_mll.c | |||
@@ -568,6 +568,16 @@ static inline void ks_outblk(struct ks_net *ks, u16 *wptr, u32 len) | |||
568 | iowrite16(*wptr++, ks->hw_addr); | 568 | iowrite16(*wptr++, ks->hw_addr); |
569 | } | 569 | } |
570 | 570 | ||
571 | static void ks_disable_int(struct ks_net *ks) | ||
572 | { | ||
573 | ks_wrreg16(ks, KS_IER, 0x0000); | ||
574 | } /* ks_disable_int */ | ||
575 | |||
576 | static void ks_enable_int(struct ks_net *ks) | ||
577 | { | ||
578 | ks_wrreg16(ks, KS_IER, ks->rc_ier); | ||
579 | } /* ks_enable_int */ | ||
580 | |||
571 | /** | 581 | /** |
572 | * ks_tx_fifo_space - return the available hardware buffer size. | 582 | * ks_tx_fifo_space - return the available hardware buffer size. |
573 | * @ks: The chip information | 583 | * @ks: The chip information |
@@ -681,6 +691,47 @@ static void ks_soft_reset(struct ks_net *ks, unsigned op) | |||
681 | } | 691 | } |
682 | 692 | ||
683 | 693 | ||
694 | void ks_enable_qmu(struct ks_net *ks) | ||
695 | { | ||
696 | u16 w; | ||
697 | |||
698 | w = ks_rdreg16(ks, KS_TXCR); | ||
699 | /* Enables QMU Transmit (TXCR). */ | ||
700 | ks_wrreg16(ks, KS_TXCR, w | TXCR_TXE); | ||
701 | |||
702 | /* | ||
703 | * RX Frame Count Threshold Enable and Auto-Dequeue RXQ Frame | ||
704 | * Enable | ||
705 | */ | ||
706 | |||
707 | w = ks_rdreg16(ks, KS_RXQCR); | ||
708 | ks_wrreg16(ks, KS_RXQCR, w | RXQCR_RXFCTE); | ||
709 | |||
710 | /* Enables QMU Receive (RXCR1). */ | ||
711 | w = ks_rdreg16(ks, KS_RXCR1); | ||
712 | ks_wrreg16(ks, KS_RXCR1, w | RXCR1_RXE); | ||
713 | ks->enabled = true; | ||
714 | } /* ks_enable_qmu */ | ||
715 | |||
716 | static void ks_disable_qmu(struct ks_net *ks) | ||
717 | { | ||
718 | u16 w; | ||
719 | |||
720 | w = ks_rdreg16(ks, KS_TXCR); | ||
721 | |||
722 | /* Disables QMU Transmit (TXCR). */ | ||
723 | w &= ~TXCR_TXE; | ||
724 | ks_wrreg16(ks, KS_TXCR, w); | ||
725 | |||
726 | /* Disables QMU Receive (RXCR1). */ | ||
727 | w = ks_rdreg16(ks, KS_RXCR1); | ||
728 | w &= ~RXCR1_RXE ; | ||
729 | ks_wrreg16(ks, KS_RXCR1, w); | ||
730 | |||
731 | ks->enabled = false; | ||
732 | |||
733 | } /* ks_disable_qmu */ | ||
734 | |||
684 | /** | 735 | /** |
685 | * ks_read_qmu - read 1 pkt data from the QMU. | 736 | * ks_read_qmu - read 1 pkt data from the QMU. |
686 | * @ks: The chip information | 737 | * @ks: The chip information |
@@ -752,7 +803,7 @@ static void ks_rcv(struct ks_net *ks, struct net_device *netdev) | |||
752 | (frame_hdr->len < RX_BUF_SIZE) && frame_hdr->len)) { | 803 | (frame_hdr->len < RX_BUF_SIZE) && frame_hdr->len)) { |
753 | skb_reserve(skb, 2); | 804 | skb_reserve(skb, 2); |
754 | /* read data block including CRC 4 bytes */ | 805 | /* read data block including CRC 4 bytes */ |
755 | ks_read_qmu(ks, (u16 *)skb->data, frame_hdr->len + 4); | 806 | ks_read_qmu(ks, (u16 *)skb->data, frame_hdr->len); |
756 | skb_put(skb, frame_hdr->len); | 807 | skb_put(skb, frame_hdr->len); |
757 | skb->dev = netdev; | 808 | skb->dev = netdev; |
758 | skb->protocol = eth_type_trans(skb, netdev); | 809 | skb->protocol = eth_type_trans(skb, netdev); |
@@ -861,7 +912,7 @@ static int ks_net_open(struct net_device *netdev) | |||
861 | ks_dbg(ks, "%s - entry\n", __func__); | 912 | ks_dbg(ks, "%s - entry\n", __func__); |
862 | 913 | ||
863 | /* reset the HW */ | 914 | /* reset the HW */ |
864 | err = request_irq(ks->irq, ks_irq, KS_INT_FLAGS, DRV_NAME, ks); | 915 | err = request_irq(ks->irq, ks_irq, KS_INT_FLAGS, DRV_NAME, netdev); |
865 | 916 | ||
866 | if (err) { | 917 | if (err) { |
867 | printk(KERN_ERR "Failed to request IRQ: %d: %d\n", | 918 | printk(KERN_ERR "Failed to request IRQ: %d: %d\n", |
@@ -869,6 +920,15 @@ static int ks_net_open(struct net_device *netdev) | |||
869 | return err; | 920 | return err; |
870 | } | 921 | } |
871 | 922 | ||
923 | /* wake up powermode to normal mode */ | ||
924 | ks_set_powermode(ks, PMECR_PM_NORMAL); | ||
925 | mdelay(1); /* wait for normal mode to take effect */ | ||
926 | |||
927 | ks_wrreg16(ks, KS_ISR, 0xffff); | ||
928 | ks_enable_int(ks); | ||
929 | ks_enable_qmu(ks); | ||
930 | netif_start_queue(ks->netdev); | ||
931 | |||
872 | if (netif_msg_ifup(ks)) | 932 | if (netif_msg_ifup(ks)) |
873 | ks_dbg(ks, "network device %s up\n", netdev->name); | 933 | ks_dbg(ks, "network device %s up\n", netdev->name); |
874 | 934 | ||
@@ -892,19 +952,14 @@ static int ks_net_stop(struct net_device *netdev) | |||
892 | 952 | ||
893 | netif_stop_queue(netdev); | 953 | netif_stop_queue(netdev); |
894 | 954 | ||
895 | kfree(ks->frame_head_info); | ||
896 | |||
897 | mutex_lock(&ks->lock); | 955 | mutex_lock(&ks->lock); |
898 | 956 | ||
899 | /* turn off the IRQs and ack any outstanding */ | 957 | /* turn off the IRQs and ack any outstanding */ |
900 | ks_wrreg16(ks, KS_IER, 0x0000); | 958 | ks_wrreg16(ks, KS_IER, 0x0000); |
901 | ks_wrreg16(ks, KS_ISR, 0xffff); | 959 | ks_wrreg16(ks, KS_ISR, 0xffff); |
902 | 960 | ||
903 | /* shutdown RX process */ | 961 | /* shutdown RX/TX QMU */ |
904 | ks_wrreg16(ks, KS_RXCR1, 0x0000); | 962 | ks_disable_qmu(ks); |
905 | |||
906 | /* shutdown TX process */ | ||
907 | ks_wrreg16(ks, KS_TXCR, 0x0000); | ||
908 | 963 | ||
909 | /* set powermode to soft power down to save power */ | 964 | /* set powermode to soft power down to save power */ |
910 | ks_set_powermode(ks, PMECR_PM_SOFTDOWN); | 965 | ks_set_powermode(ks, PMECR_PM_SOFTDOWN); |
@@ -929,17 +984,8 @@ static int ks_net_stop(struct net_device *netdev) | |||
929 | */ | 984 | */ |
930 | static void ks_write_qmu(struct ks_net *ks, u8 *pdata, u16 len) | 985 | static void ks_write_qmu(struct ks_net *ks, u8 *pdata, u16 len) |
931 | { | 986 | { |
932 | unsigned fid = ks->fid; | ||
933 | |||
934 | fid = ks->fid; | ||
935 | ks->fid = (ks->fid + 1) & TXFR_TXFID_MASK; | ||
936 | |||
937 | /* reduce the tx interrupt occurrances. */ | ||
938 | if (!fid) | ||
939 | fid |= TXFR_TXIC; /* irq on completion */ | ||
940 | |||
941 | /* start header at txb[0] to align txw entries */ | 987 | /* start header at txb[0] to align txw entries */ |
942 | ks->txh.txw[0] = cpu_to_le16(fid); | 988 | ks->txh.txw[0] = 0; |
943 | ks->txh.txw[1] = cpu_to_le16(len); | 989 | ks->txh.txw[1] = cpu_to_le16(len); |
944 | 990 | ||
945 | /* 1. set sudo-DMA mode */ | 991 | /* 1. set sudo-DMA mode */ |
@@ -957,16 +1003,6 @@ static void ks_write_qmu(struct ks_net *ks, u8 *pdata, u16 len) | |||
957 | ; | 1003 | ; |
958 | } | 1004 | } |
959 | 1005 | ||
960 | static void ks_disable_int(struct ks_net *ks) | ||
961 | { | ||
962 | ks_wrreg16(ks, KS_IER, 0x0000); | ||
963 | } /* ks_disable_int */ | ||
964 | |||
965 | static void ks_enable_int(struct ks_net *ks) | ||
966 | { | ||
967 | ks_wrreg16(ks, KS_IER, ks->rc_ier); | ||
968 | } /* ks_enable_int */ | ||
969 | |||
970 | /** | 1006 | /** |
971 | * ks_start_xmit - transmit packet | 1007 | * ks_start_xmit - transmit packet |
972 | * @skb : The buffer to transmit | 1008 | * @skb : The buffer to transmit |
@@ -1410,25 +1446,6 @@ static int ks_read_selftest(struct ks_net *ks) | |||
1410 | return ret; | 1446 | return ret; |
1411 | } | 1447 | } |
1412 | 1448 | ||
1413 | static void ks_disable(struct ks_net *ks) | ||
1414 | { | ||
1415 | u16 w; | ||
1416 | |||
1417 | w = ks_rdreg16(ks, KS_TXCR); | ||
1418 | |||
1419 | /* Disables QMU Transmit (TXCR). */ | ||
1420 | w &= ~TXCR_TXE; | ||
1421 | ks_wrreg16(ks, KS_TXCR, w); | ||
1422 | |||
1423 | /* Disables QMU Receive (RXCR1). */ | ||
1424 | w = ks_rdreg16(ks, KS_RXCR1); | ||
1425 | w &= ~RXCR1_RXE ; | ||
1426 | ks_wrreg16(ks, KS_RXCR1, w); | ||
1427 | |||
1428 | ks->enabled = false; | ||
1429 | |||
1430 | } /* ks_disable */ | ||
1431 | |||
1432 | static void ks_setup(struct ks_net *ks) | 1449 | static void ks_setup(struct ks_net *ks) |
1433 | { | 1450 | { |
1434 | u16 w; | 1451 | u16 w; |
@@ -1463,7 +1480,7 @@ static void ks_setup(struct ks_net *ks) | |||
1463 | w = TXCR_TXFCE | TXCR_TXPE | TXCR_TXCRC | TXCR_TCGIP; | 1480 | w = TXCR_TXFCE | TXCR_TXPE | TXCR_TXCRC | TXCR_TCGIP; |
1464 | ks_wrreg16(ks, KS_TXCR, w); | 1481 | ks_wrreg16(ks, KS_TXCR, w); |
1465 | 1482 | ||
1466 | w = RXCR1_RXFCE | RXCR1_RXBE | RXCR1_RXUE; | 1483 | w = RXCR1_RXFCE | RXCR1_RXBE | RXCR1_RXUE | RXCR1_RXME | RXCR1_RXIPFCC; |
1467 | 1484 | ||
1468 | if (ks->promiscuous) /* bPromiscuous */ | 1485 | if (ks->promiscuous) /* bPromiscuous */ |
1469 | w |= (RXCR1_RXAE | RXCR1_RXINVF); | 1486 | w |= (RXCR1_RXAE | RXCR1_RXINVF); |
@@ -1486,28 +1503,6 @@ static void ks_setup_int(struct ks_net *ks) | |||
1486 | ks->rc_ier = (IRQ_LCI | IRQ_TXI | IRQ_RXI); | 1503 | ks->rc_ier = (IRQ_LCI | IRQ_TXI | IRQ_RXI); |
1487 | } /* ks_setup_int */ | 1504 | } /* ks_setup_int */ |
1488 | 1505 | ||
1489 | void ks_enable(struct ks_net *ks) | ||
1490 | { | ||
1491 | u16 w; | ||
1492 | |||
1493 | w = ks_rdreg16(ks, KS_TXCR); | ||
1494 | /* Enables QMU Transmit (TXCR). */ | ||
1495 | ks_wrreg16(ks, KS_TXCR, w | TXCR_TXE); | ||
1496 | |||
1497 | /* | ||
1498 | * RX Frame Count Threshold Enable and Auto-Dequeue RXQ Frame | ||
1499 | * Enable | ||
1500 | */ | ||
1501 | |||
1502 | w = ks_rdreg16(ks, KS_RXQCR); | ||
1503 | ks_wrreg16(ks, KS_RXQCR, w | RXQCR_RXFCTE); | ||
1504 | |||
1505 | /* Enables QMU Receive (RXCR1). */ | ||
1506 | w = ks_rdreg16(ks, KS_RXCR1); | ||
1507 | ks_wrreg16(ks, KS_RXCR1, w | RXCR1_RXE); | ||
1508 | ks->enabled = true; | ||
1509 | } /* ks_enable */ | ||
1510 | |||
1511 | static int ks_hw_init(struct ks_net *ks) | 1506 | static int ks_hw_init(struct ks_net *ks) |
1512 | { | 1507 | { |
1513 | #define MHEADER_SIZE (sizeof(struct type_frame_head) * MAX_RECV_FRAMES) | 1508 | #define MHEADER_SIZE (sizeof(struct type_frame_head) * MAX_RECV_FRAMES) |
@@ -1612,11 +1607,9 @@ static int __devinit ks8851_probe(struct platform_device *pdev) | |||
1612 | 1607 | ||
1613 | ks_soft_reset(ks, GRR_GSR); | 1608 | ks_soft_reset(ks, GRR_GSR); |
1614 | ks_hw_init(ks); | 1609 | ks_hw_init(ks); |
1615 | ks_disable(ks); | 1610 | ks_disable_qmu(ks); |
1616 | ks_setup(ks); | 1611 | ks_setup(ks); |
1617 | ks_setup_int(ks); | 1612 | ks_setup_int(ks); |
1618 | ks_enable_int(ks); | ||
1619 | ks_enable(ks); | ||
1620 | memcpy(netdev->dev_addr, ks->mac_addr, 6); | 1613 | memcpy(netdev->dev_addr, ks->mac_addr, 6); |
1621 | 1614 | ||
1622 | data = ks_rdreg16(ks, KS_OBCR); | 1615 | data = ks_rdreg16(ks, KS_OBCR); |
@@ -1658,6 +1651,7 @@ static int __devexit ks8851_remove(struct platform_device *pdev) | |||
1658 | struct ks_net *ks = netdev_priv(netdev); | 1651 | struct ks_net *ks = netdev_priv(netdev); |
1659 | struct resource *iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 1652 | struct resource *iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
1660 | 1653 | ||
1654 | kfree(ks->frame_head_info); | ||
1661 | unregister_netdev(netdev); | 1655 | unregister_netdev(netdev); |
1662 | iounmap(ks->hw_addr); | 1656 | iounmap(ks->hw_addr); |
1663 | free_netdev(netdev); | 1657 | free_netdev(netdev); |
diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c index 3aabfd9dd212..2490aa39804c 100644 --- a/drivers/net/macvlan.c +++ b/drivers/net/macvlan.c | |||
@@ -360,6 +360,7 @@ static int macvlan_init(struct net_device *dev) | |||
360 | dev->state = (dev->state & ~MACVLAN_STATE_MASK) | | 360 | dev->state = (dev->state & ~MACVLAN_STATE_MASK) | |
361 | (lowerdev->state & MACVLAN_STATE_MASK); | 361 | (lowerdev->state & MACVLAN_STATE_MASK); |
362 | dev->features = lowerdev->features & MACVLAN_FEATURES; | 362 | dev->features = lowerdev->features & MACVLAN_FEATURES; |
363 | dev->gso_max_size = lowerdev->gso_max_size; | ||
363 | dev->iflink = lowerdev->ifindex; | 364 | dev->iflink = lowerdev->ifindex; |
364 | dev->hard_header_len = lowerdev->hard_header_len; | 365 | dev->hard_header_len = lowerdev->hard_header_len; |
365 | 366 | ||
@@ -596,6 +597,7 @@ static int macvlan_device_event(struct notifier_block *unused, | |||
596 | case NETDEV_FEAT_CHANGE: | 597 | case NETDEV_FEAT_CHANGE: |
597 | list_for_each_entry(vlan, &port->vlans, list) { | 598 | list_for_each_entry(vlan, &port->vlans, list) { |
598 | vlan->dev->features = dev->features & MACVLAN_FEATURES; | 599 | vlan->dev->features = dev->features & MACVLAN_FEATURES; |
600 | vlan->dev->gso_max_size = dev->gso_max_size; | ||
599 | netdev_features_change(vlan->dev); | 601 | netdev_features_change(vlan->dev); |
600 | } | 602 | } |
601 | break; | 603 | break; |
diff --git a/drivers/net/netxen/netxen_nic.h b/drivers/net/netxen/netxen_nic.h index 7384f59df615..e1237b802872 100644 --- a/drivers/net/netxen/netxen_nic.h +++ b/drivers/net/netxen/netxen_nic.h | |||
@@ -1163,6 +1163,8 @@ struct netxen_adapter { | |||
1163 | u32 int_vec_bit; | 1163 | u32 int_vec_bit; |
1164 | u32 heartbit; | 1164 | u32 heartbit; |
1165 | 1165 | ||
1166 | u8 mac_addr[ETH_ALEN]; | ||
1167 | |||
1166 | struct netxen_adapter_stats stats; | 1168 | struct netxen_adapter_stats stats; |
1167 | 1169 | ||
1168 | struct netxen_recv_context recv_ctx; | 1170 | struct netxen_recv_context recv_ctx; |
diff --git a/drivers/net/netxen/netxen_nic_hdr.h b/drivers/net/netxen/netxen_nic_hdr.h index 1c46da632125..17bb3818d84e 100644 --- a/drivers/net/netxen/netxen_nic_hdr.h +++ b/drivers/net/netxen/netxen_nic_hdr.h | |||
@@ -545,6 +545,8 @@ enum { | |||
545 | #define NETXEN_NIU_TEST_MUX_CTL (NETXEN_CRB_NIU + 0x00094) | 545 | #define NETXEN_NIU_TEST_MUX_CTL (NETXEN_CRB_NIU + 0x00094) |
546 | #define NETXEN_NIU_XG_PAUSE_CTL (NETXEN_CRB_NIU + 0x00098) | 546 | #define NETXEN_NIU_XG_PAUSE_CTL (NETXEN_CRB_NIU + 0x00098) |
547 | #define NETXEN_NIU_XG_PAUSE_LEVEL (NETXEN_CRB_NIU + 0x000dc) | 547 | #define NETXEN_NIU_XG_PAUSE_LEVEL (NETXEN_CRB_NIU + 0x000dc) |
548 | #define NETXEN_NIU_FRAME_COUNT_SELECT (NETXEN_CRB_NIU + 0x000ac) | ||
549 | #define NETXEN_NIU_FRAME_COUNT (NETXEN_CRB_NIU + 0x000b0) | ||
548 | #define NETXEN_NIU_XG_SEL (NETXEN_CRB_NIU + 0x00128) | 550 | #define NETXEN_NIU_XG_SEL (NETXEN_CRB_NIU + 0x00128) |
549 | #define NETXEN_NIU_GB_PAUSE_CTL (NETXEN_CRB_NIU + 0x0030c) | 551 | #define NETXEN_NIU_GB_PAUSE_CTL (NETXEN_CRB_NIU + 0x0030c) |
550 | 552 | ||
diff --git a/drivers/net/netxen/netxen_nic_hw.c b/drivers/net/netxen/netxen_nic_hw.c index 3185a98b0917..52a3798d8d94 100644 --- a/drivers/net/netxen/netxen_nic_hw.c +++ b/drivers/net/netxen/netxen_nic_hw.c | |||
@@ -383,24 +383,51 @@ int netxen_niu_disable_xg_port(struct netxen_adapter *adapter) | |||
383 | 383 | ||
384 | int netxen_p2_nic_set_promisc(struct netxen_adapter *adapter, u32 mode) | 384 | int netxen_p2_nic_set_promisc(struct netxen_adapter *adapter, u32 mode) |
385 | { | 385 | { |
386 | __u32 reg; | 386 | u32 mac_cfg; |
387 | u32 cnt = 0; | ||
388 | __u32 reg = 0x0200; | ||
387 | u32 port = adapter->physical_port; | 389 | u32 port = adapter->physical_port; |
390 | u16 board_type = adapter->ahw.board_type; | ||
388 | 391 | ||
389 | if (port > NETXEN_NIU_MAX_XG_PORTS) | 392 | if (port > NETXEN_NIU_MAX_XG_PORTS) |
390 | return -EINVAL; | 393 | return -EINVAL; |
391 | 394 | ||
392 | reg = NXRD32(adapter, NETXEN_NIU_XGE_CONFIG_1 + (0x10000 * port)); | 395 | mac_cfg = NXRD32(adapter, NETXEN_NIU_XGE_CONFIG_0 + (0x10000 * port)); |
393 | if (mode == NETXEN_NIU_PROMISC_MODE) | 396 | mac_cfg &= ~0x4; |
394 | reg = (reg | 0x2000UL); | 397 | NXWR32(adapter, NETXEN_NIU_XGE_CONFIG_0 + (0x10000 * port), mac_cfg); |
395 | else | ||
396 | reg = (reg & ~0x2000UL); | ||
397 | 398 | ||
398 | if (mode == NETXEN_NIU_ALLMULTI_MODE) | 399 | if ((board_type == NETXEN_BRDTYPE_P2_SB31_10G_IMEZ) || |
399 | reg = (reg | 0x1000UL); | 400 | (board_type == NETXEN_BRDTYPE_P2_SB31_10G_HMEZ)) |
400 | else | 401 | reg = (0x20 << port); |
401 | reg = (reg & ~0x1000UL); | 402 | |
403 | NXWR32(adapter, NETXEN_NIU_FRAME_COUNT_SELECT, reg); | ||
404 | |||
405 | mdelay(10); | ||
406 | |||
407 | while (NXRD32(adapter, NETXEN_NIU_FRAME_COUNT) && ++cnt < 20) | ||
408 | mdelay(10); | ||
409 | |||
410 | if (cnt < 20) { | ||
411 | |||
412 | reg = NXRD32(adapter, | ||
413 | NETXEN_NIU_XGE_CONFIG_1 + (0x10000 * port)); | ||
414 | |||
415 | if (mode == NETXEN_NIU_PROMISC_MODE) | ||
416 | reg = (reg | 0x2000UL); | ||
417 | else | ||
418 | reg = (reg & ~0x2000UL); | ||
419 | |||
420 | if (mode == NETXEN_NIU_ALLMULTI_MODE) | ||
421 | reg = (reg | 0x1000UL); | ||
422 | else | ||
423 | reg = (reg & ~0x1000UL); | ||
424 | |||
425 | NXWR32(adapter, | ||
426 | NETXEN_NIU_XGE_CONFIG_1 + (0x10000 * port), reg); | ||
427 | } | ||
402 | 428 | ||
403 | NXWR32(adapter, NETXEN_NIU_XGE_CONFIG_1 + (0x10000 * port), reg); | 429 | mac_cfg |= 0x4; |
430 | NXWR32(adapter, NETXEN_NIU_XGE_CONFIG_0 + (0x10000 * port), mac_cfg); | ||
404 | 431 | ||
405 | return 0; | 432 | return 0; |
406 | } | 433 | } |
@@ -436,7 +463,7 @@ netxen_nic_enable_mcast_filter(struct netxen_adapter *adapter) | |||
436 | { | 463 | { |
437 | u32 val = 0; | 464 | u32 val = 0; |
438 | u16 port = adapter->physical_port; | 465 | u16 port = adapter->physical_port; |
439 | u8 *addr = adapter->netdev->dev_addr; | 466 | u8 *addr = adapter->mac_addr; |
440 | 467 | ||
441 | if (adapter->mc_enabled) | 468 | if (adapter->mc_enabled) |
442 | return 0; | 469 | return 0; |
@@ -465,7 +492,7 @@ netxen_nic_disable_mcast_filter(struct netxen_adapter *adapter) | |||
465 | { | 492 | { |
466 | u32 val = 0; | 493 | u32 val = 0; |
467 | u16 port = adapter->physical_port; | 494 | u16 port = adapter->physical_port; |
468 | u8 *addr = adapter->netdev->dev_addr; | 495 | u8 *addr = adapter->mac_addr; |
469 | 496 | ||
470 | if (!adapter->mc_enabled) | 497 | if (!adapter->mc_enabled) |
471 | return 0; | 498 | return 0; |
@@ -660,7 +687,7 @@ void netxen_p3_nic_set_multi(struct net_device *netdev) | |||
660 | 687 | ||
661 | list_splice_tail_init(&adapter->mac_list, &del_list); | 688 | list_splice_tail_init(&adapter->mac_list, &del_list); |
662 | 689 | ||
663 | nx_p3_nic_add_mac(adapter, netdev->dev_addr, &del_list); | 690 | nx_p3_nic_add_mac(adapter, adapter->mac_addr, &del_list); |
664 | nx_p3_nic_add_mac(adapter, bcast_addr, &del_list); | 691 | nx_p3_nic_add_mac(adapter, bcast_addr, &del_list); |
665 | 692 | ||
666 | if (netdev->flags & IFF_PROMISC) { | 693 | if (netdev->flags & IFF_PROMISC) { |
diff --git a/drivers/net/netxen/netxen_nic_init.c b/drivers/net/netxen/netxen_nic_init.c index e40b914d6faf..8a0904368e08 100644 --- a/drivers/net/netxen/netxen_nic_init.c +++ b/drivers/net/netxen/netxen_nic_init.c | |||
@@ -544,6 +544,8 @@ int netxen_pinit_from_rom(struct netxen_adapter *adapter, int verbose) | |||
544 | continue; | 544 | continue; |
545 | if (off == (ROMUSB_GLB + 0x1c)) /* MS clock */ | 545 | if (off == (ROMUSB_GLB + 0x1c)) /* MS clock */ |
546 | continue; | 546 | continue; |
547 | if ((off & 0x0ff00000) == NETXEN_CRB_DDR_NET) | ||
548 | continue; | ||
547 | if (off == (NETXEN_CRB_PEG_NET_1 + 0x18)) | 549 | if (off == (NETXEN_CRB_PEG_NET_1 + 0x18)) |
548 | buf[i].data = 0x1020; | 550 | buf[i].data = 0x1020; |
549 | /* skip the function enable register */ | 551 | /* skip the function enable register */ |
diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c index 0b4a56a8c8d5..3bf78dbfbf0f 100644 --- a/drivers/net/netxen/netxen_nic_main.c +++ b/drivers/net/netxen/netxen_nic_main.c | |||
@@ -437,6 +437,7 @@ netxen_read_mac_addr(struct netxen_adapter *adapter) | |||
437 | netdev->dev_addr[i] = *(p + 5 - i); | 437 | netdev->dev_addr[i] = *(p + 5 - i); |
438 | 438 | ||
439 | memcpy(netdev->perm_addr, netdev->dev_addr, netdev->addr_len); | 439 | memcpy(netdev->perm_addr, netdev->dev_addr, netdev->addr_len); |
440 | memcpy(adapter->mac_addr, netdev->dev_addr, netdev->addr_len); | ||
440 | 441 | ||
441 | /* set station address */ | 442 | /* set station address */ |
442 | 443 | ||
@@ -459,6 +460,7 @@ int netxen_nic_set_mac(struct net_device *netdev, void *p) | |||
459 | netxen_napi_disable(adapter); | 460 | netxen_napi_disable(adapter); |
460 | } | 461 | } |
461 | 462 | ||
463 | memcpy(adapter->mac_addr, addr->sa_data, netdev->addr_len); | ||
462 | memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len); | 464 | memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len); |
463 | adapter->macaddr_set(adapter, addr->sa_data); | 465 | adapter->macaddr_set(adapter, addr->sa_data); |
464 | 466 | ||
@@ -956,7 +958,7 @@ netxen_nic_up(struct netxen_adapter *adapter, struct net_device *netdev) | |||
956 | return err; | 958 | return err; |
957 | } | 959 | } |
958 | if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) | 960 | if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) |
959 | adapter->macaddr_set(adapter, netdev->dev_addr); | 961 | adapter->macaddr_set(adapter, adapter->mac_addr); |
960 | 962 | ||
961 | adapter->set_multi(netdev); | 963 | adapter->set_multi(netdev); |
962 | adapter->set_mtu(adapter, netdev->mtu); | 964 | adapter->set_mtu(adapter, netdev->mtu); |
diff --git a/drivers/net/phy/mdio-gpio.c b/drivers/net/phy/mdio-gpio.c index 8659d341e769..35897134a5dd 100644 --- a/drivers/net/phy/mdio-gpio.c +++ b/drivers/net/phy/mdio-gpio.c | |||
@@ -139,7 +139,7 @@ out: | |||
139 | return NULL; | 139 | return NULL; |
140 | } | 140 | } |
141 | 141 | ||
142 | static void __devinit mdio_gpio_bus_deinit(struct device *dev) | 142 | static void mdio_gpio_bus_deinit(struct device *dev) |
143 | { | 143 | { |
144 | struct mii_bus *bus = dev_get_drvdata(dev); | 144 | struct mii_bus *bus = dev_get_drvdata(dev); |
145 | struct mdio_gpio_info *bitbang = bus->priv; | 145 | struct mdio_gpio_info *bitbang = bus->priv; |
diff --git a/drivers/net/ppp_generic.c b/drivers/net/ppp_generic.c index 9bf2a6be9031..965adb6174c3 100644 --- a/drivers/net/ppp_generic.c +++ b/drivers/net/ppp_generic.c | |||
@@ -1944,8 +1944,15 @@ ppp_receive_mp_frame(struct ppp *ppp, struct sk_buff *skb, struct channel *pch) | |||
1944 | } | 1944 | } |
1945 | 1945 | ||
1946 | /* Pull completed packets off the queue and receive them. */ | 1946 | /* Pull completed packets off the queue and receive them. */ |
1947 | while ((skb = ppp_mp_reconstruct(ppp))) | 1947 | while ((skb = ppp_mp_reconstruct(ppp))) { |
1948 | ppp_receive_nonmp_frame(ppp, skb); | 1948 | if (pskb_may_pull(skb, 2)) |
1949 | ppp_receive_nonmp_frame(ppp, skb); | ||
1950 | else { | ||
1951 | ++ppp->dev->stats.rx_length_errors; | ||
1952 | kfree_skb(skb); | ||
1953 | ppp_receive_error(ppp); | ||
1954 | } | ||
1955 | } | ||
1949 | 1956 | ||
1950 | return; | 1957 | return; |
1951 | 1958 | ||
diff --git a/drivers/net/r6040.c b/drivers/net/r6040.c index 7dfcb58b0eb4..8b14c6eda7c3 100644 --- a/drivers/net/r6040.c +++ b/drivers/net/r6040.c | |||
@@ -1085,7 +1085,7 @@ static int __devinit r6040_init_one(struct pci_dev *pdev, | |||
1085 | int bar = 0; | 1085 | int bar = 0; |
1086 | u16 *adrp; | 1086 | u16 *adrp; |
1087 | 1087 | ||
1088 | printk(KERN_INFO "%s\n", version); | 1088 | printk("%s\n", version); |
1089 | 1089 | ||
1090 | err = pci_enable_device(pdev); | 1090 | err = pci_enable_device(pdev); |
1091 | if (err) | 1091 | if (err) |
diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c index fa4935678488..0fe2fc90f207 100644 --- a/drivers/net/r8169.c +++ b/drivers/net/r8169.c | |||
@@ -3235,6 +3235,10 @@ static void __devexit rtl8169_remove_one(struct pci_dev *pdev) | |||
3235 | flush_scheduled_work(); | 3235 | flush_scheduled_work(); |
3236 | 3236 | ||
3237 | unregister_netdev(dev); | 3237 | unregister_netdev(dev); |
3238 | |||
3239 | /* restore original MAC address */ | ||
3240 | rtl_rar_set(tp, dev->perm_addr); | ||
3241 | |||
3238 | rtl_disable_msi(pdev, tp); | 3242 | rtl_disable_msi(pdev, tp); |
3239 | rtl8169_release_board(pdev, dev, tp->mmio_addr); | 3243 | rtl8169_release_board(pdev, dev, tp->mmio_addr); |
3240 | pci_set_drvdata(pdev, NULL); | 3244 | pci_set_drvdata(pdev, NULL); |
@@ -3243,9 +3247,9 @@ static void __devexit rtl8169_remove_one(struct pci_dev *pdev) | |||
3243 | static void rtl8169_set_rxbufsize(struct rtl8169_private *tp, | 3247 | static void rtl8169_set_rxbufsize(struct rtl8169_private *tp, |
3244 | struct net_device *dev) | 3248 | struct net_device *dev) |
3245 | { | 3249 | { |
3246 | unsigned int mtu = dev->mtu; | 3250 | unsigned int max_frame = dev->mtu + VLAN_ETH_HLEN + ETH_FCS_LEN; |
3247 | 3251 | ||
3248 | tp->rx_buf_sz = (mtu > RX_BUF_SIZE) ? mtu + ETH_HLEN + 8 : RX_BUF_SIZE; | 3252 | tp->rx_buf_sz = (max_frame > RX_BUF_SIZE) ? max_frame : RX_BUF_SIZE; |
3249 | } | 3253 | } |
3250 | 3254 | ||
3251 | static int rtl8169_open(struct net_device *dev) | 3255 | static int rtl8169_open(struct net_device *dev) |
@@ -4881,6 +4885,9 @@ static void rtl_shutdown(struct pci_dev *pdev) | |||
4881 | 4885 | ||
4882 | rtl8169_net_suspend(dev); | 4886 | rtl8169_net_suspend(dev); |
4883 | 4887 | ||
4888 | /* restore original MAC address */ | ||
4889 | rtl_rar_set(tp, dev->perm_addr); | ||
4890 | |||
4884 | spin_lock_irq(&tp->lock); | 4891 | spin_lock_irq(&tp->lock); |
4885 | 4892 | ||
4886 | rtl8169_asic_down(ioaddr); | 4893 | rtl8169_asic_down(ioaddr); |
diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c index ddccf5fa56b6..0dd7839322bc 100644 --- a/drivers/net/s2io.c +++ b/drivers/net/s2io.c | |||
@@ -3494,6 +3494,7 @@ static void s2io_reset(struct s2io_nic *sp) | |||
3494 | 3494 | ||
3495 | /* Restore the PCI state saved during initialization. */ | 3495 | /* Restore the PCI state saved during initialization. */ |
3496 | pci_restore_state(sp->pdev); | 3496 | pci_restore_state(sp->pdev); |
3497 | pci_save_state(sp->pdev); | ||
3497 | pci_read_config_word(sp->pdev, 0x2, &val16); | 3498 | pci_read_config_word(sp->pdev, 0x2, &val16); |
3498 | if (check_pci_device_id(val16) != (u16)PCI_ANY_ID) | 3499 | if (check_pci_device_id(val16) != (u16)PCI_ANY_ID) |
3499 | break; | 3500 | break; |
diff --git a/drivers/net/smc91x.c b/drivers/net/smc91x.c index 05c91ee6921e..f12206bdbb75 100644 --- a/drivers/net/smc91x.c +++ b/drivers/net/smc91x.c | |||
@@ -2283,7 +2283,7 @@ static int __devinit smc_drv_probe(struct platform_device *pdev) | |||
2283 | 2283 | ||
2284 | ndev->irq = ires->start; | 2284 | ndev->irq = ires->start; |
2285 | 2285 | ||
2286 | if (ires->flags & IRQF_TRIGGER_MASK) | 2286 | if (irq_flags == -1 || ires->flags & IRQF_TRIGGER_MASK) |
2287 | irq_flags = ires->flags & IRQF_TRIGGER_MASK; | 2287 | irq_flags = ires->flags & IRQF_TRIGGER_MASK; |
2288 | 2288 | ||
2289 | ret = smc_request_attrib(pdev, ndev); | 2289 | ret = smc_request_attrib(pdev, ndev); |
diff --git a/drivers/net/smsc911x.c b/drivers/net/smsc911x.c index ccdd196f5297..f9cdcbcb77d4 100644 --- a/drivers/net/smsc911x.c +++ b/drivers/net/smsc911x.c | |||
@@ -986,7 +986,7 @@ static int smsc911x_poll(struct napi_struct *napi, int budget) | |||
986 | struct net_device *dev = pdata->dev; | 986 | struct net_device *dev = pdata->dev; |
987 | int npackets = 0; | 987 | int npackets = 0; |
988 | 988 | ||
989 | while (likely(netif_running(dev)) && (npackets < budget)) { | 989 | while (npackets < budget) { |
990 | unsigned int pktlength; | 990 | unsigned int pktlength; |
991 | unsigned int pktwords; | 991 | unsigned int pktwords; |
992 | struct sk_buff *skb; | 992 | struct sk_buff *skb; |
diff --git a/drivers/net/smsc9420.c b/drivers/net/smsc9420.c index b4909a2dec66..0f7909276237 100644 --- a/drivers/net/smsc9420.c +++ b/drivers/net/smsc9420.c | |||
@@ -252,6 +252,9 @@ static int smsc9420_ethtool_get_settings(struct net_device *dev, | |||
252 | { | 252 | { |
253 | struct smsc9420_pdata *pd = netdev_priv(dev); | 253 | struct smsc9420_pdata *pd = netdev_priv(dev); |
254 | 254 | ||
255 | if (!pd->phy_dev) | ||
256 | return -ENODEV; | ||
257 | |||
255 | cmd->maxtxpkt = 1; | 258 | cmd->maxtxpkt = 1; |
256 | cmd->maxrxpkt = 1; | 259 | cmd->maxrxpkt = 1; |
257 | return phy_ethtool_gset(pd->phy_dev, cmd); | 260 | return phy_ethtool_gset(pd->phy_dev, cmd); |
@@ -262,6 +265,9 @@ static int smsc9420_ethtool_set_settings(struct net_device *dev, | |||
262 | { | 265 | { |
263 | struct smsc9420_pdata *pd = netdev_priv(dev); | 266 | struct smsc9420_pdata *pd = netdev_priv(dev); |
264 | 267 | ||
268 | if (!pd->phy_dev) | ||
269 | return -ENODEV; | ||
270 | |||
265 | return phy_ethtool_sset(pd->phy_dev, cmd); | 271 | return phy_ethtool_sset(pd->phy_dev, cmd); |
266 | } | 272 | } |
267 | 273 | ||
@@ -290,6 +296,10 @@ static void smsc9420_ethtool_set_msglevel(struct net_device *netdev, u32 data) | |||
290 | static int smsc9420_ethtool_nway_reset(struct net_device *netdev) | 296 | static int smsc9420_ethtool_nway_reset(struct net_device *netdev) |
291 | { | 297 | { |
292 | struct smsc9420_pdata *pd = netdev_priv(netdev); | 298 | struct smsc9420_pdata *pd = netdev_priv(netdev); |
299 | |||
300 | if (!pd->phy_dev) | ||
301 | return -ENODEV; | ||
302 | |||
293 | return phy_start_aneg(pd->phy_dev); | 303 | return phy_start_aneg(pd->phy_dev); |
294 | } | 304 | } |
295 | 305 | ||
@@ -312,6 +322,10 @@ smsc9420_ethtool_getregs(struct net_device *dev, struct ethtool_regs *regs, | |||
312 | for (i = 0; i < 0x100; i += (sizeof(u32))) | 322 | for (i = 0; i < 0x100; i += (sizeof(u32))) |
313 | data[j++] = smsc9420_reg_read(pd, i); | 323 | data[j++] = smsc9420_reg_read(pd, i); |
314 | 324 | ||
325 | // cannot read phy registers if the net device is down | ||
326 | if (!phy_dev) | ||
327 | return; | ||
328 | |||
315 | for (i = 0; i <= 31; i++) | 329 | for (i = 0; i <= 31; i++) |
316 | data[j++] = smsc9420_mii_read(phy_dev->bus, phy_dev->addr, i); | 330 | data[j++] = smsc9420_mii_read(phy_dev->bus, phy_dev->addr, i); |
317 | } | 331 | } |
diff --git a/drivers/net/stmmac/stmmac_main.c b/drivers/net/stmmac/stmmac_main.c index c2f14dc9ba28..9542995ba667 100644 --- a/drivers/net/stmmac/stmmac_main.c +++ b/drivers/net/stmmac/stmmac_main.c | |||
@@ -416,13 +416,8 @@ static void init_dma_desc_rings(struct net_device *dev) | |||
416 | unsigned int txsize = priv->dma_tx_size; | 416 | unsigned int txsize = priv->dma_tx_size; |
417 | unsigned int rxsize = priv->dma_rx_size; | 417 | unsigned int rxsize = priv->dma_rx_size; |
418 | unsigned int bfsize = priv->dma_buf_sz; | 418 | unsigned int bfsize = priv->dma_buf_sz; |
419 | int buff2_needed = 0; | 419 | int buff2_needed = 0, dis_ic = 0; |
420 | int dis_ic = 0; | ||
421 | 420 | ||
422 | #ifdef CONFIG_STMMAC_TIMER | ||
423 | /* Using Timers disable interrupts on completion for the reception */ | ||
424 | dis_ic = 1; | ||
425 | #endif | ||
426 | /* Set the Buffer size according to the MTU; | 421 | /* Set the Buffer size according to the MTU; |
427 | * indeed, in case of jumbo we need to bump-up the buffer sizes. | 422 | * indeed, in case of jumbo we need to bump-up the buffer sizes. |
428 | */ | 423 | */ |
@@ -437,6 +432,11 @@ static void init_dma_desc_rings(struct net_device *dev) | |||
437 | else | 432 | else |
438 | bfsize = DMA_BUFFER_SIZE; | 433 | bfsize = DMA_BUFFER_SIZE; |
439 | 434 | ||
435 | #ifdef CONFIG_STMMAC_TIMER | ||
436 | /* Disable interrupts on completion for the reception if timer is on */ | ||
437 | if (likely(priv->tm->enable)) | ||
438 | dis_ic = 1; | ||
439 | #endif | ||
440 | /* If the MTU exceeds 8k so use the second buffer in the chain */ | 440 | /* If the MTU exceeds 8k so use the second buffer in the chain */ |
441 | if (bfsize >= BUF_SIZE_8KiB) | 441 | if (bfsize >= BUF_SIZE_8KiB) |
442 | buff2_needed = 1; | 442 | buff2_needed = 1; |
@@ -809,20 +809,22 @@ static void stmmac_tx(struct stmmac_priv *priv) | |||
809 | 809 | ||
810 | static inline void stmmac_enable_irq(struct stmmac_priv *priv) | 810 | static inline void stmmac_enable_irq(struct stmmac_priv *priv) |
811 | { | 811 | { |
812 | #ifndef CONFIG_STMMAC_TIMER | 812 | #ifdef CONFIG_STMMAC_TIMER |
813 | writel(DMA_INTR_DEFAULT_MASK, priv->dev->base_addr + DMA_INTR_ENA); | 813 | if (likely(priv->tm->enable)) |
814 | #else | 814 | priv->tm->timer_start(tmrate); |
815 | priv->tm->timer_start(tmrate); | 815 | else |
816 | #endif | 816 | #endif |
817 | writel(DMA_INTR_DEFAULT_MASK, priv->dev->base_addr + DMA_INTR_ENA); | ||
817 | } | 818 | } |
818 | 819 | ||
819 | static inline void stmmac_disable_irq(struct stmmac_priv *priv) | 820 | static inline void stmmac_disable_irq(struct stmmac_priv *priv) |
820 | { | 821 | { |
821 | #ifndef CONFIG_STMMAC_TIMER | 822 | #ifdef CONFIG_STMMAC_TIMER |
822 | writel(0, priv->dev->base_addr + DMA_INTR_ENA); | 823 | if (likely(priv->tm->enable)) |
823 | #else | 824 | priv->tm->timer_stop(); |
824 | priv->tm->timer_stop(); | 825 | else |
825 | #endif | 826 | #endif |
827 | writel(0, priv->dev->base_addr + DMA_INTR_ENA); | ||
826 | } | 828 | } |
827 | 829 | ||
828 | static int stmmac_has_work(struct stmmac_priv *priv) | 830 | static int stmmac_has_work(struct stmmac_priv *priv) |
@@ -1031,22 +1033,23 @@ static int stmmac_open(struct net_device *dev) | |||
1031 | } | 1033 | } |
1032 | 1034 | ||
1033 | #ifdef CONFIG_STMMAC_TIMER | 1035 | #ifdef CONFIG_STMMAC_TIMER |
1034 | priv->tm = kmalloc(sizeof(struct stmmac_timer *), GFP_KERNEL); | 1036 | priv->tm = kzalloc(sizeof(struct stmmac_timer *), GFP_KERNEL); |
1035 | if (unlikely(priv->tm == NULL)) { | 1037 | if (unlikely(priv->tm == NULL)) { |
1036 | pr_err("%s: ERROR: timer memory alloc failed \n", __func__); | 1038 | pr_err("%s: ERROR: timer memory alloc failed \n", __func__); |
1037 | return -ENOMEM; | 1039 | return -ENOMEM; |
1038 | } | 1040 | } |
1039 | priv->tm->freq = tmrate; | 1041 | priv->tm->freq = tmrate; |
1040 | 1042 | ||
1041 | /* Test if the HW timer can be actually used. | 1043 | /* Test if the external timer can be actually used. |
1042 | * In case of failure continue with no timer. */ | 1044 | * In case of failure continue without timer. */ |
1043 | if (unlikely((stmmac_open_ext_timer(dev, priv->tm)) < 0)) { | 1045 | if (unlikely((stmmac_open_ext_timer(dev, priv->tm)) < 0)) { |
1044 | pr_warning("stmmaceth: cannot attach the HW timer\n"); | 1046 | pr_warning("stmmaceth: cannot attach the external timer.\n"); |
1045 | tmrate = 0; | 1047 | tmrate = 0; |
1046 | priv->tm->freq = 0; | 1048 | priv->tm->freq = 0; |
1047 | priv->tm->timer_start = stmmac_no_timer_started; | 1049 | priv->tm->timer_start = stmmac_no_timer_started; |
1048 | priv->tm->timer_stop = stmmac_no_timer_stopped; | 1050 | priv->tm->timer_stop = stmmac_no_timer_stopped; |
1049 | } | 1051 | } else |
1052 | priv->tm->enable = 1; | ||
1050 | #endif | 1053 | #endif |
1051 | 1054 | ||
1052 | /* Create and initialize the TX/RX descriptors chains. */ | 1055 | /* Create and initialize the TX/RX descriptors chains. */ |
@@ -1322,9 +1325,11 @@ static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev) | |||
1322 | 1325 | ||
1323 | /* Interrupt on completition only for the latest segment */ | 1326 | /* Interrupt on completition only for the latest segment */ |
1324 | priv->mac_type->ops->close_tx_desc(desc); | 1327 | priv->mac_type->ops->close_tx_desc(desc); |
1328 | |||
1325 | #ifdef CONFIG_STMMAC_TIMER | 1329 | #ifdef CONFIG_STMMAC_TIMER |
1326 | /* Clean IC while using timers */ | 1330 | /* Clean IC while using timer */ |
1327 | priv->mac_type->ops->clear_tx_ic(desc); | 1331 | if (likely(priv->tm->enable)) |
1332 | priv->mac_type->ops->clear_tx_ic(desc); | ||
1328 | #endif | 1333 | #endif |
1329 | /* To avoid raise condition */ | 1334 | /* To avoid raise condition */ |
1330 | priv->mac_type->ops->set_tx_owner(first); | 1335 | priv->mac_type->ops->set_tx_owner(first); |
@@ -2028,7 +2033,8 @@ static int stmmac_suspend(struct platform_device *pdev, pm_message_t state) | |||
2028 | 2033 | ||
2029 | #ifdef CONFIG_STMMAC_TIMER | 2034 | #ifdef CONFIG_STMMAC_TIMER |
2030 | priv->tm->timer_stop(); | 2035 | priv->tm->timer_stop(); |
2031 | dis_ic = 1; | 2036 | if (likely(priv->tm->enable)) |
2037 | dis_ic = 1; | ||
2032 | #endif | 2038 | #endif |
2033 | napi_disable(&priv->napi); | 2039 | napi_disable(&priv->napi); |
2034 | 2040 | ||
diff --git a/drivers/net/stmmac/stmmac_timer.c b/drivers/net/stmmac/stmmac_timer.c index b838c6582077..679f61ffb1f8 100644 --- a/drivers/net/stmmac/stmmac_timer.c +++ b/drivers/net/stmmac/stmmac_timer.c | |||
@@ -63,7 +63,7 @@ int stmmac_open_ext_timer(struct net_device *dev, struct stmmac_timer *tm) | |||
63 | 63 | ||
64 | stmmac_rtc = rtc_class_open(CONFIG_RTC_HCTOSYS_DEVICE); | 64 | stmmac_rtc = rtc_class_open(CONFIG_RTC_HCTOSYS_DEVICE); |
65 | if (stmmac_rtc == NULL) { | 65 | if (stmmac_rtc == NULL) { |
66 | pr_error("open rtc device failed\n"); | 66 | pr_err("open rtc device failed\n"); |
67 | return -ENODEV; | 67 | return -ENODEV; |
68 | } | 68 | } |
69 | 69 | ||
@@ -71,7 +71,7 @@ int stmmac_open_ext_timer(struct net_device *dev, struct stmmac_timer *tm) | |||
71 | 71 | ||
72 | /* Periodic mode is not supported */ | 72 | /* Periodic mode is not supported */ |
73 | if ((rtc_irq_set_freq(stmmac_rtc, &stmmac_task, tm->freq) < 0)) { | 73 | if ((rtc_irq_set_freq(stmmac_rtc, &stmmac_task, tm->freq) < 0)) { |
74 | pr_error("set periodic failed\n"); | 74 | pr_err("set periodic failed\n"); |
75 | rtc_irq_unregister(stmmac_rtc, &stmmac_task); | 75 | rtc_irq_unregister(stmmac_rtc, &stmmac_task); |
76 | rtc_class_close(stmmac_rtc); | 76 | rtc_class_close(stmmac_rtc); |
77 | return -1; | 77 | return -1; |
diff --git a/drivers/net/stmmac/stmmac_timer.h b/drivers/net/stmmac/stmmac_timer.h index f795cae33725..6863590d184b 100644 --- a/drivers/net/stmmac/stmmac_timer.h +++ b/drivers/net/stmmac/stmmac_timer.h | |||
@@ -26,6 +26,7 @@ struct stmmac_timer { | |||
26 | void (*timer_start) (unsigned int new_freq); | 26 | void (*timer_start) (unsigned int new_freq); |
27 | void (*timer_stop) (void); | 27 | void (*timer_stop) (void); |
28 | unsigned int freq; | 28 | unsigned int freq; |
29 | unsigned int enable; | ||
29 | }; | 30 | }; |
30 | 31 | ||
31 | /* Open the HW timer device and return 0 in case of success */ | 32 | /* Open the HW timer device and return 0 in case of success */ |
diff --git a/drivers/net/sungem.c b/drivers/net/sungem.c index 7019a0d1a82b..61640b99b705 100644 --- a/drivers/net/sungem.c +++ b/drivers/net/sungem.c | |||
@@ -2063,7 +2063,15 @@ static int gem_check_invariants(struct gem *gp) | |||
2063 | mif_cfg &= ~MIF_CFG_PSELECT; | 2063 | mif_cfg &= ~MIF_CFG_PSELECT; |
2064 | writel(mif_cfg, gp->regs + MIF_CFG); | 2064 | writel(mif_cfg, gp->regs + MIF_CFG); |
2065 | } else { | 2065 | } else { |
2066 | gp->phy_type = phy_serialink; | 2066 | #ifdef CONFIG_SPARC |
2067 | const char *p; | ||
2068 | |||
2069 | p = of_get_property(gp->of_node, "shared-pins", NULL); | ||
2070 | if (p && !strcmp(p, "serdes")) | ||
2071 | gp->phy_type = phy_serdes; | ||
2072 | else | ||
2073 | #endif | ||
2074 | gp->phy_type = phy_serialink; | ||
2067 | } | 2075 | } |
2068 | if (gp->phy_type == phy_mii_mdio1 || | 2076 | if (gp->phy_type == phy_mii_mdio1 || |
2069 | gp->phy_type == phy_mii_mdio0) { | 2077 | gp->phy_type == phy_mii_mdio0) { |
diff --git a/drivers/net/usb/hso.c b/drivers/net/usb/hso.c index fa4e58196c21..43bc3fcc0d85 100644 --- a/drivers/net/usb/hso.c +++ b/drivers/net/usb/hso.c | |||
@@ -378,7 +378,7 @@ static void dbg_dump(int line_count, const char *func_name, unsigned char *buf, | |||
378 | } | 378 | } |
379 | 379 | ||
380 | #define DUMP(buf_, len_) \ | 380 | #define DUMP(buf_, len_) \ |
381 | dbg_dump(__LINE__, __func__, buf_, len_) | 381 | dbg_dump(__LINE__, __func__, (unsigned char *)buf_, len_) |
382 | 382 | ||
383 | #define DUMP1(buf_, len_) \ | 383 | #define DUMP1(buf_, len_) \ |
384 | do { \ | 384 | do { \ |
@@ -1363,7 +1363,7 @@ static void hso_serial_close(struct tty_struct *tty, struct file *filp) | |||
1363 | /* reset the rts and dtr */ | 1363 | /* reset the rts and dtr */ |
1364 | /* do the actual close */ | 1364 | /* do the actual close */ |
1365 | serial->open_count--; | 1365 | serial->open_count--; |
1366 | kref_put(&serial->parent->ref, hso_serial_ref_free); | 1366 | |
1367 | if (serial->open_count <= 0) { | 1367 | if (serial->open_count <= 0) { |
1368 | serial->open_count = 0; | 1368 | serial->open_count = 0; |
1369 | spin_lock_irq(&serial->serial_lock); | 1369 | spin_lock_irq(&serial->serial_lock); |
@@ -1383,6 +1383,8 @@ static void hso_serial_close(struct tty_struct *tty, struct file *filp) | |||
1383 | usb_autopm_put_interface(serial->parent->interface); | 1383 | usb_autopm_put_interface(serial->parent->interface); |
1384 | 1384 | ||
1385 | mutex_unlock(&serial->parent->mutex); | 1385 | mutex_unlock(&serial->parent->mutex); |
1386 | |||
1387 | kref_put(&serial->parent->ref, hso_serial_ref_free); | ||
1386 | } | 1388 | } |
1387 | 1389 | ||
1388 | /* close the requested serial port */ | 1390 | /* close the requested serial port */ |
@@ -1527,7 +1529,7 @@ static void tiocmget_intr_callback(struct urb *urb) | |||
1527 | dev_warn(&usb->dev, | 1529 | dev_warn(&usb->dev, |
1528 | "hso received invalid serial state notification\n"); | 1530 | "hso received invalid serial state notification\n"); |
1529 | DUMP(serial_state_notification, | 1531 | DUMP(serial_state_notification, |
1530 | sizeof(hso_serial_state_notifation)) | 1532 | sizeof(struct hso_serial_state_notification)); |
1531 | } else { | 1533 | } else { |
1532 | 1534 | ||
1533 | UART_state_bitmap = le16_to_cpu(serial_state_notification-> | 1535 | UART_state_bitmap = le16_to_cpu(serial_state_notification-> |
diff --git a/drivers/net/veth.c b/drivers/net/veth.c index ade5b344f75d..52af5017c46b 100644 --- a/drivers/net/veth.c +++ b/drivers/net/veth.c | |||
@@ -210,32 +210,29 @@ rx_drop: | |||
210 | static struct net_device_stats *veth_get_stats(struct net_device *dev) | 210 | static struct net_device_stats *veth_get_stats(struct net_device *dev) |
211 | { | 211 | { |
212 | struct veth_priv *priv; | 212 | struct veth_priv *priv; |
213 | struct net_device_stats *dev_stats; | ||
214 | int cpu; | 213 | int cpu; |
215 | struct veth_net_stats *stats; | 214 | struct veth_net_stats *stats, total = {0}; |
216 | 215 | ||
217 | priv = netdev_priv(dev); | 216 | priv = netdev_priv(dev); |
218 | dev_stats = &dev->stats; | ||
219 | |||
220 | dev_stats->rx_packets = 0; | ||
221 | dev_stats->tx_packets = 0; | ||
222 | dev_stats->rx_bytes = 0; | ||
223 | dev_stats->tx_bytes = 0; | ||
224 | dev_stats->tx_dropped = 0; | ||
225 | dev_stats->rx_dropped = 0; | ||
226 | 217 | ||
227 | for_each_online_cpu(cpu) { | 218 | for_each_possible_cpu(cpu) { |
228 | stats = per_cpu_ptr(priv->stats, cpu); | 219 | stats = per_cpu_ptr(priv->stats, cpu); |
229 | 220 | ||
230 | dev_stats->rx_packets += stats->rx_packets; | 221 | total.rx_packets += stats->rx_packets; |
231 | dev_stats->tx_packets += stats->tx_packets; | 222 | total.tx_packets += stats->tx_packets; |
232 | dev_stats->rx_bytes += stats->rx_bytes; | 223 | total.rx_bytes += stats->rx_bytes; |
233 | dev_stats->tx_bytes += stats->tx_bytes; | 224 | total.tx_bytes += stats->tx_bytes; |
234 | dev_stats->tx_dropped += stats->tx_dropped; | 225 | total.tx_dropped += stats->tx_dropped; |
235 | dev_stats->rx_dropped += stats->rx_dropped; | 226 | total.rx_dropped += stats->rx_dropped; |
236 | } | 227 | } |
237 | 228 | dev->stats.rx_packets = total.rx_packets; | |
238 | return dev_stats; | 229 | dev->stats.tx_packets = total.tx_packets; |
230 | dev->stats.rx_bytes = total.rx_bytes; | ||
231 | dev->stats.tx_bytes = total.tx_bytes; | ||
232 | dev->stats.tx_dropped = total.tx_dropped; | ||
233 | dev->stats.rx_dropped = total.rx_dropped; | ||
234 | |||
235 | return &dev->stats; | ||
239 | } | 236 | } |
240 | 237 | ||
241 | static int veth_open(struct net_device *dev) | 238 | static int veth_open(struct net_device *dev) |
diff --git a/drivers/net/wan/cosa.c b/drivers/net/wan/cosa.c index e2c33c06190b..8e25ca7080c7 100644 --- a/drivers/net/wan/cosa.c +++ b/drivers/net/wan/cosa.c | |||
@@ -907,6 +907,7 @@ static ssize_t cosa_write(struct file *file, | |||
907 | current->state = TASK_RUNNING; | 907 | current->state = TASK_RUNNING; |
908 | chan->tx_status = 1; | 908 | chan->tx_status = 1; |
909 | spin_unlock_irqrestore(&cosa->lock, flags); | 909 | spin_unlock_irqrestore(&cosa->lock, flags); |
910 | up(&chan->wsem); | ||
910 | return -ERESTARTSYS; | 911 | return -ERESTARTSYS; |
911 | } | 912 | } |
912 | } | 913 | } |
diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index 9c6ab5378f6e..95a8e232b58f 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c | |||
@@ -1125,7 +1125,6 @@ ath5k_mode_setup(struct ath5k_softc *sc) | |||
1125 | /* configure operational mode */ | 1125 | /* configure operational mode */ |
1126 | ath5k_hw_set_opmode(ah); | 1126 | ath5k_hw_set_opmode(ah); |
1127 | 1127 | ||
1128 | ath5k_hw_set_mcast_filter(ah, 0, 0); | ||
1129 | ATH5K_DBG(sc, ATH5K_DEBUG_MODE, "RX filter 0x%x\n", rfilt); | 1128 | ATH5K_DBG(sc, ATH5K_DEBUG_MODE, "RX filter 0x%x\n", rfilt); |
1130 | } | 1129 | } |
1131 | 1130 | ||
diff --git a/drivers/net/wireless/ath/ath5k/led.c b/drivers/net/wireless/ath/ath5k/led.c index b767c3b67b24..b548c8eaaae1 100644 --- a/drivers/net/wireless/ath/ath5k/led.c +++ b/drivers/net/wireless/ath/ath5k/led.c | |||
@@ -63,12 +63,16 @@ static const struct pci_device_id ath5k_led_devices[] = { | |||
63 | { ATH_SDEVICE(PCI_VENDOR_ID_AMBIT, 0x0422), ATH_LED(1, 1) }, | 63 | { ATH_SDEVICE(PCI_VENDOR_ID_AMBIT, 0x0422), ATH_LED(1, 1) }, |
64 | /* E-machines E510 (tuliom@gmail.com) */ | 64 | /* E-machines E510 (tuliom@gmail.com) */ |
65 | { ATH_SDEVICE(PCI_VENDOR_ID_AMBIT, 0x0428), ATH_LED(3, 0) }, | 65 | { ATH_SDEVICE(PCI_VENDOR_ID_AMBIT, 0x0428), ATH_LED(3, 0) }, |
66 | /* BenQ Joybook R55v (nowymarluk@wp.pl) */ | ||
67 | { ATH_SDEVICE(PCI_VENDOR_ID_QMI, 0x0100), ATH_LED(1, 0) }, | ||
66 | /* Acer Extensa 5620z (nekoreeve@gmail.com) */ | 68 | /* Acer Extensa 5620z (nekoreeve@gmail.com) */ |
67 | { ATH_SDEVICE(PCI_VENDOR_ID_QMI, 0x0105), ATH_LED(3, 0) }, | 69 | { ATH_SDEVICE(PCI_VENDOR_ID_QMI, 0x0105), ATH_LED(3, 0) }, |
68 | /* Fukato Datacask Jupiter 1014a (mrb74@gmx.at) */ | 70 | /* Fukato Datacask Jupiter 1014a (mrb74@gmx.at) */ |
69 | { ATH_SDEVICE(PCI_VENDOR_ID_AZWAVE, 0x1026), ATH_LED(3, 0) }, | 71 | { ATH_SDEVICE(PCI_VENDOR_ID_AZWAVE, 0x1026), ATH_LED(3, 0) }, |
70 | /* IBM ThinkPad AR5BXB6 (legovini@spiro.fisica.unipd.it) */ | 72 | /* IBM ThinkPad AR5BXB6 (legovini@spiro.fisica.unipd.it) */ |
71 | { ATH_SDEVICE(PCI_VENDOR_ID_IBM, 0x058a), ATH_LED(1, 0) }, | 73 | { ATH_SDEVICE(PCI_VENDOR_ID_IBM, 0x058a), ATH_LED(1, 0) }, |
74 | /* HP Compaq CQ60-206US (ddreggors@jumptv.com) */ | ||
75 | { ATH_SDEVICE(PCI_VENDOR_ID_HP, 0x0137a), ATH_LED(3, 1) }, | ||
72 | /* HP Compaq C700 (nitrousnrg@gmail.com) */ | 76 | /* HP Compaq C700 (nitrousnrg@gmail.com) */ |
73 | { ATH_SDEVICE(PCI_VENDOR_ID_HP, 0x0137b), ATH_LED(3, 1) }, | 77 | { ATH_SDEVICE(PCI_VENDOR_ID_HP, 0x0137b), ATH_LED(3, 1) }, |
74 | /* IBM-specific AR5212 (all others) */ | 78 | /* IBM-specific AR5212 (all others) */ |
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 52bed89063d4..43d2be9867fc 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c | |||
@@ -1555,6 +1555,8 @@ void ath_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw) | |||
1555 | BIT(NL80211_IFTYPE_ADHOC) | | 1555 | BIT(NL80211_IFTYPE_ADHOC) | |
1556 | BIT(NL80211_IFTYPE_MESH_POINT); | 1556 | BIT(NL80211_IFTYPE_MESH_POINT); |
1557 | 1557 | ||
1558 | hw->wiphy->ps_default = false; | ||
1559 | |||
1558 | hw->queues = 4; | 1560 | hw->queues = 4; |
1559 | hw->max_rates = 4; | 1561 | hw->max_rates = 4; |
1560 | hw->channel_change_time = 5000; | 1562 | hw->channel_change_time = 5000; |
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c index 86f35827f008..098dda1a67c1 100644 --- a/drivers/net/wireless/b43/main.c +++ b/drivers/net/wireless/b43/main.c | |||
@@ -4521,9 +4521,8 @@ static int b43_op_beacon_set_tim(struct ieee80211_hw *hw, | |||
4521 | { | 4521 | { |
4522 | struct b43_wl *wl = hw_to_b43_wl(hw); | 4522 | struct b43_wl *wl = hw_to_b43_wl(hw); |
4523 | 4523 | ||
4524 | mutex_lock(&wl->mutex); | 4524 | /* FIXME: add locking */ |
4525 | b43_update_templates(wl); | 4525 | b43_update_templates(wl); |
4526 | mutex_unlock(&wl->mutex); | ||
4527 | 4526 | ||
4528 | return 0; | 4527 | return 0; |
4529 | } | 4528 | } |
diff --git a/drivers/net/wireless/ipw2x00/ipw2100.c b/drivers/net/wireless/ipw2x00/ipw2100.c index 240cff1e6979..6e2fc0cb6f8a 100644 --- a/drivers/net/wireless/ipw2x00/ipw2100.c +++ b/drivers/net/wireless/ipw2x00/ipw2100.c | |||
@@ -6029,7 +6029,7 @@ static struct net_device *ipw2100_alloc_device(struct pci_dev *pci_dev, | |||
6029 | struct ipw2100_priv *priv; | 6029 | struct ipw2100_priv *priv; |
6030 | struct net_device *dev; | 6030 | struct net_device *dev; |
6031 | 6031 | ||
6032 | dev = alloc_ieee80211(sizeof(struct ipw2100_priv), 0); | 6032 | dev = alloc_ieee80211(sizeof(struct ipw2100_priv)); |
6033 | if (!dev) | 6033 | if (!dev) |
6034 | return NULL; | 6034 | return NULL; |
6035 | priv = libipw_priv(dev); | 6035 | priv = libipw_priv(dev); |
@@ -6342,7 +6342,7 @@ static int ipw2100_pci_init_one(struct pci_dev *pci_dev, | |||
6342 | sysfs_remove_group(&pci_dev->dev.kobj, | 6342 | sysfs_remove_group(&pci_dev->dev.kobj, |
6343 | &ipw2100_attribute_group); | 6343 | &ipw2100_attribute_group); |
6344 | 6344 | ||
6345 | free_ieee80211(dev, 0); | 6345 | free_ieee80211(dev); |
6346 | pci_set_drvdata(pci_dev, NULL); | 6346 | pci_set_drvdata(pci_dev, NULL); |
6347 | } | 6347 | } |
6348 | 6348 | ||
@@ -6400,7 +6400,7 @@ static void __devexit ipw2100_pci_remove_one(struct pci_dev *pci_dev) | |||
6400 | if (dev->base_addr) | 6400 | if (dev->base_addr) |
6401 | iounmap((void __iomem *)dev->base_addr); | 6401 | iounmap((void __iomem *)dev->base_addr); |
6402 | 6402 | ||
6403 | free_ieee80211(dev, 0); | 6403 | free_ieee80211(dev); |
6404 | } | 6404 | } |
6405 | 6405 | ||
6406 | pci_release_regions(pci_dev); | 6406 | pci_release_regions(pci_dev); |
diff --git a/drivers/net/wireless/ipw2x00/ipw2200.c b/drivers/net/wireless/ipw2x00/ipw2200.c index 827824d45de9..a6ca536e44f8 100644 --- a/drivers/net/wireless/ipw2x00/ipw2200.c +++ b/drivers/net/wireless/ipw2x00/ipw2200.c | |||
@@ -104,25 +104,6 @@ static int antenna = CFG_SYS_ANTENNA_BOTH; | |||
104 | static int rtap_iface = 0; /* def: 0 -- do not create rtap interface */ | 104 | static int rtap_iface = 0; /* def: 0 -- do not create rtap interface */ |
105 | #endif | 105 | #endif |
106 | 106 | ||
107 | static struct ieee80211_rate ipw2200_rates[] = { | ||
108 | { .bitrate = 10 }, | ||
109 | { .bitrate = 20, .flags = IEEE80211_RATE_SHORT_PREAMBLE }, | ||
110 | { .bitrate = 55, .flags = IEEE80211_RATE_SHORT_PREAMBLE }, | ||
111 | { .bitrate = 110, .flags = IEEE80211_RATE_SHORT_PREAMBLE }, | ||
112 | { .bitrate = 60 }, | ||
113 | { .bitrate = 90 }, | ||
114 | { .bitrate = 120 }, | ||
115 | { .bitrate = 180 }, | ||
116 | { .bitrate = 240 }, | ||
117 | { .bitrate = 360 }, | ||
118 | { .bitrate = 480 }, | ||
119 | { .bitrate = 540 } | ||
120 | }; | ||
121 | |||
122 | #define ipw2200_a_rates (ipw2200_rates + 4) | ||
123 | #define ipw2200_num_a_rates 8 | ||
124 | #define ipw2200_bg_rates (ipw2200_rates + 0) | ||
125 | #define ipw2200_num_bg_rates 12 | ||
126 | 107 | ||
127 | #ifdef CONFIG_IPW2200_QOS | 108 | #ifdef CONFIG_IPW2200_QOS |
128 | static int qos_enable = 0; | 109 | static int qos_enable = 0; |
@@ -8674,6 +8655,24 @@ static int ipw_sw_reset(struct ipw_priv *priv, int option) | |||
8674 | * | 8655 | * |
8675 | */ | 8656 | */ |
8676 | 8657 | ||
8658 | static int ipw_wx_get_name(struct net_device *dev, | ||
8659 | struct iw_request_info *info, | ||
8660 | union iwreq_data *wrqu, char *extra) | ||
8661 | { | ||
8662 | struct ipw_priv *priv = libipw_priv(dev); | ||
8663 | mutex_lock(&priv->mutex); | ||
8664 | if (priv->status & STATUS_RF_KILL_MASK) | ||
8665 | strcpy(wrqu->name, "radio off"); | ||
8666 | else if (!(priv->status & STATUS_ASSOCIATED)) | ||
8667 | strcpy(wrqu->name, "unassociated"); | ||
8668 | else | ||
8669 | snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11%c", | ||
8670 | ipw_modes[priv->assoc_request.ieee_mode]); | ||
8671 | IPW_DEBUG_WX("Name: %s\n", wrqu->name); | ||
8672 | mutex_unlock(&priv->mutex); | ||
8673 | return 0; | ||
8674 | } | ||
8675 | |||
8677 | static int ipw_set_channel(struct ipw_priv *priv, u8 channel) | 8676 | static int ipw_set_channel(struct ipw_priv *priv, u8 channel) |
8678 | { | 8677 | { |
8679 | if (channel == 0) { | 8678 | if (channel == 0) { |
@@ -9973,7 +9972,7 @@ static int ipw_wx_sw_reset(struct net_device *dev, | |||
9973 | /* Rebase the WE IOCTLs to zero for the handler array */ | 9972 | /* Rebase the WE IOCTLs to zero for the handler array */ |
9974 | #define IW_IOCTL(x) [(x)-SIOCSIWCOMMIT] | 9973 | #define IW_IOCTL(x) [(x)-SIOCSIWCOMMIT] |
9975 | static iw_handler ipw_wx_handlers[] = { | 9974 | static iw_handler ipw_wx_handlers[] = { |
9976 | IW_IOCTL(SIOCGIWNAME) = (iw_handler) cfg80211_wext_giwname, | 9975 | IW_IOCTL(SIOCGIWNAME) = ipw_wx_get_name, |
9977 | IW_IOCTL(SIOCSIWFREQ) = ipw_wx_set_freq, | 9976 | IW_IOCTL(SIOCSIWFREQ) = ipw_wx_set_freq, |
9978 | IW_IOCTL(SIOCGIWFREQ) = ipw_wx_get_freq, | 9977 | IW_IOCTL(SIOCGIWFREQ) = ipw_wx_get_freq, |
9979 | IW_IOCTL(SIOCSIWMODE) = ipw_wx_set_mode, | 9978 | IW_IOCTL(SIOCSIWMODE) = ipw_wx_set_mode, |
@@ -11417,100 +11416,16 @@ static void ipw_bg_down(struct work_struct *work) | |||
11417 | /* Called by register_netdev() */ | 11416 | /* Called by register_netdev() */ |
11418 | static int ipw_net_init(struct net_device *dev) | 11417 | static int ipw_net_init(struct net_device *dev) |
11419 | { | 11418 | { |
11420 | int i, rc = 0; | ||
11421 | struct ipw_priv *priv = libipw_priv(dev); | 11419 | struct ipw_priv *priv = libipw_priv(dev); |
11422 | const struct libipw_geo *geo = libipw_get_geo(priv->ieee); | ||
11423 | struct wireless_dev *wdev = &priv->ieee->wdev; | ||
11424 | mutex_lock(&priv->mutex); | 11420 | mutex_lock(&priv->mutex); |
11425 | 11421 | ||
11426 | if (ipw_up(priv)) { | 11422 | if (ipw_up(priv)) { |
11427 | rc = -EIO; | 11423 | mutex_unlock(&priv->mutex); |
11428 | goto out; | 11424 | return -EIO; |
11429 | } | ||
11430 | |||
11431 | memcpy(wdev->wiphy->perm_addr, priv->mac_addr, ETH_ALEN); | ||
11432 | |||
11433 | /* fill-out priv->ieee->bg_band */ | ||
11434 | if (geo->bg_channels) { | ||
11435 | struct ieee80211_supported_band *bg_band = &priv->ieee->bg_band; | ||
11436 | |||
11437 | bg_band->band = IEEE80211_BAND_2GHZ; | ||
11438 | bg_band->n_channels = geo->bg_channels; | ||
11439 | bg_band->channels = | ||
11440 | kzalloc(geo->bg_channels * | ||
11441 | sizeof(struct ieee80211_channel), GFP_KERNEL); | ||
11442 | /* translate geo->bg to bg_band.channels */ | ||
11443 | for (i = 0; i < geo->bg_channels; i++) { | ||
11444 | bg_band->channels[i].band = IEEE80211_BAND_2GHZ; | ||
11445 | bg_band->channels[i].center_freq = geo->bg[i].freq; | ||
11446 | bg_band->channels[i].hw_value = geo->bg[i].channel; | ||
11447 | bg_band->channels[i].max_power = geo->bg[i].max_power; | ||
11448 | if (geo->bg[i].flags & LIBIPW_CH_PASSIVE_ONLY) | ||
11449 | bg_band->channels[i].flags |= | ||
11450 | IEEE80211_CHAN_PASSIVE_SCAN; | ||
11451 | if (geo->bg[i].flags & LIBIPW_CH_NO_IBSS) | ||
11452 | bg_band->channels[i].flags |= | ||
11453 | IEEE80211_CHAN_NO_IBSS; | ||
11454 | if (geo->bg[i].flags & LIBIPW_CH_RADAR_DETECT) | ||
11455 | bg_band->channels[i].flags |= | ||
11456 | IEEE80211_CHAN_RADAR; | ||
11457 | /* No equivalent for LIBIPW_CH_80211H_RULES, | ||
11458 | LIBIPW_CH_UNIFORM_SPREADING, or | ||
11459 | LIBIPW_CH_B_ONLY... */ | ||
11460 | } | ||
11461 | /* point at bitrate info */ | ||
11462 | bg_band->bitrates = ipw2200_bg_rates; | ||
11463 | bg_band->n_bitrates = ipw2200_num_bg_rates; | ||
11464 | |||
11465 | wdev->wiphy->bands[IEEE80211_BAND_2GHZ] = bg_band; | ||
11466 | } | ||
11467 | |||
11468 | /* fill-out priv->ieee->a_band */ | ||
11469 | if (geo->a_channels) { | ||
11470 | struct ieee80211_supported_band *a_band = &priv->ieee->a_band; | ||
11471 | |||
11472 | a_band->band = IEEE80211_BAND_5GHZ; | ||
11473 | a_band->n_channels = geo->a_channels; | ||
11474 | a_band->channels = | ||
11475 | kzalloc(geo->a_channels * | ||
11476 | sizeof(struct ieee80211_channel), GFP_KERNEL); | ||
11477 | /* translate geo->bg to a_band.channels */ | ||
11478 | for (i = 0; i < geo->a_channels; i++) { | ||
11479 | a_band->channels[i].band = IEEE80211_BAND_2GHZ; | ||
11480 | a_band->channels[i].center_freq = geo->a[i].freq; | ||
11481 | a_band->channels[i].hw_value = geo->a[i].channel; | ||
11482 | a_band->channels[i].max_power = geo->a[i].max_power; | ||
11483 | if (geo->a[i].flags & LIBIPW_CH_PASSIVE_ONLY) | ||
11484 | a_band->channels[i].flags |= | ||
11485 | IEEE80211_CHAN_PASSIVE_SCAN; | ||
11486 | if (geo->a[i].flags & LIBIPW_CH_NO_IBSS) | ||
11487 | a_band->channels[i].flags |= | ||
11488 | IEEE80211_CHAN_NO_IBSS; | ||
11489 | if (geo->a[i].flags & LIBIPW_CH_RADAR_DETECT) | ||
11490 | a_band->channels[i].flags |= | ||
11491 | IEEE80211_CHAN_RADAR; | ||
11492 | /* No equivalent for LIBIPW_CH_80211H_RULES, | ||
11493 | LIBIPW_CH_UNIFORM_SPREADING, or | ||
11494 | LIBIPW_CH_B_ONLY... */ | ||
11495 | } | ||
11496 | /* point at bitrate info */ | ||
11497 | a_band->bitrates = ipw2200_a_rates; | ||
11498 | a_band->n_bitrates = ipw2200_num_a_rates; | ||
11499 | |||
11500 | wdev->wiphy->bands[IEEE80211_BAND_5GHZ] = a_band; | ||
11501 | } | ||
11502 | |||
11503 | set_wiphy_dev(wdev->wiphy, &priv->pci_dev->dev); | ||
11504 | |||
11505 | /* With that information in place, we can now register the wiphy... */ | ||
11506 | if (wiphy_register(wdev->wiphy)) { | ||
11507 | rc = -EIO; | ||
11508 | goto out; | ||
11509 | } | 11425 | } |
11510 | 11426 | ||
11511 | out: | ||
11512 | mutex_unlock(&priv->mutex); | 11427 | mutex_unlock(&priv->mutex); |
11513 | return rc; | 11428 | return 0; |
11514 | } | 11429 | } |
11515 | 11430 | ||
11516 | /* PCI driver stuff */ | 11431 | /* PCI driver stuff */ |
@@ -11641,7 +11556,7 @@ static int ipw_prom_alloc(struct ipw_priv *priv) | |||
11641 | if (priv->prom_net_dev) | 11556 | if (priv->prom_net_dev) |
11642 | return -EPERM; | 11557 | return -EPERM; |
11643 | 11558 | ||
11644 | priv->prom_net_dev = alloc_ieee80211(sizeof(struct ipw_prom_priv), 1); | 11559 | priv->prom_net_dev = alloc_ieee80211(sizeof(struct ipw_prom_priv)); |
11645 | if (priv->prom_net_dev == NULL) | 11560 | if (priv->prom_net_dev == NULL) |
11646 | return -ENOMEM; | 11561 | return -ENOMEM; |
11647 | 11562 | ||
@@ -11660,7 +11575,7 @@ static int ipw_prom_alloc(struct ipw_priv *priv) | |||
11660 | 11575 | ||
11661 | rc = register_netdev(priv->prom_net_dev); | 11576 | rc = register_netdev(priv->prom_net_dev); |
11662 | if (rc) { | 11577 | if (rc) { |
11663 | free_ieee80211(priv->prom_net_dev, 1); | 11578 | free_ieee80211(priv->prom_net_dev); |
11664 | priv->prom_net_dev = NULL; | 11579 | priv->prom_net_dev = NULL; |
11665 | return rc; | 11580 | return rc; |
11666 | } | 11581 | } |
@@ -11674,7 +11589,7 @@ static void ipw_prom_free(struct ipw_priv *priv) | |||
11674 | return; | 11589 | return; |
11675 | 11590 | ||
11676 | unregister_netdev(priv->prom_net_dev); | 11591 | unregister_netdev(priv->prom_net_dev); |
11677 | free_ieee80211(priv->prom_net_dev, 1); | 11592 | free_ieee80211(priv->prom_net_dev); |
11678 | 11593 | ||
11679 | priv->prom_net_dev = NULL; | 11594 | priv->prom_net_dev = NULL; |
11680 | } | 11595 | } |
@@ -11702,7 +11617,7 @@ static int __devinit ipw_pci_probe(struct pci_dev *pdev, | |||
11702 | struct ipw_priv *priv; | 11617 | struct ipw_priv *priv; |
11703 | int i; | 11618 | int i; |
11704 | 11619 | ||
11705 | net_dev = alloc_ieee80211(sizeof(struct ipw_priv), 0); | 11620 | net_dev = alloc_ieee80211(sizeof(struct ipw_priv)); |
11706 | if (net_dev == NULL) { | 11621 | if (net_dev == NULL) { |
11707 | err = -ENOMEM; | 11622 | err = -ENOMEM; |
11708 | goto out; | 11623 | goto out; |
@@ -11850,7 +11765,7 @@ static int __devinit ipw_pci_probe(struct pci_dev *pdev, | |||
11850 | pci_disable_device(pdev); | 11765 | pci_disable_device(pdev); |
11851 | pci_set_drvdata(pdev, NULL); | 11766 | pci_set_drvdata(pdev, NULL); |
11852 | out_free_ieee80211: | 11767 | out_free_ieee80211: |
11853 | free_ieee80211(priv->net_dev, 0); | 11768 | free_ieee80211(priv->net_dev); |
11854 | out: | 11769 | out: |
11855 | return err; | 11770 | return err; |
11856 | } | 11771 | } |
@@ -11917,7 +11832,7 @@ static void __devexit ipw_pci_remove(struct pci_dev *pdev) | |||
11917 | pci_release_regions(pdev); | 11832 | pci_release_regions(pdev); |
11918 | pci_disable_device(pdev); | 11833 | pci_disable_device(pdev); |
11919 | pci_set_drvdata(pdev, NULL); | 11834 | pci_set_drvdata(pdev, NULL); |
11920 | free_ieee80211(priv->net_dev, 0); | 11835 | free_ieee80211(priv->net_dev); |
11921 | free_firmware(); | 11836 | free_firmware(); |
11922 | } | 11837 | } |
11923 | 11838 | ||
diff --git a/drivers/net/wireless/ipw2x00/libipw.h b/drivers/net/wireless/ipw2x00/libipw.h index bf45391172f3..1e334ff6bd52 100644 --- a/drivers/net/wireless/ipw2x00/libipw.h +++ b/drivers/net/wireless/ipw2x00/libipw.h | |||
@@ -31,7 +31,6 @@ | |||
31 | #include <linux/ieee80211.h> | 31 | #include <linux/ieee80211.h> |
32 | 32 | ||
33 | #include <net/lib80211.h> | 33 | #include <net/lib80211.h> |
34 | #include <net/cfg80211.h> | ||
35 | 34 | ||
36 | #define LIBIPW_VERSION "git-1.1.13" | 35 | #define LIBIPW_VERSION "git-1.1.13" |
37 | 36 | ||
@@ -784,15 +783,12 @@ struct libipw_geo { | |||
784 | 783 | ||
785 | struct libipw_device { | 784 | struct libipw_device { |
786 | struct net_device *dev; | 785 | struct net_device *dev; |
787 | struct wireless_dev wdev; | ||
788 | struct libipw_security sec; | 786 | struct libipw_security sec; |
789 | 787 | ||
790 | /* Bookkeeping structures */ | 788 | /* Bookkeeping structures */ |
791 | struct libipw_stats ieee_stats; | 789 | struct libipw_stats ieee_stats; |
792 | 790 | ||
793 | struct libipw_geo geo; | 791 | struct libipw_geo geo; |
794 | struct ieee80211_supported_band bg_band; | ||
795 | struct ieee80211_supported_band a_band; | ||
796 | 792 | ||
797 | /* Probe / Beacon management */ | 793 | /* Probe / Beacon management */ |
798 | struct list_head network_free_list; | 794 | struct list_head network_free_list; |
@@ -1018,8 +1014,8 @@ static inline int libipw_is_cck_rate(u8 rate) | |||
1018 | } | 1014 | } |
1019 | 1015 | ||
1020 | /* ieee80211.c */ | 1016 | /* ieee80211.c */ |
1021 | extern void free_ieee80211(struct net_device *dev, int monitor); | 1017 | extern void free_ieee80211(struct net_device *dev); |
1022 | extern struct net_device *alloc_ieee80211(int sizeof_priv, int monitor); | 1018 | extern struct net_device *alloc_ieee80211(int sizeof_priv); |
1023 | extern int libipw_change_mtu(struct net_device *dev, int new_mtu); | 1019 | extern int libipw_change_mtu(struct net_device *dev, int new_mtu); |
1024 | 1020 | ||
1025 | extern void libipw_networks_age(struct libipw_device *ieee, | 1021 | extern void libipw_networks_age(struct libipw_device *ieee, |
diff --git a/drivers/net/wireless/ipw2x00/libipw_module.c b/drivers/net/wireless/ipw2x00/libipw_module.c index a0e9f6aed7da..eb2b60834c17 100644 --- a/drivers/net/wireless/ipw2x00/libipw_module.c +++ b/drivers/net/wireless/ipw2x00/libipw_module.c | |||
@@ -62,9 +62,6 @@ MODULE_DESCRIPTION(DRV_DESCRIPTION); | |||
62 | MODULE_AUTHOR(DRV_COPYRIGHT); | 62 | MODULE_AUTHOR(DRV_COPYRIGHT); |
63 | MODULE_LICENSE("GPL"); | 63 | MODULE_LICENSE("GPL"); |
64 | 64 | ||
65 | struct cfg80211_ops libipw_config_ops = { }; | ||
66 | void *libipw_wiphy_privid = &libipw_wiphy_privid; | ||
67 | |||
68 | static int libipw_networks_allocate(struct libipw_device *ieee) | 65 | static int libipw_networks_allocate(struct libipw_device *ieee) |
69 | { | 66 | { |
70 | if (ieee->networks) | 67 | if (ieee->networks) |
@@ -143,7 +140,7 @@ int libipw_change_mtu(struct net_device *dev, int new_mtu) | |||
143 | } | 140 | } |
144 | EXPORT_SYMBOL(libipw_change_mtu); | 141 | EXPORT_SYMBOL(libipw_change_mtu); |
145 | 142 | ||
146 | struct net_device *alloc_ieee80211(int sizeof_priv, int monitor) | 143 | struct net_device *alloc_ieee80211(int sizeof_priv) |
147 | { | 144 | { |
148 | struct libipw_device *ieee; | 145 | struct libipw_device *ieee; |
149 | struct net_device *dev; | 146 | struct net_device *dev; |
@@ -160,31 +157,10 @@ struct net_device *alloc_ieee80211(int sizeof_priv, int monitor) | |||
160 | 157 | ||
161 | ieee->dev = dev; | 158 | ieee->dev = dev; |
162 | 159 | ||
163 | if (!monitor) { | ||
164 | ieee->wdev.wiphy = wiphy_new(&libipw_config_ops, 0); | ||
165 | if (!ieee->wdev.wiphy) { | ||
166 | LIBIPW_ERROR("Unable to allocate wiphy.\n"); | ||
167 | goto failed_free_netdev; | ||
168 | } | ||
169 | |||
170 | ieee->dev->ieee80211_ptr = &ieee->wdev; | ||
171 | ieee->wdev.iftype = NL80211_IFTYPE_STATION; | ||
172 | |||
173 | /* Fill-out wiphy structure bits we know... Not enough info | ||
174 | here to call set_wiphy_dev or set MAC address or channel info | ||
175 | -- have to do that in ->ndo_init... */ | ||
176 | ieee->wdev.wiphy->privid = libipw_wiphy_privid; | ||
177 | |||
178 | ieee->wdev.wiphy->max_scan_ssids = 1; | ||
179 | ieee->wdev.wiphy->max_scan_ie_len = 0; | ||
180 | ieee->wdev.wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | ||
181 | | BIT(NL80211_IFTYPE_ADHOC); | ||
182 | } | ||
183 | |||
184 | err = libipw_networks_allocate(ieee); | 160 | err = libipw_networks_allocate(ieee); |
185 | if (err) { | 161 | if (err) { |
186 | LIBIPW_ERROR("Unable to allocate beacon storage: %d\n", err); | 162 | LIBIPW_ERROR("Unable to allocate beacon storage: %d\n", err); |
187 | goto failed_free_wiphy; | 163 | goto failed_free_netdev; |
188 | } | 164 | } |
189 | libipw_networks_initialize(ieee); | 165 | libipw_networks_initialize(ieee); |
190 | 166 | ||
@@ -217,31 +193,19 @@ struct net_device *alloc_ieee80211(int sizeof_priv, int monitor) | |||
217 | 193 | ||
218 | return dev; | 194 | return dev; |
219 | 195 | ||
220 | failed_free_wiphy: | ||
221 | if (!monitor) | ||
222 | wiphy_free(ieee->wdev.wiphy); | ||
223 | failed_free_netdev: | 196 | failed_free_netdev: |
224 | free_netdev(dev); | 197 | free_netdev(dev); |
225 | failed: | 198 | failed: |
226 | return NULL; | 199 | return NULL; |
227 | } | 200 | } |
228 | 201 | ||
229 | void free_ieee80211(struct net_device *dev, int monitor) | 202 | void free_ieee80211(struct net_device *dev) |
230 | { | 203 | { |
231 | struct libipw_device *ieee = netdev_priv(dev); | 204 | struct libipw_device *ieee = netdev_priv(dev); |
232 | 205 | ||
233 | lib80211_crypt_info_free(&ieee->crypt_info); | 206 | lib80211_crypt_info_free(&ieee->crypt_info); |
234 | 207 | ||
235 | libipw_networks_free(ieee); | 208 | libipw_networks_free(ieee); |
236 | |||
237 | /* free cfg80211 resources */ | ||
238 | if (!monitor) { | ||
239 | wiphy_unregister(ieee->wdev.wiphy); | ||
240 | kfree(ieee->a_band.channels); | ||
241 | kfree(ieee->bg_band.channels); | ||
242 | wiphy_free(ieee->wdev.wiphy); | ||
243 | } | ||
244 | |||
245 | free_netdev(dev); | 209 | free_netdev(dev); |
246 | } | 210 | } |
247 | 211 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c index 2716b91ba9fa..950267ab556a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-1000.c +++ b/drivers/net/wireless/iwlwifi/iwl-1000.c | |||
@@ -161,5 +161,6 @@ struct iwl_cfg iwl1000_bgn_cfg = { | |||
161 | .max_ll_items = OTP_MAX_LL_ITEMS_1000, | 161 | .max_ll_items = OTP_MAX_LL_ITEMS_1000, |
162 | .shadow_ram_support = false, | 162 | .shadow_ram_support = false, |
163 | .ht_greenfield_support = true, | 163 | .ht_greenfield_support = true, |
164 | .use_rts_for_ht = true, /* use rts/cts protection */ | ||
164 | }; | 165 | }; |
165 | 166 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c index c295b8ee9228..1473452ba22f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-6000.c +++ b/drivers/net/wireless/iwlwifi/iwl-6000.c | |||
@@ -175,6 +175,7 @@ struct iwl_cfg iwl6000h_2agn_cfg = { | |||
175 | .max_ll_items = OTP_MAX_LL_ITEMS_6x00, | 175 | .max_ll_items = OTP_MAX_LL_ITEMS_6x00, |
176 | .shadow_ram_support = true, | 176 | .shadow_ram_support = true, |
177 | .ht_greenfield_support = true, | 177 | .ht_greenfield_support = true, |
178 | .use_rts_for_ht = true, /* use rts/cts protection */ | ||
178 | }; | 179 | }; |
179 | 180 | ||
180 | /* | 181 | /* |
@@ -198,6 +199,7 @@ struct iwl_cfg iwl6000i_2agn_cfg = { | |||
198 | .max_ll_items = OTP_MAX_LL_ITEMS_6x00, | 199 | .max_ll_items = OTP_MAX_LL_ITEMS_6x00, |
199 | .shadow_ram_support = true, | 200 | .shadow_ram_support = true, |
200 | .ht_greenfield_support = true, | 201 | .ht_greenfield_support = true, |
202 | .use_rts_for_ht = true, /* use rts/cts protection */ | ||
201 | }; | 203 | }; |
202 | 204 | ||
203 | struct iwl_cfg iwl6050_2agn_cfg = { | 205 | struct iwl_cfg iwl6050_2agn_cfg = { |
@@ -218,6 +220,7 @@ struct iwl_cfg iwl6050_2agn_cfg = { | |||
218 | .max_ll_items = OTP_MAX_LL_ITEMS_6x00, | 220 | .max_ll_items = OTP_MAX_LL_ITEMS_6x00, |
219 | .shadow_ram_support = true, | 221 | .shadow_ram_support = true, |
220 | .ht_greenfield_support = true, | 222 | .ht_greenfield_support = true, |
223 | .use_rts_for_ht = true, /* use rts/cts protection */ | ||
221 | }; | 224 | }; |
222 | 225 | ||
223 | struct iwl_cfg iwl6000_3agn_cfg = { | 226 | struct iwl_cfg iwl6000_3agn_cfg = { |
@@ -238,6 +241,7 @@ struct iwl_cfg iwl6000_3agn_cfg = { | |||
238 | .max_ll_items = OTP_MAX_LL_ITEMS_6x00, | 241 | .max_ll_items = OTP_MAX_LL_ITEMS_6x00, |
239 | .shadow_ram_support = true, | 242 | .shadow_ram_support = true, |
240 | .ht_greenfield_support = true, | 243 | .ht_greenfield_support = true, |
244 | .use_rts_for_ht = true, /* use rts/cts protection */ | ||
241 | }; | 245 | }; |
242 | 246 | ||
243 | struct iwl_cfg iwl6050_3agn_cfg = { | 247 | struct iwl_cfg iwl6050_3agn_cfg = { |
@@ -258,6 +262,7 @@ struct iwl_cfg iwl6050_3agn_cfg = { | |||
258 | .max_ll_items = OTP_MAX_LL_ITEMS_6x00, | 262 | .max_ll_items = OTP_MAX_LL_ITEMS_6x00, |
259 | .shadow_ram_support = true, | 263 | .shadow_ram_support = true, |
260 | .ht_greenfield_support = true, | 264 | .ht_greenfield_support = true, |
265 | .use_rts_for_ht = true, /* use rts/cts protection */ | ||
261 | }; | 266 | }; |
262 | 267 | ||
263 | MODULE_FIRMWARE(IWL6000_MODULE_FIRMWARE(IWL6000_UCODE_API_MAX)); | 268 | MODULE_FIRMWARE(IWL6000_MODULE_FIRMWARE(IWL6000_UCODE_API_MAX)); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c index 346dc06fa7b7..81726ee32858 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c | |||
@@ -418,6 +418,15 @@ static void rs_tl_turn_on_agg(struct iwl_priv *priv, u8 tid, | |||
418 | else if (tid == IWL_AGG_ALL_TID) | 418 | else if (tid == IWL_AGG_ALL_TID) |
419 | for (tid = 0; tid < TID_MAX_LOAD_COUNT; tid++) | 419 | for (tid = 0; tid < TID_MAX_LOAD_COUNT; tid++) |
420 | rs_tl_turn_on_agg_for_tid(priv, lq_data, tid, sta); | 420 | rs_tl_turn_on_agg_for_tid(priv, lq_data, tid, sta); |
421 | if (priv->cfg->use_rts_for_ht) { | ||
422 | /* | ||
423 | * switch to RTS/CTS if it is the prefer protection method | ||
424 | * for HT traffic | ||
425 | */ | ||
426 | IWL_DEBUG_HT(priv, "use RTS/CTS protection for HT\n"); | ||
427 | priv->staging_rxon.flags &= ~RXON_FLG_SELF_CTS_EN; | ||
428 | iwlcore_commit_rxon(priv); | ||
429 | } | ||
421 | } | 430 | } |
422 | 431 | ||
423 | static inline int get_num_of_ant_from_rate(u32 rate_n_flags) | 432 | static inline int get_num_of_ant_from_rate(u32 rate_n_flags) |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index eaafae091f5b..921dc4a26fe2 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c | |||
@@ -116,9 +116,6 @@ int iwl_commit_rxon(struct iwl_priv *priv) | |||
116 | 116 | ||
117 | /* always get timestamp with Rx frame */ | 117 | /* always get timestamp with Rx frame */ |
118 | priv->staging_rxon.flags |= RXON_FLG_TSF2HOST_MSK; | 118 | priv->staging_rxon.flags |= RXON_FLG_TSF2HOST_MSK; |
119 | /* allow CTS-to-self if possible. this is relevant only for | ||
120 | * 5000, but will not damage 4965 */ | ||
121 | priv->staging_rxon.flags |= RXON_FLG_SELF_CTS_EN; | ||
122 | 119 | ||
123 | ret = iwl_check_rxon_cmd(priv); | 120 | ret = iwl_check_rxon_cmd(priv); |
124 | if (ret) { | 121 | if (ret) { |
@@ -218,6 +215,13 @@ int iwl_commit_rxon(struct iwl_priv *priv) | |||
218 | "Could not send WEP static key.\n"); | 215 | "Could not send WEP static key.\n"); |
219 | } | 216 | } |
220 | 217 | ||
218 | /* | ||
219 | * allow CTS-to-self if possible for new association. | ||
220 | * this is relevant only for 5000 series and up, | ||
221 | * but will not damage 4965 | ||
222 | */ | ||
223 | priv->staging_rxon.flags |= RXON_FLG_SELF_CTS_EN; | ||
224 | |||
221 | /* Apply the new configuration | 225 | /* Apply the new configuration |
222 | * RXON assoc doesn't clear the station table in uCode, | 226 | * RXON assoc doesn't clear the station table in uCode, |
223 | */ | 227 | */ |
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index e50103a956b1..7754538c2194 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h | |||
@@ -213,6 +213,7 @@ struct iwl_mod_params { | |||
213 | * @pa_type: used by 6000 series only to identify the type of Power Amplifier | 213 | * @pa_type: used by 6000 series only to identify the type of Power Amplifier |
214 | * @max_ll_items: max number of OTP blocks | 214 | * @max_ll_items: max number of OTP blocks |
215 | * @shadow_ram_support: shadow support for OTP memory | 215 | * @shadow_ram_support: shadow support for OTP memory |
216 | * @use_rts_for_ht: use rts/cts protection for HT traffic | ||
216 | * | 217 | * |
217 | * We enable the driver to be backward compatible wrt API version. The | 218 | * We enable the driver to be backward compatible wrt API version. The |
218 | * driver specifies which APIs it supports (with @ucode_api_max being the | 219 | * driver specifies which APIs it supports (with @ucode_api_max being the |
@@ -255,6 +256,7 @@ struct iwl_cfg { | |||
255 | const bool shadow_ram_support; | 256 | const bool shadow_ram_support; |
256 | const bool ht_greenfield_support; | 257 | const bool ht_greenfield_support; |
257 | const bool broken_powersave; | 258 | const bool broken_powersave; |
259 | bool use_rts_for_ht; | ||
258 | }; | 260 | }; |
259 | 261 | ||
260 | /*************************** | 262 | /*************************** |
diff --git a/drivers/net/wireless/libertas/ethtool.c b/drivers/net/wireless/libertas/ethtool.c index 039b555e4d76..53d56ab83c03 100644 --- a/drivers/net/wireless/libertas/ethtool.c +++ b/drivers/net/wireless/libertas/ethtool.c | |||
@@ -169,16 +169,19 @@ static int lbs_ethtool_set_wol(struct net_device *dev, | |||
169 | struct lbs_private *priv = dev->ml_priv; | 169 | struct lbs_private *priv = dev->ml_priv; |
170 | uint32_t criteria = 0; | 170 | uint32_t criteria = 0; |
171 | 171 | ||
172 | if (priv->wol_criteria == 0xffffffff && wol->wolopts) | ||
173 | return -EOPNOTSUPP; | ||
174 | |||
175 | if (wol->wolopts & ~(WAKE_UCAST|WAKE_MCAST|WAKE_BCAST|WAKE_PHY)) | 172 | if (wol->wolopts & ~(WAKE_UCAST|WAKE_MCAST|WAKE_BCAST|WAKE_PHY)) |
176 | return -EOPNOTSUPP; | 173 | return -EOPNOTSUPP; |
177 | 174 | ||
178 | if (wol->wolopts & WAKE_UCAST) criteria |= EHS_WAKE_ON_UNICAST_DATA; | 175 | if (wol->wolopts & WAKE_UCAST) |
179 | if (wol->wolopts & WAKE_MCAST) criteria |= EHS_WAKE_ON_MULTICAST_DATA; | 176 | criteria |= EHS_WAKE_ON_UNICAST_DATA; |
180 | if (wol->wolopts & WAKE_BCAST) criteria |= EHS_WAKE_ON_BROADCAST_DATA; | 177 | if (wol->wolopts & WAKE_MCAST) |
181 | if (wol->wolopts & WAKE_PHY) criteria |= EHS_WAKE_ON_MAC_EVENT; | 178 | criteria |= EHS_WAKE_ON_MULTICAST_DATA; |
179 | if (wol->wolopts & WAKE_BCAST) | ||
180 | criteria |= EHS_WAKE_ON_BROADCAST_DATA; | ||
181 | if (wol->wolopts & WAKE_PHY) | ||
182 | criteria |= EHS_WAKE_ON_MAC_EVENT; | ||
183 | if (wol->wolopts == 0) | ||
184 | criteria |= EHS_REMOVE_WAKEUP; | ||
182 | 185 | ||
183 | return lbs_host_sleep_cfg(priv, criteria, (struct wol_config *)NULL); | 186 | return lbs_host_sleep_cfg(priv, criteria, (struct wol_config *)NULL); |
184 | } | 187 | } |
diff --git a/drivers/net/wireless/p54/p54usb.c b/drivers/net/wireless/p54/p54usb.c index 17e199546eeb..92af9b96bb7a 100644 --- a/drivers/net/wireless/p54/p54usb.c +++ b/drivers/net/wireless/p54/p54usb.c | |||
@@ -426,12 +426,16 @@ static const char p54u_romboot_3887[] = "~~~~"; | |||
426 | static int p54u_firmware_reset_3887(struct ieee80211_hw *dev) | 426 | static int p54u_firmware_reset_3887(struct ieee80211_hw *dev) |
427 | { | 427 | { |
428 | struct p54u_priv *priv = dev->priv; | 428 | struct p54u_priv *priv = dev->priv; |
429 | u8 buf[4]; | 429 | u8 *buf; |
430 | int ret; | 430 | int ret; |
431 | 431 | ||
432 | memcpy(&buf, p54u_romboot_3887, sizeof(buf)); | 432 | buf = kmalloc(4, GFP_KERNEL); |
433 | if (!buf) | ||
434 | return -ENOMEM; | ||
435 | memcpy(buf, p54u_romboot_3887, 4); | ||
433 | ret = p54u_bulk_msg(priv, P54U_PIPE_DATA, | 436 | ret = p54u_bulk_msg(priv, P54U_PIPE_DATA, |
434 | buf, sizeof(buf)); | 437 | buf, 4); |
438 | kfree(buf); | ||
435 | if (ret) | 439 | if (ret) |
436 | dev_err(&priv->udev->dev, "(p54usb) unable to jump to " | 440 | dev_err(&priv->udev->dev, "(p54usb) unable to jump to " |
437 | "boot ROM (%d)!\n", ret); | 441 | "boot ROM (%d)!\n", ret); |
diff --git a/drivers/net/wireless/rtl818x/rtl8187_rfkill.c b/drivers/net/wireless/rtl818x/rtl8187_rfkill.c index 9fab13e4004e..cad8037ab2af 100644 --- a/drivers/net/wireless/rtl818x/rtl8187_rfkill.c +++ b/drivers/net/wireless/rtl818x/rtl8187_rfkill.c | |||
@@ -18,6 +18,7 @@ | |||
18 | #include <net/mac80211.h> | 18 | #include <net/mac80211.h> |
19 | 19 | ||
20 | #include "rtl8187.h" | 20 | #include "rtl8187.h" |
21 | #include "rtl8187_rfkill.h" | ||
21 | 22 | ||
22 | static bool rtl8187_is_radio_enabled(struct rtl8187_priv *priv) | 23 | static bool rtl8187_is_radio_enabled(struct rtl8187_priv *priv) |
23 | { | 24 | { |
diff --git a/drivers/pci/dmar.c b/drivers/pci/dmar.c index e5f8fc164fd3..b952ebc7a78b 100644 --- a/drivers/pci/dmar.c +++ b/drivers/pci/dmar.c | |||
@@ -609,6 +609,9 @@ int __init check_zero_address(void) | |||
609 | dmi_get_system_info(DMI_BIOS_VENDOR), | 609 | dmi_get_system_info(DMI_BIOS_VENDOR), |
610 | dmi_get_system_info(DMI_BIOS_VERSION), | 610 | dmi_get_system_info(DMI_BIOS_VERSION), |
611 | dmi_get_system_info(DMI_PRODUCT_VERSION)); | 611 | dmi_get_system_info(DMI_PRODUCT_VERSION)); |
612 | #ifdef CONFIG_DMAR | ||
613 | dmar_disabled = 1; | ||
614 | #endif | ||
612 | return 0; | 615 | return 0; |
613 | } | 616 | } |
614 | break; | 617 | break; |
diff --git a/drivers/platform/x86/acerhdf.c b/drivers/platform/x86/acerhdf.c index 0a8f735f6c4a..ab64522aaa64 100644 --- a/drivers/platform/x86/acerhdf.c +++ b/drivers/platform/x86/acerhdf.c | |||
@@ -52,7 +52,7 @@ | |||
52 | */ | 52 | */ |
53 | #undef START_IN_KERNEL_MODE | 53 | #undef START_IN_KERNEL_MODE |
54 | 54 | ||
55 | #define DRV_VER "0.5.17" | 55 | #define DRV_VER "0.5.18" |
56 | 56 | ||
57 | /* | 57 | /* |
58 | * According to the Atom N270 datasheet, | 58 | * According to the Atom N270 datasheet, |
@@ -61,7 +61,7 @@ | |||
61 | * measured by the on-die thermal monitor are within 0 <= Tj <= 90. So, | 61 | * measured by the on-die thermal monitor are within 0 <= Tj <= 90. So, |
62 | * assume 89°C is critical temperature. | 62 | * assume 89°C is critical temperature. |
63 | */ | 63 | */ |
64 | #define ACERHDF_TEMP_CRIT 89 | 64 | #define ACERHDF_TEMP_CRIT 89000 |
65 | #define ACERHDF_FAN_OFF 0 | 65 | #define ACERHDF_FAN_OFF 0 |
66 | #define ACERHDF_FAN_AUTO 1 | 66 | #define ACERHDF_FAN_AUTO 1 |
67 | 67 | ||
@@ -69,7 +69,7 @@ | |||
69 | * No matter what value the user puts into the fanon variable, turn on the fan | 69 | * No matter what value the user puts into the fanon variable, turn on the fan |
70 | * at 80 degree Celsius to prevent hardware damage | 70 | * at 80 degree Celsius to prevent hardware damage |
71 | */ | 71 | */ |
72 | #define ACERHDF_MAX_FANON 80 | 72 | #define ACERHDF_MAX_FANON 80000 |
73 | 73 | ||
74 | /* | 74 | /* |
75 | * Maximum interval between two temperature checks is 15 seconds, as the die | 75 | * Maximum interval between two temperature checks is 15 seconds, as the die |
@@ -85,8 +85,8 @@ static int kernelmode; | |||
85 | #endif | 85 | #endif |
86 | 86 | ||
87 | static unsigned int interval = 10; | 87 | static unsigned int interval = 10; |
88 | static unsigned int fanon = 63; | 88 | static unsigned int fanon = 63000; |
89 | static unsigned int fanoff = 58; | 89 | static unsigned int fanoff = 58000; |
90 | static unsigned int verbose; | 90 | static unsigned int verbose; |
91 | static unsigned int fanstate = ACERHDF_FAN_AUTO; | 91 | static unsigned int fanstate = ACERHDF_FAN_AUTO; |
92 | static char force_bios[16]; | 92 | static char force_bios[16]; |
@@ -171,7 +171,7 @@ static int acerhdf_get_temp(int *temp) | |||
171 | if (ec_read(bios_cfg->tempreg, &read_temp)) | 171 | if (ec_read(bios_cfg->tempreg, &read_temp)) |
172 | return -EINVAL; | 172 | return -EINVAL; |
173 | 173 | ||
174 | *temp = read_temp; | 174 | *temp = read_temp * 1000; |
175 | 175 | ||
176 | return 0; | 176 | return 0; |
177 | } | 177 | } |
diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c index d93108d148fc..a848c7e20aeb 100644 --- a/drivers/platform/x86/thinkpad_acpi.c +++ b/drivers/platform/x86/thinkpad_acpi.c | |||
@@ -1680,36 +1680,48 @@ static void tpacpi_remove_driver_attributes(struct device_driver *drv) | |||
1680 | | (__bv1) << 8 | (__bv2) } | 1680 | | (__bv1) << 8 | (__bv2) } |
1681 | 1681 | ||
1682 | #define TPV_Q_X(__v, __bid1, __bid2, __bv1, __bv2, \ | 1682 | #define TPV_Q_X(__v, __bid1, __bid2, __bv1, __bv2, \ |
1683 | __eid1, __eid2, __ev1, __ev2) \ | 1683 | __eid, __ev1, __ev2) \ |
1684 | { .vendor = (__v), \ | 1684 | { .vendor = (__v), \ |
1685 | .bios = TPID(__bid1, __bid2), \ | 1685 | .bios = TPID(__bid1, __bid2), \ |
1686 | .ec = TPID(__eid1, __eid2), \ | 1686 | .ec = __eid, \ |
1687 | .quirks = (__ev1) << 24 | (__ev2) << 16 \ | 1687 | .quirks = (__ev1) << 24 | (__ev2) << 16 \ |
1688 | | (__bv1) << 8 | (__bv2) } | 1688 | | (__bv1) << 8 | (__bv2) } |
1689 | 1689 | ||
1690 | #define TPV_QI0(__id1, __id2, __bv1, __bv2) \ | 1690 | #define TPV_QI0(__id1, __id2, __bv1, __bv2) \ |
1691 | TPV_Q(PCI_VENDOR_ID_IBM, __id1, __id2, __bv1, __bv2) | 1691 | TPV_Q(PCI_VENDOR_ID_IBM, __id1, __id2, __bv1, __bv2) |
1692 | 1692 | ||
1693 | /* Outdated IBM BIOSes often lack the EC id string */ | ||
1693 | #define TPV_QI1(__id1, __id2, __bv1, __bv2, __ev1, __ev2) \ | 1694 | #define TPV_QI1(__id1, __id2, __bv1, __bv2, __ev1, __ev2) \ |
1694 | TPV_Q_X(PCI_VENDOR_ID_IBM, __id1, __id2, \ | 1695 | TPV_Q_X(PCI_VENDOR_ID_IBM, __id1, __id2, \ |
1695 | __bv1, __bv2, __id1, __id2, __ev1, __ev2) | 1696 | __bv1, __bv2, TPID(__id1, __id2), \ |
1697 | __ev1, __ev2), \ | ||
1698 | TPV_Q_X(PCI_VENDOR_ID_IBM, __id1, __id2, \ | ||
1699 | __bv1, __bv2, TPACPI_MATCH_UNKNOWN, \ | ||
1700 | __ev1, __ev2) | ||
1696 | 1701 | ||
1702 | /* Outdated IBM BIOSes often lack the EC id string */ | ||
1697 | #define TPV_QI2(__bid1, __bid2, __bv1, __bv2, \ | 1703 | #define TPV_QI2(__bid1, __bid2, __bv1, __bv2, \ |
1698 | __eid1, __eid2, __ev1, __ev2) \ | 1704 | __eid1, __eid2, __ev1, __ev2) \ |
1699 | TPV_Q_X(PCI_VENDOR_ID_IBM, __bid1, __bid2, \ | 1705 | TPV_Q_X(PCI_VENDOR_ID_IBM, __bid1, __bid2, \ |
1700 | __bv1, __bv2, __eid1, __eid2, __ev1, __ev2) | 1706 | __bv1, __bv2, TPID(__eid1, __eid2), \ |
1707 | __ev1, __ev2), \ | ||
1708 | TPV_Q_X(PCI_VENDOR_ID_IBM, __bid1, __bid2, \ | ||
1709 | __bv1, __bv2, TPACPI_MATCH_UNKNOWN, \ | ||
1710 | __ev1, __ev2) | ||
1701 | 1711 | ||
1702 | #define TPV_QL0(__id1, __id2, __bv1, __bv2) \ | 1712 | #define TPV_QL0(__id1, __id2, __bv1, __bv2) \ |
1703 | TPV_Q(PCI_VENDOR_ID_LENOVO, __id1, __id2, __bv1, __bv2) | 1713 | TPV_Q(PCI_VENDOR_ID_LENOVO, __id1, __id2, __bv1, __bv2) |
1704 | 1714 | ||
1705 | #define TPV_QL1(__id1, __id2, __bv1, __bv2, __ev1, __ev2) \ | 1715 | #define TPV_QL1(__id1, __id2, __bv1, __bv2, __ev1, __ev2) \ |
1706 | TPV_Q_X(PCI_VENDOR_ID_LENOVO, __id1, __id2, \ | 1716 | TPV_Q_X(PCI_VENDOR_ID_LENOVO, __id1, __id2, \ |
1707 | __bv1, __bv2, __id1, __id2, __ev1, __ev2) | 1717 | __bv1, __bv2, TPID(__id1, __id2), \ |
1718 | __ev1, __ev2) | ||
1708 | 1719 | ||
1709 | #define TPV_QL2(__bid1, __bid2, __bv1, __bv2, \ | 1720 | #define TPV_QL2(__bid1, __bid2, __bv1, __bv2, \ |
1710 | __eid1, __eid2, __ev1, __ev2) \ | 1721 | __eid1, __eid2, __ev1, __ev2) \ |
1711 | TPV_Q_X(PCI_VENDOR_ID_LENOVO, __bid1, __bid2, \ | 1722 | TPV_Q_X(PCI_VENDOR_ID_LENOVO, __bid1, __bid2, \ |
1712 | __bv1, __bv2, __eid1, __eid2, __ev1, __ev2) | 1723 | __bv1, __bv2, TPID(__eid1, __eid2), \ |
1724 | __ev1, __ev2) | ||
1713 | 1725 | ||
1714 | static const struct tpacpi_quirk tpacpi_bios_version_qtable[] __initconst = { | 1726 | static const struct tpacpi_quirk tpacpi_bios_version_qtable[] __initconst = { |
1715 | /* Numeric models ------------------ */ | 1727 | /* Numeric models ------------------ */ |
@@ -6313,7 +6325,7 @@ static int brightness_write(char *buf) | |||
6313 | * Doing it this way makes the syscall restartable in case of EINTR | 6325 | * Doing it this way makes the syscall restartable in case of EINTR |
6314 | */ | 6326 | */ |
6315 | rc = brightness_set(level); | 6327 | rc = brightness_set(level); |
6316 | return (rc == -EINTR)? ERESTARTSYS : rc; | 6328 | return (rc == -EINTR)? -ERESTARTSYS : rc; |
6317 | } | 6329 | } |
6318 | 6330 | ||
6319 | static struct ibm_struct brightness_driver_data = { | 6331 | static struct ibm_struct brightness_driver_data = { |
diff --git a/drivers/scsi/bfa/bfad_fwimg.c b/drivers/scsi/bfa/bfad_fwimg.c index b2f6949bc8d3..bd34b0db2d6b 100644 --- a/drivers/scsi/bfa/bfad_fwimg.c +++ b/drivers/scsi/bfa/bfad_fwimg.c | |||
@@ -41,6 +41,8 @@ u32 *bfi_image_cb; | |||
41 | 41 | ||
42 | #define BFAD_FW_FILE_CT "ctfw.bin" | 42 | #define BFAD_FW_FILE_CT "ctfw.bin" |
43 | #define BFAD_FW_FILE_CB "cbfw.bin" | 43 | #define BFAD_FW_FILE_CB "cbfw.bin" |
44 | MODULE_FIRMWARE(BFAD_FW_FILE_CT); | ||
45 | MODULE_FIRMWARE(BFAD_FW_FILE_CB); | ||
44 | 46 | ||
45 | u32 * | 47 | u32 * |
46 | bfad_read_firmware(struct pci_dev *pdev, u32 **bfi_image, | 48 | bfad_read_firmware(struct pci_dev *pdev, u32 **bfi_image, |
diff --git a/drivers/scsi/bfa/bfad_im.c b/drivers/scsi/bfa/bfad_im.c index 158c99243c08..55d012a9a668 100644 --- a/drivers/scsi/bfa/bfad_im.c +++ b/drivers/scsi/bfa/bfad_im.c | |||
@@ -948,7 +948,7 @@ bfad_os_fc_host_init(struct bfad_im_port_s *im_port) | |||
948 | if (bfad_supported_fc4s & (BFA_PORT_ROLE_FCP_IM | BFA_PORT_ROLE_FCP_TM)) | 948 | if (bfad_supported_fc4s & (BFA_PORT_ROLE_FCP_IM | BFA_PORT_ROLE_FCP_TM)) |
949 | /* For FCP type 0x08 */ | 949 | /* For FCP type 0x08 */ |
950 | fc_host_supported_fc4s(host)[2] = 1; | 950 | fc_host_supported_fc4s(host)[2] = 1; |
951 | if (bfad_supported_fc4s | BFA_PORT_ROLE_FCP_IPFC) | 951 | if (bfad_supported_fc4s & BFA_PORT_ROLE_FCP_IPFC) |
952 | /* For LLC/SNAP type 0x05 */ | 952 | /* For LLC/SNAP type 0x05 */ |
953 | fc_host_supported_fc4s(host)[3] = 0x20; | 953 | fc_host_supported_fc4s(host)[3] = 0x20; |
954 | /* For fibre channel services type 0x20 */ | 954 | /* For fibre channel services type 0x20 */ |
diff --git a/drivers/scsi/gdth.c b/drivers/scsi/gdth.c index 185e6bc4dd40..9e8fce0f0c1b 100644 --- a/drivers/scsi/gdth.c +++ b/drivers/scsi/gdth.c | |||
@@ -2900,7 +2900,7 @@ static int gdth_read_event(gdth_ha_str *ha, int handle, gdth_evt_str *estr) | |||
2900 | eindex = handle; | 2900 | eindex = handle; |
2901 | estr->event_source = 0; | 2901 | estr->event_source = 0; |
2902 | 2902 | ||
2903 | if (eindex >= MAX_EVENTS) { | 2903 | if (eindex < 0 || eindex >= MAX_EVENTS) { |
2904 | spin_unlock_irqrestore(&ha->smp_lock, flags); | 2904 | spin_unlock_irqrestore(&ha->smp_lock, flags); |
2905 | return eindex; | 2905 | return eindex; |
2906 | } | 2906 | } |
diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c index 5f045505a1f4..76d294fc7846 100644 --- a/drivers/scsi/ipr.c +++ b/drivers/scsi/ipr.c | |||
@@ -4189,6 +4189,25 @@ static irqreturn_t ipr_handle_other_interrupt(struct ipr_ioa_cfg *ioa_cfg, | |||
4189 | } | 4189 | } |
4190 | 4190 | ||
4191 | /** | 4191 | /** |
4192 | * ipr_isr_eh - Interrupt service routine error handler | ||
4193 | * @ioa_cfg: ioa config struct | ||
4194 | * @msg: message to log | ||
4195 | * | ||
4196 | * Return value: | ||
4197 | * none | ||
4198 | **/ | ||
4199 | static void ipr_isr_eh(struct ipr_ioa_cfg *ioa_cfg, char *msg) | ||
4200 | { | ||
4201 | ioa_cfg->errors_logged++; | ||
4202 | dev_err(&ioa_cfg->pdev->dev, "%s\n", msg); | ||
4203 | |||
4204 | if (WAIT_FOR_DUMP == ioa_cfg->sdt_state) | ||
4205 | ioa_cfg->sdt_state = GET_DUMP; | ||
4206 | |||
4207 | ipr_initiate_ioa_reset(ioa_cfg, IPR_SHUTDOWN_NONE); | ||
4208 | } | ||
4209 | |||
4210 | /** | ||
4192 | * ipr_isr - Interrupt service routine | 4211 | * ipr_isr - Interrupt service routine |
4193 | * @irq: irq number | 4212 | * @irq: irq number |
4194 | * @devp: pointer to ioa config struct | 4213 | * @devp: pointer to ioa config struct |
@@ -4203,6 +4222,7 @@ static irqreturn_t ipr_isr(int irq, void *devp) | |||
4203 | volatile u32 int_reg, int_mask_reg; | 4222 | volatile u32 int_reg, int_mask_reg; |
4204 | u32 ioasc; | 4223 | u32 ioasc; |
4205 | u16 cmd_index; | 4224 | u16 cmd_index; |
4225 | int num_hrrq = 0; | ||
4206 | struct ipr_cmnd *ipr_cmd; | 4226 | struct ipr_cmnd *ipr_cmd; |
4207 | irqreturn_t rc = IRQ_NONE; | 4227 | irqreturn_t rc = IRQ_NONE; |
4208 | 4228 | ||
@@ -4233,13 +4253,7 @@ static irqreturn_t ipr_isr(int irq, void *devp) | |||
4233 | IPR_HRRQ_REQ_RESP_HANDLE_MASK) >> IPR_HRRQ_REQ_RESP_HANDLE_SHIFT; | 4253 | IPR_HRRQ_REQ_RESP_HANDLE_MASK) >> IPR_HRRQ_REQ_RESP_HANDLE_SHIFT; |
4234 | 4254 | ||
4235 | if (unlikely(cmd_index >= IPR_NUM_CMD_BLKS)) { | 4255 | if (unlikely(cmd_index >= IPR_NUM_CMD_BLKS)) { |
4236 | ioa_cfg->errors_logged++; | 4256 | ipr_isr_eh(ioa_cfg, "Invalid response handle from IOA"); |
4237 | dev_err(&ioa_cfg->pdev->dev, "Invalid response handle from IOA\n"); | ||
4238 | |||
4239 | if (WAIT_FOR_DUMP == ioa_cfg->sdt_state) | ||
4240 | ioa_cfg->sdt_state = GET_DUMP; | ||
4241 | |||
4242 | ipr_initiate_ioa_reset(ioa_cfg, IPR_SHUTDOWN_NONE); | ||
4243 | spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); | 4257 | spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); |
4244 | return IRQ_HANDLED; | 4258 | return IRQ_HANDLED; |
4245 | } | 4259 | } |
@@ -4266,8 +4280,18 @@ static irqreturn_t ipr_isr(int irq, void *devp) | |||
4266 | 4280 | ||
4267 | if (ipr_cmd != NULL) { | 4281 | if (ipr_cmd != NULL) { |
4268 | /* Clear the PCI interrupt */ | 4282 | /* Clear the PCI interrupt */ |
4269 | writel(IPR_PCII_HRRQ_UPDATED, ioa_cfg->regs.clr_interrupt_reg); | 4283 | do { |
4270 | int_reg = readl(ioa_cfg->regs.sense_interrupt_reg) & ~int_mask_reg; | 4284 | writel(IPR_PCII_HRRQ_UPDATED, ioa_cfg->regs.clr_interrupt_reg); |
4285 | int_reg = readl(ioa_cfg->regs.sense_interrupt_reg) & ~int_mask_reg; | ||
4286 | } while (int_reg & IPR_PCII_HRRQ_UPDATED && | ||
4287 | num_hrrq++ < IPR_MAX_HRRQ_RETRIES); | ||
4288 | |||
4289 | if (int_reg & IPR_PCII_HRRQ_UPDATED) { | ||
4290 | ipr_isr_eh(ioa_cfg, "Error clearing HRRQ"); | ||
4291 | spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); | ||
4292 | return IRQ_HANDLED; | ||
4293 | } | ||
4294 | |||
4271 | } else | 4295 | } else |
4272 | break; | 4296 | break; |
4273 | } | 4297 | } |
diff --git a/drivers/scsi/ipr.h b/drivers/scsi/ipr.h index 163245a1c3e5..19bbcf39f0c9 100644 --- a/drivers/scsi/ipr.h +++ b/drivers/scsi/ipr.h | |||
@@ -144,6 +144,7 @@ | |||
144 | #define IPR_IOA_MAX_SECTORS 32767 | 144 | #define IPR_IOA_MAX_SECTORS 32767 |
145 | #define IPR_VSET_MAX_SECTORS 512 | 145 | #define IPR_VSET_MAX_SECTORS 512 |
146 | #define IPR_MAX_CDB_LEN 16 | 146 | #define IPR_MAX_CDB_LEN 16 |
147 | #define IPR_MAX_HRRQ_RETRIES 3 | ||
147 | 148 | ||
148 | #define IPR_DEFAULT_BUS_WIDTH 16 | 149 | #define IPR_DEFAULT_BUS_WIDTH 16 |
149 | #define IPR_80MBs_SCSI_RATE ((80 * 10) / (IPR_DEFAULT_BUS_WIDTH / 8)) | 150 | #define IPR_80MBs_SCSI_RATE ((80 * 10) / (IPR_DEFAULT_BUS_WIDTH / 8)) |
diff --git a/drivers/scsi/libsas/sas_expander.c b/drivers/scsi/libsas/sas_expander.c index b3381959acce..33cf988c8c8a 100644 --- a/drivers/scsi/libsas/sas_expander.c +++ b/drivers/scsi/libsas/sas_expander.c | |||
@@ -960,7 +960,6 @@ static int sas_ex_discover_dev(struct domain_device *dev, int phy_id) | |||
960 | 960 | ||
961 | } | 961 | } |
962 | } | 962 | } |
963 | res = 0; | ||
964 | } | 963 | } |
965 | 964 | ||
966 | return res; | 965 | return res; |
diff --git a/drivers/scsi/pmcraid.c b/drivers/scsi/pmcraid.c index f7c70e2a8224..0a97bc9074bb 100644 --- a/drivers/scsi/pmcraid.c +++ b/drivers/scsi/pmcraid.c | |||
@@ -1071,7 +1071,7 @@ static struct pmcraid_cmd *pmcraid_init_hcam | |||
1071 | 1071 | ||
1072 | ioarcb->data_transfer_length = cpu_to_le32(rcb_size); | 1072 | ioarcb->data_transfer_length = cpu_to_le32(rcb_size); |
1073 | 1073 | ||
1074 | ioadl[0].flags |= cpu_to_le32(IOADL_FLAGS_READ_LAST); | 1074 | ioadl[0].flags |= IOADL_FLAGS_READ_LAST; |
1075 | ioadl[0].data_len = cpu_to_le32(rcb_size); | 1075 | ioadl[0].data_len = cpu_to_le32(rcb_size); |
1076 | ioadl[0].address = cpu_to_le32(dma); | 1076 | ioadl[0].address = cpu_to_le32(dma); |
1077 | 1077 | ||
@@ -2251,7 +2251,7 @@ static void pmcraid_request_sense(struct pmcraid_cmd *cmd) | |||
2251 | 2251 | ||
2252 | ioadl->address = cpu_to_le64(cmd->sense_buffer_dma); | 2252 | ioadl->address = cpu_to_le64(cmd->sense_buffer_dma); |
2253 | ioadl->data_len = cpu_to_le32(SCSI_SENSE_BUFFERSIZE); | 2253 | ioadl->data_len = cpu_to_le32(SCSI_SENSE_BUFFERSIZE); |
2254 | ioadl->flags = cpu_to_le32(IOADL_FLAGS_LAST_DESC); | 2254 | ioadl->flags = IOADL_FLAGS_LAST_DESC; |
2255 | 2255 | ||
2256 | /* request sense might be called as part of error response processing | 2256 | /* request sense might be called as part of error response processing |
2257 | * which runs in tasklets context. It is possible that mid-layer might | 2257 | * which runs in tasklets context. It is possible that mid-layer might |
@@ -3017,7 +3017,7 @@ static int pmcraid_build_ioadl( | |||
3017 | ioadl[i].flags = 0; | 3017 | ioadl[i].flags = 0; |
3018 | } | 3018 | } |
3019 | /* setup last descriptor */ | 3019 | /* setup last descriptor */ |
3020 | ioadl[i - 1].flags = cpu_to_le32(IOADL_FLAGS_LAST_DESC); | 3020 | ioadl[i - 1].flags = IOADL_FLAGS_LAST_DESC; |
3021 | 3021 | ||
3022 | return 0; | 3022 | return 0; |
3023 | } | 3023 | } |
@@ -3387,7 +3387,7 @@ static int pmcraid_build_passthrough_ioadls( | |||
3387 | } | 3387 | } |
3388 | 3388 | ||
3389 | /* setup the last descriptor */ | 3389 | /* setup the last descriptor */ |
3390 | ioadl[i - 1].flags = cpu_to_le32(IOADL_FLAGS_LAST_DESC); | 3390 | ioadl[i - 1].flags = IOADL_FLAGS_LAST_DESC; |
3391 | 3391 | ||
3392 | return 0; | 3392 | return 0; |
3393 | } | 3393 | } |
@@ -5314,7 +5314,7 @@ static void pmcraid_querycfg(struct pmcraid_cmd *cmd) | |||
5314 | cpu_to_le32(sizeof(struct pmcraid_config_table)); | 5314 | cpu_to_le32(sizeof(struct pmcraid_config_table)); |
5315 | 5315 | ||
5316 | ioadl = &(ioarcb->add_data.u.ioadl[0]); | 5316 | ioadl = &(ioarcb->add_data.u.ioadl[0]); |
5317 | ioadl->flags = cpu_to_le32(IOADL_FLAGS_LAST_DESC); | 5317 | ioadl->flags = IOADL_FLAGS_LAST_DESC; |
5318 | ioadl->address = cpu_to_le64(pinstance->cfg_table_bus_addr); | 5318 | ioadl->address = cpu_to_le64(pinstance->cfg_table_bus_addr); |
5319 | ioadl->data_len = cpu_to_le32(sizeof(struct pmcraid_config_table)); | 5319 | ioadl->data_len = cpu_to_le32(sizeof(struct pmcraid_config_table)); |
5320 | 5320 | ||
diff --git a/drivers/scsi/scsi_transport_fc.c b/drivers/scsi/scsi_transport_fc.c index a67fed10598a..c6f70dae9b2e 100644 --- a/drivers/scsi/scsi_transport_fc.c +++ b/drivers/scsi/scsi_transport_fc.c | |||
@@ -3656,6 +3656,7 @@ fc_bsg_host_dispatch(struct request_queue *q, struct Scsi_Host *shost, | |||
3656 | fail_host_msg: | 3656 | fail_host_msg: |
3657 | /* return the errno failure code as the only status */ | 3657 | /* return the errno failure code as the only status */ |
3658 | BUG_ON(job->reply_len < sizeof(uint32_t)); | 3658 | BUG_ON(job->reply_len < sizeof(uint32_t)); |
3659 | job->reply->reply_payload_rcv_len = 0; | ||
3659 | job->reply->result = ret; | 3660 | job->reply->result = ret; |
3660 | job->reply_len = sizeof(uint32_t); | 3661 | job->reply_len = sizeof(uint32_t); |
3661 | fc_bsg_jobdone(job); | 3662 | fc_bsg_jobdone(job); |
@@ -3741,6 +3742,7 @@ check_bidi: | |||
3741 | fail_rport_msg: | 3742 | fail_rport_msg: |
3742 | /* return the errno failure code as the only status */ | 3743 | /* return the errno failure code as the only status */ |
3743 | BUG_ON(job->reply_len < sizeof(uint32_t)); | 3744 | BUG_ON(job->reply_len < sizeof(uint32_t)); |
3745 | job->reply->reply_payload_rcv_len = 0; | ||
3744 | job->reply->result = ret; | 3746 | job->reply->result = ret; |
3745 | job->reply_len = sizeof(uint32_t); | 3747 | job->reply_len = sizeof(uint32_t); |
3746 | fc_bsg_jobdone(job); | 3748 | fc_bsg_jobdone(job); |
@@ -3797,6 +3799,7 @@ fc_bsg_request_handler(struct request_queue *q, struct Scsi_Host *shost, | |||
3797 | /* check if we have the msgcode value at least */ | 3799 | /* check if we have the msgcode value at least */ |
3798 | if (job->request_len < sizeof(uint32_t)) { | 3800 | if (job->request_len < sizeof(uint32_t)) { |
3799 | BUG_ON(job->reply_len < sizeof(uint32_t)); | 3801 | BUG_ON(job->reply_len < sizeof(uint32_t)); |
3802 | job->reply->reply_payload_rcv_len = 0; | ||
3800 | job->reply->result = -ENOMSG; | 3803 | job->reply->result = -ENOMSG; |
3801 | job->reply_len = sizeof(uint32_t); | 3804 | job->reply_len = sizeof(uint32_t); |
3802 | fc_bsg_jobdone(job); | 3805 | fc_bsg_jobdone(job); |
diff --git a/drivers/serial/suncore.c b/drivers/serial/suncore.c index a2d4a19550ab..ed7d958b0a01 100644 --- a/drivers/serial/suncore.c +++ b/drivers/serial/suncore.c | |||
@@ -53,20 +53,21 @@ void sunserial_unregister_minors(struct uart_driver *drv, int count) | |||
53 | EXPORT_SYMBOL(sunserial_unregister_minors); | 53 | EXPORT_SYMBOL(sunserial_unregister_minors); |
54 | 54 | ||
55 | int sunserial_console_match(struct console *con, struct device_node *dp, | 55 | int sunserial_console_match(struct console *con, struct device_node *dp, |
56 | struct uart_driver *drv, int line) | 56 | struct uart_driver *drv, int line, bool ignore_line) |
57 | { | 57 | { |
58 | int off; | ||
59 | |||
60 | if (!con || of_console_device != dp) | 58 | if (!con || of_console_device != dp) |
61 | return 0; | 59 | return 0; |
62 | 60 | ||
63 | off = 0; | 61 | if (!ignore_line) { |
64 | if (of_console_options && | 62 | int off = 0; |
65 | *of_console_options == 'b') | ||
66 | off = 1; | ||
67 | 63 | ||
68 | if ((line & 1) != off) | 64 | if (of_console_options && |
69 | return 0; | 65 | *of_console_options == 'b') |
66 | off = 1; | ||
67 | |||
68 | if ((line & 1) != off) | ||
69 | return 0; | ||
70 | } | ||
70 | 71 | ||
71 | con->index = line; | 72 | con->index = line; |
72 | drv->cons = con; | 73 | drv->cons = con; |
@@ -76,23 +77,24 @@ int sunserial_console_match(struct console *con, struct device_node *dp, | |||
76 | } | 77 | } |
77 | EXPORT_SYMBOL(sunserial_console_match); | 78 | EXPORT_SYMBOL(sunserial_console_match); |
78 | 79 | ||
79 | void | 80 | void sunserial_console_termios(struct console *con, struct device_node *uart_dp) |
80 | sunserial_console_termios(struct console *con) | ||
81 | { | 81 | { |
82 | struct device_node *dp; | 82 | const char *mode, *s; |
83 | const char *od, *mode, *s; | ||
84 | char mode_prop[] = "ttyX-mode"; | 83 | char mode_prop[] = "ttyX-mode"; |
85 | int baud, bits, stop, cflag; | 84 | int baud, bits, stop, cflag; |
86 | char parity; | 85 | char parity; |
87 | 86 | ||
88 | dp = of_find_node_by_path("/options"); | 87 | if (!strcmp(uart_dp->name, "rsc") || |
89 | od = of_get_property(dp, "output-device", NULL); | 88 | !strcmp(uart_dp->name, "rsc-console") || |
90 | if (!strcmp(od, "rsc")) { | 89 | !strcmp(uart_dp->name, "rsc-control")) { |
91 | mode = of_get_property(of_console_device, | 90 | mode = of_get_property(uart_dp, |
92 | "ssp-console-modes", NULL); | 91 | "ssp-console-modes", NULL); |
93 | if (!mode) | 92 | if (!mode) |
94 | mode = "115200,8,n,1,-"; | 93 | mode = "115200,8,n,1,-"; |
94 | } else if (!strcmp(uart_dp->name, "lom-console")) { | ||
95 | mode = "9600,8,n,1,-"; | ||
95 | } else { | 96 | } else { |
97 | struct device_node *dp; | ||
96 | char c; | 98 | char c; |
97 | 99 | ||
98 | c = 'a'; | 100 | c = 'a'; |
@@ -101,6 +103,7 @@ sunserial_console_termios(struct console *con) | |||
101 | 103 | ||
102 | mode_prop[3] = c; | 104 | mode_prop[3] = c; |
103 | 105 | ||
106 | dp = of_find_node_by_path("/options"); | ||
104 | mode = of_get_property(dp, mode_prop, NULL); | 107 | mode = of_get_property(dp, mode_prop, NULL); |
105 | if (!mode) | 108 | if (!mode) |
106 | mode = "9600,8,n,1,-"; | 109 | mode = "9600,8,n,1,-"; |
diff --git a/drivers/serial/suncore.h b/drivers/serial/suncore.h index 042668aa602e..db2057936c31 100644 --- a/drivers/serial/suncore.h +++ b/drivers/serial/suncore.h | |||
@@ -26,7 +26,8 @@ extern int sunserial_register_minors(struct uart_driver *, int); | |||
26 | extern void sunserial_unregister_minors(struct uart_driver *, int); | 26 | extern void sunserial_unregister_minors(struct uart_driver *, int); |
27 | 27 | ||
28 | extern int sunserial_console_match(struct console *, struct device_node *, | 28 | extern int sunserial_console_match(struct console *, struct device_node *, |
29 | struct uart_driver *, int); | 29 | struct uart_driver *, int, bool); |
30 | extern void sunserial_console_termios(struct console *); | 30 | extern void sunserial_console_termios(struct console *, |
31 | struct device_node *); | ||
31 | 32 | ||
32 | #endif /* !(_SERIAL_SUN_H) */ | 33 | #endif /* !(_SERIAL_SUN_H) */ |
diff --git a/drivers/serial/sunhv.c b/drivers/serial/sunhv.c index d548652dee50..d14cca7fb88d 100644 --- a/drivers/serial/sunhv.c +++ b/drivers/serial/sunhv.c | |||
@@ -566,7 +566,7 @@ static int __devinit hv_probe(struct of_device *op, const struct of_device_id *m | |||
566 | goto out_free_con_read_page; | 566 | goto out_free_con_read_page; |
567 | 567 | ||
568 | sunserial_console_match(&sunhv_console, op->node, | 568 | sunserial_console_match(&sunhv_console, op->node, |
569 | &sunhv_reg, port->line); | 569 | &sunhv_reg, port->line, false); |
570 | 570 | ||
571 | err = uart_add_one_port(&sunhv_reg, port); | 571 | err = uart_add_one_port(&sunhv_reg, port); |
572 | if (err) | 572 | if (err) |
diff --git a/drivers/serial/sunsab.c b/drivers/serial/sunsab.c index d1ad34128635..d514e28d0755 100644 --- a/drivers/serial/sunsab.c +++ b/drivers/serial/sunsab.c | |||
@@ -883,7 +883,7 @@ static int sunsab_console_setup(struct console *con, char *options) | |||
883 | printk("Console: ttyS%d (SAB82532)\n", | 883 | printk("Console: ttyS%d (SAB82532)\n", |
884 | (sunsab_reg.minor - 64) + con->index); | 884 | (sunsab_reg.minor - 64) + con->index); |
885 | 885 | ||
886 | sunserial_console_termios(con); | 886 | sunserial_console_termios(con, to_of_device(up->port.dev)->node); |
887 | 887 | ||
888 | switch (con->cflag & CBAUD) { | 888 | switch (con->cflag & CBAUD) { |
889 | case B150: baud = 150; break; | 889 | case B150: baud = 150; break; |
@@ -1027,10 +1027,12 @@ static int __devinit sab_probe(struct of_device *op, const struct of_device_id * | |||
1027 | goto out1; | 1027 | goto out1; |
1028 | 1028 | ||
1029 | sunserial_console_match(SUNSAB_CONSOLE(), op->node, | 1029 | sunserial_console_match(SUNSAB_CONSOLE(), op->node, |
1030 | &sunsab_reg, up[0].port.line); | 1030 | &sunsab_reg, up[0].port.line, |
1031 | false); | ||
1031 | 1032 | ||
1032 | sunserial_console_match(SUNSAB_CONSOLE(), op->node, | 1033 | sunserial_console_match(SUNSAB_CONSOLE(), op->node, |
1033 | &sunsab_reg, up[1].port.line); | 1034 | &sunsab_reg, up[1].port.line, |
1035 | false); | ||
1034 | 1036 | ||
1035 | err = uart_add_one_port(&sunsab_reg, &up[0].port); | 1037 | err = uart_add_one_port(&sunsab_reg, &up[0].port); |
1036 | if (err) | 1038 | if (err) |
@@ -1116,7 +1118,6 @@ static int __init sunsab_init(void) | |||
1116 | if (!sunsab_ports) | 1118 | if (!sunsab_ports) |
1117 | return -ENOMEM; | 1119 | return -ENOMEM; |
1118 | 1120 | ||
1119 | sunsab_reg.cons = SUNSAB_CONSOLE(); | ||
1120 | err = sunserial_register_minors(&sunsab_reg, num_channels); | 1121 | err = sunserial_register_minors(&sunsab_reg, num_channels); |
1121 | if (err) { | 1122 | if (err) { |
1122 | kfree(sunsab_ports); | 1123 | kfree(sunsab_ports); |
diff --git a/drivers/serial/sunsu.c b/drivers/serial/sunsu.c index 68d262b15749..170d3d68c8f0 100644 --- a/drivers/serial/sunsu.c +++ b/drivers/serial/sunsu.c | |||
@@ -1329,11 +1329,9 @@ static void sunsu_console_write(struct console *co, const char *s, | |||
1329 | */ | 1329 | */ |
1330 | static int __init sunsu_console_setup(struct console *co, char *options) | 1330 | static int __init sunsu_console_setup(struct console *co, char *options) |
1331 | { | 1331 | { |
1332 | static struct ktermios dummy; | ||
1333 | struct ktermios termios; | ||
1332 | struct uart_port *port; | 1334 | struct uart_port *port; |
1333 | int baud = 9600; | ||
1334 | int bits = 8; | ||
1335 | int parity = 'n'; | ||
1336 | int flow = 'n'; | ||
1337 | 1335 | ||
1338 | printk("Console: ttyS%d (SU)\n", | 1336 | printk("Console: ttyS%d (SU)\n", |
1339 | (sunsu_reg.minor - 64) + co->index); | 1337 | (sunsu_reg.minor - 64) + co->index); |
@@ -1352,10 +1350,15 @@ static int __init sunsu_console_setup(struct console *co, char *options) | |||
1352 | */ | 1350 | */ |
1353 | spin_lock_init(&port->lock); | 1351 | spin_lock_init(&port->lock); |
1354 | 1352 | ||
1355 | if (options) | 1353 | /* Get firmware console settings. */ |
1356 | uart_parse_options(options, &baud, &parity, &bits, &flow); | 1354 | sunserial_console_termios(co, to_of_device(port->dev)->node); |
1357 | 1355 | ||
1358 | return uart_set_options(port, co, baud, parity, bits, flow); | 1356 | memset(&termios, 0, sizeof(struct ktermios)); |
1357 | termios.c_cflag = co->cflag; | ||
1358 | port->mctrl |= TIOCM_DTR; | ||
1359 | port->ops->set_termios(port, &termios, &dummy); | ||
1360 | |||
1361 | return 0; | ||
1359 | } | 1362 | } |
1360 | 1363 | ||
1361 | static struct console sunsu_console = { | 1364 | static struct console sunsu_console = { |
@@ -1409,6 +1412,7 @@ static int __devinit su_probe(struct of_device *op, const struct of_device_id *m | |||
1409 | struct uart_sunsu_port *up; | 1412 | struct uart_sunsu_port *up; |
1410 | struct resource *rp; | 1413 | struct resource *rp; |
1411 | enum su_type type; | 1414 | enum su_type type; |
1415 | bool ignore_line; | ||
1412 | int err; | 1416 | int err; |
1413 | 1417 | ||
1414 | type = su_get_type(dp); | 1418 | type = su_get_type(dp); |
@@ -1467,8 +1471,14 @@ static int __devinit su_probe(struct of_device *op, const struct of_device_id *m | |||
1467 | 1471 | ||
1468 | up->port.ops = &sunsu_pops; | 1472 | up->port.ops = &sunsu_pops; |
1469 | 1473 | ||
1474 | ignore_line = false; | ||
1475 | if (!strcmp(dp->name, "rsc-console") || | ||
1476 | !strcmp(dp->name, "lom-console")) | ||
1477 | ignore_line = true; | ||
1478 | |||
1470 | sunserial_console_match(SUNSU_CONSOLE(), dp, | 1479 | sunserial_console_match(SUNSU_CONSOLE(), dp, |
1471 | &sunsu_reg, up->port.line); | 1480 | &sunsu_reg, up->port.line, |
1481 | ignore_line); | ||
1472 | err = uart_add_one_port(&sunsu_reg, &up->port); | 1482 | err = uart_add_one_port(&sunsu_reg, &up->port); |
1473 | if (err) | 1483 | if (err) |
1474 | goto out_unmap; | 1484 | goto out_unmap; |
@@ -1517,6 +1527,10 @@ static const struct of_device_id su_match[] = { | |||
1517 | .name = "serial", | 1527 | .name = "serial", |
1518 | .compatible = "su", | 1528 | .compatible = "su", |
1519 | }, | 1529 | }, |
1530 | { | ||
1531 | .type = "serial", | ||
1532 | .compatible = "su", | ||
1533 | }, | ||
1520 | {}, | 1534 | {}, |
1521 | }; | 1535 | }; |
1522 | MODULE_DEVICE_TABLE(of, su_match); | 1536 | MODULE_DEVICE_TABLE(of, su_match); |
@@ -1548,6 +1562,12 @@ static int __init sunsu_init(void) | |||
1548 | num_uart++; | 1562 | num_uart++; |
1549 | } | 1563 | } |
1550 | } | 1564 | } |
1565 | for_each_node_by_type(dp, "serial") { | ||
1566 | if (of_device_is_compatible(dp, "su")) { | ||
1567 | if (su_get_type(dp) == SU_PORT_PORT) | ||
1568 | num_uart++; | ||
1569 | } | ||
1570 | } | ||
1551 | 1571 | ||
1552 | if (num_uart) { | 1572 | if (num_uart) { |
1553 | err = sunserial_register_minors(&sunsu_reg, num_uart); | 1573 | err = sunserial_register_minors(&sunsu_reg, num_uart); |
diff --git a/drivers/serial/sunzilog.c b/drivers/serial/sunzilog.c index ef693ae22e7f..2c7a66af4f52 100644 --- a/drivers/serial/sunzilog.c +++ b/drivers/serial/sunzilog.c | |||
@@ -1180,7 +1180,7 @@ static int __init sunzilog_console_setup(struct console *con, char *options) | |||
1180 | (sunzilog_reg.minor - 64) + con->index, con->index); | 1180 | (sunzilog_reg.minor - 64) + con->index, con->index); |
1181 | 1181 | ||
1182 | /* Get firmware console settings. */ | 1182 | /* Get firmware console settings. */ |
1183 | sunserial_console_termios(con); | 1183 | sunserial_console_termios(con, to_of_device(up->port.dev)->node); |
1184 | 1184 | ||
1185 | /* Firmware console speed is limited to 150-->38400 baud so | 1185 | /* Firmware console speed is limited to 150-->38400 baud so |
1186 | * this hackish cflag thing is OK. | 1186 | * this hackish cflag thing is OK. |
@@ -1416,7 +1416,8 @@ static int __devinit zs_probe(struct of_device *op, const struct of_device_id *m | |||
1416 | 1416 | ||
1417 | if (!keyboard_mouse) { | 1417 | if (!keyboard_mouse) { |
1418 | if (sunserial_console_match(SUNZILOG_CONSOLE(), op->node, | 1418 | if (sunserial_console_match(SUNZILOG_CONSOLE(), op->node, |
1419 | &sunzilog_reg, up[0].port.line)) | 1419 | &sunzilog_reg, up[0].port.line, |
1420 | false)) | ||
1420 | up->flags |= SUNZILOG_FLAG_IS_CONS; | 1421 | up->flags |= SUNZILOG_FLAG_IS_CONS; |
1421 | err = uart_add_one_port(&sunzilog_reg, &up[0].port); | 1422 | err = uart_add_one_port(&sunzilog_reg, &up[0].port); |
1422 | if (err) { | 1423 | if (err) { |
@@ -1425,7 +1426,8 @@ static int __devinit zs_probe(struct of_device *op, const struct of_device_id *m | |||
1425 | return err; | 1426 | return err; |
1426 | } | 1427 | } |
1427 | if (sunserial_console_match(SUNZILOG_CONSOLE(), op->node, | 1428 | if (sunserial_console_match(SUNZILOG_CONSOLE(), op->node, |
1428 | &sunzilog_reg, up[1].port.line)) | 1429 | &sunzilog_reg, up[1].port.line, |
1430 | false)) | ||
1429 | up->flags |= SUNZILOG_FLAG_IS_CONS; | 1431 | up->flags |= SUNZILOG_FLAG_IS_CONS; |
1430 | err = uart_add_one_port(&sunzilog_reg, &up[1].port); | 1432 | err = uart_add_one_port(&sunzilog_reg, &up[1].port); |
1431 | if (err) { | 1433 | if (err) { |
diff --git a/drivers/spi/spi_stmp.c b/drivers/spi/spi_stmp.c index d871dc23909c..2552bb364005 100644 --- a/drivers/spi/spi_stmp.c +++ b/drivers/spi/spi_stmp.c | |||
@@ -242,7 +242,7 @@ static int stmp_spi_txrx_dma(struct stmp_spi *ss, int cs, | |||
242 | wait_for_completion(&ss->done); | 242 | wait_for_completion(&ss->done); |
243 | 243 | ||
244 | if (!busy_wait(readl(ss->regs + HW_SSP_CTRL0) & BM_SSP_CTRL0_RUN)) | 244 | if (!busy_wait(readl(ss->regs + HW_SSP_CTRL0) & BM_SSP_CTRL0_RUN)) |
245 | status = ETIMEDOUT; | 245 | status = -ETIMEDOUT; |
246 | 246 | ||
247 | if (!dma_buf) | 247 | if (!dma_buf) |
248 | dma_unmap_single(ss->master_dev, spi_buf_dma, len, dir); | 248 | dma_unmap_single(ss->master_dev, spi_buf_dma, len, dir); |
diff --git a/drivers/ssb/scan.c b/drivers/ssb/scan.c index b74212d698c7..e8b89e8ac9bd 100644 --- a/drivers/ssb/scan.c +++ b/drivers/ssb/scan.c | |||
@@ -162,6 +162,8 @@ static u8 chipid_to_nrcores(u16 chipid) | |||
162 | static u32 scan_read32(struct ssb_bus *bus, u8 current_coreidx, | 162 | static u32 scan_read32(struct ssb_bus *bus, u8 current_coreidx, |
163 | u16 offset) | 163 | u16 offset) |
164 | { | 164 | { |
165 | u32 lo, hi; | ||
166 | |||
165 | switch (bus->bustype) { | 167 | switch (bus->bustype) { |
166 | case SSB_BUSTYPE_SSB: | 168 | case SSB_BUSTYPE_SSB: |
167 | offset += current_coreidx * SSB_CORE_SIZE; | 169 | offset += current_coreidx * SSB_CORE_SIZE; |
@@ -174,7 +176,9 @@ static u32 scan_read32(struct ssb_bus *bus, u8 current_coreidx, | |||
174 | offset -= 0x800; | 176 | offset -= 0x800; |
175 | } else | 177 | } else |
176 | ssb_pcmcia_switch_segment(bus, 0); | 178 | ssb_pcmcia_switch_segment(bus, 0); |
177 | break; | 179 | lo = readw(bus->mmio + offset); |
180 | hi = readw(bus->mmio + offset + 2); | ||
181 | return lo | (hi << 16); | ||
178 | case SSB_BUSTYPE_SDIO: | 182 | case SSB_BUSTYPE_SDIO: |
179 | offset += current_coreidx * SSB_CORE_SIZE; | 183 | offset += current_coreidx * SSB_CORE_SIZE; |
180 | return ssb_sdio_scan_read32(bus, offset); | 184 | return ssb_sdio_scan_read32(bus, offset); |
diff --git a/drivers/staging/go7007/s2250-board.c b/drivers/staging/go7007/s2250-board.c index 8c85a9c3665a..f4a6541c3e60 100644 --- a/drivers/staging/go7007/s2250-board.c +++ b/drivers/staging/go7007/s2250-board.c | |||
@@ -261,7 +261,7 @@ static int read_reg_fp(struct i2c_client *client, u16 addr, u16 *val) | |||
261 | 261 | ||
262 | memset(buf, 0xcd, 6); | 262 | memset(buf, 0xcd, 6); |
263 | usb = go->hpi_context; | 263 | usb = go->hpi_context; |
264 | if (down_interruptible(&usb->i2c_lock) != 0) { | 264 | if (mutex_lock_interruptible(&usb->i2c_lock) != 0) { |
265 | printk(KERN_INFO "i2c lock failed\n"); | 265 | printk(KERN_INFO "i2c lock failed\n"); |
266 | kfree(buf); | 266 | kfree(buf); |
267 | return -EINTR; | 267 | return -EINTR; |
@@ -270,7 +270,7 @@ static int read_reg_fp(struct i2c_client *client, u16 addr, u16 *val) | |||
270 | kfree(buf); | 270 | kfree(buf); |
271 | return -EFAULT; | 271 | return -EFAULT; |
272 | } | 272 | } |
273 | up(&usb->i2c_lock); | 273 | mutex_unlock(&usb->i2c_lock); |
274 | 274 | ||
275 | *val = (buf[0] << 8) | buf[1]; | 275 | *val = (buf[0] << 8) | buf[1]; |
276 | kfree(buf); | 276 | kfree(buf); |
diff --git a/drivers/staging/go7007/s2250-loader.h b/drivers/staging/go7007/s2250-loader.h new file mode 100644 index 000000000000..b7c301af16cc --- /dev/null +++ b/drivers/staging/go7007/s2250-loader.h | |||
@@ -0,0 +1,24 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2005-2006 Micronas USA Inc. | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License (Version 2) as | ||
6 | * published by the Free Software Foundation. | ||
7 | * | ||
8 | * This program is distributed in the hope that it will be useful, | ||
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
11 | * GNU General Public License for more details. | ||
12 | * | ||
13 | * You should have received a copy of the GNU General Public License | ||
14 | * along with this program; if not, write to the Free Software Foundation, | ||
15 | * Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. | ||
16 | */ | ||
17 | |||
18 | #ifndef _S2250_LOADER_H_ | ||
19 | #define _S2250_LOADER_H_ | ||
20 | |||
21 | extern int s2250loader_init(void); | ||
22 | extern void s2250loader_cleanup(void); | ||
23 | |||
24 | #endif | ||
diff --git a/drivers/staging/octeon/ethernet-mdio.c b/drivers/staging/octeon/ethernet-mdio.c index 42230e62a222..31a58e508924 100644 --- a/drivers/staging/octeon/ethernet-mdio.c +++ b/drivers/staging/octeon/ethernet-mdio.c | |||
@@ -170,7 +170,7 @@ static u32 cvm_oct_get_link(struct net_device *dev) | |||
170 | return ret; | 170 | return ret; |
171 | } | 171 | } |
172 | 172 | ||
173 | struct const ethtool_ops cvm_oct_ethtool_ops = { | 173 | const struct ethtool_ops cvm_oct_ethtool_ops = { |
174 | .get_drvinfo = cvm_oct_get_drvinfo, | 174 | .get_drvinfo = cvm_oct_get_drvinfo, |
175 | .get_settings = cvm_oct_get_settings, | 175 | .get_settings = cvm_oct_get_settings, |
176 | .set_settings = cvm_oct_set_settings, | 176 | .set_settings = cvm_oct_set_settings, |
diff --git a/drivers/staging/octeon/ethernet-spi.c b/drivers/staging/octeon/ethernet-spi.c index 66190b0cb68f..00dc0f4bad19 100644 --- a/drivers/staging/octeon/ethernet-spi.c +++ b/drivers/staging/octeon/ethernet-spi.c | |||
@@ -317,6 +317,6 @@ void cvm_oct_spi_uninit(struct net_device *dev) | |||
317 | cvmx_write_csr(CVMX_SPXX_INT_MSK(interface), 0); | 317 | cvmx_write_csr(CVMX_SPXX_INT_MSK(interface), 0); |
318 | cvmx_write_csr(CVMX_STXX_INT_MSK(interface), 0); | 318 | cvmx_write_csr(CVMX_STXX_INT_MSK(interface), 0); |
319 | } | 319 | } |
320 | free_irq(8 + 46, &number_spi_ports); | 320 | free_irq(OCTEON_IRQ_RML, &number_spi_ports); |
321 | } | 321 | } |
322 | } | 322 | } |
diff --git a/drivers/staging/octeon/ethernet.c b/drivers/staging/octeon/ethernet.c index b8479517dce2..492c5029992d 100644 --- a/drivers/staging/octeon/ethernet.c +++ b/drivers/staging/octeon/ethernet.c | |||
@@ -111,6 +111,16 @@ MODULE_PARM_DESC(disable_core_queueing, "\n" | |||
111 | "\tallows packets to be sent without lock contention in the packet\n" | 111 | "\tallows packets to be sent without lock contention in the packet\n" |
112 | "\tscheduler resulting in some cases in improved throughput.\n"); | 112 | "\tscheduler resulting in some cases in improved throughput.\n"); |
113 | 113 | ||
114 | |||
115 | /* | ||
116 | * The offset from mac_addr_base that should be used for the next port | ||
117 | * that is configured. By convention, if any mgmt ports exist on the | ||
118 | * chip, they get the first mac addresses, The ports controlled by | ||
119 | * this driver are numbered sequencially following any mgmt addresses | ||
120 | * that may exist. | ||
121 | */ | ||
122 | static unsigned int cvm_oct_mac_addr_offset; | ||
123 | |||
114 | /** | 124 | /** |
115 | * Periodic timer to check auto negotiation | 125 | * Periodic timer to check auto negotiation |
116 | */ | 126 | */ |
@@ -474,16 +484,30 @@ static int cvm_oct_common_set_mac_address(struct net_device *dev, void *addr) | |||
474 | */ | 484 | */ |
475 | int cvm_oct_common_init(struct net_device *dev) | 485 | int cvm_oct_common_init(struct net_device *dev) |
476 | { | 486 | { |
477 | static int count; | ||
478 | char mac[8] = { 0x00, 0x00, | ||
479 | octeon_bootinfo->mac_addr_base[0], | ||
480 | octeon_bootinfo->mac_addr_base[1], | ||
481 | octeon_bootinfo->mac_addr_base[2], | ||
482 | octeon_bootinfo->mac_addr_base[3], | ||
483 | octeon_bootinfo->mac_addr_base[4], | ||
484 | octeon_bootinfo->mac_addr_base[5] + count | ||
485 | }; | ||
486 | struct octeon_ethernet *priv = netdev_priv(dev); | 487 | struct octeon_ethernet *priv = netdev_priv(dev); |
488 | struct sockaddr sa; | ||
489 | u64 mac = ((u64)(octeon_bootinfo->mac_addr_base[0] & 0xff) << 40) | | ||
490 | ((u64)(octeon_bootinfo->mac_addr_base[1] & 0xff) << 32) | | ||
491 | ((u64)(octeon_bootinfo->mac_addr_base[2] & 0xff) << 24) | | ||
492 | ((u64)(octeon_bootinfo->mac_addr_base[3] & 0xff) << 16) | | ||
493 | ((u64)(octeon_bootinfo->mac_addr_base[4] & 0xff) << 8) | | ||
494 | (u64)(octeon_bootinfo->mac_addr_base[5] & 0xff); | ||
495 | |||
496 | mac += cvm_oct_mac_addr_offset; | ||
497 | sa.sa_data[0] = (mac >> 40) & 0xff; | ||
498 | sa.sa_data[1] = (mac >> 32) & 0xff; | ||
499 | sa.sa_data[2] = (mac >> 24) & 0xff; | ||
500 | sa.sa_data[3] = (mac >> 16) & 0xff; | ||
501 | sa.sa_data[4] = (mac >> 8) & 0xff; | ||
502 | sa.sa_data[5] = mac & 0xff; | ||
503 | |||
504 | if (cvm_oct_mac_addr_offset >= octeon_bootinfo->mac_addr_count) | ||
505 | printk(KERN_DEBUG "%s: Using MAC outside of the assigned range:" | ||
506 | " %02x:%02x:%02x:%02x:%02x:%02x\n", dev->name, | ||
507 | sa.sa_data[0] & 0xff, sa.sa_data[1] & 0xff, | ||
508 | sa.sa_data[2] & 0xff, sa.sa_data[3] & 0xff, | ||
509 | sa.sa_data[4] & 0xff, sa.sa_data[5] & 0xff); | ||
510 | cvm_oct_mac_addr_offset++; | ||
487 | 511 | ||
488 | /* | 512 | /* |
489 | * Force the interface to use the POW send if always_use_pow | 513 | * Force the interface to use the POW send if always_use_pow |
@@ -496,14 +520,12 @@ int cvm_oct_common_init(struct net_device *dev) | |||
496 | if (priv->queue != -1 && USE_HW_TCPUDP_CHECKSUM) | 520 | if (priv->queue != -1 && USE_HW_TCPUDP_CHECKSUM) |
497 | dev->features |= NETIF_F_IP_CSUM; | 521 | dev->features |= NETIF_F_IP_CSUM; |
498 | 522 | ||
499 | count++; | ||
500 | |||
501 | /* We do our own locking, Linux doesn't need to */ | 523 | /* We do our own locking, Linux doesn't need to */ |
502 | dev->features |= NETIF_F_LLTX; | 524 | dev->features |= NETIF_F_LLTX; |
503 | SET_ETHTOOL_OPS(dev, &cvm_oct_ethtool_ops); | 525 | SET_ETHTOOL_OPS(dev, &cvm_oct_ethtool_ops); |
504 | 526 | ||
505 | cvm_oct_mdio_setup_device(dev); | 527 | cvm_oct_mdio_setup_device(dev); |
506 | dev->netdev_ops->ndo_set_mac_address(dev, mac); | 528 | dev->netdev_ops->ndo_set_mac_address(dev, &sa); |
507 | dev->netdev_ops->ndo_change_mtu(dev, dev->mtu); | 529 | dev->netdev_ops->ndo_change_mtu(dev, dev->mtu); |
508 | 530 | ||
509 | /* | 531 | /* |
@@ -620,6 +642,13 @@ static int __init cvm_oct_init_module(void) | |||
620 | 642 | ||
621 | pr_notice("cavium-ethernet %s\n", OCTEON_ETHERNET_VERSION); | 643 | pr_notice("cavium-ethernet %s\n", OCTEON_ETHERNET_VERSION); |
622 | 644 | ||
645 | if (OCTEON_IS_MODEL(OCTEON_CN52XX)) | ||
646 | cvm_oct_mac_addr_offset = 2; /* First two are the mgmt ports. */ | ||
647 | else if (OCTEON_IS_MODEL(OCTEON_CN56XX)) | ||
648 | cvm_oct_mac_addr_offset = 1; /* First one is the mgmt port. */ | ||
649 | else | ||
650 | cvm_oct_mac_addr_offset = 0; | ||
651 | |||
623 | cvm_oct_proc_initialize(); | 652 | cvm_oct_proc_initialize(); |
624 | cvm_oct_rx_initialize(); | 653 | cvm_oct_rx_initialize(); |
625 | cvm_oct_configure_common_hw(); | 654 | cvm_oct_configure_common_hw(); |
diff --git a/drivers/uio/uio_pdrv_genirq.c b/drivers/uio/uio_pdrv_genirq.c index 02347c57357d..aa53db9f2e88 100644 --- a/drivers/uio/uio_pdrv_genirq.c +++ b/drivers/uio/uio_pdrv_genirq.c | |||
@@ -178,6 +178,7 @@ static int uio_pdrv_genirq_probe(struct platform_device *pdev) | |||
178 | return 0; | 178 | return 0; |
179 | bad1: | 179 | bad1: |
180 | kfree(priv); | 180 | kfree(priv); |
181 | pm_runtime_disable(&pdev->dev); | ||
181 | bad0: | 182 | bad0: |
182 | return ret; | 183 | return ret; |
183 | } | 184 | } |
diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c index e3861b21e776..e4eca7810bcf 100644 --- a/drivers/usb/class/cdc-acm.c +++ b/drivers/usb/class/cdc-acm.c | |||
@@ -609,9 +609,9 @@ static int acm_tty_open(struct tty_struct *tty, struct file *filp) | |||
609 | 609 | ||
610 | acm->throttle = 0; | 610 | acm->throttle = 0; |
611 | 611 | ||
612 | tasklet_schedule(&acm->urb_task); | ||
613 | set_bit(ASYNCB_INITIALIZED, &acm->port.flags); | 612 | set_bit(ASYNCB_INITIALIZED, &acm->port.flags); |
614 | rv = tty_port_block_til_ready(&acm->port, tty, filp); | 613 | rv = tty_port_block_til_ready(&acm->port, tty, filp); |
614 | tasklet_schedule(&acm->urb_task); | ||
615 | done: | 615 | done: |
616 | mutex_unlock(&acm->mutex); | 616 | mutex_unlock(&acm->mutex); |
617 | err_out: | 617 | err_out: |
@@ -686,15 +686,21 @@ static void acm_tty_close(struct tty_struct *tty, struct file *filp) | |||
686 | 686 | ||
687 | /* Perform the closing process and see if we need to do the hardware | 687 | /* Perform the closing process and see if we need to do the hardware |
688 | shutdown */ | 688 | shutdown */ |
689 | if (!acm || tty_port_close_start(&acm->port, tty, filp) == 0) | 689 | if (!acm) |
690 | return; | ||
691 | if (tty_port_close_start(&acm->port, tty, filp) == 0) { | ||
692 | mutex_lock(&open_mutex); | ||
693 | if (!acm->dev) { | ||
694 | tty_port_tty_set(&acm->port, NULL); | ||
695 | acm_tty_unregister(acm); | ||
696 | tty->driver_data = NULL; | ||
697 | } | ||
698 | mutex_unlock(&open_mutex); | ||
690 | return; | 699 | return; |
700 | } | ||
691 | acm_port_down(acm, 0); | 701 | acm_port_down(acm, 0); |
692 | tty_port_close_end(&acm->port, tty); | 702 | tty_port_close_end(&acm->port, tty); |
693 | mutex_lock(&open_mutex); | ||
694 | tty_port_tty_set(&acm->port, NULL); | 703 | tty_port_tty_set(&acm->port, NULL); |
695 | if (!acm->dev) | ||
696 | acm_tty_unregister(acm); | ||
697 | mutex_unlock(&open_mutex); | ||
698 | } | 704 | } |
699 | 705 | ||
700 | static int acm_tty_write(struct tty_struct *tty, | 706 | static int acm_tty_write(struct tty_struct *tty, |
diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c index 78bb7710f36d..24eb74781919 100644 --- a/drivers/usb/host/ohci-hcd.c +++ b/drivers/usb/host/ohci-hcd.c | |||
@@ -87,6 +87,7 @@ static int ohci_restart (struct ohci_hcd *ohci); | |||
87 | #ifdef CONFIG_PCI | 87 | #ifdef CONFIG_PCI |
88 | static void quirk_amd_pll(int state); | 88 | static void quirk_amd_pll(int state); |
89 | static void amd_iso_dev_put(void); | 89 | static void amd_iso_dev_put(void); |
90 | static void sb800_prefetch(struct ohci_hcd *ohci, int on); | ||
90 | #else | 91 | #else |
91 | static inline void quirk_amd_pll(int state) | 92 | static inline void quirk_amd_pll(int state) |
92 | { | 93 | { |
@@ -96,6 +97,10 @@ static inline void amd_iso_dev_put(void) | |||
96 | { | 97 | { |
97 | return; | 98 | return; |
98 | } | 99 | } |
100 | static inline void sb800_prefetch(struct ohci_hcd *ohci, int on) | ||
101 | { | ||
102 | return; | ||
103 | } | ||
99 | #endif | 104 | #endif |
100 | 105 | ||
101 | 106 | ||
diff --git a/drivers/usb/host/ohci-pci.c b/drivers/usb/host/ohci-pci.c index d2ba04dd785e..b8a1148f248e 100644 --- a/drivers/usb/host/ohci-pci.c +++ b/drivers/usb/host/ohci-pci.c | |||
@@ -177,6 +177,13 @@ static int ohci_quirk_amd700(struct usb_hcd *hcd) | |||
177 | return 0; | 177 | return 0; |
178 | 178 | ||
179 | pci_read_config_byte(amd_smbus_dev, PCI_REVISION_ID, &rev); | 179 | pci_read_config_byte(amd_smbus_dev, PCI_REVISION_ID, &rev); |
180 | |||
181 | /* SB800 needs pre-fetch fix */ | ||
182 | if ((rev >= 0x40) && (rev <= 0x4f)) { | ||
183 | ohci->flags |= OHCI_QUIRK_AMD_PREFETCH; | ||
184 | ohci_dbg(ohci, "enabled AMD prefetch quirk\n"); | ||
185 | } | ||
186 | |||
180 | if ((rev > 0x3b) || (rev < 0x30)) { | 187 | if ((rev > 0x3b) || (rev < 0x30)) { |
181 | pci_dev_put(amd_smbus_dev); | 188 | pci_dev_put(amd_smbus_dev); |
182 | amd_smbus_dev = NULL; | 189 | amd_smbus_dev = NULL; |
@@ -262,6 +269,19 @@ static void amd_iso_dev_put(void) | |||
262 | 269 | ||
263 | } | 270 | } |
264 | 271 | ||
272 | static void sb800_prefetch(struct ohci_hcd *ohci, int on) | ||
273 | { | ||
274 | struct pci_dev *pdev; | ||
275 | u16 misc; | ||
276 | |||
277 | pdev = to_pci_dev(ohci_to_hcd(ohci)->self.controller); | ||
278 | pci_read_config_word(pdev, 0x50, &misc); | ||
279 | if (on == 0) | ||
280 | pci_write_config_word(pdev, 0x50, misc & 0xfcff); | ||
281 | else | ||
282 | pci_write_config_word(pdev, 0x50, misc | 0x0300); | ||
283 | } | ||
284 | |||
265 | /* List of quirks for OHCI */ | 285 | /* List of quirks for OHCI */ |
266 | static const struct pci_device_id ohci_pci_quirks[] = { | 286 | static const struct pci_device_id ohci_pci_quirks[] = { |
267 | { | 287 | { |
diff --git a/drivers/usb/host/ohci-q.c b/drivers/usb/host/ohci-q.c index 16fecb8ecc39..35288bcae0db 100644 --- a/drivers/usb/host/ohci-q.c +++ b/drivers/usb/host/ohci-q.c | |||
@@ -49,9 +49,12 @@ __acquires(ohci->lock) | |||
49 | switch (usb_pipetype (urb->pipe)) { | 49 | switch (usb_pipetype (urb->pipe)) { |
50 | case PIPE_ISOCHRONOUS: | 50 | case PIPE_ISOCHRONOUS: |
51 | ohci_to_hcd(ohci)->self.bandwidth_isoc_reqs--; | 51 | ohci_to_hcd(ohci)->self.bandwidth_isoc_reqs--; |
52 | if (ohci_to_hcd(ohci)->self.bandwidth_isoc_reqs == 0 | 52 | if (ohci_to_hcd(ohci)->self.bandwidth_isoc_reqs == 0) { |
53 | && quirk_amdiso(ohci)) | 53 | if (quirk_amdiso(ohci)) |
54 | quirk_amd_pll(1); | 54 | quirk_amd_pll(1); |
55 | if (quirk_amdprefetch(ohci)) | ||
56 | sb800_prefetch(ohci, 0); | ||
57 | } | ||
55 | break; | 58 | break; |
56 | case PIPE_INTERRUPT: | 59 | case PIPE_INTERRUPT: |
57 | ohci_to_hcd(ohci)->self.bandwidth_int_reqs--; | 60 | ohci_to_hcd(ohci)->self.bandwidth_int_reqs--; |
@@ -680,9 +683,12 @@ static void td_submit_urb ( | |||
680 | data + urb->iso_frame_desc [cnt].offset, | 683 | data + urb->iso_frame_desc [cnt].offset, |
681 | urb->iso_frame_desc [cnt].length, urb, cnt); | 684 | urb->iso_frame_desc [cnt].length, urb, cnt); |
682 | } | 685 | } |
683 | if (ohci_to_hcd(ohci)->self.bandwidth_isoc_reqs == 0 | 686 | if (ohci_to_hcd(ohci)->self.bandwidth_isoc_reqs == 0) { |
684 | && quirk_amdiso(ohci)) | 687 | if (quirk_amdiso(ohci)) |
685 | quirk_amd_pll(0); | 688 | quirk_amd_pll(0); |
689 | if (quirk_amdprefetch(ohci)) | ||
690 | sb800_prefetch(ohci, 1); | ||
691 | } | ||
686 | periodic = ohci_to_hcd(ohci)->self.bandwidth_isoc_reqs++ == 0 | 692 | periodic = ohci_to_hcd(ohci)->self.bandwidth_isoc_reqs++ == 0 |
687 | && ohci_to_hcd(ohci)->self.bandwidth_int_reqs == 0; | 693 | && ohci_to_hcd(ohci)->self.bandwidth_int_reqs == 0; |
688 | break; | 694 | break; |
diff --git a/drivers/usb/host/ohci.h b/drivers/usb/host/ohci.h index 222011f6172c..5bf15fed0d9f 100644 --- a/drivers/usb/host/ohci.h +++ b/drivers/usb/host/ohci.h | |||
@@ -402,6 +402,7 @@ struct ohci_hcd { | |||
402 | #define OHCI_QUIRK_FRAME_NO 0x80 /* no big endian frame_no shift */ | 402 | #define OHCI_QUIRK_FRAME_NO 0x80 /* no big endian frame_no shift */ |
403 | #define OHCI_QUIRK_HUB_POWER 0x100 /* distrust firmware power/oc setup */ | 403 | #define OHCI_QUIRK_HUB_POWER 0x100 /* distrust firmware power/oc setup */ |
404 | #define OHCI_QUIRK_AMD_ISO 0x200 /* ISO transfers*/ | 404 | #define OHCI_QUIRK_AMD_ISO 0x200 /* ISO transfers*/ |
405 | #define OHCI_QUIRK_AMD_PREFETCH 0x400 /* pre-fetch for ISO transfer */ | ||
405 | // there are also chip quirks/bugs in init logic | 406 | // there are also chip quirks/bugs in init logic |
406 | 407 | ||
407 | struct work_struct nec_work; /* Worker for NEC quirk */ | 408 | struct work_struct nec_work; /* Worker for NEC quirk */ |
@@ -433,6 +434,10 @@ static inline int quirk_amdiso(struct ohci_hcd *ohci) | |||
433 | { | 434 | { |
434 | return ohci->flags & OHCI_QUIRK_AMD_ISO; | 435 | return ohci->flags & OHCI_QUIRK_AMD_ISO; |
435 | } | 436 | } |
437 | static inline int quirk_amdprefetch(struct ohci_hcd *ohci) | ||
438 | { | ||
439 | return ohci->flags & OHCI_QUIRK_AMD_PREFETCH; | ||
440 | } | ||
436 | #else | 441 | #else |
437 | static inline int quirk_nec(struct ohci_hcd *ohci) | 442 | static inline int quirk_nec(struct ohci_hcd *ohci) |
438 | { | 443 | { |
@@ -446,6 +451,10 @@ static inline int quirk_amdiso(struct ohci_hcd *ohci) | |||
446 | { | 451 | { |
447 | return 0; | 452 | return 0; |
448 | } | 453 | } |
454 | static inline int quirk_amdprefetch(struct ohci_hcd *ohci) | ||
455 | { | ||
456 | return 0; | ||
457 | } | ||
449 | #endif | 458 | #endif |
450 | 459 | ||
451 | /* convert between an hcd pointer and the corresponding ohci_hcd */ | 460 | /* convert between an hcd pointer and the corresponding ohci_hcd */ |
diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c index 1db4fea8c170..b8fd270a8b0d 100644 --- a/drivers/usb/host/xhci-mem.c +++ b/drivers/usb/host/xhci-mem.c | |||
@@ -802,9 +802,11 @@ void xhci_mem_cleanup(struct xhci_hcd *xhci) | |||
802 | int i; | 802 | int i; |
803 | 803 | ||
804 | /* Free the Event Ring Segment Table and the actual Event Ring */ | 804 | /* Free the Event Ring Segment Table and the actual Event Ring */ |
805 | xhci_writel(xhci, 0, &xhci->ir_set->erst_size); | 805 | if (xhci->ir_set) { |
806 | xhci_write_64(xhci, 0, &xhci->ir_set->erst_base); | 806 | xhci_writel(xhci, 0, &xhci->ir_set->erst_size); |
807 | xhci_write_64(xhci, 0, &xhci->ir_set->erst_dequeue); | 807 | xhci_write_64(xhci, 0, &xhci->ir_set->erst_base); |
808 | xhci_write_64(xhci, 0, &xhci->ir_set->erst_dequeue); | ||
809 | } | ||
808 | size = sizeof(struct xhci_erst_entry)*(xhci->erst.num_entries); | 810 | size = sizeof(struct xhci_erst_entry)*(xhci->erst.num_entries); |
809 | if (xhci->erst.entries) | 811 | if (xhci->erst.entries) |
810 | pci_free_consistent(pdev, size, | 812 | pci_free_consistent(pdev, size, |
@@ -841,9 +843,9 @@ void xhci_mem_cleanup(struct xhci_hcd *xhci) | |||
841 | xhci->dcbaa, xhci->dcbaa->dma); | 843 | xhci->dcbaa, xhci->dcbaa->dma); |
842 | xhci->dcbaa = NULL; | 844 | xhci->dcbaa = NULL; |
843 | 845 | ||
846 | scratchpad_free(xhci); | ||
844 | xhci->page_size = 0; | 847 | xhci->page_size = 0; |
845 | xhci->page_shift = 0; | 848 | xhci->page_shift = 0; |
846 | scratchpad_free(xhci); | ||
847 | } | 849 | } |
848 | 850 | ||
849 | int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags) | 851 | int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags) |
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index 173c39c76489..821b7b4709de 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c | |||
@@ -864,9 +864,11 @@ static struct xhci_segment *trb_in_td( | |||
864 | cur_seg = start_seg; | 864 | cur_seg = start_seg; |
865 | 865 | ||
866 | do { | 866 | do { |
867 | if (start_dma == 0) | ||
868 | return 0; | ||
867 | /* We may get an event for a Link TRB in the middle of a TD */ | 869 | /* We may get an event for a Link TRB in the middle of a TD */ |
868 | end_seg_dma = xhci_trb_virt_to_dma(cur_seg, | 870 | end_seg_dma = xhci_trb_virt_to_dma(cur_seg, |
869 | &start_seg->trbs[TRBS_PER_SEGMENT - 1]); | 871 | &cur_seg->trbs[TRBS_PER_SEGMENT - 1]); |
870 | /* If the end TRB isn't in this segment, this is set to 0 */ | 872 | /* If the end TRB isn't in this segment, this is set to 0 */ |
871 | end_trb_dma = xhci_trb_virt_to_dma(cur_seg, end_trb); | 873 | end_trb_dma = xhci_trb_virt_to_dma(cur_seg, end_trb); |
872 | 874 | ||
@@ -893,8 +895,9 @@ static struct xhci_segment *trb_in_td( | |||
893 | } | 895 | } |
894 | cur_seg = cur_seg->next; | 896 | cur_seg = cur_seg->next; |
895 | start_dma = xhci_trb_virt_to_dma(cur_seg, &cur_seg->trbs[0]); | 897 | start_dma = xhci_trb_virt_to_dma(cur_seg, &cur_seg->trbs[0]); |
896 | } while (1); | 898 | } while (cur_seg != start_seg); |
897 | 899 | ||
900 | return 0; | ||
898 | } | 901 | } |
899 | 902 | ||
900 | /* | 903 | /* |
diff --git a/drivers/usb/mon/mon_bin.c b/drivers/usb/mon/mon_bin.c index 9ed3e741bee1..10f3205798e8 100644 --- a/drivers/usb/mon/mon_bin.c +++ b/drivers/usb/mon/mon_bin.c | |||
@@ -348,12 +348,12 @@ static unsigned int mon_buff_area_alloc_contiguous(struct mon_reader_bin *rp, | |||
348 | 348 | ||
349 | /* | 349 | /* |
350 | * Return a few (kilo-)bytes to the head of the buffer. | 350 | * Return a few (kilo-)bytes to the head of the buffer. |
351 | * This is used if a DMA fetch fails. | 351 | * This is used if a data fetch fails. |
352 | */ | 352 | */ |
353 | static void mon_buff_area_shrink(struct mon_reader_bin *rp, unsigned int size) | 353 | static void mon_buff_area_shrink(struct mon_reader_bin *rp, unsigned int size) |
354 | { | 354 | { |
355 | 355 | ||
356 | size = (size + PKT_ALIGN-1) & ~(PKT_ALIGN-1); | 356 | /* size &= ~(PKT_ALIGN-1); -- we're called with aligned size */ |
357 | rp->b_cnt -= size; | 357 | rp->b_cnt -= size; |
358 | if (rp->b_in < size) | 358 | if (rp->b_in < size) |
359 | rp->b_in += rp->b_size; | 359 | rp->b_in += rp->b_size; |
@@ -433,6 +433,7 @@ static void mon_bin_event(struct mon_reader_bin *rp, struct urb *urb, | |||
433 | unsigned int urb_length; | 433 | unsigned int urb_length; |
434 | unsigned int offset; | 434 | unsigned int offset; |
435 | unsigned int length; | 435 | unsigned int length; |
436 | unsigned int delta; | ||
436 | unsigned int ndesc, lendesc; | 437 | unsigned int ndesc, lendesc; |
437 | unsigned char dir; | 438 | unsigned char dir; |
438 | struct mon_bin_hdr *ep; | 439 | struct mon_bin_hdr *ep; |
@@ -537,8 +538,10 @@ static void mon_bin_event(struct mon_reader_bin *rp, struct urb *urb, | |||
537 | if (length != 0) { | 538 | if (length != 0) { |
538 | ep->flag_data = mon_bin_get_data(rp, offset, urb, length); | 539 | ep->flag_data = mon_bin_get_data(rp, offset, urb, length); |
539 | if (ep->flag_data != 0) { /* Yes, it's 0x00, not '0' */ | 540 | if (ep->flag_data != 0) { /* Yes, it's 0x00, not '0' */ |
540 | ep->len_cap = 0; | 541 | delta = (ep->len_cap + PKT_ALIGN-1) & ~(PKT_ALIGN-1); |
541 | mon_buff_area_shrink(rp, length); | 542 | ep->len_cap -= length; |
543 | delta -= (ep->len_cap + PKT_ALIGN-1) & ~(PKT_ALIGN-1); | ||
544 | mon_buff_area_shrink(rp, delta); | ||
542 | } | 545 | } |
543 | } else { | 546 | } else { |
544 | ep->flag_data = data_tag; | 547 | ep->flag_data = data_tag; |
diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c index 698252a4dc5d..bd254ec97d14 100644 --- a/drivers/usb/serial/cp210x.c +++ b/drivers/usb/serial/cp210x.c | |||
@@ -50,6 +50,8 @@ static int cp210x_tiocmset_port(struct usb_serial_port *port, struct file *, | |||
50 | static void cp210x_break_ctl(struct tty_struct *, int); | 50 | static void cp210x_break_ctl(struct tty_struct *, int); |
51 | static int cp210x_startup(struct usb_serial *); | 51 | static int cp210x_startup(struct usb_serial *); |
52 | static void cp210x_disconnect(struct usb_serial *); | 52 | static void cp210x_disconnect(struct usb_serial *); |
53 | static void cp210x_dtr_rts(struct usb_serial_port *p, int on); | ||
54 | static int cp210x_carrier_raised(struct usb_serial_port *p); | ||
53 | 55 | ||
54 | static int debug; | 56 | static int debug; |
55 | 57 | ||
@@ -143,6 +145,8 @@ static struct usb_serial_driver cp210x_device = { | |||
143 | .tiocmset = cp210x_tiocmset, | 145 | .tiocmset = cp210x_tiocmset, |
144 | .attach = cp210x_startup, | 146 | .attach = cp210x_startup, |
145 | .disconnect = cp210x_disconnect, | 147 | .disconnect = cp210x_disconnect, |
148 | .dtr_rts = cp210x_dtr_rts, | ||
149 | .carrier_raised = cp210x_carrier_raised | ||
146 | }; | 150 | }; |
147 | 151 | ||
148 | /* Config request types */ | 152 | /* Config request types */ |
@@ -746,6 +750,14 @@ static int cp210x_tiocmset_port(struct usb_serial_port *port, struct file *file, | |||
746 | return cp210x_set_config(port, CP210X_SET_MHS, &control, 2); | 750 | return cp210x_set_config(port, CP210X_SET_MHS, &control, 2); |
747 | } | 751 | } |
748 | 752 | ||
753 | static void cp210x_dtr_rts(struct usb_serial_port *p, int on) | ||
754 | { | ||
755 | if (on) | ||
756 | cp210x_tiocmset_port(p, NULL, TIOCM_DTR|TIOCM_RTS, 0); | ||
757 | else | ||
758 | cp210x_tiocmset_port(p, NULL, 0, TIOCM_DTR|TIOCM_RTS); | ||
759 | } | ||
760 | |||
749 | static int cp210x_tiocmget (struct tty_struct *tty, struct file *file) | 761 | static int cp210x_tiocmget (struct tty_struct *tty, struct file *file) |
750 | { | 762 | { |
751 | struct usb_serial_port *port = tty->driver_data; | 763 | struct usb_serial_port *port = tty->driver_data; |
@@ -768,6 +780,15 @@ static int cp210x_tiocmget (struct tty_struct *tty, struct file *file) | |||
768 | return result; | 780 | return result; |
769 | } | 781 | } |
770 | 782 | ||
783 | static int cp210x_carrier_raised(struct usb_serial_port *p) | ||
784 | { | ||
785 | unsigned int control; | ||
786 | cp210x_get_config(p, CP210X_GET_MDMSTS, &control, 1); | ||
787 | if (control & CONTROL_DCD) | ||
788 | return 1; | ||
789 | return 0; | ||
790 | } | ||
791 | |||
771 | static void cp210x_break_ctl (struct tty_struct *tty, int break_state) | 792 | static void cp210x_break_ctl (struct tty_struct *tty, int break_state) |
772 | { | 793 | { |
773 | struct usb_serial_port *port = tty->driver_data; | 794 | struct usb_serial_port *port = tty->driver_data; |
diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index cd44c68954df..319aaf9725b3 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c | |||
@@ -308,6 +308,7 @@ static int option_resume(struct usb_serial *serial); | |||
308 | 308 | ||
309 | #define DLINK_VENDOR_ID 0x1186 | 309 | #define DLINK_VENDOR_ID 0x1186 |
310 | #define DLINK_PRODUCT_DWM_652 0x3e04 | 310 | #define DLINK_PRODUCT_DWM_652 0x3e04 |
311 | #define DLINK_PRODUCT_DWM_652_U5 0xce16 | ||
311 | 312 | ||
312 | #define QISDA_VENDOR_ID 0x1da5 | 313 | #define QISDA_VENDOR_ID 0x1da5 |
313 | #define QISDA_PRODUCT_H21_4512 0x4512 | 314 | #define QISDA_PRODUCT_H21_4512 0x4512 |
@@ -586,6 +587,7 @@ static struct usb_device_id option_ids[] = { | |||
586 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_AC2726, 0xff, 0xff, 0xff) }, | 587 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_AC2726, 0xff, 0xff, 0xff) }, |
587 | { USB_DEVICE(BENQ_VENDOR_ID, BENQ_PRODUCT_H10) }, | 588 | { USB_DEVICE(BENQ_VENDOR_ID, BENQ_PRODUCT_H10) }, |
588 | { USB_DEVICE(DLINK_VENDOR_ID, DLINK_PRODUCT_DWM_652) }, | 589 | { USB_DEVICE(DLINK_VENDOR_ID, DLINK_PRODUCT_DWM_652) }, |
590 | { USB_DEVICE(ALINK_VENDOR_ID, DLINK_PRODUCT_DWM_652_U5) }, /* Yes, ALINK_VENDOR_ID */ | ||
589 | { USB_DEVICE(QISDA_VENDOR_ID, QISDA_PRODUCT_H21_4512) }, | 591 | { USB_DEVICE(QISDA_VENDOR_ID, QISDA_PRODUCT_H21_4512) }, |
590 | { USB_DEVICE(QISDA_VENDOR_ID, QISDA_PRODUCT_H21_4523) }, | 592 | { USB_DEVICE(QISDA_VENDOR_ID, QISDA_PRODUCT_H21_4523) }, |
591 | { USB_DEVICE(QISDA_VENDOR_ID, QISDA_PRODUCT_H20_4515) }, | 593 | { USB_DEVICE(QISDA_VENDOR_ID, QISDA_PRODUCT_H20_4515) }, |
diff --git a/drivers/video/da8xx-fb.c b/drivers/video/da8xx-fb.c index d065894ce38f..035d56835b75 100644 --- a/drivers/video/da8xx-fb.c +++ b/drivers/video/da8xx-fb.c | |||
@@ -704,7 +704,7 @@ static int __init fb_probe(struct platform_device *device) | |||
704 | 704 | ||
705 | if (i == ARRAY_SIZE(known_lcd_panels)) { | 705 | if (i == ARRAY_SIZE(known_lcd_panels)) { |
706 | dev_err(&device->dev, "GLCD: No valid panel found\n"); | 706 | dev_err(&device->dev, "GLCD: No valid panel found\n"); |
707 | ret = ENODEV; | 707 | ret = -ENODEV; |
708 | goto err_clk_disable; | 708 | goto err_clk_disable; |
709 | } else | 709 | } else |
710 | dev_info(&device->dev, "GLCD: Found %s panel\n", | 710 | dev_info(&device->dev, "GLCD: Found %s panel\n", |
diff --git a/drivers/watchdog/pnx4008_wdt.c b/drivers/watchdog/pnx4008_wdt.c index f24d04132eda..4d227b152001 100644 --- a/drivers/watchdog/pnx4008_wdt.c +++ b/drivers/watchdog/pnx4008_wdt.c | |||
@@ -317,7 +317,7 @@ static int __devexit pnx4008_wdt_remove(struct platform_device *pdev) | |||
317 | 317 | ||
318 | static struct platform_driver platform_wdt_driver = { | 318 | static struct platform_driver platform_wdt_driver = { |
319 | .driver = { | 319 | .driver = { |
320 | .name = "watchdog", | 320 | .name = "pnx4008-watchdog", |
321 | .owner = THIS_MODULE, | 321 | .owner = THIS_MODULE, |
322 | }, | 322 | }, |
323 | .probe = pnx4008_wdt_probe, | 323 | .probe = pnx4008_wdt_probe, |
@@ -352,4 +352,4 @@ MODULE_PARM_DESC(nowayout, | |||
352 | 352 | ||
353 | MODULE_LICENSE("GPL"); | 353 | MODULE_LICENSE("GPL"); |
354 | MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR); | 354 | MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR); |
355 | MODULE_ALIAS("platform:watchdog"); | 355 | MODULE_ALIAS("platform:pnx4008-watchdog"); |
diff --git a/fs/9p/cache.c b/fs/9p/cache.c index 51c94e26a346..bcc5357a9069 100644 --- a/fs/9p/cache.c +++ b/fs/9p/cache.c | |||
@@ -343,18 +343,7 @@ int __v9fs_fscache_release_page(struct page *page, gfp_t gfp) | |||
343 | 343 | ||
344 | BUG_ON(!vcookie->fscache); | 344 | BUG_ON(!vcookie->fscache); |
345 | 345 | ||
346 | if (PageFsCache(page)) { | 346 | return fscache_maybe_release_page(vnode->cache, page, gfp); |
347 | if (fscache_check_page_write(vcookie->fscache, page)) { | ||
348 | if (!(gfp & __GFP_WAIT)) | ||
349 | return 0; | ||
350 | fscache_wait_on_page_write(vcookie->fscache, page); | ||
351 | } | ||
352 | |||
353 | fscache_uncache_page(vcookie->fscache, page); | ||
354 | ClearPageFsCache(page); | ||
355 | } | ||
356 | |||
357 | return 1; | ||
358 | } | 347 | } |
359 | 348 | ||
360 | void __v9fs_fscache_invalidate_page(struct page *page) | 349 | void __v9fs_fscache_invalidate_page(struct page *page) |
@@ -368,7 +357,6 @@ void __v9fs_fscache_invalidate_page(struct page *page) | |||
368 | fscache_wait_on_page_write(vcookie->fscache, page); | 357 | fscache_wait_on_page_write(vcookie->fscache, page); |
369 | BUG_ON(!PageLocked(page)); | 358 | BUG_ON(!PageLocked(page)); |
370 | fscache_uncache_page(vcookie->fscache, page); | 359 | fscache_uncache_page(vcookie->fscache, page); |
371 | ClearPageFsCache(page); | ||
372 | } | 360 | } |
373 | } | 361 | } |
374 | 362 | ||
diff --git a/fs/afs/file.c b/fs/afs/file.c index 681c2a7b013f..39b301662f22 100644 --- a/fs/afs/file.c +++ b/fs/afs/file.c | |||
@@ -315,7 +315,6 @@ static void afs_invalidatepage(struct page *page, unsigned long offset) | |||
315 | struct afs_vnode *vnode = AFS_FS_I(page->mapping->host); | 315 | struct afs_vnode *vnode = AFS_FS_I(page->mapping->host); |
316 | fscache_wait_on_page_write(vnode->cache, page); | 316 | fscache_wait_on_page_write(vnode->cache, page); |
317 | fscache_uncache_page(vnode->cache, page); | 317 | fscache_uncache_page(vnode->cache, page); |
318 | ClearPageFsCache(page); | ||
319 | } | 318 | } |
320 | #endif | 319 | #endif |
321 | 320 | ||
@@ -349,17 +348,9 @@ static int afs_releasepage(struct page *page, gfp_t gfp_flags) | |||
349 | /* deny if page is being written to the cache and the caller hasn't | 348 | /* deny if page is being written to the cache and the caller hasn't |
350 | * elected to wait */ | 349 | * elected to wait */ |
351 | #ifdef CONFIG_AFS_FSCACHE | 350 | #ifdef CONFIG_AFS_FSCACHE |
352 | if (PageFsCache(page)) { | 351 | if (!fscache_maybe_release_page(vnode->cache, page, gfp_flags)) { |
353 | if (fscache_check_page_write(vnode->cache, page)) { | 352 | _leave(" = F [cache busy]"); |
354 | if (!(gfp_flags & __GFP_WAIT)) { | 353 | return 0; |
355 | _leave(" = F [cache busy]"); | ||
356 | return 0; | ||
357 | } | ||
358 | fscache_wait_on_page_write(vnode->cache, page); | ||
359 | } | ||
360 | |||
361 | fscache_uncache_page(vnode->cache, page); | ||
362 | ClearPageFsCache(page); | ||
363 | } | 354 | } |
364 | #endif | 355 | #endif |
365 | 356 | ||
diff --git a/fs/cachefiles/interface.c b/fs/cachefiles/interface.c index 431accd475a7..27089311fbea 100644 --- a/fs/cachefiles/interface.c +++ b/fs/cachefiles/interface.c | |||
@@ -114,8 +114,9 @@ nomem_lookup_data: | |||
114 | 114 | ||
115 | /* | 115 | /* |
116 | * attempt to look up the nominated node in this cache | 116 | * attempt to look up the nominated node in this cache |
117 | * - return -ETIMEDOUT to be scheduled again | ||
117 | */ | 118 | */ |
118 | static void cachefiles_lookup_object(struct fscache_object *_object) | 119 | static int cachefiles_lookup_object(struct fscache_object *_object) |
119 | { | 120 | { |
120 | struct cachefiles_lookup_data *lookup_data; | 121 | struct cachefiles_lookup_data *lookup_data; |
121 | struct cachefiles_object *parent, *object; | 122 | struct cachefiles_object *parent, *object; |
@@ -145,13 +146,15 @@ static void cachefiles_lookup_object(struct fscache_object *_object) | |||
145 | object->fscache.cookie->def->type != FSCACHE_COOKIE_TYPE_INDEX) | 146 | object->fscache.cookie->def->type != FSCACHE_COOKIE_TYPE_INDEX) |
146 | cachefiles_attr_changed(&object->fscache); | 147 | cachefiles_attr_changed(&object->fscache); |
147 | 148 | ||
148 | if (ret < 0) { | 149 | if (ret < 0 && ret != -ETIMEDOUT) { |
149 | printk(KERN_WARNING "CacheFiles: Lookup failed error %d\n", | 150 | if (ret != -ENOBUFS) |
150 | ret); | 151 | printk(KERN_WARNING |
152 | "CacheFiles: Lookup failed error %d\n", ret); | ||
151 | fscache_object_lookup_error(&object->fscache); | 153 | fscache_object_lookup_error(&object->fscache); |
152 | } | 154 | } |
153 | 155 | ||
154 | _leave(" [%d]", ret); | 156 | _leave(" [%d]", ret); |
157 | return ret; | ||
155 | } | 158 | } |
156 | 159 | ||
157 | /* | 160 | /* |
@@ -331,6 +334,7 @@ static void cachefiles_put_object(struct fscache_object *_object) | |||
331 | } | 334 | } |
332 | 335 | ||
333 | cache = object->fscache.cache; | 336 | cache = object->fscache.cache; |
337 | fscache_object_destroy(&object->fscache); | ||
334 | kmem_cache_free(cachefiles_object_jar, object); | 338 | kmem_cache_free(cachefiles_object_jar, object); |
335 | fscache_object_destroyed(cache); | 339 | fscache_object_destroyed(cache); |
336 | } | 340 | } |
@@ -403,12 +407,26 @@ static int cachefiles_attr_changed(struct fscache_object *_object) | |||
403 | if (oi_size == ni_size) | 407 | if (oi_size == ni_size) |
404 | return 0; | 408 | return 0; |
405 | 409 | ||
406 | newattrs.ia_size = ni_size; | ||
407 | newattrs.ia_valid = ATTR_SIZE; | ||
408 | |||
409 | cachefiles_begin_secure(cache, &saved_cred); | 410 | cachefiles_begin_secure(cache, &saved_cred); |
410 | mutex_lock(&object->backer->d_inode->i_mutex); | 411 | mutex_lock(&object->backer->d_inode->i_mutex); |
412 | |||
413 | /* if there's an extension to a partial page at the end of the backing | ||
414 | * file, we need to discard the partial page so that we pick up new | ||
415 | * data after it */ | ||
416 | if (oi_size & ~PAGE_MASK && ni_size > oi_size) { | ||
417 | _debug("discard tail %llx", oi_size); | ||
418 | newattrs.ia_valid = ATTR_SIZE; | ||
419 | newattrs.ia_size = oi_size & PAGE_MASK; | ||
420 | ret = notify_change(object->backer, &newattrs); | ||
421 | if (ret < 0) | ||
422 | goto truncate_failed; | ||
423 | } | ||
424 | |||
425 | newattrs.ia_valid = ATTR_SIZE; | ||
426 | newattrs.ia_size = ni_size; | ||
411 | ret = notify_change(object->backer, &newattrs); | 427 | ret = notify_change(object->backer, &newattrs); |
428 | |||
429 | truncate_failed: | ||
412 | mutex_unlock(&object->backer->d_inode->i_mutex); | 430 | mutex_unlock(&object->backer->d_inode->i_mutex); |
413 | cachefiles_end_secure(cache, saved_cred); | 431 | cachefiles_end_secure(cache, saved_cred); |
414 | 432 | ||
diff --git a/fs/cachefiles/namei.c b/fs/cachefiles/namei.c index 4ce818ae39ea..14ac4806e291 100644 --- a/fs/cachefiles/namei.c +++ b/fs/cachefiles/namei.c | |||
@@ -21,17 +21,81 @@ | |||
21 | #include <linux/security.h> | 21 | #include <linux/security.h> |
22 | #include "internal.h" | 22 | #include "internal.h" |
23 | 23 | ||
24 | static int cachefiles_wait_bit(void *flags) | 24 | #define CACHEFILES_KEYBUF_SIZE 512 |
25 | |||
26 | /* | ||
27 | * dump debugging info about an object | ||
28 | */ | ||
29 | static noinline | ||
30 | void __cachefiles_printk_object(struct cachefiles_object *object, | ||
31 | const char *prefix, | ||
32 | u8 *keybuf) | ||
25 | { | 33 | { |
26 | schedule(); | 34 | struct fscache_cookie *cookie; |
27 | return 0; | 35 | unsigned keylen, loop; |
36 | |||
37 | printk(KERN_ERR "%sobject: OBJ%x\n", | ||
38 | prefix, object->fscache.debug_id); | ||
39 | printk(KERN_ERR "%sobjstate=%s fl=%lx swfl=%lx ev=%lx[%lx]\n", | ||
40 | prefix, fscache_object_states[object->fscache.state], | ||
41 | object->fscache.flags, object->fscache.work.flags, | ||
42 | object->fscache.events, | ||
43 | object->fscache.event_mask & FSCACHE_OBJECT_EVENTS_MASK); | ||
44 | printk(KERN_ERR "%sops=%u inp=%u exc=%u\n", | ||
45 | prefix, object->fscache.n_ops, object->fscache.n_in_progress, | ||
46 | object->fscache.n_exclusive); | ||
47 | printk(KERN_ERR "%sparent=%p\n", | ||
48 | prefix, object->fscache.parent); | ||
49 | |||
50 | spin_lock(&object->fscache.lock); | ||
51 | cookie = object->fscache.cookie; | ||
52 | if (cookie) { | ||
53 | printk(KERN_ERR "%scookie=%p [pr=%p nd=%p fl=%lx]\n", | ||
54 | prefix, | ||
55 | object->fscache.cookie, | ||
56 | object->fscache.cookie->parent, | ||
57 | object->fscache.cookie->netfs_data, | ||
58 | object->fscache.cookie->flags); | ||
59 | if (keybuf) | ||
60 | keylen = cookie->def->get_key(cookie->netfs_data, keybuf, | ||
61 | CACHEFILES_KEYBUF_SIZE); | ||
62 | else | ||
63 | keylen = 0; | ||
64 | } else { | ||
65 | printk(KERN_ERR "%scookie=NULL\n", prefix); | ||
66 | keylen = 0; | ||
67 | } | ||
68 | spin_unlock(&object->fscache.lock); | ||
69 | |||
70 | if (keylen) { | ||
71 | printk(KERN_ERR "%skey=[%u] '", prefix, keylen); | ||
72 | for (loop = 0; loop < keylen; loop++) | ||
73 | printk("%02x", keybuf[loop]); | ||
74 | printk("'\n"); | ||
75 | } | ||
76 | } | ||
77 | |||
78 | /* | ||
79 | * dump debugging info about a pair of objects | ||
80 | */ | ||
81 | static noinline void cachefiles_printk_object(struct cachefiles_object *object, | ||
82 | struct cachefiles_object *xobject) | ||
83 | { | ||
84 | u8 *keybuf; | ||
85 | |||
86 | keybuf = kmalloc(CACHEFILES_KEYBUF_SIZE, GFP_NOIO); | ||
87 | if (object) | ||
88 | __cachefiles_printk_object(object, "", keybuf); | ||
89 | if (xobject) | ||
90 | __cachefiles_printk_object(xobject, "x", keybuf); | ||
91 | kfree(keybuf); | ||
28 | } | 92 | } |
29 | 93 | ||
30 | /* | 94 | /* |
31 | * record the fact that an object is now active | 95 | * record the fact that an object is now active |
32 | */ | 96 | */ |
33 | static void cachefiles_mark_object_active(struct cachefiles_cache *cache, | 97 | static int cachefiles_mark_object_active(struct cachefiles_cache *cache, |
34 | struct cachefiles_object *object) | 98 | struct cachefiles_object *object) |
35 | { | 99 | { |
36 | struct cachefiles_object *xobject; | 100 | struct cachefiles_object *xobject; |
37 | struct rb_node **_p, *_parent = NULL; | 101 | struct rb_node **_p, *_parent = NULL; |
@@ -42,8 +106,11 @@ static void cachefiles_mark_object_active(struct cachefiles_cache *cache, | |||
42 | try_again: | 106 | try_again: |
43 | write_lock(&cache->active_lock); | 107 | write_lock(&cache->active_lock); |
44 | 108 | ||
45 | if (test_and_set_bit(CACHEFILES_OBJECT_ACTIVE, &object->flags)) | 109 | if (test_and_set_bit(CACHEFILES_OBJECT_ACTIVE, &object->flags)) { |
110 | printk(KERN_ERR "CacheFiles: Error: Object already active\n"); | ||
111 | cachefiles_printk_object(object, NULL); | ||
46 | BUG(); | 112 | BUG(); |
113 | } | ||
47 | 114 | ||
48 | dentry = object->dentry; | 115 | dentry = object->dentry; |
49 | _p = &cache->active_nodes.rb_node; | 116 | _p = &cache->active_nodes.rb_node; |
@@ -66,8 +133,8 @@ try_again: | |||
66 | rb_insert_color(&object->active_node, &cache->active_nodes); | 133 | rb_insert_color(&object->active_node, &cache->active_nodes); |
67 | 134 | ||
68 | write_unlock(&cache->active_lock); | 135 | write_unlock(&cache->active_lock); |
69 | _leave(""); | 136 | _leave(" = 0"); |
70 | return; | 137 | return 0; |
71 | 138 | ||
72 | /* an old object from a previous incarnation is hogging the slot - we | 139 | /* an old object from a previous incarnation is hogging the slot - we |
73 | * need to wait for it to be destroyed */ | 140 | * need to wait for it to be destroyed */ |
@@ -76,44 +143,70 @@ wait_for_old_object: | |||
76 | printk(KERN_ERR "\n"); | 143 | printk(KERN_ERR "\n"); |
77 | printk(KERN_ERR "CacheFiles: Error:" | 144 | printk(KERN_ERR "CacheFiles: Error:" |
78 | " Unexpected object collision\n"); | 145 | " Unexpected object collision\n"); |
79 | printk(KERN_ERR "xobject: OBJ%x\n", | 146 | cachefiles_printk_object(object, xobject); |
80 | xobject->fscache.debug_id); | ||
81 | printk(KERN_ERR "xobjstate=%s\n", | ||
82 | fscache_object_states[xobject->fscache.state]); | ||
83 | printk(KERN_ERR "xobjflags=%lx\n", xobject->fscache.flags); | ||
84 | printk(KERN_ERR "xobjevent=%lx [%lx]\n", | ||
85 | xobject->fscache.events, xobject->fscache.event_mask); | ||
86 | printk(KERN_ERR "xops=%u inp=%u exc=%u\n", | ||
87 | xobject->fscache.n_ops, xobject->fscache.n_in_progress, | ||
88 | xobject->fscache.n_exclusive); | ||
89 | printk(KERN_ERR "xcookie=%p [pr=%p nd=%p fl=%lx]\n", | ||
90 | xobject->fscache.cookie, | ||
91 | xobject->fscache.cookie->parent, | ||
92 | xobject->fscache.cookie->netfs_data, | ||
93 | xobject->fscache.cookie->flags); | ||
94 | printk(KERN_ERR "xparent=%p\n", | ||
95 | xobject->fscache.parent); | ||
96 | printk(KERN_ERR "object: OBJ%x\n", | ||
97 | object->fscache.debug_id); | ||
98 | printk(KERN_ERR "cookie=%p [pr=%p nd=%p fl=%lx]\n", | ||
99 | object->fscache.cookie, | ||
100 | object->fscache.cookie->parent, | ||
101 | object->fscache.cookie->netfs_data, | ||
102 | object->fscache.cookie->flags); | ||
103 | printk(KERN_ERR "parent=%p\n", | ||
104 | object->fscache.parent); | ||
105 | BUG(); | 147 | BUG(); |
106 | } | 148 | } |
107 | atomic_inc(&xobject->usage); | 149 | atomic_inc(&xobject->usage); |
108 | write_unlock(&cache->active_lock); | 150 | write_unlock(&cache->active_lock); |
109 | 151 | ||
110 | _debug(">>> wait"); | 152 | if (test_bit(CACHEFILES_OBJECT_ACTIVE, &xobject->flags)) { |
111 | wait_on_bit(&xobject->flags, CACHEFILES_OBJECT_ACTIVE, | 153 | wait_queue_head_t *wq; |
112 | cachefiles_wait_bit, TASK_UNINTERRUPTIBLE); | 154 | |
113 | _debug("<<< waited"); | 155 | signed long timeout = 60 * HZ; |
156 | wait_queue_t wait; | ||
157 | bool requeue; | ||
158 | |||
159 | /* if the object we're waiting for is queued for processing, | ||
160 | * then just put ourselves on the queue behind it */ | ||
161 | if (slow_work_is_queued(&xobject->fscache.work)) { | ||
162 | _debug("queue OBJ%x behind OBJ%x immediately", | ||
163 | object->fscache.debug_id, | ||
164 | xobject->fscache.debug_id); | ||
165 | goto requeue; | ||
166 | } | ||
167 | |||
168 | /* otherwise we sleep until either the object we're waiting for | ||
169 | * is done, or the slow-work facility wants the thread back to | ||
170 | * do other work */ | ||
171 | wq = bit_waitqueue(&xobject->flags, CACHEFILES_OBJECT_ACTIVE); | ||
172 | init_wait(&wait); | ||
173 | requeue = false; | ||
174 | do { | ||
175 | prepare_to_wait(wq, &wait, TASK_UNINTERRUPTIBLE); | ||
176 | if (!test_bit(CACHEFILES_OBJECT_ACTIVE, &xobject->flags)) | ||
177 | break; | ||
178 | requeue = slow_work_sleep_till_thread_needed( | ||
179 | &object->fscache.work, &timeout); | ||
180 | } while (timeout > 0 && !requeue); | ||
181 | finish_wait(wq, &wait); | ||
182 | |||
183 | if (requeue && | ||
184 | test_bit(CACHEFILES_OBJECT_ACTIVE, &xobject->flags)) { | ||
185 | _debug("queue OBJ%x behind OBJ%x after wait", | ||
186 | object->fscache.debug_id, | ||
187 | xobject->fscache.debug_id); | ||
188 | goto requeue; | ||
189 | } | ||
190 | |||
191 | if (timeout <= 0) { | ||
192 | printk(KERN_ERR "\n"); | ||
193 | printk(KERN_ERR "CacheFiles: Error: Overlong" | ||
194 | " wait for old active object to go away\n"); | ||
195 | cachefiles_printk_object(object, xobject); | ||
196 | goto requeue; | ||
197 | } | ||
198 | } | ||
199 | |||
200 | ASSERT(!test_bit(CACHEFILES_OBJECT_ACTIVE, &xobject->flags)); | ||
114 | 201 | ||
115 | cache->cache.ops->put_object(&xobject->fscache); | 202 | cache->cache.ops->put_object(&xobject->fscache); |
116 | goto try_again; | 203 | goto try_again; |
204 | |||
205 | requeue: | ||
206 | clear_bit(CACHEFILES_OBJECT_ACTIVE, &object->flags); | ||
207 | cache->cache.ops->put_object(&xobject->fscache); | ||
208 | _leave(" = -ETIMEDOUT"); | ||
209 | return -ETIMEDOUT; | ||
117 | } | 210 | } |
118 | 211 | ||
119 | /* | 212 | /* |
@@ -254,7 +347,7 @@ int cachefiles_delete_object(struct cachefiles_cache *cache, | |||
254 | 347 | ||
255 | dir = dget_parent(object->dentry); | 348 | dir = dget_parent(object->dentry); |
256 | 349 | ||
257 | mutex_lock(&dir->d_inode->i_mutex); | 350 | mutex_lock_nested(&dir->d_inode->i_mutex, I_MUTEX_PARENT); |
258 | ret = cachefiles_bury_object(cache, dir, object->dentry); | 351 | ret = cachefiles_bury_object(cache, dir, object->dentry); |
259 | 352 | ||
260 | dput(dir); | 353 | dput(dir); |
@@ -307,7 +400,7 @@ lookup_again: | |||
307 | /* search the current directory for the element name */ | 400 | /* search the current directory for the element name */ |
308 | _debug("lookup '%s'", name); | 401 | _debug("lookup '%s'", name); |
309 | 402 | ||
310 | mutex_lock(&dir->d_inode->i_mutex); | 403 | mutex_lock_nested(&dir->d_inode->i_mutex, I_MUTEX_PARENT); |
311 | 404 | ||
312 | start = jiffies; | 405 | start = jiffies; |
313 | next = lookup_one_len(name, dir, nlen); | 406 | next = lookup_one_len(name, dir, nlen); |
@@ -418,12 +511,15 @@ lookup_again: | |||
418 | } | 511 | } |
419 | 512 | ||
420 | /* note that we're now using this object */ | 513 | /* note that we're now using this object */ |
421 | cachefiles_mark_object_active(cache, object); | 514 | ret = cachefiles_mark_object_active(cache, object); |
422 | 515 | ||
423 | mutex_unlock(&dir->d_inode->i_mutex); | 516 | mutex_unlock(&dir->d_inode->i_mutex); |
424 | dput(dir); | 517 | dput(dir); |
425 | dir = NULL; | 518 | dir = NULL; |
426 | 519 | ||
520 | if (ret == -ETIMEDOUT) | ||
521 | goto mark_active_timed_out; | ||
522 | |||
427 | _debug("=== OBTAINED_OBJECT ==="); | 523 | _debug("=== OBTAINED_OBJECT ==="); |
428 | 524 | ||
429 | if (object->new) { | 525 | if (object->new) { |
@@ -467,6 +563,10 @@ create_error: | |||
467 | cachefiles_io_error(cache, "Create/mkdir failed"); | 563 | cachefiles_io_error(cache, "Create/mkdir failed"); |
468 | goto error; | 564 | goto error; |
469 | 565 | ||
566 | mark_active_timed_out: | ||
567 | _debug("mark active timed out"); | ||
568 | goto release_dentry; | ||
569 | |||
470 | check_error: | 570 | check_error: |
471 | _debug("check error %d", ret); | 571 | _debug("check error %d", ret); |
472 | write_lock(&cache->active_lock); | 572 | write_lock(&cache->active_lock); |
@@ -474,7 +574,7 @@ check_error: | |||
474 | clear_bit(CACHEFILES_OBJECT_ACTIVE, &object->flags); | 574 | clear_bit(CACHEFILES_OBJECT_ACTIVE, &object->flags); |
475 | wake_up_bit(&object->flags, CACHEFILES_OBJECT_ACTIVE); | 575 | wake_up_bit(&object->flags, CACHEFILES_OBJECT_ACTIVE); |
476 | write_unlock(&cache->active_lock); | 576 | write_unlock(&cache->active_lock); |
477 | 577 | release_dentry: | |
478 | dput(object->dentry); | 578 | dput(object->dentry); |
479 | object->dentry = NULL; | 579 | object->dentry = NULL; |
480 | goto error_out; | 580 | goto error_out; |
@@ -495,9 +595,6 @@ error: | |||
495 | error_out2: | 595 | error_out2: |
496 | dput(dir); | 596 | dput(dir); |
497 | error_out: | 597 | error_out: |
498 | if (ret == -ENOSPC) | ||
499 | ret = -ENOBUFS; | ||
500 | |||
501 | _leave(" = error %d", -ret); | 598 | _leave(" = error %d", -ret); |
502 | return ret; | 599 | return ret; |
503 | } | 600 | } |
diff --git a/fs/cachefiles/rdwr.c b/fs/cachefiles/rdwr.c index a69787e7dd96..1d8332563863 100644 --- a/fs/cachefiles/rdwr.c +++ b/fs/cachefiles/rdwr.c | |||
@@ -40,8 +40,10 @@ static int cachefiles_read_waiter(wait_queue_t *wait, unsigned mode, | |||
40 | 40 | ||
41 | _debug("--- monitor %p %lx ---", page, page->flags); | 41 | _debug("--- monitor %p %lx ---", page, page->flags); |
42 | 42 | ||
43 | if (!PageUptodate(page) && !PageError(page)) | 43 | if (!PageUptodate(page) && !PageError(page)) { |
44 | dump_stack(); | 44 | /* unlocked, not uptodate and not erronous? */ |
45 | _debug("page probably truncated"); | ||
46 | } | ||
45 | 47 | ||
46 | /* remove from the waitqueue */ | 48 | /* remove from the waitqueue */ |
47 | list_del(&wait->task_list); | 49 | list_del(&wait->task_list); |
@@ -61,6 +63,84 @@ static int cachefiles_read_waiter(wait_queue_t *wait, unsigned mode, | |||
61 | } | 63 | } |
62 | 64 | ||
63 | /* | 65 | /* |
66 | * handle a probably truncated page | ||
67 | * - check to see if the page is still relevant and reissue the read if | ||
68 | * possible | ||
69 | * - return -EIO on error, -ENODATA if the page is gone, -EINPROGRESS if we | ||
70 | * must wait again and 0 if successful | ||
71 | */ | ||
72 | static int cachefiles_read_reissue(struct cachefiles_object *object, | ||
73 | struct cachefiles_one_read *monitor) | ||
74 | { | ||
75 | struct address_space *bmapping = object->backer->d_inode->i_mapping; | ||
76 | struct page *backpage = monitor->back_page, *backpage2; | ||
77 | int ret; | ||
78 | |||
79 | kenter("{ino=%lx},{%lx,%lx}", | ||
80 | object->backer->d_inode->i_ino, | ||
81 | backpage->index, backpage->flags); | ||
82 | |||
83 | /* skip if the page was truncated away completely */ | ||
84 | if (backpage->mapping != bmapping) { | ||
85 | kleave(" = -ENODATA [mapping]"); | ||
86 | return -ENODATA; | ||
87 | } | ||
88 | |||
89 | backpage2 = find_get_page(bmapping, backpage->index); | ||
90 | if (!backpage2) { | ||
91 | kleave(" = -ENODATA [gone]"); | ||
92 | return -ENODATA; | ||
93 | } | ||
94 | |||
95 | if (backpage != backpage2) { | ||
96 | put_page(backpage2); | ||
97 | kleave(" = -ENODATA [different]"); | ||
98 | return -ENODATA; | ||
99 | } | ||
100 | |||
101 | /* the page is still there and we already have a ref on it, so we don't | ||
102 | * need a second */ | ||
103 | put_page(backpage2); | ||
104 | |||
105 | INIT_LIST_HEAD(&monitor->op_link); | ||
106 | add_page_wait_queue(backpage, &monitor->monitor); | ||
107 | |||
108 | if (trylock_page(backpage)) { | ||
109 | ret = -EIO; | ||
110 | if (PageError(backpage)) | ||
111 | goto unlock_discard; | ||
112 | ret = 0; | ||
113 | if (PageUptodate(backpage)) | ||
114 | goto unlock_discard; | ||
115 | |||
116 | kdebug("reissue read"); | ||
117 | ret = bmapping->a_ops->readpage(NULL, backpage); | ||
118 | if (ret < 0) | ||
119 | goto unlock_discard; | ||
120 | } | ||
121 | |||
122 | /* but the page may have been read before the monitor was installed, so | ||
123 | * the monitor may miss the event - so we have to ensure that we do get | ||
124 | * one in such a case */ | ||
125 | if (trylock_page(backpage)) { | ||
126 | _debug("jumpstart %p {%lx}", backpage, backpage->flags); | ||
127 | unlock_page(backpage); | ||
128 | } | ||
129 | |||
130 | /* it'll reappear on the todo list */ | ||
131 | kleave(" = -EINPROGRESS"); | ||
132 | return -EINPROGRESS; | ||
133 | |||
134 | unlock_discard: | ||
135 | unlock_page(backpage); | ||
136 | spin_lock_irq(&object->work_lock); | ||
137 | list_del(&monitor->op_link); | ||
138 | spin_unlock_irq(&object->work_lock); | ||
139 | kleave(" = %d", ret); | ||
140 | return ret; | ||
141 | } | ||
142 | |||
143 | /* | ||
64 | * copy data from backing pages to netfs pages to complete a read operation | 144 | * copy data from backing pages to netfs pages to complete a read operation |
65 | * - driven by FS-Cache's thread pool | 145 | * - driven by FS-Cache's thread pool |
66 | */ | 146 | */ |
@@ -92,20 +172,26 @@ static void cachefiles_read_copier(struct fscache_operation *_op) | |||
92 | 172 | ||
93 | _debug("- copy {%lu}", monitor->back_page->index); | 173 | _debug("- copy {%lu}", monitor->back_page->index); |
94 | 174 | ||
95 | error = -EIO; | 175 | recheck: |
96 | if (PageUptodate(monitor->back_page)) { | 176 | if (PageUptodate(monitor->back_page)) { |
97 | copy_highpage(monitor->netfs_page, monitor->back_page); | 177 | copy_highpage(monitor->netfs_page, monitor->back_page); |
98 | 178 | ||
99 | pagevec_add(&pagevec, monitor->netfs_page); | 179 | pagevec_add(&pagevec, monitor->netfs_page); |
100 | fscache_mark_pages_cached(monitor->op, &pagevec); | 180 | fscache_mark_pages_cached(monitor->op, &pagevec); |
101 | error = 0; | 181 | error = 0; |
102 | } | 182 | } else if (!PageError(monitor->back_page)) { |
103 | 183 | /* the page has probably been truncated */ | |
104 | if (error) | 184 | error = cachefiles_read_reissue(object, monitor); |
185 | if (error == -EINPROGRESS) | ||
186 | goto next; | ||
187 | goto recheck; | ||
188 | } else { | ||
105 | cachefiles_io_error_obj( | 189 | cachefiles_io_error_obj( |
106 | object, | 190 | object, |
107 | "Readpage failed on backing file %lx", | 191 | "Readpage failed on backing file %lx", |
108 | (unsigned long) monitor->back_page->flags); | 192 | (unsigned long) monitor->back_page->flags); |
193 | error = -EIO; | ||
194 | } | ||
109 | 195 | ||
110 | page_cache_release(monitor->back_page); | 196 | page_cache_release(monitor->back_page); |
111 | 197 | ||
@@ -114,6 +200,7 @@ static void cachefiles_read_copier(struct fscache_operation *_op) | |||
114 | fscache_put_retrieval(op); | 200 | fscache_put_retrieval(op); |
115 | kfree(monitor); | 201 | kfree(monitor); |
116 | 202 | ||
203 | next: | ||
117 | /* let the thread pool have some air occasionally */ | 204 | /* let the thread pool have some air occasionally */ |
118 | max--; | 205 | max--; |
119 | if (max < 0 || need_resched()) { | 206 | if (max < 0 || need_resched()) { |
@@ -333,7 +420,8 @@ int cachefiles_read_or_alloc_page(struct fscache_retrieval *op, | |||
333 | 420 | ||
334 | shift = PAGE_SHIFT - inode->i_sb->s_blocksize_bits; | 421 | shift = PAGE_SHIFT - inode->i_sb->s_blocksize_bits; |
335 | 422 | ||
336 | op->op.flags = FSCACHE_OP_FAST; | 423 | op->op.flags &= FSCACHE_OP_KEEP_FLAGS; |
424 | op->op.flags |= FSCACHE_OP_FAST; | ||
337 | op->op.processor = cachefiles_read_copier; | 425 | op->op.processor = cachefiles_read_copier; |
338 | 426 | ||
339 | pagevec_init(&pagevec, 0); | 427 | pagevec_init(&pagevec, 0); |
@@ -639,7 +727,8 @@ int cachefiles_read_or_alloc_pages(struct fscache_retrieval *op, | |||
639 | 727 | ||
640 | pagevec_init(&pagevec, 0); | 728 | pagevec_init(&pagevec, 0); |
641 | 729 | ||
642 | op->op.flags = FSCACHE_OP_FAST; | 730 | op->op.flags &= FSCACHE_OP_KEEP_FLAGS; |
731 | op->op.flags |= FSCACHE_OP_FAST; | ||
643 | op->op.processor = cachefiles_read_copier; | 732 | op->op.processor = cachefiles_read_copier; |
644 | 733 | ||
645 | INIT_LIST_HEAD(&backpages); | 734 | INIT_LIST_HEAD(&backpages); |
@@ -801,7 +890,8 @@ int cachefiles_write_page(struct fscache_storage *op, struct page *page) | |||
801 | struct cachefiles_cache *cache; | 890 | struct cachefiles_cache *cache; |
802 | mm_segment_t old_fs; | 891 | mm_segment_t old_fs; |
803 | struct file *file; | 892 | struct file *file; |
804 | loff_t pos; | 893 | loff_t pos, eof; |
894 | size_t len; | ||
805 | void *data; | 895 | void *data; |
806 | int ret; | 896 | int ret; |
807 | 897 | ||
@@ -835,15 +925,29 @@ int cachefiles_write_page(struct fscache_storage *op, struct page *page) | |||
835 | ret = -EIO; | 925 | ret = -EIO; |
836 | if (file->f_op->write) { | 926 | if (file->f_op->write) { |
837 | pos = (loff_t) page->index << PAGE_SHIFT; | 927 | pos = (loff_t) page->index << PAGE_SHIFT; |
928 | |||
929 | /* we mustn't write more data than we have, so we have | ||
930 | * to beware of a partial page at EOF */ | ||
931 | eof = object->fscache.store_limit_l; | ||
932 | len = PAGE_SIZE; | ||
933 | if (eof & ~PAGE_MASK) { | ||
934 | ASSERTCMP(pos, <, eof); | ||
935 | if (eof - pos < PAGE_SIZE) { | ||
936 | _debug("cut short %llx to %llx", | ||
937 | pos, eof); | ||
938 | len = eof - pos; | ||
939 | ASSERTCMP(pos + len, ==, eof); | ||
940 | } | ||
941 | } | ||
942 | |||
838 | data = kmap(page); | 943 | data = kmap(page); |
839 | old_fs = get_fs(); | 944 | old_fs = get_fs(); |
840 | set_fs(KERNEL_DS); | 945 | set_fs(KERNEL_DS); |
841 | ret = file->f_op->write( | 946 | ret = file->f_op->write( |
842 | file, (const void __user *) data, PAGE_SIZE, | 947 | file, (const void __user *) data, len, &pos); |
843 | &pos); | ||
844 | set_fs(old_fs); | 948 | set_fs(old_fs); |
845 | kunmap(page); | 949 | kunmap(page); |
846 | if (ret != PAGE_SIZE) | 950 | if (ret != len) |
847 | ret = -EIO; | 951 | ret = -EIO; |
848 | } | 952 | } |
849 | fput(file); | 953 | fput(file); |
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c index 9a5e4f5f3122..29f1da761bbf 100644 --- a/fs/cifs/cifsfs.c +++ b/fs/cifs/cifsfs.c | |||
@@ -1037,7 +1037,7 @@ init_cifs(void) | |||
1037 | if (rc) | 1037 | if (rc) |
1038 | goto out_unregister_key_type; | 1038 | goto out_unregister_key_type; |
1039 | #endif | 1039 | #endif |
1040 | rc = slow_work_register_user(); | 1040 | rc = slow_work_register_user(THIS_MODULE); |
1041 | if (rc) | 1041 | if (rc) |
1042 | goto out_unregister_resolver_key; | 1042 | goto out_unregister_resolver_key; |
1043 | 1043 | ||
diff --git a/fs/fcntl.c b/fs/fcntl.c index fc089f2f7f56..2cf93ec40a67 100644 --- a/fs/fcntl.c +++ b/fs/fcntl.c | |||
@@ -284,7 +284,7 @@ static int f_setown_ex(struct file *filp, unsigned long arg) | |||
284 | type = PIDTYPE_PID; | 284 | type = PIDTYPE_PID; |
285 | break; | 285 | break; |
286 | 286 | ||
287 | case F_OWNER_GID: | 287 | case F_OWNER_PGRP: |
288 | type = PIDTYPE_PGID; | 288 | type = PIDTYPE_PGID; |
289 | break; | 289 | break; |
290 | 290 | ||
@@ -321,7 +321,7 @@ static int f_getown_ex(struct file *filp, unsigned long arg) | |||
321 | break; | 321 | break; |
322 | 322 | ||
323 | case PIDTYPE_PGID: | 323 | case PIDTYPE_PGID: |
324 | owner.type = F_OWNER_GID; | 324 | owner.type = F_OWNER_PGRP; |
325 | break; | 325 | break; |
326 | 326 | ||
327 | default: | 327 | default: |
diff --git a/fs/fscache/Kconfig b/fs/fscache/Kconfig index 9bbb8ce7bea0..864dac20a242 100644 --- a/fs/fscache/Kconfig +++ b/fs/fscache/Kconfig | |||
@@ -54,3 +54,10 @@ config FSCACHE_DEBUG | |||
54 | enabled by setting bits in /sys/modules/fscache/parameter/debug. | 54 | enabled by setting bits in /sys/modules/fscache/parameter/debug. |
55 | 55 | ||
56 | See Documentation/filesystems/caching/fscache.txt for more information. | 56 | See Documentation/filesystems/caching/fscache.txt for more information. |
57 | |||
58 | config FSCACHE_OBJECT_LIST | ||
59 | bool "Maintain global object list for debugging purposes" | ||
60 | depends on FSCACHE && PROC_FS | ||
61 | help | ||
62 | Maintain a global list of active fscache objects that can be | ||
63 | retrieved through /proc/fs/fscache/objects for debugging purposes | ||
diff --git a/fs/fscache/Makefile b/fs/fscache/Makefile index 91571b95aacc..6d561531cb36 100644 --- a/fs/fscache/Makefile +++ b/fs/fscache/Makefile | |||
@@ -15,5 +15,6 @@ fscache-y := \ | |||
15 | fscache-$(CONFIG_PROC_FS) += proc.o | 15 | fscache-$(CONFIG_PROC_FS) += proc.o |
16 | fscache-$(CONFIG_FSCACHE_STATS) += stats.o | 16 | fscache-$(CONFIG_FSCACHE_STATS) += stats.o |
17 | fscache-$(CONFIG_FSCACHE_HISTOGRAM) += histogram.o | 17 | fscache-$(CONFIG_FSCACHE_HISTOGRAM) += histogram.o |
18 | fscache-$(CONFIG_FSCACHE_OBJECT_LIST) += object-list.o | ||
18 | 19 | ||
19 | obj-$(CONFIG_FSCACHE) := fscache.o | 20 | obj-$(CONFIG_FSCACHE) := fscache.o |
diff --git a/fs/fscache/cache.c b/fs/fscache/cache.c index e21985bbb1fb..6a3c48abd677 100644 --- a/fs/fscache/cache.c +++ b/fs/fscache/cache.c | |||
@@ -263,6 +263,7 @@ int fscache_add_cache(struct fscache_cache *cache, | |||
263 | spin_lock(&cache->object_list_lock); | 263 | spin_lock(&cache->object_list_lock); |
264 | list_add_tail(&ifsdef->cache_link, &cache->object_list); | 264 | list_add_tail(&ifsdef->cache_link, &cache->object_list); |
265 | spin_unlock(&cache->object_list_lock); | 265 | spin_unlock(&cache->object_list_lock); |
266 | fscache_objlist_add(ifsdef); | ||
266 | 267 | ||
267 | /* add the cache's netfs definition index object to the top level index | 268 | /* add the cache's netfs definition index object to the top level index |
268 | * cookie as a known backing object */ | 269 | * cookie as a known backing object */ |
@@ -380,11 +381,15 @@ void fscache_withdraw_cache(struct fscache_cache *cache) | |||
380 | 381 | ||
381 | /* make sure all pages pinned by operations on behalf of the netfs are | 382 | /* make sure all pages pinned by operations on behalf of the netfs are |
382 | * written to disk */ | 383 | * written to disk */ |
384 | fscache_stat(&fscache_n_cop_sync_cache); | ||
383 | cache->ops->sync_cache(cache); | 385 | cache->ops->sync_cache(cache); |
386 | fscache_stat_d(&fscache_n_cop_sync_cache); | ||
384 | 387 | ||
385 | /* dissociate all the netfs pages backed by this cache from the block | 388 | /* dissociate all the netfs pages backed by this cache from the block |
386 | * mappings in the cache */ | 389 | * mappings in the cache */ |
390 | fscache_stat(&fscache_n_cop_dissociate_pages); | ||
387 | cache->ops->dissociate_pages(cache); | 391 | cache->ops->dissociate_pages(cache); |
392 | fscache_stat_d(&fscache_n_cop_dissociate_pages); | ||
388 | 393 | ||
389 | /* we now have to destroy all the active objects pertaining to this | 394 | /* we now have to destroy all the active objects pertaining to this |
390 | * cache - which we do by passing them off to thread pool to be | 395 | * cache - which we do by passing them off to thread pool to be |
diff --git a/fs/fscache/cookie.c b/fs/fscache/cookie.c index 72fd18f6c71f..990535071a8a 100644 --- a/fs/fscache/cookie.c +++ b/fs/fscache/cookie.c | |||
@@ -36,6 +36,7 @@ void fscache_cookie_init_once(void *_cookie) | |||
36 | 36 | ||
37 | memset(cookie, 0, sizeof(*cookie)); | 37 | memset(cookie, 0, sizeof(*cookie)); |
38 | spin_lock_init(&cookie->lock); | 38 | spin_lock_init(&cookie->lock); |
39 | spin_lock_init(&cookie->stores_lock); | ||
39 | INIT_HLIST_HEAD(&cookie->backing_objects); | 40 | INIT_HLIST_HEAD(&cookie->backing_objects); |
40 | } | 41 | } |
41 | 42 | ||
@@ -102,7 +103,9 @@ struct fscache_cookie *__fscache_acquire_cookie( | |||
102 | cookie->netfs_data = netfs_data; | 103 | cookie->netfs_data = netfs_data; |
103 | cookie->flags = 0; | 104 | cookie->flags = 0; |
104 | 105 | ||
105 | INIT_RADIX_TREE(&cookie->stores, GFP_NOFS); | 106 | /* radix tree insertion won't use the preallocation pool unless it's |
107 | * told it may not wait */ | ||
108 | INIT_RADIX_TREE(&cookie->stores, GFP_NOFS & ~__GFP_WAIT); | ||
106 | 109 | ||
107 | switch (cookie->def->type) { | 110 | switch (cookie->def->type) { |
108 | case FSCACHE_COOKIE_TYPE_INDEX: | 111 | case FSCACHE_COOKIE_TYPE_INDEX: |
@@ -249,7 +252,9 @@ static int fscache_alloc_object(struct fscache_cache *cache, | |||
249 | 252 | ||
250 | /* ask the cache to allocate an object (we may end up with duplicate | 253 | /* ask the cache to allocate an object (we may end up with duplicate |
251 | * objects at this stage, but we sort that out later) */ | 254 | * objects at this stage, but we sort that out later) */ |
255 | fscache_stat(&fscache_n_cop_alloc_object); | ||
252 | object = cache->ops->alloc_object(cache, cookie); | 256 | object = cache->ops->alloc_object(cache, cookie); |
257 | fscache_stat_d(&fscache_n_cop_alloc_object); | ||
253 | if (IS_ERR(object)) { | 258 | if (IS_ERR(object)) { |
254 | fscache_stat(&fscache_n_object_no_alloc); | 259 | fscache_stat(&fscache_n_object_no_alloc); |
255 | ret = PTR_ERR(object); | 260 | ret = PTR_ERR(object); |
@@ -270,8 +275,11 @@ static int fscache_alloc_object(struct fscache_cache *cache, | |||
270 | /* only attach if we managed to allocate all we needed, otherwise | 275 | /* only attach if we managed to allocate all we needed, otherwise |
271 | * discard the object we just allocated and instead use the one | 276 | * discard the object we just allocated and instead use the one |
272 | * attached to the cookie */ | 277 | * attached to the cookie */ |
273 | if (fscache_attach_object(cookie, object) < 0) | 278 | if (fscache_attach_object(cookie, object) < 0) { |
279 | fscache_stat(&fscache_n_cop_put_object); | ||
274 | cache->ops->put_object(object); | 280 | cache->ops->put_object(object); |
281 | fscache_stat_d(&fscache_n_cop_put_object); | ||
282 | } | ||
275 | 283 | ||
276 | _leave(" = 0"); | 284 | _leave(" = 0"); |
277 | return 0; | 285 | return 0; |
@@ -287,7 +295,9 @@ object_already_extant: | |||
287 | return 0; | 295 | return 0; |
288 | 296 | ||
289 | error_put: | 297 | error_put: |
298 | fscache_stat(&fscache_n_cop_put_object); | ||
290 | cache->ops->put_object(object); | 299 | cache->ops->put_object(object); |
300 | fscache_stat_d(&fscache_n_cop_put_object); | ||
291 | error: | 301 | error: |
292 | _leave(" = %d", ret); | 302 | _leave(" = %d", ret); |
293 | return ret; | 303 | return ret; |
@@ -349,6 +359,8 @@ static int fscache_attach_object(struct fscache_cookie *cookie, | |||
349 | object->cookie = cookie; | 359 | object->cookie = cookie; |
350 | atomic_inc(&cookie->usage); | 360 | atomic_inc(&cookie->usage); |
351 | hlist_add_head(&object->cookie_link, &cookie->backing_objects); | 361 | hlist_add_head(&object->cookie_link, &cookie->backing_objects); |
362 | |||
363 | fscache_objlist_add(object); | ||
352 | ret = 0; | 364 | ret = 0; |
353 | 365 | ||
354 | cant_attach_object: | 366 | cant_attach_object: |
@@ -403,6 +415,8 @@ void __fscache_relinquish_cookie(struct fscache_cookie *cookie, int retire) | |||
403 | unsigned long event; | 415 | unsigned long event; |
404 | 416 | ||
405 | fscache_stat(&fscache_n_relinquishes); | 417 | fscache_stat(&fscache_n_relinquishes); |
418 | if (retire) | ||
419 | fscache_stat(&fscache_n_relinquishes_retire); | ||
406 | 420 | ||
407 | if (!cookie) { | 421 | if (!cookie) { |
408 | fscache_stat(&fscache_n_relinquishes_null); | 422 | fscache_stat(&fscache_n_relinquishes_null); |
@@ -428,12 +442,8 @@ void __fscache_relinquish_cookie(struct fscache_cookie *cookie, int retire) | |||
428 | 442 | ||
429 | event = retire ? FSCACHE_OBJECT_EV_RETIRE : FSCACHE_OBJECT_EV_RELEASE; | 443 | event = retire ? FSCACHE_OBJECT_EV_RETIRE : FSCACHE_OBJECT_EV_RELEASE; |
430 | 444 | ||
431 | /* detach pointers back to the netfs */ | ||
432 | spin_lock(&cookie->lock); | 445 | spin_lock(&cookie->lock); |
433 | 446 | ||
434 | cookie->netfs_data = NULL; | ||
435 | cookie->def = NULL; | ||
436 | |||
437 | /* break links with all the active objects */ | 447 | /* break links with all the active objects */ |
438 | while (!hlist_empty(&cookie->backing_objects)) { | 448 | while (!hlist_empty(&cookie->backing_objects)) { |
439 | object = hlist_entry(cookie->backing_objects.first, | 449 | object = hlist_entry(cookie->backing_objects.first, |
@@ -456,6 +466,10 @@ void __fscache_relinquish_cookie(struct fscache_cookie *cookie, int retire) | |||
456 | BUG(); | 466 | BUG(); |
457 | } | 467 | } |
458 | 468 | ||
469 | /* detach pointers back to the netfs */ | ||
470 | cookie->netfs_data = NULL; | ||
471 | cookie->def = NULL; | ||
472 | |||
459 | spin_unlock(&cookie->lock); | 473 | spin_unlock(&cookie->lock); |
460 | 474 | ||
461 | if (cookie->parent) { | 475 | if (cookie->parent) { |
diff --git a/fs/fscache/internal.h b/fs/fscache/internal.h index 1c341304621f..edd7434ab6e5 100644 --- a/fs/fscache/internal.h +++ b/fs/fscache/internal.h | |||
@@ -17,6 +17,7 @@ | |||
17 | * - cache->object_list_lock | 17 | * - cache->object_list_lock |
18 | * - object->lock | 18 | * - object->lock |
19 | * - object->parent->lock | 19 | * - object->parent->lock |
20 | * - cookie->stores_lock | ||
20 | * - fscache_thread_lock | 21 | * - fscache_thread_lock |
21 | * | 22 | * |
22 | */ | 23 | */ |
@@ -88,17 +89,31 @@ extern int fscache_wait_bit_interruptible(void *); | |||
88 | /* | 89 | /* |
89 | * object.c | 90 | * object.c |
90 | */ | 91 | */ |
92 | extern const char fscache_object_states_short[FSCACHE_OBJECT__NSTATES][5]; | ||
93 | |||
91 | extern void fscache_withdrawing_object(struct fscache_cache *, | 94 | extern void fscache_withdrawing_object(struct fscache_cache *, |
92 | struct fscache_object *); | 95 | struct fscache_object *); |
93 | extern void fscache_enqueue_object(struct fscache_object *); | 96 | extern void fscache_enqueue_object(struct fscache_object *); |
94 | 97 | ||
95 | /* | 98 | /* |
99 | * object-list.c | ||
100 | */ | ||
101 | #ifdef CONFIG_FSCACHE_OBJECT_LIST | ||
102 | extern const struct file_operations fscache_objlist_fops; | ||
103 | |||
104 | extern void fscache_objlist_add(struct fscache_object *); | ||
105 | #else | ||
106 | #define fscache_objlist_add(object) do {} while(0) | ||
107 | #endif | ||
108 | |||
109 | /* | ||
96 | * operation.c | 110 | * operation.c |
97 | */ | 111 | */ |
98 | extern int fscache_submit_exclusive_op(struct fscache_object *, | 112 | extern int fscache_submit_exclusive_op(struct fscache_object *, |
99 | struct fscache_operation *); | 113 | struct fscache_operation *); |
100 | extern int fscache_submit_op(struct fscache_object *, | 114 | extern int fscache_submit_op(struct fscache_object *, |
101 | struct fscache_operation *); | 115 | struct fscache_operation *); |
116 | extern int fscache_cancel_op(struct fscache_operation *); | ||
102 | extern void fscache_abort_object(struct fscache_object *); | 117 | extern void fscache_abort_object(struct fscache_object *); |
103 | extern void fscache_start_operations(struct fscache_object *); | 118 | extern void fscache_start_operations(struct fscache_object *); |
104 | extern void fscache_operation_gc(struct work_struct *); | 119 | extern void fscache_operation_gc(struct work_struct *); |
@@ -127,6 +142,8 @@ extern atomic_t fscache_n_op_enqueue; | |||
127 | extern atomic_t fscache_n_op_deferred_release; | 142 | extern atomic_t fscache_n_op_deferred_release; |
128 | extern atomic_t fscache_n_op_release; | 143 | extern atomic_t fscache_n_op_release; |
129 | extern atomic_t fscache_n_op_gc; | 144 | extern atomic_t fscache_n_op_gc; |
145 | extern atomic_t fscache_n_op_cancelled; | ||
146 | extern atomic_t fscache_n_op_rejected; | ||
130 | 147 | ||
131 | extern atomic_t fscache_n_attr_changed; | 148 | extern atomic_t fscache_n_attr_changed; |
132 | extern atomic_t fscache_n_attr_changed_ok; | 149 | extern atomic_t fscache_n_attr_changed_ok; |
@@ -138,6 +155,8 @@ extern atomic_t fscache_n_allocs; | |||
138 | extern atomic_t fscache_n_allocs_ok; | 155 | extern atomic_t fscache_n_allocs_ok; |
139 | extern atomic_t fscache_n_allocs_wait; | 156 | extern atomic_t fscache_n_allocs_wait; |
140 | extern atomic_t fscache_n_allocs_nobufs; | 157 | extern atomic_t fscache_n_allocs_nobufs; |
158 | extern atomic_t fscache_n_allocs_intr; | ||
159 | extern atomic_t fscache_n_allocs_object_dead; | ||
141 | extern atomic_t fscache_n_alloc_ops; | 160 | extern atomic_t fscache_n_alloc_ops; |
142 | extern atomic_t fscache_n_alloc_op_waits; | 161 | extern atomic_t fscache_n_alloc_op_waits; |
143 | 162 | ||
@@ -148,6 +167,7 @@ extern atomic_t fscache_n_retrievals_nodata; | |||
148 | extern atomic_t fscache_n_retrievals_nobufs; | 167 | extern atomic_t fscache_n_retrievals_nobufs; |
149 | extern atomic_t fscache_n_retrievals_intr; | 168 | extern atomic_t fscache_n_retrievals_intr; |
150 | extern atomic_t fscache_n_retrievals_nomem; | 169 | extern atomic_t fscache_n_retrievals_nomem; |
170 | extern atomic_t fscache_n_retrievals_object_dead; | ||
151 | extern atomic_t fscache_n_retrieval_ops; | 171 | extern atomic_t fscache_n_retrieval_ops; |
152 | extern atomic_t fscache_n_retrieval_op_waits; | 172 | extern atomic_t fscache_n_retrieval_op_waits; |
153 | 173 | ||
@@ -158,6 +178,14 @@ extern atomic_t fscache_n_stores_nobufs; | |||
158 | extern atomic_t fscache_n_stores_oom; | 178 | extern atomic_t fscache_n_stores_oom; |
159 | extern atomic_t fscache_n_store_ops; | 179 | extern atomic_t fscache_n_store_ops; |
160 | extern atomic_t fscache_n_store_calls; | 180 | extern atomic_t fscache_n_store_calls; |
181 | extern atomic_t fscache_n_store_pages; | ||
182 | extern atomic_t fscache_n_store_radix_deletes; | ||
183 | extern atomic_t fscache_n_store_pages_over_limit; | ||
184 | |||
185 | extern atomic_t fscache_n_store_vmscan_not_storing; | ||
186 | extern atomic_t fscache_n_store_vmscan_gone; | ||
187 | extern atomic_t fscache_n_store_vmscan_busy; | ||
188 | extern atomic_t fscache_n_store_vmscan_cancelled; | ||
161 | 189 | ||
162 | extern atomic_t fscache_n_marks; | 190 | extern atomic_t fscache_n_marks; |
163 | extern atomic_t fscache_n_uncaches; | 191 | extern atomic_t fscache_n_uncaches; |
@@ -176,6 +204,7 @@ extern atomic_t fscache_n_updates_run; | |||
176 | extern atomic_t fscache_n_relinquishes; | 204 | extern atomic_t fscache_n_relinquishes; |
177 | extern atomic_t fscache_n_relinquishes_null; | 205 | extern atomic_t fscache_n_relinquishes_null; |
178 | extern atomic_t fscache_n_relinquishes_waitcrt; | 206 | extern atomic_t fscache_n_relinquishes_waitcrt; |
207 | extern atomic_t fscache_n_relinquishes_retire; | ||
179 | 208 | ||
180 | extern atomic_t fscache_n_cookie_index; | 209 | extern atomic_t fscache_n_cookie_index; |
181 | extern atomic_t fscache_n_cookie_data; | 210 | extern atomic_t fscache_n_cookie_data; |
@@ -186,6 +215,7 @@ extern atomic_t fscache_n_object_no_alloc; | |||
186 | extern atomic_t fscache_n_object_lookups; | 215 | extern atomic_t fscache_n_object_lookups; |
187 | extern atomic_t fscache_n_object_lookups_negative; | 216 | extern atomic_t fscache_n_object_lookups_negative; |
188 | extern atomic_t fscache_n_object_lookups_positive; | 217 | extern atomic_t fscache_n_object_lookups_positive; |
218 | extern atomic_t fscache_n_object_lookups_timed_out; | ||
189 | extern atomic_t fscache_n_object_created; | 219 | extern atomic_t fscache_n_object_created; |
190 | extern atomic_t fscache_n_object_avail; | 220 | extern atomic_t fscache_n_object_avail; |
191 | extern atomic_t fscache_n_object_dead; | 221 | extern atomic_t fscache_n_object_dead; |
@@ -195,15 +225,41 @@ extern atomic_t fscache_n_checkaux_okay; | |||
195 | extern atomic_t fscache_n_checkaux_update; | 225 | extern atomic_t fscache_n_checkaux_update; |
196 | extern atomic_t fscache_n_checkaux_obsolete; | 226 | extern atomic_t fscache_n_checkaux_obsolete; |
197 | 227 | ||
228 | extern atomic_t fscache_n_cop_alloc_object; | ||
229 | extern atomic_t fscache_n_cop_lookup_object; | ||
230 | extern atomic_t fscache_n_cop_lookup_complete; | ||
231 | extern atomic_t fscache_n_cop_grab_object; | ||
232 | extern atomic_t fscache_n_cop_update_object; | ||
233 | extern atomic_t fscache_n_cop_drop_object; | ||
234 | extern atomic_t fscache_n_cop_put_object; | ||
235 | extern atomic_t fscache_n_cop_sync_cache; | ||
236 | extern atomic_t fscache_n_cop_attr_changed; | ||
237 | extern atomic_t fscache_n_cop_read_or_alloc_page; | ||
238 | extern atomic_t fscache_n_cop_read_or_alloc_pages; | ||
239 | extern atomic_t fscache_n_cop_allocate_page; | ||
240 | extern atomic_t fscache_n_cop_allocate_pages; | ||
241 | extern atomic_t fscache_n_cop_write_page; | ||
242 | extern atomic_t fscache_n_cop_uncache_page; | ||
243 | extern atomic_t fscache_n_cop_dissociate_pages; | ||
244 | |||
198 | static inline void fscache_stat(atomic_t *stat) | 245 | static inline void fscache_stat(atomic_t *stat) |
199 | { | 246 | { |
200 | atomic_inc(stat); | 247 | atomic_inc(stat); |
201 | } | 248 | } |
202 | 249 | ||
250 | static inline void fscache_stat_d(atomic_t *stat) | ||
251 | { | ||
252 | atomic_dec(stat); | ||
253 | } | ||
254 | |||
255 | #define __fscache_stat(stat) (stat) | ||
256 | |||
203 | extern const struct file_operations fscache_stats_fops; | 257 | extern const struct file_operations fscache_stats_fops; |
204 | #else | 258 | #else |
205 | 259 | ||
260 | #define __fscache_stat(stat) (NULL) | ||
206 | #define fscache_stat(stat) do {} while (0) | 261 | #define fscache_stat(stat) do {} while (0) |
262 | #define fscache_stat_d(stat) do {} while (0) | ||
207 | #endif | 263 | #endif |
208 | 264 | ||
209 | /* | 265 | /* |
diff --git a/fs/fscache/main.c b/fs/fscache/main.c index 4de41b597499..add6bdb53f04 100644 --- a/fs/fscache/main.c +++ b/fs/fscache/main.c | |||
@@ -48,7 +48,7 @@ static int __init fscache_init(void) | |||
48 | { | 48 | { |
49 | int ret; | 49 | int ret; |
50 | 50 | ||
51 | ret = slow_work_register_user(); | 51 | ret = slow_work_register_user(THIS_MODULE); |
52 | if (ret < 0) | 52 | if (ret < 0) |
53 | goto error_slow_work; | 53 | goto error_slow_work; |
54 | 54 | ||
@@ -80,7 +80,7 @@ error_kobj: | |||
80 | error_cookie_jar: | 80 | error_cookie_jar: |
81 | fscache_proc_cleanup(); | 81 | fscache_proc_cleanup(); |
82 | error_proc: | 82 | error_proc: |
83 | slow_work_unregister_user(); | 83 | slow_work_unregister_user(THIS_MODULE); |
84 | error_slow_work: | 84 | error_slow_work: |
85 | return ret; | 85 | return ret; |
86 | } | 86 | } |
@@ -97,7 +97,7 @@ static void __exit fscache_exit(void) | |||
97 | kobject_put(fscache_root); | 97 | kobject_put(fscache_root); |
98 | kmem_cache_destroy(fscache_cookie_jar); | 98 | kmem_cache_destroy(fscache_cookie_jar); |
99 | fscache_proc_cleanup(); | 99 | fscache_proc_cleanup(); |
100 | slow_work_unregister_user(); | 100 | slow_work_unregister_user(THIS_MODULE); |
101 | printk(KERN_NOTICE "FS-Cache: Unloaded\n"); | 101 | printk(KERN_NOTICE "FS-Cache: Unloaded\n"); |
102 | } | 102 | } |
103 | 103 | ||
diff --git a/fs/fscache/object-list.c b/fs/fscache/object-list.c new file mode 100644 index 000000000000..e590242fa41a --- /dev/null +++ b/fs/fscache/object-list.c | |||
@@ -0,0 +1,432 @@ | |||
1 | /* Global fscache object list maintainer and viewer | ||
2 | * | ||
3 | * Copyright (C) 2009 Red Hat, Inc. All Rights Reserved. | ||
4 | * Written by David Howells (dhowells@redhat.com) | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or | ||
7 | * modify it under the terms of the GNU General Public Licence | ||
8 | * as published by the Free Software Foundation; either version | ||
9 | * 2 of the Licence, or (at your option) any later version. | ||
10 | */ | ||
11 | |||
12 | #define FSCACHE_DEBUG_LEVEL COOKIE | ||
13 | #include <linux/module.h> | ||
14 | #include <linux/seq_file.h> | ||
15 | #include <linux/key.h> | ||
16 | #include <keys/user-type.h> | ||
17 | #include "internal.h" | ||
18 | |||
19 | static struct rb_root fscache_object_list; | ||
20 | static DEFINE_RWLOCK(fscache_object_list_lock); | ||
21 | |||
22 | struct fscache_objlist_data { | ||
23 | unsigned long config; /* display configuration */ | ||
24 | #define FSCACHE_OBJLIST_CONFIG_KEY 0x00000001 /* show object keys */ | ||
25 | #define FSCACHE_OBJLIST_CONFIG_AUX 0x00000002 /* show object auxdata */ | ||
26 | #define FSCACHE_OBJLIST_CONFIG_COOKIE 0x00000004 /* show objects with cookies */ | ||
27 | #define FSCACHE_OBJLIST_CONFIG_NOCOOKIE 0x00000008 /* show objects without cookies */ | ||
28 | #define FSCACHE_OBJLIST_CONFIG_BUSY 0x00000010 /* show busy objects */ | ||
29 | #define FSCACHE_OBJLIST_CONFIG_IDLE 0x00000020 /* show idle objects */ | ||
30 | #define FSCACHE_OBJLIST_CONFIG_PENDWR 0x00000040 /* show objects with pending writes */ | ||
31 | #define FSCACHE_OBJLIST_CONFIG_NOPENDWR 0x00000080 /* show objects without pending writes */ | ||
32 | #define FSCACHE_OBJLIST_CONFIG_READS 0x00000100 /* show objects with active reads */ | ||
33 | #define FSCACHE_OBJLIST_CONFIG_NOREADS 0x00000200 /* show objects without active reads */ | ||
34 | #define FSCACHE_OBJLIST_CONFIG_EVENTS 0x00000400 /* show objects with events */ | ||
35 | #define FSCACHE_OBJLIST_CONFIG_NOEVENTS 0x00000800 /* show objects without no events */ | ||
36 | #define FSCACHE_OBJLIST_CONFIG_WORK 0x00001000 /* show objects with slow work */ | ||
37 | #define FSCACHE_OBJLIST_CONFIG_NOWORK 0x00002000 /* show objects without slow work */ | ||
38 | |||
39 | u8 buf[512]; /* key and aux data buffer */ | ||
40 | }; | ||
41 | |||
42 | /* | ||
43 | * Add an object to the object list | ||
44 | * - we use the address of the fscache_object structure as the key into the | ||
45 | * tree | ||
46 | */ | ||
47 | void fscache_objlist_add(struct fscache_object *obj) | ||
48 | { | ||
49 | struct fscache_object *xobj; | ||
50 | struct rb_node **p = &fscache_object_list.rb_node, *parent = NULL; | ||
51 | |||
52 | write_lock(&fscache_object_list_lock); | ||
53 | |||
54 | while (*p) { | ||
55 | parent = *p; | ||
56 | xobj = rb_entry(parent, struct fscache_object, objlist_link); | ||
57 | |||
58 | if (obj < xobj) | ||
59 | p = &(*p)->rb_left; | ||
60 | else if (obj > xobj) | ||
61 | p = &(*p)->rb_right; | ||
62 | else | ||
63 | BUG(); | ||
64 | } | ||
65 | |||
66 | rb_link_node(&obj->objlist_link, parent, p); | ||
67 | rb_insert_color(&obj->objlist_link, &fscache_object_list); | ||
68 | |||
69 | write_unlock(&fscache_object_list_lock); | ||
70 | } | ||
71 | |||
72 | /** | ||
73 | * fscache_object_destroy - Note that a cache object is about to be destroyed | ||
74 | * @object: The object to be destroyed | ||
75 | * | ||
76 | * Note the imminent destruction and deallocation of a cache object record. | ||
77 | */ | ||
78 | void fscache_object_destroy(struct fscache_object *obj) | ||
79 | { | ||
80 | write_lock(&fscache_object_list_lock); | ||
81 | |||
82 | BUG_ON(RB_EMPTY_ROOT(&fscache_object_list)); | ||
83 | rb_erase(&obj->objlist_link, &fscache_object_list); | ||
84 | |||
85 | write_unlock(&fscache_object_list_lock); | ||
86 | } | ||
87 | EXPORT_SYMBOL(fscache_object_destroy); | ||
88 | |||
89 | /* | ||
90 | * find the object in the tree on or after the specified index | ||
91 | */ | ||
92 | static struct fscache_object *fscache_objlist_lookup(loff_t *_pos) | ||
93 | { | ||
94 | struct fscache_object *pobj, *obj, *minobj = NULL; | ||
95 | struct rb_node *p; | ||
96 | unsigned long pos; | ||
97 | |||
98 | if (*_pos >= (unsigned long) ERR_PTR(-ENOENT)) | ||
99 | return NULL; | ||
100 | pos = *_pos; | ||
101 | |||
102 | /* banners (can't represent line 0 by pos 0 as that would involve | ||
103 | * returning a NULL pointer) */ | ||
104 | if (pos == 0) | ||
105 | return (struct fscache_object *) ++(*_pos); | ||
106 | if (pos < 3) | ||
107 | return (struct fscache_object *)pos; | ||
108 | |||
109 | pobj = (struct fscache_object *)pos; | ||
110 | p = fscache_object_list.rb_node; | ||
111 | while (p) { | ||
112 | obj = rb_entry(p, struct fscache_object, objlist_link); | ||
113 | if (pobj < obj) { | ||
114 | if (!minobj || minobj > obj) | ||
115 | minobj = obj; | ||
116 | p = p->rb_left; | ||
117 | } else if (pobj > obj) { | ||
118 | p = p->rb_right; | ||
119 | } else { | ||
120 | minobj = obj; | ||
121 | break; | ||
122 | } | ||
123 | obj = NULL; | ||
124 | } | ||
125 | |||
126 | if (!minobj) | ||
127 | *_pos = (unsigned long) ERR_PTR(-ENOENT); | ||
128 | else if (minobj != obj) | ||
129 | *_pos = (unsigned long) minobj; | ||
130 | return minobj; | ||
131 | } | ||
132 | |||
133 | /* | ||
134 | * set up the iterator to start reading from the first line | ||
135 | */ | ||
136 | static void *fscache_objlist_start(struct seq_file *m, loff_t *_pos) | ||
137 | __acquires(&fscache_object_list_lock) | ||
138 | { | ||
139 | read_lock(&fscache_object_list_lock); | ||
140 | return fscache_objlist_lookup(_pos); | ||
141 | } | ||
142 | |||
143 | /* | ||
144 | * move to the next line | ||
145 | */ | ||
146 | static void *fscache_objlist_next(struct seq_file *m, void *v, loff_t *_pos) | ||
147 | { | ||
148 | (*_pos)++; | ||
149 | return fscache_objlist_lookup(_pos); | ||
150 | } | ||
151 | |||
152 | /* | ||
153 | * clean up after reading | ||
154 | */ | ||
155 | static void fscache_objlist_stop(struct seq_file *m, void *v) | ||
156 | __releases(&fscache_object_list_lock) | ||
157 | { | ||
158 | read_unlock(&fscache_object_list_lock); | ||
159 | } | ||
160 | |||
161 | /* | ||
162 | * display an object | ||
163 | */ | ||
164 | static int fscache_objlist_show(struct seq_file *m, void *v) | ||
165 | { | ||
166 | struct fscache_objlist_data *data = m->private; | ||
167 | struct fscache_object *obj = v; | ||
168 | unsigned long config = data->config; | ||
169 | uint16_t keylen, auxlen; | ||
170 | char _type[3], *type; | ||
171 | bool no_cookie; | ||
172 | u8 *buf = data->buf, *p; | ||
173 | |||
174 | if ((unsigned long) v == 1) { | ||
175 | seq_puts(m, "OBJECT PARENT STAT CHLDN OPS OOP IPR EX READS" | ||
176 | " EM EV F S" | ||
177 | " | NETFS_COOKIE_DEF TY FL NETFS_DATA"); | ||
178 | if (config & (FSCACHE_OBJLIST_CONFIG_KEY | | ||
179 | FSCACHE_OBJLIST_CONFIG_AUX)) | ||
180 | seq_puts(m, " "); | ||
181 | if (config & FSCACHE_OBJLIST_CONFIG_KEY) | ||
182 | seq_puts(m, "OBJECT_KEY"); | ||
183 | if ((config & (FSCACHE_OBJLIST_CONFIG_KEY | | ||
184 | FSCACHE_OBJLIST_CONFIG_AUX)) == | ||
185 | (FSCACHE_OBJLIST_CONFIG_KEY | FSCACHE_OBJLIST_CONFIG_AUX)) | ||
186 | seq_puts(m, ", "); | ||
187 | if (config & FSCACHE_OBJLIST_CONFIG_AUX) | ||
188 | seq_puts(m, "AUX_DATA"); | ||
189 | seq_puts(m, "\n"); | ||
190 | return 0; | ||
191 | } | ||
192 | |||
193 | if ((unsigned long) v == 2) { | ||
194 | seq_puts(m, "======== ======== ==== ===== === === === == =====" | ||
195 | " == == = =" | ||
196 | " | ================ == == ================"); | ||
197 | if (config & (FSCACHE_OBJLIST_CONFIG_KEY | | ||
198 | FSCACHE_OBJLIST_CONFIG_AUX)) | ||
199 | seq_puts(m, " ================"); | ||
200 | seq_puts(m, "\n"); | ||
201 | return 0; | ||
202 | } | ||
203 | |||
204 | /* filter out any unwanted objects */ | ||
205 | #define FILTER(criterion, _yes, _no) \ | ||
206 | do { \ | ||
207 | unsigned long yes = FSCACHE_OBJLIST_CONFIG_##_yes; \ | ||
208 | unsigned long no = FSCACHE_OBJLIST_CONFIG_##_no; \ | ||
209 | if (criterion) { \ | ||
210 | if (!(config & yes)) \ | ||
211 | return 0; \ | ||
212 | } else { \ | ||
213 | if (!(config & no)) \ | ||
214 | return 0; \ | ||
215 | } \ | ||
216 | } while(0) | ||
217 | |||
218 | if (~config) { | ||
219 | FILTER(obj->cookie, | ||
220 | COOKIE, NOCOOKIE); | ||
221 | FILTER(obj->state != FSCACHE_OBJECT_ACTIVE || | ||
222 | obj->n_ops != 0 || | ||
223 | obj->n_obj_ops != 0 || | ||
224 | obj->flags || | ||
225 | !list_empty(&obj->dependents), | ||
226 | BUSY, IDLE); | ||
227 | FILTER(test_bit(FSCACHE_OBJECT_PENDING_WRITE, &obj->flags), | ||
228 | PENDWR, NOPENDWR); | ||
229 | FILTER(atomic_read(&obj->n_reads), | ||
230 | READS, NOREADS); | ||
231 | FILTER(obj->events & obj->event_mask, | ||
232 | EVENTS, NOEVENTS); | ||
233 | FILTER(obj->work.flags & ~(1UL << SLOW_WORK_VERY_SLOW), | ||
234 | WORK, NOWORK); | ||
235 | } | ||
236 | |||
237 | seq_printf(m, | ||
238 | "%8x %8x %s %5u %3u %3u %3u %2u %5u %2lx %2lx %1lx %1lx | ", | ||
239 | obj->debug_id, | ||
240 | obj->parent ? obj->parent->debug_id : -1, | ||
241 | fscache_object_states_short[obj->state], | ||
242 | obj->n_children, | ||
243 | obj->n_ops, | ||
244 | obj->n_obj_ops, | ||
245 | obj->n_in_progress, | ||
246 | obj->n_exclusive, | ||
247 | atomic_read(&obj->n_reads), | ||
248 | obj->event_mask & FSCACHE_OBJECT_EVENTS_MASK, | ||
249 | obj->events, | ||
250 | obj->flags, | ||
251 | obj->work.flags); | ||
252 | |||
253 | no_cookie = true; | ||
254 | keylen = auxlen = 0; | ||
255 | if (obj->cookie) { | ||
256 | spin_lock(&obj->lock); | ||
257 | if (obj->cookie) { | ||
258 | switch (obj->cookie->def->type) { | ||
259 | case 0: | ||
260 | type = "IX"; | ||
261 | break; | ||
262 | case 1: | ||
263 | type = "DT"; | ||
264 | break; | ||
265 | default: | ||
266 | sprintf(_type, "%02u", | ||
267 | obj->cookie->def->type); | ||
268 | type = _type; | ||
269 | break; | ||
270 | } | ||
271 | |||
272 | seq_printf(m, "%-16s %s %2lx %16p", | ||
273 | obj->cookie->def->name, | ||
274 | type, | ||
275 | obj->cookie->flags, | ||
276 | obj->cookie->netfs_data); | ||
277 | |||
278 | if (obj->cookie->def->get_key && | ||
279 | config & FSCACHE_OBJLIST_CONFIG_KEY) | ||
280 | keylen = obj->cookie->def->get_key( | ||
281 | obj->cookie->netfs_data, | ||
282 | buf, 400); | ||
283 | |||
284 | if (obj->cookie->def->get_aux && | ||
285 | config & FSCACHE_OBJLIST_CONFIG_AUX) | ||
286 | auxlen = obj->cookie->def->get_aux( | ||
287 | obj->cookie->netfs_data, | ||
288 | buf + keylen, 512 - keylen); | ||
289 | |||
290 | no_cookie = false; | ||
291 | } | ||
292 | spin_unlock(&obj->lock); | ||
293 | |||
294 | if (!no_cookie && (keylen > 0 || auxlen > 0)) { | ||
295 | seq_printf(m, " "); | ||
296 | for (p = buf; keylen > 0; keylen--) | ||
297 | seq_printf(m, "%02x", *p++); | ||
298 | if (auxlen > 0) { | ||
299 | if (config & FSCACHE_OBJLIST_CONFIG_KEY) | ||
300 | seq_printf(m, ", "); | ||
301 | for (; auxlen > 0; auxlen--) | ||
302 | seq_printf(m, "%02x", *p++); | ||
303 | } | ||
304 | } | ||
305 | } | ||
306 | |||
307 | if (no_cookie) | ||
308 | seq_printf(m, "<no_cookie>\n"); | ||
309 | else | ||
310 | seq_printf(m, "\n"); | ||
311 | return 0; | ||
312 | } | ||
313 | |||
314 | static const struct seq_operations fscache_objlist_ops = { | ||
315 | .start = fscache_objlist_start, | ||
316 | .stop = fscache_objlist_stop, | ||
317 | .next = fscache_objlist_next, | ||
318 | .show = fscache_objlist_show, | ||
319 | }; | ||
320 | |||
321 | /* | ||
322 | * get the configuration for filtering the list | ||
323 | */ | ||
324 | static void fscache_objlist_config(struct fscache_objlist_data *data) | ||
325 | { | ||
326 | #ifdef CONFIG_KEYS | ||
327 | struct user_key_payload *confkey; | ||
328 | unsigned long config; | ||
329 | struct key *key; | ||
330 | const char *buf; | ||
331 | int len; | ||
332 | |||
333 | key = request_key(&key_type_user, "fscache:objlist", NULL); | ||
334 | if (IS_ERR(key)) | ||
335 | goto no_config; | ||
336 | |||
337 | config = 0; | ||
338 | rcu_read_lock(); | ||
339 | |||
340 | confkey = key->payload.data; | ||
341 | buf = confkey->data; | ||
342 | |||
343 | for (len = confkey->datalen - 1; len >= 0; len--) { | ||
344 | switch (buf[len]) { | ||
345 | case 'K': config |= FSCACHE_OBJLIST_CONFIG_KEY; break; | ||
346 | case 'A': config |= FSCACHE_OBJLIST_CONFIG_AUX; break; | ||
347 | case 'C': config |= FSCACHE_OBJLIST_CONFIG_COOKIE; break; | ||
348 | case 'c': config |= FSCACHE_OBJLIST_CONFIG_NOCOOKIE; break; | ||
349 | case 'B': config |= FSCACHE_OBJLIST_CONFIG_BUSY; break; | ||
350 | case 'b': config |= FSCACHE_OBJLIST_CONFIG_IDLE; break; | ||
351 | case 'W': config |= FSCACHE_OBJLIST_CONFIG_PENDWR; break; | ||
352 | case 'w': config |= FSCACHE_OBJLIST_CONFIG_NOPENDWR; break; | ||
353 | case 'R': config |= FSCACHE_OBJLIST_CONFIG_READS; break; | ||
354 | case 'r': config |= FSCACHE_OBJLIST_CONFIG_NOREADS; break; | ||
355 | case 'S': config |= FSCACHE_OBJLIST_CONFIG_WORK; break; | ||
356 | case 's': config |= FSCACHE_OBJLIST_CONFIG_NOWORK; break; | ||
357 | } | ||
358 | } | ||
359 | |||
360 | rcu_read_unlock(); | ||
361 | key_put(key); | ||
362 | |||
363 | if (!(config & (FSCACHE_OBJLIST_CONFIG_COOKIE | FSCACHE_OBJLIST_CONFIG_NOCOOKIE))) | ||
364 | config |= FSCACHE_OBJLIST_CONFIG_COOKIE | FSCACHE_OBJLIST_CONFIG_NOCOOKIE; | ||
365 | if (!(config & (FSCACHE_OBJLIST_CONFIG_BUSY | FSCACHE_OBJLIST_CONFIG_IDLE))) | ||
366 | config |= FSCACHE_OBJLIST_CONFIG_BUSY | FSCACHE_OBJLIST_CONFIG_IDLE; | ||
367 | if (!(config & (FSCACHE_OBJLIST_CONFIG_PENDWR | FSCACHE_OBJLIST_CONFIG_NOPENDWR))) | ||
368 | config |= FSCACHE_OBJLIST_CONFIG_PENDWR | FSCACHE_OBJLIST_CONFIG_NOPENDWR; | ||
369 | if (!(config & (FSCACHE_OBJLIST_CONFIG_READS | FSCACHE_OBJLIST_CONFIG_NOREADS))) | ||
370 | config |= FSCACHE_OBJLIST_CONFIG_READS | FSCACHE_OBJLIST_CONFIG_NOREADS; | ||
371 | if (!(config & (FSCACHE_OBJLIST_CONFIG_EVENTS | FSCACHE_OBJLIST_CONFIG_NOEVENTS))) | ||
372 | config |= FSCACHE_OBJLIST_CONFIG_EVENTS | FSCACHE_OBJLIST_CONFIG_NOEVENTS; | ||
373 | if (!(config & (FSCACHE_OBJLIST_CONFIG_WORK | FSCACHE_OBJLIST_CONFIG_NOWORK))) | ||
374 | config |= FSCACHE_OBJLIST_CONFIG_WORK | FSCACHE_OBJLIST_CONFIG_NOWORK; | ||
375 | |||
376 | data->config = config; | ||
377 | return; | ||
378 | |||
379 | no_config: | ||
380 | #endif | ||
381 | data->config = ULONG_MAX; | ||
382 | } | ||
383 | |||
384 | /* | ||
385 | * open "/proc/fs/fscache/objects" to provide a list of active objects | ||
386 | * - can be configured by a user-defined key added to the caller's keyrings | ||
387 | */ | ||
388 | static int fscache_objlist_open(struct inode *inode, struct file *file) | ||
389 | { | ||
390 | struct fscache_objlist_data *data; | ||
391 | struct seq_file *m; | ||
392 | int ret; | ||
393 | |||
394 | ret = seq_open(file, &fscache_objlist_ops); | ||
395 | if (ret < 0) | ||
396 | return ret; | ||
397 | |||
398 | m = file->private_data; | ||
399 | |||
400 | /* buffer for key extraction */ | ||
401 | data = kmalloc(sizeof(struct fscache_objlist_data), GFP_KERNEL); | ||
402 | if (!data) { | ||
403 | seq_release(inode, file); | ||
404 | return -ENOMEM; | ||
405 | } | ||
406 | |||
407 | /* get the configuration key */ | ||
408 | fscache_objlist_config(data); | ||
409 | |||
410 | m->private = data; | ||
411 | return 0; | ||
412 | } | ||
413 | |||
414 | /* | ||
415 | * clean up on close | ||
416 | */ | ||
417 | static int fscache_objlist_release(struct inode *inode, struct file *file) | ||
418 | { | ||
419 | struct seq_file *m = file->private_data; | ||
420 | |||
421 | kfree(m->private); | ||
422 | m->private = NULL; | ||
423 | return seq_release(inode, file); | ||
424 | } | ||
425 | |||
426 | const struct file_operations fscache_objlist_fops = { | ||
427 | .owner = THIS_MODULE, | ||
428 | .open = fscache_objlist_open, | ||
429 | .read = seq_read, | ||
430 | .llseek = seq_lseek, | ||
431 | .release = fscache_objlist_release, | ||
432 | }; | ||
diff --git a/fs/fscache/object.c b/fs/fscache/object.c index 392a41b1b79d..e513ac599c8e 100644 --- a/fs/fscache/object.c +++ b/fs/fscache/object.c | |||
@@ -14,9 +14,10 @@ | |||
14 | 14 | ||
15 | #define FSCACHE_DEBUG_LEVEL COOKIE | 15 | #define FSCACHE_DEBUG_LEVEL COOKIE |
16 | #include <linux/module.h> | 16 | #include <linux/module.h> |
17 | #include <linux/seq_file.h> | ||
17 | #include "internal.h" | 18 | #include "internal.h" |
18 | 19 | ||
19 | const char *fscache_object_states[] = { | 20 | const char *fscache_object_states[FSCACHE_OBJECT__NSTATES] = { |
20 | [FSCACHE_OBJECT_INIT] = "OBJECT_INIT", | 21 | [FSCACHE_OBJECT_INIT] = "OBJECT_INIT", |
21 | [FSCACHE_OBJECT_LOOKING_UP] = "OBJECT_LOOKING_UP", | 22 | [FSCACHE_OBJECT_LOOKING_UP] = "OBJECT_LOOKING_UP", |
22 | [FSCACHE_OBJECT_CREATING] = "OBJECT_CREATING", | 23 | [FSCACHE_OBJECT_CREATING] = "OBJECT_CREATING", |
@@ -33,9 +34,28 @@ const char *fscache_object_states[] = { | |||
33 | }; | 34 | }; |
34 | EXPORT_SYMBOL(fscache_object_states); | 35 | EXPORT_SYMBOL(fscache_object_states); |
35 | 36 | ||
37 | const char fscache_object_states_short[FSCACHE_OBJECT__NSTATES][5] = { | ||
38 | [FSCACHE_OBJECT_INIT] = "INIT", | ||
39 | [FSCACHE_OBJECT_LOOKING_UP] = "LOOK", | ||
40 | [FSCACHE_OBJECT_CREATING] = "CRTN", | ||
41 | [FSCACHE_OBJECT_AVAILABLE] = "AVBL", | ||
42 | [FSCACHE_OBJECT_ACTIVE] = "ACTV", | ||
43 | [FSCACHE_OBJECT_UPDATING] = "UPDT", | ||
44 | [FSCACHE_OBJECT_DYING] = "DYNG", | ||
45 | [FSCACHE_OBJECT_LC_DYING] = "LCDY", | ||
46 | [FSCACHE_OBJECT_ABORT_INIT] = "ABTI", | ||
47 | [FSCACHE_OBJECT_RELEASING] = "RELS", | ||
48 | [FSCACHE_OBJECT_RECYCLING] = "RCYC", | ||
49 | [FSCACHE_OBJECT_WITHDRAWING] = "WTHD", | ||
50 | [FSCACHE_OBJECT_DEAD] = "DEAD", | ||
51 | }; | ||
52 | |||
36 | static void fscache_object_slow_work_put_ref(struct slow_work *); | 53 | static void fscache_object_slow_work_put_ref(struct slow_work *); |
37 | static int fscache_object_slow_work_get_ref(struct slow_work *); | 54 | static int fscache_object_slow_work_get_ref(struct slow_work *); |
38 | static void fscache_object_slow_work_execute(struct slow_work *); | 55 | static void fscache_object_slow_work_execute(struct slow_work *); |
56 | #ifdef CONFIG_SLOW_WORK_PROC | ||
57 | static void fscache_object_slow_work_desc(struct slow_work *, struct seq_file *); | ||
58 | #endif | ||
39 | static void fscache_initialise_object(struct fscache_object *); | 59 | static void fscache_initialise_object(struct fscache_object *); |
40 | static void fscache_lookup_object(struct fscache_object *); | 60 | static void fscache_lookup_object(struct fscache_object *); |
41 | static void fscache_object_available(struct fscache_object *); | 61 | static void fscache_object_available(struct fscache_object *); |
@@ -45,9 +65,13 @@ static void fscache_enqueue_dependents(struct fscache_object *); | |||
45 | static void fscache_dequeue_object(struct fscache_object *); | 65 | static void fscache_dequeue_object(struct fscache_object *); |
46 | 66 | ||
47 | const struct slow_work_ops fscache_object_slow_work_ops = { | 67 | const struct slow_work_ops fscache_object_slow_work_ops = { |
68 | .owner = THIS_MODULE, | ||
48 | .get_ref = fscache_object_slow_work_get_ref, | 69 | .get_ref = fscache_object_slow_work_get_ref, |
49 | .put_ref = fscache_object_slow_work_put_ref, | 70 | .put_ref = fscache_object_slow_work_put_ref, |
50 | .execute = fscache_object_slow_work_execute, | 71 | .execute = fscache_object_slow_work_execute, |
72 | #ifdef CONFIG_SLOW_WORK_PROC | ||
73 | .desc = fscache_object_slow_work_desc, | ||
74 | #endif | ||
51 | }; | 75 | }; |
52 | EXPORT_SYMBOL(fscache_object_slow_work_ops); | 76 | EXPORT_SYMBOL(fscache_object_slow_work_ops); |
53 | 77 | ||
@@ -81,6 +105,7 @@ static inline void fscache_done_parent_op(struct fscache_object *object) | |||
81 | static void fscache_object_state_machine(struct fscache_object *object) | 105 | static void fscache_object_state_machine(struct fscache_object *object) |
82 | { | 106 | { |
83 | enum fscache_object_state new_state; | 107 | enum fscache_object_state new_state; |
108 | struct fscache_cookie *cookie; | ||
84 | 109 | ||
85 | ASSERT(object != NULL); | 110 | ASSERT(object != NULL); |
86 | 111 | ||
@@ -120,20 +145,31 @@ static void fscache_object_state_machine(struct fscache_object *object) | |||
120 | case FSCACHE_OBJECT_UPDATING: | 145 | case FSCACHE_OBJECT_UPDATING: |
121 | clear_bit(FSCACHE_OBJECT_EV_UPDATE, &object->events); | 146 | clear_bit(FSCACHE_OBJECT_EV_UPDATE, &object->events); |
122 | fscache_stat(&fscache_n_updates_run); | 147 | fscache_stat(&fscache_n_updates_run); |
148 | fscache_stat(&fscache_n_cop_update_object); | ||
123 | object->cache->ops->update_object(object); | 149 | object->cache->ops->update_object(object); |
150 | fscache_stat_d(&fscache_n_cop_update_object); | ||
124 | goto active_transit; | 151 | goto active_transit; |
125 | 152 | ||
126 | /* handle an object dying during lookup or creation */ | 153 | /* handle an object dying during lookup or creation */ |
127 | case FSCACHE_OBJECT_LC_DYING: | 154 | case FSCACHE_OBJECT_LC_DYING: |
128 | object->event_mask &= ~(1 << FSCACHE_OBJECT_EV_UPDATE); | 155 | object->event_mask &= ~(1 << FSCACHE_OBJECT_EV_UPDATE); |
156 | fscache_stat(&fscache_n_cop_lookup_complete); | ||
129 | object->cache->ops->lookup_complete(object); | 157 | object->cache->ops->lookup_complete(object); |
158 | fscache_stat_d(&fscache_n_cop_lookup_complete); | ||
130 | 159 | ||
131 | spin_lock(&object->lock); | 160 | spin_lock(&object->lock); |
132 | object->state = FSCACHE_OBJECT_DYING; | 161 | object->state = FSCACHE_OBJECT_DYING; |
133 | if (test_and_clear_bit(FSCACHE_COOKIE_CREATING, | 162 | cookie = object->cookie; |
134 | &object->cookie->flags)) | 163 | if (cookie) { |
135 | wake_up_bit(&object->cookie->flags, | 164 | if (test_and_clear_bit(FSCACHE_COOKIE_LOOKING_UP, |
136 | FSCACHE_COOKIE_CREATING); | 165 | &cookie->flags)) |
166 | wake_up_bit(&cookie->flags, | ||
167 | FSCACHE_COOKIE_LOOKING_UP); | ||
168 | if (test_and_clear_bit(FSCACHE_COOKIE_CREATING, | ||
169 | &cookie->flags)) | ||
170 | wake_up_bit(&cookie->flags, | ||
171 | FSCACHE_COOKIE_CREATING); | ||
172 | } | ||
137 | spin_unlock(&object->lock); | 173 | spin_unlock(&object->lock); |
138 | 174 | ||
139 | fscache_done_parent_op(object); | 175 | fscache_done_parent_op(object); |
@@ -165,6 +201,7 @@ static void fscache_object_state_machine(struct fscache_object *object) | |||
165 | } | 201 | } |
166 | spin_unlock(&object->lock); | 202 | spin_unlock(&object->lock); |
167 | fscache_enqueue_dependents(object); | 203 | fscache_enqueue_dependents(object); |
204 | fscache_start_operations(object); | ||
168 | goto terminal_transit; | 205 | goto terminal_transit; |
169 | 206 | ||
170 | /* handle an abort during initialisation */ | 207 | /* handle an abort during initialisation */ |
@@ -316,14 +353,29 @@ static void fscache_object_slow_work_execute(struct slow_work *work) | |||
316 | 353 | ||
317 | _enter("{OBJ%x}", object->debug_id); | 354 | _enter("{OBJ%x}", object->debug_id); |
318 | 355 | ||
319 | clear_bit(FSCACHE_OBJECT_EV_REQUEUE, &object->events); | ||
320 | |||
321 | start = jiffies; | 356 | start = jiffies; |
322 | fscache_object_state_machine(object); | 357 | fscache_object_state_machine(object); |
323 | fscache_hist(fscache_objs_histogram, start); | 358 | fscache_hist(fscache_objs_histogram, start); |
324 | if (object->events & object->event_mask) | 359 | if (object->events & object->event_mask) |
325 | fscache_enqueue_object(object); | 360 | fscache_enqueue_object(object); |
361 | clear_bit(FSCACHE_OBJECT_EV_REQUEUE, &object->events); | ||
362 | } | ||
363 | |||
364 | /* | ||
365 | * describe an object for slow-work debugging | ||
366 | */ | ||
367 | #ifdef CONFIG_SLOW_WORK_PROC | ||
368 | static void fscache_object_slow_work_desc(struct slow_work *work, | ||
369 | struct seq_file *m) | ||
370 | { | ||
371 | struct fscache_object *object = | ||
372 | container_of(work, struct fscache_object, work); | ||
373 | |||
374 | seq_printf(m, "FSC: OBJ%x: %s", | ||
375 | object->debug_id, | ||
376 | fscache_object_states_short[object->state]); | ||
326 | } | 377 | } |
378 | #endif | ||
327 | 379 | ||
328 | /* | 380 | /* |
329 | * initialise an object | 381 | * initialise an object |
@@ -376,7 +428,9 @@ static void fscache_initialise_object(struct fscache_object *object) | |||
376 | * binding on to us, so we need to make sure we don't | 428 | * binding on to us, so we need to make sure we don't |
377 | * add ourself to the list multiple times */ | 429 | * add ourself to the list multiple times */ |
378 | if (list_empty(&object->dep_link)) { | 430 | if (list_empty(&object->dep_link)) { |
431 | fscache_stat(&fscache_n_cop_grab_object); | ||
379 | object->cache->ops->grab_object(object); | 432 | object->cache->ops->grab_object(object); |
433 | fscache_stat_d(&fscache_n_cop_grab_object); | ||
380 | list_add(&object->dep_link, | 434 | list_add(&object->dep_link, |
381 | &parent->dependents); | 435 | &parent->dependents); |
382 | 436 | ||
@@ -414,6 +468,7 @@ static void fscache_lookup_object(struct fscache_object *object) | |||
414 | { | 468 | { |
415 | struct fscache_cookie *cookie = object->cookie; | 469 | struct fscache_cookie *cookie = object->cookie; |
416 | struct fscache_object *parent; | 470 | struct fscache_object *parent; |
471 | int ret; | ||
417 | 472 | ||
418 | _enter(""); | 473 | _enter(""); |
419 | 474 | ||
@@ -438,11 +493,20 @@ static void fscache_lookup_object(struct fscache_object *object) | |||
438 | object->cache->tag->name); | 493 | object->cache->tag->name); |
439 | 494 | ||
440 | fscache_stat(&fscache_n_object_lookups); | 495 | fscache_stat(&fscache_n_object_lookups); |
441 | object->cache->ops->lookup_object(object); | 496 | fscache_stat(&fscache_n_cop_lookup_object); |
497 | ret = object->cache->ops->lookup_object(object); | ||
498 | fscache_stat_d(&fscache_n_cop_lookup_object); | ||
442 | 499 | ||
443 | if (test_bit(FSCACHE_OBJECT_EV_ERROR, &object->events)) | 500 | if (test_bit(FSCACHE_OBJECT_EV_ERROR, &object->events)) |
444 | set_bit(FSCACHE_COOKIE_UNAVAILABLE, &cookie->flags); | 501 | set_bit(FSCACHE_COOKIE_UNAVAILABLE, &cookie->flags); |
445 | 502 | ||
503 | if (ret == -ETIMEDOUT) { | ||
504 | /* probably stuck behind another object, so move this one to | ||
505 | * the back of the queue */ | ||
506 | fscache_stat(&fscache_n_object_lookups_timed_out); | ||
507 | set_bit(FSCACHE_OBJECT_EV_REQUEUE, &object->events); | ||
508 | } | ||
509 | |||
446 | _leave(""); | 510 | _leave(""); |
447 | } | 511 | } |
448 | 512 | ||
@@ -546,7 +610,8 @@ static void fscache_object_available(struct fscache_object *object) | |||
546 | 610 | ||
547 | spin_lock(&object->lock); | 611 | spin_lock(&object->lock); |
548 | 612 | ||
549 | if (test_and_clear_bit(FSCACHE_COOKIE_CREATING, &object->cookie->flags)) | 613 | if (object->cookie && |
614 | test_and_clear_bit(FSCACHE_COOKIE_CREATING, &object->cookie->flags)) | ||
550 | wake_up_bit(&object->cookie->flags, FSCACHE_COOKIE_CREATING); | 615 | wake_up_bit(&object->cookie->flags, FSCACHE_COOKIE_CREATING); |
551 | 616 | ||
552 | fscache_done_parent_op(object); | 617 | fscache_done_parent_op(object); |
@@ -562,7 +627,9 @@ static void fscache_object_available(struct fscache_object *object) | |||
562 | } | 627 | } |
563 | spin_unlock(&object->lock); | 628 | spin_unlock(&object->lock); |
564 | 629 | ||
630 | fscache_stat(&fscache_n_cop_lookup_complete); | ||
565 | object->cache->ops->lookup_complete(object); | 631 | object->cache->ops->lookup_complete(object); |
632 | fscache_stat_d(&fscache_n_cop_lookup_complete); | ||
566 | fscache_enqueue_dependents(object); | 633 | fscache_enqueue_dependents(object); |
567 | 634 | ||
568 | fscache_hist(fscache_obj_instantiate_histogram, object->lookup_jif); | 635 | fscache_hist(fscache_obj_instantiate_histogram, object->lookup_jif); |
@@ -581,11 +648,16 @@ static void fscache_drop_object(struct fscache_object *object) | |||
581 | 648 | ||
582 | _enter("{OBJ%x,%d}", object->debug_id, object->n_children); | 649 | _enter("{OBJ%x,%d}", object->debug_id, object->n_children); |
583 | 650 | ||
651 | ASSERTCMP(object->cookie, ==, NULL); | ||
652 | ASSERT(hlist_unhashed(&object->cookie_link)); | ||
653 | |||
584 | spin_lock(&cache->object_list_lock); | 654 | spin_lock(&cache->object_list_lock); |
585 | list_del_init(&object->cache_link); | 655 | list_del_init(&object->cache_link); |
586 | spin_unlock(&cache->object_list_lock); | 656 | spin_unlock(&cache->object_list_lock); |
587 | 657 | ||
658 | fscache_stat(&fscache_n_cop_drop_object); | ||
588 | cache->ops->drop_object(object); | 659 | cache->ops->drop_object(object); |
660 | fscache_stat_d(&fscache_n_cop_drop_object); | ||
589 | 661 | ||
590 | if (parent) { | 662 | if (parent) { |
591 | _debug("release parent OBJ%x {%d}", | 663 | _debug("release parent OBJ%x {%d}", |
@@ -600,7 +672,9 @@ static void fscache_drop_object(struct fscache_object *object) | |||
600 | } | 672 | } |
601 | 673 | ||
602 | /* this just shifts the object release to the slow work processor */ | 674 | /* this just shifts the object release to the slow work processor */ |
675 | fscache_stat(&fscache_n_cop_put_object); | ||
603 | object->cache->ops->put_object(object); | 676 | object->cache->ops->put_object(object); |
677 | fscache_stat_d(&fscache_n_cop_put_object); | ||
604 | 678 | ||
605 | _leave(""); | 679 | _leave(""); |
606 | } | 680 | } |
@@ -690,8 +764,12 @@ static int fscache_object_slow_work_get_ref(struct slow_work *work) | |||
690 | { | 764 | { |
691 | struct fscache_object *object = | 765 | struct fscache_object *object = |
692 | container_of(work, struct fscache_object, work); | 766 | container_of(work, struct fscache_object, work); |
767 | int ret; | ||
693 | 768 | ||
694 | return object->cache->ops->grab_object(object) ? 0 : -EAGAIN; | 769 | fscache_stat(&fscache_n_cop_grab_object); |
770 | ret = object->cache->ops->grab_object(object) ? 0 : -EAGAIN; | ||
771 | fscache_stat_d(&fscache_n_cop_grab_object); | ||
772 | return ret; | ||
695 | } | 773 | } |
696 | 774 | ||
697 | /* | 775 | /* |
@@ -702,7 +780,9 @@ static void fscache_object_slow_work_put_ref(struct slow_work *work) | |||
702 | struct fscache_object *object = | 780 | struct fscache_object *object = |
703 | container_of(work, struct fscache_object, work); | 781 | container_of(work, struct fscache_object, work); |
704 | 782 | ||
705 | return object->cache->ops->put_object(object); | 783 | fscache_stat(&fscache_n_cop_put_object); |
784 | object->cache->ops->put_object(object); | ||
785 | fscache_stat_d(&fscache_n_cop_put_object); | ||
706 | } | 786 | } |
707 | 787 | ||
708 | /* | 788 | /* |
@@ -739,7 +819,9 @@ static void fscache_enqueue_dependents(struct fscache_object *object) | |||
739 | 819 | ||
740 | /* sort onto appropriate lists */ | 820 | /* sort onto appropriate lists */ |
741 | fscache_enqueue_object(dep); | 821 | fscache_enqueue_object(dep); |
822 | fscache_stat(&fscache_n_cop_put_object); | ||
742 | dep->cache->ops->put_object(dep); | 823 | dep->cache->ops->put_object(dep); |
824 | fscache_stat_d(&fscache_n_cop_put_object); | ||
743 | 825 | ||
744 | if (!list_empty(&object->dependents)) | 826 | if (!list_empty(&object->dependents)) |
745 | cond_resched_lock(&object->lock); | 827 | cond_resched_lock(&object->lock); |
diff --git a/fs/fscache/operation.c b/fs/fscache/operation.c index e7f8d53b8b6b..313e79a14266 100644 --- a/fs/fscache/operation.c +++ b/fs/fscache/operation.c | |||
@@ -13,6 +13,7 @@ | |||
13 | 13 | ||
14 | #define FSCACHE_DEBUG_LEVEL OPERATION | 14 | #define FSCACHE_DEBUG_LEVEL OPERATION |
15 | #include <linux/module.h> | 15 | #include <linux/module.h> |
16 | #include <linux/seq_file.h> | ||
16 | #include "internal.h" | 17 | #include "internal.h" |
17 | 18 | ||
18 | atomic_t fscache_op_debug_id; | 19 | atomic_t fscache_op_debug_id; |
@@ -31,32 +32,33 @@ void fscache_enqueue_operation(struct fscache_operation *op) | |||
31 | _enter("{OBJ%x OP%x,%u}", | 32 | _enter("{OBJ%x OP%x,%u}", |
32 | op->object->debug_id, op->debug_id, atomic_read(&op->usage)); | 33 | op->object->debug_id, op->debug_id, atomic_read(&op->usage)); |
33 | 34 | ||
35 | fscache_set_op_state(op, "EnQ"); | ||
36 | |||
37 | ASSERT(list_empty(&op->pend_link)); | ||
34 | ASSERT(op->processor != NULL); | 38 | ASSERT(op->processor != NULL); |
35 | ASSERTCMP(op->object->state, >=, FSCACHE_OBJECT_AVAILABLE); | 39 | ASSERTCMP(op->object->state, >=, FSCACHE_OBJECT_AVAILABLE); |
36 | ASSERTCMP(atomic_read(&op->usage), >, 0); | 40 | ASSERTCMP(atomic_read(&op->usage), >, 0); |
37 | 41 | ||
38 | if (list_empty(&op->pend_link)) { | 42 | fscache_stat(&fscache_n_op_enqueue); |
39 | switch (op->flags & FSCACHE_OP_TYPE) { | 43 | switch (op->flags & FSCACHE_OP_TYPE) { |
40 | case FSCACHE_OP_FAST: | 44 | case FSCACHE_OP_FAST: |
41 | _debug("queue fast"); | 45 | _debug("queue fast"); |
42 | atomic_inc(&op->usage); | 46 | atomic_inc(&op->usage); |
43 | if (!schedule_work(&op->fast_work)) | 47 | if (!schedule_work(&op->fast_work)) |
44 | fscache_put_operation(op); | 48 | fscache_put_operation(op); |
45 | break; | 49 | break; |
46 | case FSCACHE_OP_SLOW: | 50 | case FSCACHE_OP_SLOW: |
47 | _debug("queue slow"); | 51 | _debug("queue slow"); |
48 | slow_work_enqueue(&op->slow_work); | 52 | slow_work_enqueue(&op->slow_work); |
49 | break; | 53 | break; |
50 | case FSCACHE_OP_MYTHREAD: | 54 | case FSCACHE_OP_MYTHREAD: |
51 | _debug("queue for caller's attention"); | 55 | _debug("queue for caller's attention"); |
52 | break; | 56 | break; |
53 | default: | 57 | default: |
54 | printk(KERN_ERR "FS-Cache: Unexpected op type %lx", | 58 | printk(KERN_ERR "FS-Cache: Unexpected op type %lx", |
55 | op->flags); | 59 | op->flags); |
56 | BUG(); | 60 | BUG(); |
57 | break; | 61 | break; |
58 | } | ||
59 | fscache_stat(&fscache_n_op_enqueue); | ||
60 | } | 62 | } |
61 | } | 63 | } |
62 | EXPORT_SYMBOL(fscache_enqueue_operation); | 64 | EXPORT_SYMBOL(fscache_enqueue_operation); |
@@ -67,6 +69,8 @@ EXPORT_SYMBOL(fscache_enqueue_operation); | |||
67 | static void fscache_run_op(struct fscache_object *object, | 69 | static void fscache_run_op(struct fscache_object *object, |
68 | struct fscache_operation *op) | 70 | struct fscache_operation *op) |
69 | { | 71 | { |
72 | fscache_set_op_state(op, "Run"); | ||
73 | |||
70 | object->n_in_progress++; | 74 | object->n_in_progress++; |
71 | if (test_and_clear_bit(FSCACHE_OP_WAITING, &op->flags)) | 75 | if (test_and_clear_bit(FSCACHE_OP_WAITING, &op->flags)) |
72 | wake_up_bit(&op->flags, FSCACHE_OP_WAITING); | 76 | wake_up_bit(&op->flags, FSCACHE_OP_WAITING); |
@@ -87,9 +91,12 @@ int fscache_submit_exclusive_op(struct fscache_object *object, | |||
87 | 91 | ||
88 | _enter("{OBJ%x OP%x},", object->debug_id, op->debug_id); | 92 | _enter("{OBJ%x OP%x},", object->debug_id, op->debug_id); |
89 | 93 | ||
94 | fscache_set_op_state(op, "SubmitX"); | ||
95 | |||
90 | spin_lock(&object->lock); | 96 | spin_lock(&object->lock); |
91 | ASSERTCMP(object->n_ops, >=, object->n_in_progress); | 97 | ASSERTCMP(object->n_ops, >=, object->n_in_progress); |
92 | ASSERTCMP(object->n_ops, >=, object->n_exclusive); | 98 | ASSERTCMP(object->n_ops, >=, object->n_exclusive); |
99 | ASSERT(list_empty(&op->pend_link)); | ||
93 | 100 | ||
94 | ret = -ENOBUFS; | 101 | ret = -ENOBUFS; |
95 | if (fscache_object_is_active(object)) { | 102 | if (fscache_object_is_active(object)) { |
@@ -190,9 +197,12 @@ int fscache_submit_op(struct fscache_object *object, | |||
190 | 197 | ||
191 | ASSERTCMP(atomic_read(&op->usage), >, 0); | 198 | ASSERTCMP(atomic_read(&op->usage), >, 0); |
192 | 199 | ||
200 | fscache_set_op_state(op, "Submit"); | ||
201 | |||
193 | spin_lock(&object->lock); | 202 | spin_lock(&object->lock); |
194 | ASSERTCMP(object->n_ops, >=, object->n_in_progress); | 203 | ASSERTCMP(object->n_ops, >=, object->n_in_progress); |
195 | ASSERTCMP(object->n_ops, >=, object->n_exclusive); | 204 | ASSERTCMP(object->n_ops, >=, object->n_exclusive); |
205 | ASSERT(list_empty(&op->pend_link)); | ||
196 | 206 | ||
197 | ostate = object->state; | 207 | ostate = object->state; |
198 | smp_rmb(); | 208 | smp_rmb(); |
@@ -222,6 +232,11 @@ int fscache_submit_op(struct fscache_object *object, | |||
222 | list_add_tail(&op->pend_link, &object->pending_ops); | 232 | list_add_tail(&op->pend_link, &object->pending_ops); |
223 | fscache_stat(&fscache_n_op_pend); | 233 | fscache_stat(&fscache_n_op_pend); |
224 | ret = 0; | 234 | ret = 0; |
235 | } else if (object->state == FSCACHE_OBJECT_DYING || | ||
236 | object->state == FSCACHE_OBJECT_LC_DYING || | ||
237 | object->state == FSCACHE_OBJECT_WITHDRAWING) { | ||
238 | fscache_stat(&fscache_n_op_rejected); | ||
239 | ret = -ENOBUFS; | ||
225 | } else if (!test_bit(FSCACHE_IOERROR, &object->cache->flags)) { | 240 | } else if (!test_bit(FSCACHE_IOERROR, &object->cache->flags)) { |
226 | fscache_report_unexpected_submission(object, op, ostate); | 241 | fscache_report_unexpected_submission(object, op, ostate); |
227 | ASSERT(!fscache_object_is_active(object)); | 242 | ASSERT(!fscache_object_is_active(object)); |
@@ -264,12 +279,7 @@ void fscache_start_operations(struct fscache_object *object) | |||
264 | stop = true; | 279 | stop = true; |
265 | } | 280 | } |
266 | list_del_init(&op->pend_link); | 281 | list_del_init(&op->pend_link); |
267 | object->n_in_progress++; | 282 | fscache_run_op(object, op); |
268 | |||
269 | if (test_and_clear_bit(FSCACHE_OP_WAITING, &op->flags)) | ||
270 | wake_up_bit(&op->flags, FSCACHE_OP_WAITING); | ||
271 | if (op->processor) | ||
272 | fscache_enqueue_operation(op); | ||
273 | 283 | ||
274 | /* the pending queue was holding a ref on the object */ | 284 | /* the pending queue was holding a ref on the object */ |
275 | fscache_put_operation(op); | 285 | fscache_put_operation(op); |
@@ -282,6 +292,36 @@ void fscache_start_operations(struct fscache_object *object) | |||
282 | } | 292 | } |
283 | 293 | ||
284 | /* | 294 | /* |
295 | * cancel an operation that's pending on an object | ||
296 | */ | ||
297 | int fscache_cancel_op(struct fscache_operation *op) | ||
298 | { | ||
299 | struct fscache_object *object = op->object; | ||
300 | int ret; | ||
301 | |||
302 | _enter("OBJ%x OP%x}", op->object->debug_id, op->debug_id); | ||
303 | |||
304 | spin_lock(&object->lock); | ||
305 | |||
306 | ret = -EBUSY; | ||
307 | if (!list_empty(&op->pend_link)) { | ||
308 | fscache_stat(&fscache_n_op_cancelled); | ||
309 | list_del_init(&op->pend_link); | ||
310 | object->n_ops--; | ||
311 | if (test_bit(FSCACHE_OP_EXCLUSIVE, &op->flags)) | ||
312 | object->n_exclusive--; | ||
313 | if (test_and_clear_bit(FSCACHE_OP_WAITING, &op->flags)) | ||
314 | wake_up_bit(&op->flags, FSCACHE_OP_WAITING); | ||
315 | fscache_put_operation(op); | ||
316 | ret = 0; | ||
317 | } | ||
318 | |||
319 | spin_unlock(&object->lock); | ||
320 | _leave(" = %d", ret); | ||
321 | return ret; | ||
322 | } | ||
323 | |||
324 | /* | ||
285 | * release an operation | 325 | * release an operation |
286 | * - queues pending ops if this is the last in-progress op | 326 | * - queues pending ops if this is the last in-progress op |
287 | */ | 327 | */ |
@@ -298,6 +338,8 @@ void fscache_put_operation(struct fscache_operation *op) | |||
298 | if (!atomic_dec_and_test(&op->usage)) | 338 | if (!atomic_dec_and_test(&op->usage)) |
299 | return; | 339 | return; |
300 | 340 | ||
341 | fscache_set_op_state(op, "Put"); | ||
342 | |||
301 | _debug("PUT OP"); | 343 | _debug("PUT OP"); |
302 | if (test_and_set_bit(FSCACHE_OP_DEAD, &op->flags)) | 344 | if (test_and_set_bit(FSCACHE_OP_DEAD, &op->flags)) |
303 | BUG(); | 345 | BUG(); |
@@ -311,6 +353,9 @@ void fscache_put_operation(struct fscache_operation *op) | |||
311 | 353 | ||
312 | object = op->object; | 354 | object = op->object; |
313 | 355 | ||
356 | if (test_bit(FSCACHE_OP_DEC_READ_CNT, &op->flags)) | ||
357 | atomic_dec(&object->n_reads); | ||
358 | |||
314 | /* now... we may get called with the object spinlock held, so we | 359 | /* now... we may get called with the object spinlock held, so we |
315 | * complete the cleanup here only if we can immediately acquire the | 360 | * complete the cleanup here only if we can immediately acquire the |
316 | * lock, and defer it otherwise */ | 361 | * lock, and defer it otherwise */ |
@@ -452,8 +497,27 @@ static void fscache_op_execute(struct slow_work *work) | |||
452 | _leave(""); | 497 | _leave(""); |
453 | } | 498 | } |
454 | 499 | ||
500 | /* | ||
501 | * describe an operation for slow-work debugging | ||
502 | */ | ||
503 | #ifdef CONFIG_SLOW_WORK_PROC | ||
504 | static void fscache_op_desc(struct slow_work *work, struct seq_file *m) | ||
505 | { | ||
506 | struct fscache_operation *op = | ||
507 | container_of(work, struct fscache_operation, slow_work); | ||
508 | |||
509 | seq_printf(m, "FSC: OBJ%x OP%x: %s/%s fl=%lx", | ||
510 | op->object->debug_id, op->debug_id, | ||
511 | op->name, op->state, op->flags); | ||
512 | } | ||
513 | #endif | ||
514 | |||
455 | const struct slow_work_ops fscache_op_slow_work_ops = { | 515 | const struct slow_work_ops fscache_op_slow_work_ops = { |
516 | .owner = THIS_MODULE, | ||
456 | .get_ref = fscache_op_get_ref, | 517 | .get_ref = fscache_op_get_ref, |
457 | .put_ref = fscache_op_put_ref, | 518 | .put_ref = fscache_op_put_ref, |
458 | .execute = fscache_op_execute, | 519 | .execute = fscache_op_execute, |
520 | #ifdef CONFIG_SLOW_WORK_PROC | ||
521 | .desc = fscache_op_desc, | ||
522 | #endif | ||
459 | }; | 523 | }; |
diff --git a/fs/fscache/page.c b/fs/fscache/page.c index 2568e0eb644f..c598ea4c4e7d 100644 --- a/fs/fscache/page.c +++ b/fs/fscache/page.c | |||
@@ -43,18 +43,102 @@ void __fscache_wait_on_page_write(struct fscache_cookie *cookie, struct page *pa | |||
43 | EXPORT_SYMBOL(__fscache_wait_on_page_write); | 43 | EXPORT_SYMBOL(__fscache_wait_on_page_write); |
44 | 44 | ||
45 | /* | 45 | /* |
46 | * note that a page has finished being written to the cache | 46 | * decide whether a page can be released, possibly by cancelling a store to it |
47 | * - we're allowed to sleep if __GFP_WAIT is flagged | ||
47 | */ | 48 | */ |
48 | static void fscache_end_page_write(struct fscache_cookie *cookie, struct page *page) | 49 | bool __fscache_maybe_release_page(struct fscache_cookie *cookie, |
50 | struct page *page, | ||
51 | gfp_t gfp) | ||
49 | { | 52 | { |
50 | struct page *xpage; | 53 | struct page *xpage; |
54 | void *val; | ||
55 | |||
56 | _enter("%p,%p,%x", cookie, page, gfp); | ||
57 | |||
58 | rcu_read_lock(); | ||
59 | val = radix_tree_lookup(&cookie->stores, page->index); | ||
60 | if (!val) { | ||
61 | rcu_read_unlock(); | ||
62 | fscache_stat(&fscache_n_store_vmscan_not_storing); | ||
63 | __fscache_uncache_page(cookie, page); | ||
64 | return true; | ||
65 | } | ||
66 | |||
67 | /* see if the page is actually undergoing storage - if so we can't get | ||
68 | * rid of it till the cache has finished with it */ | ||
69 | if (radix_tree_tag_get(&cookie->stores, page->index, | ||
70 | FSCACHE_COOKIE_STORING_TAG)) { | ||
71 | rcu_read_unlock(); | ||
72 | goto page_busy; | ||
73 | } | ||
74 | |||
75 | /* the page is pending storage, so we attempt to cancel the store and | ||
76 | * discard the store request so that the page can be reclaimed */ | ||
77 | spin_lock(&cookie->stores_lock); | ||
78 | rcu_read_unlock(); | ||
79 | |||
80 | if (radix_tree_tag_get(&cookie->stores, page->index, | ||
81 | FSCACHE_COOKIE_STORING_TAG)) { | ||
82 | /* the page started to undergo storage whilst we were looking, | ||
83 | * so now we can only wait or return */ | ||
84 | spin_unlock(&cookie->stores_lock); | ||
85 | goto page_busy; | ||
86 | } | ||
51 | 87 | ||
52 | spin_lock(&cookie->lock); | ||
53 | xpage = radix_tree_delete(&cookie->stores, page->index); | 88 | xpage = radix_tree_delete(&cookie->stores, page->index); |
54 | spin_unlock(&cookie->lock); | 89 | spin_unlock(&cookie->stores_lock); |
55 | ASSERT(xpage != NULL); | 90 | |
91 | if (xpage) { | ||
92 | fscache_stat(&fscache_n_store_vmscan_cancelled); | ||
93 | fscache_stat(&fscache_n_store_radix_deletes); | ||
94 | ASSERTCMP(xpage, ==, page); | ||
95 | } else { | ||
96 | fscache_stat(&fscache_n_store_vmscan_gone); | ||
97 | } | ||
56 | 98 | ||
57 | wake_up_bit(&cookie->flags, 0); | 99 | wake_up_bit(&cookie->flags, 0); |
100 | if (xpage) | ||
101 | page_cache_release(xpage); | ||
102 | __fscache_uncache_page(cookie, page); | ||
103 | return true; | ||
104 | |||
105 | page_busy: | ||
106 | /* we might want to wait here, but that could deadlock the allocator as | ||
107 | * the slow-work threads writing to the cache may all end up sleeping | ||
108 | * on memory allocation */ | ||
109 | fscache_stat(&fscache_n_store_vmscan_busy); | ||
110 | return false; | ||
111 | } | ||
112 | EXPORT_SYMBOL(__fscache_maybe_release_page); | ||
113 | |||
114 | /* | ||
115 | * note that a page has finished being written to the cache | ||
116 | */ | ||
117 | static void fscache_end_page_write(struct fscache_object *object, | ||
118 | struct page *page) | ||
119 | { | ||
120 | struct fscache_cookie *cookie; | ||
121 | struct page *xpage = NULL; | ||
122 | |||
123 | spin_lock(&object->lock); | ||
124 | cookie = object->cookie; | ||
125 | if (cookie) { | ||
126 | /* delete the page from the tree if it is now no longer | ||
127 | * pending */ | ||
128 | spin_lock(&cookie->stores_lock); | ||
129 | radix_tree_tag_clear(&cookie->stores, page->index, | ||
130 | FSCACHE_COOKIE_STORING_TAG); | ||
131 | if (!radix_tree_tag_get(&cookie->stores, page->index, | ||
132 | FSCACHE_COOKIE_PENDING_TAG)) { | ||
133 | fscache_stat(&fscache_n_store_radix_deletes); | ||
134 | xpage = radix_tree_delete(&cookie->stores, page->index); | ||
135 | } | ||
136 | spin_unlock(&cookie->stores_lock); | ||
137 | wake_up_bit(&cookie->flags, 0); | ||
138 | } | ||
139 | spin_unlock(&object->lock); | ||
140 | if (xpage) | ||
141 | page_cache_release(xpage); | ||
58 | } | 142 | } |
59 | 143 | ||
60 | /* | 144 | /* |
@@ -63,14 +147,21 @@ static void fscache_end_page_write(struct fscache_cookie *cookie, struct page *p | |||
63 | static void fscache_attr_changed_op(struct fscache_operation *op) | 147 | static void fscache_attr_changed_op(struct fscache_operation *op) |
64 | { | 148 | { |
65 | struct fscache_object *object = op->object; | 149 | struct fscache_object *object = op->object; |
150 | int ret; | ||
66 | 151 | ||
67 | _enter("{OBJ%x OP%x}", object->debug_id, op->debug_id); | 152 | _enter("{OBJ%x OP%x}", object->debug_id, op->debug_id); |
68 | 153 | ||
69 | fscache_stat(&fscache_n_attr_changed_calls); | 154 | fscache_stat(&fscache_n_attr_changed_calls); |
70 | 155 | ||
71 | if (fscache_object_is_active(object) && | 156 | if (fscache_object_is_active(object)) { |
72 | object->cache->ops->attr_changed(object) < 0) | 157 | fscache_set_op_state(op, "CallFS"); |
73 | fscache_abort_object(object); | 158 | fscache_stat(&fscache_n_cop_attr_changed); |
159 | ret = object->cache->ops->attr_changed(object); | ||
160 | fscache_stat_d(&fscache_n_cop_attr_changed); | ||
161 | fscache_set_op_state(op, "Done"); | ||
162 | if (ret < 0) | ||
163 | fscache_abort_object(object); | ||
164 | } | ||
74 | 165 | ||
75 | _leave(""); | 166 | _leave(""); |
76 | } | 167 | } |
@@ -99,6 +190,7 @@ int __fscache_attr_changed(struct fscache_cookie *cookie) | |||
99 | fscache_operation_init(op, NULL); | 190 | fscache_operation_init(op, NULL); |
100 | fscache_operation_init_slow(op, fscache_attr_changed_op); | 191 | fscache_operation_init_slow(op, fscache_attr_changed_op); |
101 | op->flags = FSCACHE_OP_SLOW | (1 << FSCACHE_OP_EXCLUSIVE); | 192 | op->flags = FSCACHE_OP_SLOW | (1 << FSCACHE_OP_EXCLUSIVE); |
193 | fscache_set_op_name(op, "Attr"); | ||
102 | 194 | ||
103 | spin_lock(&cookie->lock); | 195 | spin_lock(&cookie->lock); |
104 | 196 | ||
@@ -184,6 +276,7 @@ static struct fscache_retrieval *fscache_alloc_retrieval( | |||
184 | op->start_time = jiffies; | 276 | op->start_time = jiffies; |
185 | INIT_WORK(&op->op.fast_work, fscache_retrieval_work); | 277 | INIT_WORK(&op->op.fast_work, fscache_retrieval_work); |
186 | INIT_LIST_HEAD(&op->to_do); | 278 | INIT_LIST_HEAD(&op->to_do); |
279 | fscache_set_op_name(&op->op, "Retr"); | ||
187 | return op; | 280 | return op; |
188 | } | 281 | } |
189 | 282 | ||
@@ -221,6 +314,43 @@ static int fscache_wait_for_deferred_lookup(struct fscache_cookie *cookie) | |||
221 | } | 314 | } |
222 | 315 | ||
223 | /* | 316 | /* |
317 | * wait for an object to become active (or dead) | ||
318 | */ | ||
319 | static int fscache_wait_for_retrieval_activation(struct fscache_object *object, | ||
320 | struct fscache_retrieval *op, | ||
321 | atomic_t *stat_op_waits, | ||
322 | atomic_t *stat_object_dead) | ||
323 | { | ||
324 | int ret; | ||
325 | |||
326 | if (!test_bit(FSCACHE_OP_WAITING, &op->op.flags)) | ||
327 | goto check_if_dead; | ||
328 | |||
329 | _debug(">>> WT"); | ||
330 | fscache_stat(stat_op_waits); | ||
331 | if (wait_on_bit(&op->op.flags, FSCACHE_OP_WAITING, | ||
332 | fscache_wait_bit_interruptible, | ||
333 | TASK_INTERRUPTIBLE) < 0) { | ||
334 | ret = fscache_cancel_op(&op->op); | ||
335 | if (ret == 0) | ||
336 | return -ERESTARTSYS; | ||
337 | |||
338 | /* it's been removed from the pending queue by another party, | ||
339 | * so we should get to run shortly */ | ||
340 | wait_on_bit(&op->op.flags, FSCACHE_OP_WAITING, | ||
341 | fscache_wait_bit, TASK_UNINTERRUPTIBLE); | ||
342 | } | ||
343 | _debug("<<< GO"); | ||
344 | |||
345 | check_if_dead: | ||
346 | if (unlikely(fscache_object_is_dead(object))) { | ||
347 | fscache_stat(stat_object_dead); | ||
348 | return -ENOBUFS; | ||
349 | } | ||
350 | return 0; | ||
351 | } | ||
352 | |||
353 | /* | ||
224 | * read a page from the cache or allocate a block in which to store it | 354 | * read a page from the cache or allocate a block in which to store it |
225 | * - we return: | 355 | * - we return: |
226 | * -ENOMEM - out of memory, nothing done | 356 | * -ENOMEM - out of memory, nothing done |
@@ -257,6 +387,7 @@ int __fscache_read_or_alloc_page(struct fscache_cookie *cookie, | |||
257 | _leave(" = -ENOMEM"); | 387 | _leave(" = -ENOMEM"); |
258 | return -ENOMEM; | 388 | return -ENOMEM; |
259 | } | 389 | } |
390 | fscache_set_op_name(&op->op, "RetrRA1"); | ||
260 | 391 | ||
261 | spin_lock(&cookie->lock); | 392 | spin_lock(&cookie->lock); |
262 | 393 | ||
@@ -267,6 +398,9 @@ int __fscache_read_or_alloc_page(struct fscache_cookie *cookie, | |||
267 | 398 | ||
268 | ASSERTCMP(object->state, >, FSCACHE_OBJECT_LOOKING_UP); | 399 | ASSERTCMP(object->state, >, FSCACHE_OBJECT_LOOKING_UP); |
269 | 400 | ||
401 | atomic_inc(&object->n_reads); | ||
402 | set_bit(FSCACHE_OP_DEC_READ_CNT, &op->op.flags); | ||
403 | |||
270 | if (fscache_submit_op(object, &op->op) < 0) | 404 | if (fscache_submit_op(object, &op->op) < 0) |
271 | goto nobufs_unlock; | 405 | goto nobufs_unlock; |
272 | spin_unlock(&cookie->lock); | 406 | spin_unlock(&cookie->lock); |
@@ -279,23 +413,27 @@ int __fscache_read_or_alloc_page(struct fscache_cookie *cookie, | |||
279 | 413 | ||
280 | /* we wait for the operation to become active, and then process it | 414 | /* we wait for the operation to become active, and then process it |
281 | * *here*, in this thread, and not in the thread pool */ | 415 | * *here*, in this thread, and not in the thread pool */ |
282 | if (test_bit(FSCACHE_OP_WAITING, &op->op.flags)) { | 416 | ret = fscache_wait_for_retrieval_activation( |
283 | _debug(">>> WT"); | 417 | object, op, |
284 | fscache_stat(&fscache_n_retrieval_op_waits); | 418 | __fscache_stat(&fscache_n_retrieval_op_waits), |
285 | wait_on_bit(&op->op.flags, FSCACHE_OP_WAITING, | 419 | __fscache_stat(&fscache_n_retrievals_object_dead)); |
286 | fscache_wait_bit, TASK_UNINTERRUPTIBLE); | 420 | if (ret < 0) |
287 | _debug("<<< GO"); | 421 | goto error; |
288 | } | ||
289 | 422 | ||
290 | /* ask the cache to honour the operation */ | 423 | /* ask the cache to honour the operation */ |
291 | if (test_bit(FSCACHE_COOKIE_NO_DATA_YET, &object->cookie->flags)) { | 424 | if (test_bit(FSCACHE_COOKIE_NO_DATA_YET, &object->cookie->flags)) { |
425 | fscache_stat(&fscache_n_cop_allocate_page); | ||
292 | ret = object->cache->ops->allocate_page(op, page, gfp); | 426 | ret = object->cache->ops->allocate_page(op, page, gfp); |
427 | fscache_stat_d(&fscache_n_cop_allocate_page); | ||
293 | if (ret == 0) | 428 | if (ret == 0) |
294 | ret = -ENODATA; | 429 | ret = -ENODATA; |
295 | } else { | 430 | } else { |
431 | fscache_stat(&fscache_n_cop_read_or_alloc_page); | ||
296 | ret = object->cache->ops->read_or_alloc_page(op, page, gfp); | 432 | ret = object->cache->ops->read_or_alloc_page(op, page, gfp); |
433 | fscache_stat_d(&fscache_n_cop_read_or_alloc_page); | ||
297 | } | 434 | } |
298 | 435 | ||
436 | error: | ||
299 | if (ret == -ENOMEM) | 437 | if (ret == -ENOMEM) |
300 | fscache_stat(&fscache_n_retrievals_nomem); | 438 | fscache_stat(&fscache_n_retrievals_nomem); |
301 | else if (ret == -ERESTARTSYS) | 439 | else if (ret == -ERESTARTSYS) |
@@ -347,7 +485,6 @@ int __fscache_read_or_alloc_pages(struct fscache_cookie *cookie, | |||
347 | void *context, | 485 | void *context, |
348 | gfp_t gfp) | 486 | gfp_t gfp) |
349 | { | 487 | { |
350 | fscache_pages_retrieval_func_t func; | ||
351 | struct fscache_retrieval *op; | 488 | struct fscache_retrieval *op; |
352 | struct fscache_object *object; | 489 | struct fscache_object *object; |
353 | int ret; | 490 | int ret; |
@@ -369,6 +506,7 @@ int __fscache_read_or_alloc_pages(struct fscache_cookie *cookie, | |||
369 | op = fscache_alloc_retrieval(mapping, end_io_func, context); | 506 | op = fscache_alloc_retrieval(mapping, end_io_func, context); |
370 | if (!op) | 507 | if (!op) |
371 | return -ENOMEM; | 508 | return -ENOMEM; |
509 | fscache_set_op_name(&op->op, "RetrRAN"); | ||
372 | 510 | ||
373 | spin_lock(&cookie->lock); | 511 | spin_lock(&cookie->lock); |
374 | 512 | ||
@@ -377,6 +515,9 @@ int __fscache_read_or_alloc_pages(struct fscache_cookie *cookie, | |||
377 | object = hlist_entry(cookie->backing_objects.first, | 515 | object = hlist_entry(cookie->backing_objects.first, |
378 | struct fscache_object, cookie_link); | 516 | struct fscache_object, cookie_link); |
379 | 517 | ||
518 | atomic_inc(&object->n_reads); | ||
519 | set_bit(FSCACHE_OP_DEC_READ_CNT, &op->op.flags); | ||
520 | |||
380 | if (fscache_submit_op(object, &op->op) < 0) | 521 | if (fscache_submit_op(object, &op->op) < 0) |
381 | goto nobufs_unlock; | 522 | goto nobufs_unlock; |
382 | spin_unlock(&cookie->lock); | 523 | spin_unlock(&cookie->lock); |
@@ -389,21 +530,27 @@ int __fscache_read_or_alloc_pages(struct fscache_cookie *cookie, | |||
389 | 530 | ||
390 | /* we wait for the operation to become active, and then process it | 531 | /* we wait for the operation to become active, and then process it |
391 | * *here*, in this thread, and not in the thread pool */ | 532 | * *here*, in this thread, and not in the thread pool */ |
392 | if (test_bit(FSCACHE_OP_WAITING, &op->op.flags)) { | 533 | ret = fscache_wait_for_retrieval_activation( |
393 | _debug(">>> WT"); | 534 | object, op, |
394 | fscache_stat(&fscache_n_retrieval_op_waits); | 535 | __fscache_stat(&fscache_n_retrieval_op_waits), |
395 | wait_on_bit(&op->op.flags, FSCACHE_OP_WAITING, | 536 | __fscache_stat(&fscache_n_retrievals_object_dead)); |
396 | fscache_wait_bit, TASK_UNINTERRUPTIBLE); | 537 | if (ret < 0) |
397 | _debug("<<< GO"); | 538 | goto error; |
398 | } | ||
399 | 539 | ||
400 | /* ask the cache to honour the operation */ | 540 | /* ask the cache to honour the operation */ |
401 | if (test_bit(FSCACHE_COOKIE_NO_DATA_YET, &object->cookie->flags)) | 541 | if (test_bit(FSCACHE_COOKIE_NO_DATA_YET, &object->cookie->flags)) { |
402 | func = object->cache->ops->allocate_pages; | 542 | fscache_stat(&fscache_n_cop_allocate_pages); |
403 | else | 543 | ret = object->cache->ops->allocate_pages( |
404 | func = object->cache->ops->read_or_alloc_pages; | 544 | op, pages, nr_pages, gfp); |
405 | ret = func(op, pages, nr_pages, gfp); | 545 | fscache_stat_d(&fscache_n_cop_allocate_pages); |
546 | } else { | ||
547 | fscache_stat(&fscache_n_cop_read_or_alloc_pages); | ||
548 | ret = object->cache->ops->read_or_alloc_pages( | ||
549 | op, pages, nr_pages, gfp); | ||
550 | fscache_stat_d(&fscache_n_cop_read_or_alloc_pages); | ||
551 | } | ||
406 | 552 | ||
553 | error: | ||
407 | if (ret == -ENOMEM) | 554 | if (ret == -ENOMEM) |
408 | fscache_stat(&fscache_n_retrievals_nomem); | 555 | fscache_stat(&fscache_n_retrievals_nomem); |
409 | else if (ret == -ERESTARTSYS) | 556 | else if (ret == -ERESTARTSYS) |
@@ -461,6 +608,7 @@ int __fscache_alloc_page(struct fscache_cookie *cookie, | |||
461 | op = fscache_alloc_retrieval(page->mapping, NULL, NULL); | 608 | op = fscache_alloc_retrieval(page->mapping, NULL, NULL); |
462 | if (!op) | 609 | if (!op) |
463 | return -ENOMEM; | 610 | return -ENOMEM; |
611 | fscache_set_op_name(&op->op, "RetrAL1"); | ||
464 | 612 | ||
465 | spin_lock(&cookie->lock); | 613 | spin_lock(&cookie->lock); |
466 | 614 | ||
@@ -475,18 +623,22 @@ int __fscache_alloc_page(struct fscache_cookie *cookie, | |||
475 | 623 | ||
476 | fscache_stat(&fscache_n_alloc_ops); | 624 | fscache_stat(&fscache_n_alloc_ops); |
477 | 625 | ||
478 | if (test_bit(FSCACHE_OP_WAITING, &op->op.flags)) { | 626 | ret = fscache_wait_for_retrieval_activation( |
479 | _debug(">>> WT"); | 627 | object, op, |
480 | fscache_stat(&fscache_n_alloc_op_waits); | 628 | __fscache_stat(&fscache_n_alloc_op_waits), |
481 | wait_on_bit(&op->op.flags, FSCACHE_OP_WAITING, | 629 | __fscache_stat(&fscache_n_allocs_object_dead)); |
482 | fscache_wait_bit, TASK_UNINTERRUPTIBLE); | 630 | if (ret < 0) |
483 | _debug("<<< GO"); | 631 | goto error; |
484 | } | ||
485 | 632 | ||
486 | /* ask the cache to honour the operation */ | 633 | /* ask the cache to honour the operation */ |
634 | fscache_stat(&fscache_n_cop_allocate_page); | ||
487 | ret = object->cache->ops->allocate_page(op, page, gfp); | 635 | ret = object->cache->ops->allocate_page(op, page, gfp); |
636 | fscache_stat_d(&fscache_n_cop_allocate_page); | ||
488 | 637 | ||
489 | if (ret < 0) | 638 | error: |
639 | if (ret == -ERESTARTSYS) | ||
640 | fscache_stat(&fscache_n_allocs_intr); | ||
641 | else if (ret < 0) | ||
490 | fscache_stat(&fscache_n_allocs_nobufs); | 642 | fscache_stat(&fscache_n_allocs_nobufs); |
491 | else | 643 | else |
492 | fscache_stat(&fscache_n_allocs_ok); | 644 | fscache_stat(&fscache_n_allocs_ok); |
@@ -521,7 +673,7 @@ static void fscache_write_op(struct fscache_operation *_op) | |||
521 | struct fscache_storage *op = | 673 | struct fscache_storage *op = |
522 | container_of(_op, struct fscache_storage, op); | 674 | container_of(_op, struct fscache_storage, op); |
523 | struct fscache_object *object = op->op.object; | 675 | struct fscache_object *object = op->op.object; |
524 | struct fscache_cookie *cookie = object->cookie; | 676 | struct fscache_cookie *cookie; |
525 | struct page *page; | 677 | struct page *page; |
526 | unsigned n; | 678 | unsigned n; |
527 | void *results[1]; | 679 | void *results[1]; |
@@ -529,16 +681,19 @@ static void fscache_write_op(struct fscache_operation *_op) | |||
529 | 681 | ||
530 | _enter("{OP%x,%d}", op->op.debug_id, atomic_read(&op->op.usage)); | 682 | _enter("{OP%x,%d}", op->op.debug_id, atomic_read(&op->op.usage)); |
531 | 683 | ||
532 | spin_lock(&cookie->lock); | 684 | fscache_set_op_state(&op->op, "GetPage"); |
685 | |||
533 | spin_lock(&object->lock); | 686 | spin_lock(&object->lock); |
687 | cookie = object->cookie; | ||
534 | 688 | ||
535 | if (!fscache_object_is_active(object)) { | 689 | if (!fscache_object_is_active(object) || !cookie) { |
536 | spin_unlock(&object->lock); | 690 | spin_unlock(&object->lock); |
537 | spin_unlock(&cookie->lock); | ||
538 | _leave(""); | 691 | _leave(""); |
539 | return; | 692 | return; |
540 | } | 693 | } |
541 | 694 | ||
695 | spin_lock(&cookie->stores_lock); | ||
696 | |||
542 | fscache_stat(&fscache_n_store_calls); | 697 | fscache_stat(&fscache_n_store_calls); |
543 | 698 | ||
544 | /* find a page to store */ | 699 | /* find a page to store */ |
@@ -549,23 +704,35 @@ static void fscache_write_op(struct fscache_operation *_op) | |||
549 | goto superseded; | 704 | goto superseded; |
550 | page = results[0]; | 705 | page = results[0]; |
551 | _debug("gang %d [%lx]", n, page->index); | 706 | _debug("gang %d [%lx]", n, page->index); |
552 | if (page->index > op->store_limit) | 707 | if (page->index > op->store_limit) { |
708 | fscache_stat(&fscache_n_store_pages_over_limit); | ||
553 | goto superseded; | 709 | goto superseded; |
710 | } | ||
554 | 711 | ||
555 | radix_tree_tag_clear(&cookie->stores, page->index, | 712 | if (page) { |
556 | FSCACHE_COOKIE_PENDING_TAG); | 713 | radix_tree_tag_set(&cookie->stores, page->index, |
714 | FSCACHE_COOKIE_STORING_TAG); | ||
715 | radix_tree_tag_clear(&cookie->stores, page->index, | ||
716 | FSCACHE_COOKIE_PENDING_TAG); | ||
717 | } | ||
557 | 718 | ||
719 | spin_unlock(&cookie->stores_lock); | ||
558 | spin_unlock(&object->lock); | 720 | spin_unlock(&object->lock); |
559 | spin_unlock(&cookie->lock); | ||
560 | 721 | ||
561 | if (page) { | 722 | if (page) { |
723 | fscache_set_op_state(&op->op, "Store"); | ||
724 | fscache_stat(&fscache_n_store_pages); | ||
725 | fscache_stat(&fscache_n_cop_write_page); | ||
562 | ret = object->cache->ops->write_page(op, page); | 726 | ret = object->cache->ops->write_page(op, page); |
563 | fscache_end_page_write(cookie, page); | 727 | fscache_stat_d(&fscache_n_cop_write_page); |
564 | page_cache_release(page); | 728 | fscache_set_op_state(&op->op, "EndWrite"); |
565 | if (ret < 0) | 729 | fscache_end_page_write(object, page); |
730 | if (ret < 0) { | ||
731 | fscache_set_op_state(&op->op, "Abort"); | ||
566 | fscache_abort_object(object); | 732 | fscache_abort_object(object); |
567 | else | 733 | } else { |
568 | fscache_enqueue_operation(&op->op); | 734 | fscache_enqueue_operation(&op->op); |
735 | } | ||
569 | } | 736 | } |
570 | 737 | ||
571 | _leave(""); | 738 | _leave(""); |
@@ -575,9 +742,9 @@ superseded: | |||
575 | /* this writer is going away and there aren't any more things to | 742 | /* this writer is going away and there aren't any more things to |
576 | * write */ | 743 | * write */ |
577 | _debug("cease"); | 744 | _debug("cease"); |
745 | spin_unlock(&cookie->stores_lock); | ||
578 | clear_bit(FSCACHE_OBJECT_PENDING_WRITE, &object->flags); | 746 | clear_bit(FSCACHE_OBJECT_PENDING_WRITE, &object->flags); |
579 | spin_unlock(&object->lock); | 747 | spin_unlock(&object->lock); |
580 | spin_unlock(&cookie->lock); | ||
581 | _leave(""); | 748 | _leave(""); |
582 | } | 749 | } |
583 | 750 | ||
@@ -634,6 +801,7 @@ int __fscache_write_page(struct fscache_cookie *cookie, | |||
634 | fscache_operation_init(&op->op, fscache_release_write_op); | 801 | fscache_operation_init(&op->op, fscache_release_write_op); |
635 | fscache_operation_init_slow(&op->op, fscache_write_op); | 802 | fscache_operation_init_slow(&op->op, fscache_write_op); |
636 | op->op.flags = FSCACHE_OP_SLOW | (1 << FSCACHE_OP_WAITING); | 803 | op->op.flags = FSCACHE_OP_SLOW | (1 << FSCACHE_OP_WAITING); |
804 | fscache_set_op_name(&op->op, "Write1"); | ||
637 | 805 | ||
638 | ret = radix_tree_preload(gfp & ~__GFP_HIGHMEM); | 806 | ret = radix_tree_preload(gfp & ~__GFP_HIGHMEM); |
639 | if (ret < 0) | 807 | if (ret < 0) |
@@ -652,6 +820,7 @@ int __fscache_write_page(struct fscache_cookie *cookie, | |||
652 | /* add the page to the pending-storage radix tree on the backing | 820 | /* add the page to the pending-storage radix tree on the backing |
653 | * object */ | 821 | * object */ |
654 | spin_lock(&object->lock); | 822 | spin_lock(&object->lock); |
823 | spin_lock(&cookie->stores_lock); | ||
655 | 824 | ||
656 | _debug("store limit %llx", (unsigned long long) object->store_limit); | 825 | _debug("store limit %llx", (unsigned long long) object->store_limit); |
657 | 826 | ||
@@ -672,6 +841,7 @@ int __fscache_write_page(struct fscache_cookie *cookie, | |||
672 | if (test_and_set_bit(FSCACHE_OBJECT_PENDING_WRITE, &object->flags)) | 841 | if (test_and_set_bit(FSCACHE_OBJECT_PENDING_WRITE, &object->flags)) |
673 | goto already_pending; | 842 | goto already_pending; |
674 | 843 | ||
844 | spin_unlock(&cookie->stores_lock); | ||
675 | spin_unlock(&object->lock); | 845 | spin_unlock(&object->lock); |
676 | 846 | ||
677 | op->op.debug_id = atomic_inc_return(&fscache_op_debug_id); | 847 | op->op.debug_id = atomic_inc_return(&fscache_op_debug_id); |
@@ -693,6 +863,7 @@ int __fscache_write_page(struct fscache_cookie *cookie, | |||
693 | already_queued: | 863 | already_queued: |
694 | fscache_stat(&fscache_n_stores_again); | 864 | fscache_stat(&fscache_n_stores_again); |
695 | already_pending: | 865 | already_pending: |
866 | spin_unlock(&cookie->stores_lock); | ||
696 | spin_unlock(&object->lock); | 867 | spin_unlock(&object->lock); |
697 | spin_unlock(&cookie->lock); | 868 | spin_unlock(&cookie->lock); |
698 | radix_tree_preload_end(); | 869 | radix_tree_preload_end(); |
@@ -702,7 +873,9 @@ already_pending: | |||
702 | return 0; | 873 | return 0; |
703 | 874 | ||
704 | submit_failed: | 875 | submit_failed: |
876 | spin_lock(&cookie->stores_lock); | ||
705 | radix_tree_delete(&cookie->stores, page->index); | 877 | radix_tree_delete(&cookie->stores, page->index); |
878 | spin_unlock(&cookie->stores_lock); | ||
706 | page_cache_release(page); | 879 | page_cache_release(page); |
707 | ret = -ENOBUFS; | 880 | ret = -ENOBUFS; |
708 | goto nobufs; | 881 | goto nobufs; |
@@ -763,7 +936,9 @@ void __fscache_uncache_page(struct fscache_cookie *cookie, struct page *page) | |||
763 | if (TestClearPageFsCache(page) && | 936 | if (TestClearPageFsCache(page) && |
764 | object->cache->ops->uncache_page) { | 937 | object->cache->ops->uncache_page) { |
765 | /* the cache backend releases the cookie lock */ | 938 | /* the cache backend releases the cookie lock */ |
939 | fscache_stat(&fscache_n_cop_uncache_page); | ||
766 | object->cache->ops->uncache_page(object, page); | 940 | object->cache->ops->uncache_page(object, page); |
941 | fscache_stat_d(&fscache_n_cop_uncache_page); | ||
767 | goto done; | 942 | goto done; |
768 | } | 943 | } |
769 | 944 | ||
diff --git a/fs/fscache/proc.c b/fs/fscache/proc.c index beeab44bc31a..1d9e4951a597 100644 --- a/fs/fscache/proc.c +++ b/fs/fscache/proc.c | |||
@@ -37,10 +37,20 @@ int __init fscache_proc_init(void) | |||
37 | goto error_histogram; | 37 | goto error_histogram; |
38 | #endif | 38 | #endif |
39 | 39 | ||
40 | #ifdef CONFIG_FSCACHE_OBJECT_LIST | ||
41 | if (!proc_create("fs/fscache/objects", S_IFREG | 0444, NULL, | ||
42 | &fscache_objlist_fops)) | ||
43 | goto error_objects; | ||
44 | #endif | ||
45 | |||
40 | _leave(" = 0"); | 46 | _leave(" = 0"); |
41 | return 0; | 47 | return 0; |
42 | 48 | ||
49 | #ifdef CONFIG_FSCACHE_OBJECT_LIST | ||
50 | error_objects: | ||
51 | #endif | ||
43 | #ifdef CONFIG_FSCACHE_HISTOGRAM | 52 | #ifdef CONFIG_FSCACHE_HISTOGRAM |
53 | remove_proc_entry("fs/fscache/histogram", NULL); | ||
44 | error_histogram: | 54 | error_histogram: |
45 | #endif | 55 | #endif |
46 | #ifdef CONFIG_FSCACHE_STATS | 56 | #ifdef CONFIG_FSCACHE_STATS |
@@ -58,6 +68,9 @@ error_dir: | |||
58 | */ | 68 | */ |
59 | void fscache_proc_cleanup(void) | 69 | void fscache_proc_cleanup(void) |
60 | { | 70 | { |
71 | #ifdef CONFIG_FSCACHE_OBJECT_LIST | ||
72 | remove_proc_entry("fs/fscache/objects", NULL); | ||
73 | #endif | ||
61 | #ifdef CONFIG_FSCACHE_HISTOGRAM | 74 | #ifdef CONFIG_FSCACHE_HISTOGRAM |
62 | remove_proc_entry("fs/fscache/histogram", NULL); | 75 | remove_proc_entry("fs/fscache/histogram", NULL); |
63 | #endif | 76 | #endif |
diff --git a/fs/fscache/stats.c b/fs/fscache/stats.c index 65deb99e756b..46435f3aae68 100644 --- a/fs/fscache/stats.c +++ b/fs/fscache/stats.c | |||
@@ -25,6 +25,8 @@ atomic_t fscache_n_op_requeue; | |||
25 | atomic_t fscache_n_op_deferred_release; | 25 | atomic_t fscache_n_op_deferred_release; |
26 | atomic_t fscache_n_op_release; | 26 | atomic_t fscache_n_op_release; |
27 | atomic_t fscache_n_op_gc; | 27 | atomic_t fscache_n_op_gc; |
28 | atomic_t fscache_n_op_cancelled; | ||
29 | atomic_t fscache_n_op_rejected; | ||
28 | 30 | ||
29 | atomic_t fscache_n_attr_changed; | 31 | atomic_t fscache_n_attr_changed; |
30 | atomic_t fscache_n_attr_changed_ok; | 32 | atomic_t fscache_n_attr_changed_ok; |
@@ -36,6 +38,8 @@ atomic_t fscache_n_allocs; | |||
36 | atomic_t fscache_n_allocs_ok; | 38 | atomic_t fscache_n_allocs_ok; |
37 | atomic_t fscache_n_allocs_wait; | 39 | atomic_t fscache_n_allocs_wait; |
38 | atomic_t fscache_n_allocs_nobufs; | 40 | atomic_t fscache_n_allocs_nobufs; |
41 | atomic_t fscache_n_allocs_intr; | ||
42 | atomic_t fscache_n_allocs_object_dead; | ||
39 | atomic_t fscache_n_alloc_ops; | 43 | atomic_t fscache_n_alloc_ops; |
40 | atomic_t fscache_n_alloc_op_waits; | 44 | atomic_t fscache_n_alloc_op_waits; |
41 | 45 | ||
@@ -46,6 +50,7 @@ atomic_t fscache_n_retrievals_nodata; | |||
46 | atomic_t fscache_n_retrievals_nobufs; | 50 | atomic_t fscache_n_retrievals_nobufs; |
47 | atomic_t fscache_n_retrievals_intr; | 51 | atomic_t fscache_n_retrievals_intr; |
48 | atomic_t fscache_n_retrievals_nomem; | 52 | atomic_t fscache_n_retrievals_nomem; |
53 | atomic_t fscache_n_retrievals_object_dead; | ||
49 | atomic_t fscache_n_retrieval_ops; | 54 | atomic_t fscache_n_retrieval_ops; |
50 | atomic_t fscache_n_retrieval_op_waits; | 55 | atomic_t fscache_n_retrieval_op_waits; |
51 | 56 | ||
@@ -56,6 +61,14 @@ atomic_t fscache_n_stores_nobufs; | |||
56 | atomic_t fscache_n_stores_oom; | 61 | atomic_t fscache_n_stores_oom; |
57 | atomic_t fscache_n_store_ops; | 62 | atomic_t fscache_n_store_ops; |
58 | atomic_t fscache_n_store_calls; | 63 | atomic_t fscache_n_store_calls; |
64 | atomic_t fscache_n_store_pages; | ||
65 | atomic_t fscache_n_store_radix_deletes; | ||
66 | atomic_t fscache_n_store_pages_over_limit; | ||
67 | |||
68 | atomic_t fscache_n_store_vmscan_not_storing; | ||
69 | atomic_t fscache_n_store_vmscan_gone; | ||
70 | atomic_t fscache_n_store_vmscan_busy; | ||
71 | atomic_t fscache_n_store_vmscan_cancelled; | ||
59 | 72 | ||
60 | atomic_t fscache_n_marks; | 73 | atomic_t fscache_n_marks; |
61 | atomic_t fscache_n_uncaches; | 74 | atomic_t fscache_n_uncaches; |
@@ -74,6 +87,7 @@ atomic_t fscache_n_updates_run; | |||
74 | atomic_t fscache_n_relinquishes; | 87 | atomic_t fscache_n_relinquishes; |
75 | atomic_t fscache_n_relinquishes_null; | 88 | atomic_t fscache_n_relinquishes_null; |
76 | atomic_t fscache_n_relinquishes_waitcrt; | 89 | atomic_t fscache_n_relinquishes_waitcrt; |
90 | atomic_t fscache_n_relinquishes_retire; | ||
77 | 91 | ||
78 | atomic_t fscache_n_cookie_index; | 92 | atomic_t fscache_n_cookie_index; |
79 | atomic_t fscache_n_cookie_data; | 93 | atomic_t fscache_n_cookie_data; |
@@ -84,6 +98,7 @@ atomic_t fscache_n_object_no_alloc; | |||
84 | atomic_t fscache_n_object_lookups; | 98 | atomic_t fscache_n_object_lookups; |
85 | atomic_t fscache_n_object_lookups_negative; | 99 | atomic_t fscache_n_object_lookups_negative; |
86 | atomic_t fscache_n_object_lookups_positive; | 100 | atomic_t fscache_n_object_lookups_positive; |
101 | atomic_t fscache_n_object_lookups_timed_out; | ||
87 | atomic_t fscache_n_object_created; | 102 | atomic_t fscache_n_object_created; |
88 | atomic_t fscache_n_object_avail; | 103 | atomic_t fscache_n_object_avail; |
89 | atomic_t fscache_n_object_dead; | 104 | atomic_t fscache_n_object_dead; |
@@ -93,6 +108,23 @@ atomic_t fscache_n_checkaux_okay; | |||
93 | atomic_t fscache_n_checkaux_update; | 108 | atomic_t fscache_n_checkaux_update; |
94 | atomic_t fscache_n_checkaux_obsolete; | 109 | atomic_t fscache_n_checkaux_obsolete; |
95 | 110 | ||
111 | atomic_t fscache_n_cop_alloc_object; | ||
112 | atomic_t fscache_n_cop_lookup_object; | ||
113 | atomic_t fscache_n_cop_lookup_complete; | ||
114 | atomic_t fscache_n_cop_grab_object; | ||
115 | atomic_t fscache_n_cop_update_object; | ||
116 | atomic_t fscache_n_cop_drop_object; | ||
117 | atomic_t fscache_n_cop_put_object; | ||
118 | atomic_t fscache_n_cop_sync_cache; | ||
119 | atomic_t fscache_n_cop_attr_changed; | ||
120 | atomic_t fscache_n_cop_read_or_alloc_page; | ||
121 | atomic_t fscache_n_cop_read_or_alloc_pages; | ||
122 | atomic_t fscache_n_cop_allocate_page; | ||
123 | atomic_t fscache_n_cop_allocate_pages; | ||
124 | atomic_t fscache_n_cop_write_page; | ||
125 | atomic_t fscache_n_cop_uncache_page; | ||
126 | atomic_t fscache_n_cop_dissociate_pages; | ||
127 | |||
96 | /* | 128 | /* |
97 | * display the general statistics | 129 | * display the general statistics |
98 | */ | 130 | */ |
@@ -129,10 +161,11 @@ static int fscache_stats_show(struct seq_file *m, void *v) | |||
129 | atomic_read(&fscache_n_acquires_nobufs), | 161 | atomic_read(&fscache_n_acquires_nobufs), |
130 | atomic_read(&fscache_n_acquires_oom)); | 162 | atomic_read(&fscache_n_acquires_oom)); |
131 | 163 | ||
132 | seq_printf(m, "Lookups: n=%u neg=%u pos=%u crt=%u\n", | 164 | seq_printf(m, "Lookups: n=%u neg=%u pos=%u crt=%u tmo=%u\n", |
133 | atomic_read(&fscache_n_object_lookups), | 165 | atomic_read(&fscache_n_object_lookups), |
134 | atomic_read(&fscache_n_object_lookups_negative), | 166 | atomic_read(&fscache_n_object_lookups_negative), |
135 | atomic_read(&fscache_n_object_lookups_positive), | 167 | atomic_read(&fscache_n_object_lookups_positive), |
168 | atomic_read(&fscache_n_object_lookups_timed_out), | ||
136 | atomic_read(&fscache_n_object_created)); | 169 | atomic_read(&fscache_n_object_created)); |
137 | 170 | ||
138 | seq_printf(m, "Updates: n=%u nul=%u run=%u\n", | 171 | seq_printf(m, "Updates: n=%u nul=%u run=%u\n", |
@@ -140,10 +173,11 @@ static int fscache_stats_show(struct seq_file *m, void *v) | |||
140 | atomic_read(&fscache_n_updates_null), | 173 | atomic_read(&fscache_n_updates_null), |
141 | atomic_read(&fscache_n_updates_run)); | 174 | atomic_read(&fscache_n_updates_run)); |
142 | 175 | ||
143 | seq_printf(m, "Relinqs: n=%u nul=%u wcr=%u\n", | 176 | seq_printf(m, "Relinqs: n=%u nul=%u wcr=%u rtr=%u\n", |
144 | atomic_read(&fscache_n_relinquishes), | 177 | atomic_read(&fscache_n_relinquishes), |
145 | atomic_read(&fscache_n_relinquishes_null), | 178 | atomic_read(&fscache_n_relinquishes_null), |
146 | atomic_read(&fscache_n_relinquishes_waitcrt)); | 179 | atomic_read(&fscache_n_relinquishes_waitcrt), |
180 | atomic_read(&fscache_n_relinquishes_retire)); | ||
147 | 181 | ||
148 | seq_printf(m, "AttrChg: n=%u ok=%u nbf=%u oom=%u run=%u\n", | 182 | seq_printf(m, "AttrChg: n=%u ok=%u nbf=%u oom=%u run=%u\n", |
149 | atomic_read(&fscache_n_attr_changed), | 183 | atomic_read(&fscache_n_attr_changed), |
@@ -152,14 +186,16 @@ static int fscache_stats_show(struct seq_file *m, void *v) | |||
152 | atomic_read(&fscache_n_attr_changed_nomem), | 186 | atomic_read(&fscache_n_attr_changed_nomem), |
153 | atomic_read(&fscache_n_attr_changed_calls)); | 187 | atomic_read(&fscache_n_attr_changed_calls)); |
154 | 188 | ||
155 | seq_printf(m, "Allocs : n=%u ok=%u wt=%u nbf=%u\n", | 189 | seq_printf(m, "Allocs : n=%u ok=%u wt=%u nbf=%u int=%u\n", |
156 | atomic_read(&fscache_n_allocs), | 190 | atomic_read(&fscache_n_allocs), |
157 | atomic_read(&fscache_n_allocs_ok), | 191 | atomic_read(&fscache_n_allocs_ok), |
158 | atomic_read(&fscache_n_allocs_wait), | 192 | atomic_read(&fscache_n_allocs_wait), |
159 | atomic_read(&fscache_n_allocs_nobufs)); | 193 | atomic_read(&fscache_n_allocs_nobufs), |
160 | seq_printf(m, "Allocs : ops=%u owt=%u\n", | 194 | atomic_read(&fscache_n_allocs_intr)); |
195 | seq_printf(m, "Allocs : ops=%u owt=%u abt=%u\n", | ||
161 | atomic_read(&fscache_n_alloc_ops), | 196 | atomic_read(&fscache_n_alloc_ops), |
162 | atomic_read(&fscache_n_alloc_op_waits)); | 197 | atomic_read(&fscache_n_alloc_op_waits), |
198 | atomic_read(&fscache_n_allocs_object_dead)); | ||
163 | 199 | ||
164 | seq_printf(m, "Retrvls: n=%u ok=%u wt=%u nod=%u nbf=%u" | 200 | seq_printf(m, "Retrvls: n=%u ok=%u wt=%u nod=%u nbf=%u" |
165 | " int=%u oom=%u\n", | 201 | " int=%u oom=%u\n", |
@@ -170,9 +206,10 @@ static int fscache_stats_show(struct seq_file *m, void *v) | |||
170 | atomic_read(&fscache_n_retrievals_nobufs), | 206 | atomic_read(&fscache_n_retrievals_nobufs), |
171 | atomic_read(&fscache_n_retrievals_intr), | 207 | atomic_read(&fscache_n_retrievals_intr), |
172 | atomic_read(&fscache_n_retrievals_nomem)); | 208 | atomic_read(&fscache_n_retrievals_nomem)); |
173 | seq_printf(m, "Retrvls: ops=%u owt=%u\n", | 209 | seq_printf(m, "Retrvls: ops=%u owt=%u abt=%u\n", |
174 | atomic_read(&fscache_n_retrieval_ops), | 210 | atomic_read(&fscache_n_retrieval_ops), |
175 | atomic_read(&fscache_n_retrieval_op_waits)); | 211 | atomic_read(&fscache_n_retrieval_op_waits), |
212 | atomic_read(&fscache_n_retrievals_object_dead)); | ||
176 | 213 | ||
177 | seq_printf(m, "Stores : n=%u ok=%u agn=%u nbf=%u oom=%u\n", | 214 | seq_printf(m, "Stores : n=%u ok=%u agn=%u nbf=%u oom=%u\n", |
178 | atomic_read(&fscache_n_stores), | 215 | atomic_read(&fscache_n_stores), |
@@ -180,18 +217,49 @@ static int fscache_stats_show(struct seq_file *m, void *v) | |||
180 | atomic_read(&fscache_n_stores_again), | 217 | atomic_read(&fscache_n_stores_again), |
181 | atomic_read(&fscache_n_stores_nobufs), | 218 | atomic_read(&fscache_n_stores_nobufs), |
182 | atomic_read(&fscache_n_stores_oom)); | 219 | atomic_read(&fscache_n_stores_oom)); |
183 | seq_printf(m, "Stores : ops=%u run=%u\n", | 220 | seq_printf(m, "Stores : ops=%u run=%u pgs=%u rxd=%u olm=%u\n", |
184 | atomic_read(&fscache_n_store_ops), | 221 | atomic_read(&fscache_n_store_ops), |
185 | atomic_read(&fscache_n_store_calls)); | 222 | atomic_read(&fscache_n_store_calls), |
223 | atomic_read(&fscache_n_store_pages), | ||
224 | atomic_read(&fscache_n_store_radix_deletes), | ||
225 | atomic_read(&fscache_n_store_pages_over_limit)); | ||
186 | 226 | ||
187 | seq_printf(m, "Ops : pend=%u run=%u enq=%u\n", | 227 | seq_printf(m, "VmScan : nos=%u gon=%u bsy=%u can=%u\n", |
228 | atomic_read(&fscache_n_store_vmscan_not_storing), | ||
229 | atomic_read(&fscache_n_store_vmscan_gone), | ||
230 | atomic_read(&fscache_n_store_vmscan_busy), | ||
231 | atomic_read(&fscache_n_store_vmscan_cancelled)); | ||
232 | |||
233 | seq_printf(m, "Ops : pend=%u run=%u enq=%u can=%u rej=%u\n", | ||
188 | atomic_read(&fscache_n_op_pend), | 234 | atomic_read(&fscache_n_op_pend), |
189 | atomic_read(&fscache_n_op_run), | 235 | atomic_read(&fscache_n_op_run), |
190 | atomic_read(&fscache_n_op_enqueue)); | 236 | atomic_read(&fscache_n_op_enqueue), |
237 | atomic_read(&fscache_n_op_cancelled), | ||
238 | atomic_read(&fscache_n_op_rejected)); | ||
191 | seq_printf(m, "Ops : dfr=%u rel=%u gc=%u\n", | 239 | seq_printf(m, "Ops : dfr=%u rel=%u gc=%u\n", |
192 | atomic_read(&fscache_n_op_deferred_release), | 240 | atomic_read(&fscache_n_op_deferred_release), |
193 | atomic_read(&fscache_n_op_release), | 241 | atomic_read(&fscache_n_op_release), |
194 | atomic_read(&fscache_n_op_gc)); | 242 | atomic_read(&fscache_n_op_gc)); |
243 | |||
244 | seq_printf(m, "CacheOp: alo=%d luo=%d luc=%d gro=%d\n", | ||
245 | atomic_read(&fscache_n_cop_alloc_object), | ||
246 | atomic_read(&fscache_n_cop_lookup_object), | ||
247 | atomic_read(&fscache_n_cop_lookup_complete), | ||
248 | atomic_read(&fscache_n_cop_grab_object)); | ||
249 | seq_printf(m, "CacheOp: upo=%d dro=%d pto=%d atc=%d syn=%d\n", | ||
250 | atomic_read(&fscache_n_cop_update_object), | ||
251 | atomic_read(&fscache_n_cop_drop_object), | ||
252 | atomic_read(&fscache_n_cop_put_object), | ||
253 | atomic_read(&fscache_n_cop_attr_changed), | ||
254 | atomic_read(&fscache_n_cop_sync_cache)); | ||
255 | seq_printf(m, "CacheOp: rap=%d ras=%d alp=%d als=%d wrp=%d ucp=%d dsp=%d\n", | ||
256 | atomic_read(&fscache_n_cop_read_or_alloc_page), | ||
257 | atomic_read(&fscache_n_cop_read_or_alloc_pages), | ||
258 | atomic_read(&fscache_n_cop_allocate_page), | ||
259 | atomic_read(&fscache_n_cop_allocate_pages), | ||
260 | atomic_read(&fscache_n_cop_write_page), | ||
261 | atomic_read(&fscache_n_cop_uncache_page), | ||
262 | atomic_read(&fscache_n_cop_dissociate_pages)); | ||
195 | return 0; | 263 | return 0; |
196 | } | 264 | } |
197 | 265 | ||
diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c index 8ada78aade58..4787ae6c5c1c 100644 --- a/fs/fuse/dir.c +++ b/fs/fuse/dir.c | |||
@@ -385,6 +385,9 @@ static int fuse_create_open(struct inode *dir, struct dentry *entry, int mode, | |||
385 | if (fc->no_create) | 385 | if (fc->no_create) |
386 | return -ENOSYS; | 386 | return -ENOSYS; |
387 | 387 | ||
388 | if (flags & O_DIRECT) | ||
389 | return -EINVAL; | ||
390 | |||
388 | forget_req = fuse_get_req(fc); | 391 | forget_req = fuse_get_req(fc); |
389 | if (IS_ERR(forget_req)) | 392 | if (IS_ERR(forget_req)) |
390 | return PTR_ERR(forget_req); | 393 | return PTR_ERR(forget_req); |
diff --git a/fs/gfs2/main.c b/fs/gfs2/main.c index eacd78a5d082..5b31f7741a8f 100644 --- a/fs/gfs2/main.c +++ b/fs/gfs2/main.c | |||
@@ -114,7 +114,7 @@ static int __init init_gfs2_fs(void) | |||
114 | if (error) | 114 | if (error) |
115 | goto fail_unregister; | 115 | goto fail_unregister; |
116 | 116 | ||
117 | error = slow_work_register_user(); | 117 | error = slow_work_register_user(THIS_MODULE); |
118 | if (error) | 118 | if (error) |
119 | goto fail_slow; | 119 | goto fail_slow; |
120 | 120 | ||
@@ -163,7 +163,7 @@ static void __exit exit_gfs2_fs(void) | |||
163 | gfs2_unregister_debugfs(); | 163 | gfs2_unregister_debugfs(); |
164 | unregister_filesystem(&gfs2_fs_type); | 164 | unregister_filesystem(&gfs2_fs_type); |
165 | unregister_filesystem(&gfs2meta_fs_type); | 165 | unregister_filesystem(&gfs2meta_fs_type); |
166 | slow_work_unregister_user(); | 166 | slow_work_unregister_user(THIS_MODULE); |
167 | 167 | ||
168 | kmem_cache_destroy(gfs2_quotad_cachep); | 168 | kmem_cache_destroy(gfs2_quotad_cachep); |
169 | kmem_cache_destroy(gfs2_rgrpd_cachep); | 169 | kmem_cache_destroy(gfs2_rgrpd_cachep); |
diff --git a/fs/gfs2/recovery.c b/fs/gfs2/recovery.c index 59d2695509d3..09fa31965576 100644 --- a/fs/gfs2/recovery.c +++ b/fs/gfs2/recovery.c | |||
@@ -7,6 +7,7 @@ | |||
7 | * of the GNU General Public License version 2. | 7 | * of the GNU General Public License version 2. |
8 | */ | 8 | */ |
9 | 9 | ||
10 | #include <linux/module.h> | ||
10 | #include <linux/slab.h> | 11 | #include <linux/slab.h> |
11 | #include <linux/spinlock.h> | 12 | #include <linux/spinlock.h> |
12 | #include <linux/completion.h> | 13 | #include <linux/completion.h> |
@@ -593,6 +594,7 @@ fail: | |||
593 | } | 594 | } |
594 | 595 | ||
595 | struct slow_work_ops gfs2_recover_ops = { | 596 | struct slow_work_ops gfs2_recover_ops = { |
597 | .owner = THIS_MODULE, | ||
596 | .get_ref = gfs2_recover_get_ref, | 598 | .get_ref = gfs2_recover_get_ref, |
597 | .put_ref = gfs2_recover_put_ref, | 599 | .put_ref = gfs2_recover_put_ref, |
598 | .execute = gfs2_recover_work, | 600 | .execute = gfs2_recover_work, |
diff --git a/fs/jffs2/read.c b/fs/jffs2/read.c index cfe05c1966a5..3f39be1b0455 100644 --- a/fs/jffs2/read.c +++ b/fs/jffs2/read.c | |||
@@ -164,12 +164,15 @@ int jffs2_read_inode_range(struct jffs2_sb_info *c, struct jffs2_inode_info *f, | |||
164 | 164 | ||
165 | /* XXX FIXME: Where a single physical node actually shows up in two | 165 | /* XXX FIXME: Where a single physical node actually shows up in two |
166 | frags, we read it twice. Don't do that. */ | 166 | frags, we read it twice. Don't do that. */ |
167 | /* Now we're pointing at the first frag which overlaps our page */ | 167 | /* Now we're pointing at the first frag which overlaps our page |
168 | * (or perhaps is before it, if we've been asked to read off the | ||
169 | * end of the file). */ | ||
168 | while(offset < end) { | 170 | while(offset < end) { |
169 | D2(printk(KERN_DEBUG "jffs2_read_inode_range: offset %d, end %d\n", offset, end)); | 171 | D2(printk(KERN_DEBUG "jffs2_read_inode_range: offset %d, end %d\n", offset, end)); |
170 | if (unlikely(!frag || frag->ofs > offset)) { | 172 | if (unlikely(!frag || frag->ofs > offset || |
173 | frag->ofs + frag->size <= offset)) { | ||
171 | uint32_t holesize = end - offset; | 174 | uint32_t holesize = end - offset; |
172 | if (frag) { | 175 | if (frag && frag->ofs > offset) { |
173 | D1(printk(KERN_NOTICE "Eep. Hole in ino #%u fraglist. frag->ofs = 0x%08x, offset = 0x%08x\n", f->inocache->ino, frag->ofs, offset)); | 176 | D1(printk(KERN_NOTICE "Eep. Hole in ino #%u fraglist. frag->ofs = 0x%08x, offset = 0x%08x\n", f->inocache->ino, frag->ofs, offset)); |
174 | holesize = min(holesize, frag->ofs - offset); | 177 | holesize = min(holesize, frag->ofs - offset); |
175 | } | 178 | } |
diff --git a/fs/nfs/fscache.c b/fs/nfs/fscache.c index 70fad69eb959..fa588006588d 100644 --- a/fs/nfs/fscache.c +++ b/fs/nfs/fscache.c | |||
@@ -359,17 +359,13 @@ int nfs_fscache_release_page(struct page *page, gfp_t gfp) | |||
359 | 359 | ||
360 | BUG_ON(!cookie); | 360 | BUG_ON(!cookie); |
361 | 361 | ||
362 | if (fscache_check_page_write(cookie, page)) { | ||
363 | if (!(gfp & __GFP_WAIT)) | ||
364 | return 0; | ||
365 | fscache_wait_on_page_write(cookie, page); | ||
366 | } | ||
367 | |||
368 | if (PageFsCache(page)) { | 362 | if (PageFsCache(page)) { |
369 | dfprintk(FSCACHE, "NFS: fscache releasepage (0x%p/0x%p/0x%p)\n", | 363 | dfprintk(FSCACHE, "NFS: fscache releasepage (0x%p/0x%p/0x%p)\n", |
370 | cookie, page, nfsi); | 364 | cookie, page, nfsi); |
371 | 365 | ||
372 | fscache_uncache_page(cookie, page); | 366 | if (!fscache_maybe_release_page(cookie, page, gfp)) |
367 | return 0; | ||
368 | |||
373 | nfs_add_fscache_stats(page->mapping->host, | 369 | nfs_add_fscache_stats(page->mapping->host, |
374 | NFSIOS_FSCACHE_PAGES_UNCACHED, 1); | 370 | NFSIOS_FSCACHE_PAGES_UNCACHED, 1); |
375 | } | 371 | } |
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index ff37454fa783..741a562177fc 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c | |||
@@ -2767,7 +2767,7 @@ static int _nfs4_proc_readdir(struct dentry *dentry, struct rpc_cred *cred, | |||
2767 | .pages = &page, | 2767 | .pages = &page, |
2768 | .pgbase = 0, | 2768 | .pgbase = 0, |
2769 | .count = count, | 2769 | .count = count, |
2770 | .bitmask = NFS_SERVER(dentry->d_inode)->cache_consistency_bitmask, | 2770 | .bitmask = NFS_SERVER(dentry->d_inode)->attr_bitmask, |
2771 | }; | 2771 | }; |
2772 | struct nfs4_readdir_res res; | 2772 | struct nfs4_readdir_res res; |
2773 | struct rpc_message msg = { | 2773 | struct rpc_message msg = { |
diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c index 89fc8ee1f5a5..de059f490586 100644 --- a/fs/ocfs2/file.c +++ b/fs/ocfs2/file.c | |||
@@ -1712,7 +1712,8 @@ int ocfs2_check_range_for_refcount(struct inode *inode, loff_t pos, | |||
1712 | struct super_block *sb = inode->i_sb; | 1712 | struct super_block *sb = inode->i_sb; |
1713 | 1713 | ||
1714 | if (!ocfs2_refcount_tree(OCFS2_SB(inode->i_sb)) || | 1714 | if (!ocfs2_refcount_tree(OCFS2_SB(inode->i_sb)) || |
1715 | !(OCFS2_I(inode)->ip_dyn_features & OCFS2_HAS_REFCOUNT_FL)) | 1715 | !(OCFS2_I(inode)->ip_dyn_features & OCFS2_HAS_REFCOUNT_FL) || |
1716 | OCFS2_I(inode)->ip_dyn_features & OCFS2_INLINE_DATA_FL) | ||
1716 | return 0; | 1717 | return 0; |
1717 | 1718 | ||
1718 | cpos = pos >> OCFS2_SB(sb)->s_clustersize_bits; | 1719 | cpos = pos >> OCFS2_SB(sb)->s_clustersize_bits; |
diff --git a/fs/ocfs2/ocfs2.h b/fs/ocfs2/ocfs2.h index eae404602424..d963d8638709 100644 --- a/fs/ocfs2/ocfs2.h +++ b/fs/ocfs2/ocfs2.h | |||
@@ -35,12 +35,7 @@ | |||
35 | #include <linux/kref.h> | 35 | #include <linux/kref.h> |
36 | #include <linux/mutex.h> | 36 | #include <linux/mutex.h> |
37 | #include <linux/lockdep.h> | 37 | #include <linux/lockdep.h> |
38 | #ifndef CONFIG_OCFS2_COMPAT_JBD | 38 | #include <linux/jbd2.h> |
39 | # include <linux/jbd2.h> | ||
40 | #else | ||
41 | # include <linux/jbd.h> | ||
42 | # include "ocfs2_jbd_compat.h" | ||
43 | #endif | ||
44 | 39 | ||
45 | /* For union ocfs2_dlm_lksb */ | 40 | /* For union ocfs2_dlm_lksb */ |
46 | #include "stackglue.h" | 41 | #include "stackglue.h" |
diff --git a/fs/ocfs2/refcounttree.c b/fs/ocfs2/refcounttree.c index 60287fc56bcb..3a0df7a1b810 100644 --- a/fs/ocfs2/refcounttree.c +++ b/fs/ocfs2/refcounttree.c | |||
@@ -3743,6 +3743,9 @@ static int ocfs2_attach_refcount_tree(struct inode *inode, | |||
3743 | goto out; | 3743 | goto out; |
3744 | } | 3744 | } |
3745 | 3745 | ||
3746 | if (oi->ip_dyn_features & OCFS2_INLINE_DATA_FL) | ||
3747 | goto attach_xattr; | ||
3748 | |||
3746 | ocfs2_init_dinode_extent_tree(&di_et, INODE_CACHE(inode), di_bh); | 3749 | ocfs2_init_dinode_extent_tree(&di_et, INODE_CACHE(inode), di_bh); |
3747 | 3750 | ||
3748 | size = i_size_read(inode); | 3751 | size = i_size_read(inode); |
@@ -3769,6 +3772,7 @@ static int ocfs2_attach_refcount_tree(struct inode *inode, | |||
3769 | cpos += num_clusters; | 3772 | cpos += num_clusters; |
3770 | } | 3773 | } |
3771 | 3774 | ||
3775 | attach_xattr: | ||
3772 | if (oi->ip_dyn_features & OCFS2_HAS_XATTR_FL) { | 3776 | if (oi->ip_dyn_features & OCFS2_HAS_XATTR_FL) { |
3773 | ret = ocfs2_xattr_attach_refcount_tree(inode, di_bh, | 3777 | ret = ocfs2_xattr_attach_refcount_tree(inode, di_bh, |
3774 | &ref_tree->rf_ci, | 3778 | &ref_tree->rf_ci, |
@@ -3858,6 +3862,49 @@ out: | |||
3858 | return ret; | 3862 | return ret; |
3859 | } | 3863 | } |
3860 | 3864 | ||
3865 | static int ocfs2_duplicate_inline_data(struct inode *s_inode, | ||
3866 | struct buffer_head *s_bh, | ||
3867 | struct inode *t_inode, | ||
3868 | struct buffer_head *t_bh) | ||
3869 | { | ||
3870 | int ret; | ||
3871 | handle_t *handle; | ||
3872 | struct ocfs2_super *osb = OCFS2_SB(s_inode->i_sb); | ||
3873 | struct ocfs2_dinode *s_di = (struct ocfs2_dinode *)s_bh->b_data; | ||
3874 | struct ocfs2_dinode *t_di = (struct ocfs2_dinode *)t_bh->b_data; | ||
3875 | |||
3876 | BUG_ON(!(OCFS2_I(s_inode)->ip_dyn_features & OCFS2_INLINE_DATA_FL)); | ||
3877 | |||
3878 | handle = ocfs2_start_trans(osb, OCFS2_INODE_UPDATE_CREDITS); | ||
3879 | if (IS_ERR(handle)) { | ||
3880 | ret = PTR_ERR(handle); | ||
3881 | mlog_errno(ret); | ||
3882 | goto out; | ||
3883 | } | ||
3884 | |||
3885 | ret = ocfs2_journal_access_di(handle, INODE_CACHE(t_inode), t_bh, | ||
3886 | OCFS2_JOURNAL_ACCESS_WRITE); | ||
3887 | if (ret) { | ||
3888 | mlog_errno(ret); | ||
3889 | goto out_commit; | ||
3890 | } | ||
3891 | |||
3892 | t_di->id2.i_data.id_count = s_di->id2.i_data.id_count; | ||
3893 | memcpy(t_di->id2.i_data.id_data, s_di->id2.i_data.id_data, | ||
3894 | le16_to_cpu(s_di->id2.i_data.id_count)); | ||
3895 | spin_lock(&OCFS2_I(t_inode)->ip_lock); | ||
3896 | OCFS2_I(t_inode)->ip_dyn_features |= OCFS2_INLINE_DATA_FL; | ||
3897 | t_di->i_dyn_features = cpu_to_le16(OCFS2_I(t_inode)->ip_dyn_features); | ||
3898 | spin_unlock(&OCFS2_I(t_inode)->ip_lock); | ||
3899 | |||
3900 | ocfs2_journal_dirty(handle, t_bh); | ||
3901 | |||
3902 | out_commit: | ||
3903 | ocfs2_commit_trans(osb, handle); | ||
3904 | out: | ||
3905 | return ret; | ||
3906 | } | ||
3907 | |||
3861 | static int ocfs2_duplicate_extent_list(struct inode *s_inode, | 3908 | static int ocfs2_duplicate_extent_list(struct inode *s_inode, |
3862 | struct inode *t_inode, | 3909 | struct inode *t_inode, |
3863 | struct buffer_head *t_bh, | 3910 | struct buffer_head *t_bh, |
@@ -3997,6 +4044,14 @@ static int ocfs2_create_reflink_node(struct inode *s_inode, | |||
3997 | goto out; | 4044 | goto out; |
3998 | } | 4045 | } |
3999 | 4046 | ||
4047 | if (OCFS2_I(s_inode)->ip_dyn_features & OCFS2_INLINE_DATA_FL) { | ||
4048 | ret = ocfs2_duplicate_inline_data(s_inode, s_bh, | ||
4049 | t_inode, t_bh); | ||
4050 | if (ret) | ||
4051 | mlog_errno(ret); | ||
4052 | goto out; | ||
4053 | } | ||
4054 | |||
4000 | ret = ocfs2_lock_refcount_tree(osb, le64_to_cpu(di->i_refcount_loc), | 4055 | ret = ocfs2_lock_refcount_tree(osb, le64_to_cpu(di->i_refcount_loc), |
4001 | 1, &ref_tree, &ref_root_bh); | 4056 | 1, &ref_tree, &ref_root_bh); |
4002 | if (ret) { | 4057 | if (ret) { |
@@ -4013,10 +4068,6 @@ static int ocfs2_create_reflink_node(struct inode *s_inode, | |||
4013 | goto out_unlock_refcount; | 4068 | goto out_unlock_refcount; |
4014 | } | 4069 | } |
4015 | 4070 | ||
4016 | ret = ocfs2_complete_reflink(s_inode, s_bh, t_inode, t_bh, preserve); | ||
4017 | if (ret) | ||
4018 | mlog_errno(ret); | ||
4019 | |||
4020 | out_unlock_refcount: | 4071 | out_unlock_refcount: |
4021 | ocfs2_unlock_refcount_tree(osb, ref_tree, 1); | 4072 | ocfs2_unlock_refcount_tree(osb, ref_tree, 1); |
4022 | brelse(ref_root_bh); | 4073 | brelse(ref_root_bh); |
@@ -4068,9 +4119,17 @@ static int __ocfs2_reflink(struct dentry *old_dentry, | |||
4068 | ret = ocfs2_reflink_xattrs(inode, old_bh, | 4119 | ret = ocfs2_reflink_xattrs(inode, old_bh, |
4069 | new_inode, new_bh, | 4120 | new_inode, new_bh, |
4070 | preserve); | 4121 | preserve); |
4071 | if (ret) | 4122 | if (ret) { |
4072 | mlog_errno(ret); | 4123 | mlog_errno(ret); |
4124 | goto inode_unlock; | ||
4125 | } | ||
4073 | } | 4126 | } |
4127 | |||
4128 | ret = ocfs2_complete_reflink(inode, old_bh, | ||
4129 | new_inode, new_bh, preserve); | ||
4130 | if (ret) | ||
4131 | mlog_errno(ret); | ||
4132 | |||
4074 | inode_unlock: | 4133 | inode_unlock: |
4075 | ocfs2_inode_unlock(new_inode, 1); | 4134 | ocfs2_inode_unlock(new_inode, 1); |
4076 | brelse(new_bh); | 4135 | brelse(new_bh); |
diff --git a/fs/ocfs2/super.c b/fs/ocfs2/super.c index c0e48aeebb1c..14f47d2bfe02 100644 --- a/fs/ocfs2/super.c +++ b/fs/ocfs2/super.c | |||
@@ -773,18 +773,20 @@ static int ocfs2_sb_probe(struct super_block *sb, | |||
773 | if (tmpstat < 0) { | 773 | if (tmpstat < 0) { |
774 | status = tmpstat; | 774 | status = tmpstat; |
775 | mlog_errno(status); | 775 | mlog_errno(status); |
776 | goto bail; | 776 | break; |
777 | } | 777 | } |
778 | di = (struct ocfs2_dinode *) (*bh)->b_data; | 778 | di = (struct ocfs2_dinode *) (*bh)->b_data; |
779 | memset(stats, 0, sizeof(struct ocfs2_blockcheck_stats)); | 779 | memset(stats, 0, sizeof(struct ocfs2_blockcheck_stats)); |
780 | spin_lock_init(&stats->b_lock); | 780 | spin_lock_init(&stats->b_lock); |
781 | status = ocfs2_verify_volume(di, *bh, blksize, stats); | 781 | tmpstat = ocfs2_verify_volume(di, *bh, blksize, stats); |
782 | if (status >= 0) | 782 | if (tmpstat < 0) { |
783 | goto bail; | 783 | brelse(*bh); |
784 | brelse(*bh); | 784 | *bh = NULL; |
785 | *bh = NULL; | 785 | } |
786 | if (status != -EAGAIN) | 786 | if (tmpstat != -EAGAIN) { |
787 | status = tmpstat; | ||
787 | break; | 788 | break; |
789 | } | ||
788 | } | 790 | } |
789 | 791 | ||
790 | bail: | 792 | bail: |
@@ -1645,6 +1647,10 @@ static int ocfs2_statfs(struct dentry *dentry, struct kstatfs *buf) | |||
1645 | buf->f_bavail = buf->f_bfree; | 1647 | buf->f_bavail = buf->f_bfree; |
1646 | buf->f_files = numbits; | 1648 | buf->f_files = numbits; |
1647 | buf->f_ffree = freebits; | 1649 | buf->f_ffree = freebits; |
1650 | buf->f_fsid.val[0] = crc32_le(0, osb->uuid_str, OCFS2_VOL_UUID_LEN) | ||
1651 | & 0xFFFFFFFFUL; | ||
1652 | buf->f_fsid.val[1] = crc32_le(0, osb->uuid_str + OCFS2_VOL_UUID_LEN, | ||
1653 | OCFS2_VOL_UUID_LEN) & 0xFFFFFFFFUL; | ||
1648 | 1654 | ||
1649 | brelse(bh); | 1655 | brelse(bh); |
1650 | 1656 | ||
diff --git a/fs/ocfs2/uptodate.c b/fs/ocfs2/uptodate.c index b6284f235d2f..c61369342a27 100644 --- a/fs/ocfs2/uptodate.c +++ b/fs/ocfs2/uptodate.c | |||
@@ -53,11 +53,6 @@ | |||
53 | #include <linux/highmem.h> | 53 | #include <linux/highmem.h> |
54 | #include <linux/buffer_head.h> | 54 | #include <linux/buffer_head.h> |
55 | #include <linux/rbtree.h> | 55 | #include <linux/rbtree.h> |
56 | #ifndef CONFIG_OCFS2_COMPAT_JBD | ||
57 | # include <linux/jbd2.h> | ||
58 | #else | ||
59 | # include <linux/jbd.h> | ||
60 | #endif | ||
61 | 56 | ||
62 | #define MLOG_MASK_PREFIX ML_UPTODATE | 57 | #define MLOG_MASK_PREFIX ML_UPTODATE |
63 | 58 | ||
diff --git a/fs/proc/array.c b/fs/proc/array.c index 07f77a7945c3..822c2d506518 100644 --- a/fs/proc/array.c +++ b/fs/proc/array.c | |||
@@ -571,7 +571,7 @@ static int do_task_stat(struct seq_file *m, struct pid_namespace *ns, | |||
571 | rsslim, | 571 | rsslim, |
572 | mm ? mm->start_code : 0, | 572 | mm ? mm->start_code : 0, |
573 | mm ? mm->end_code : 0, | 573 | mm ? mm->end_code : 0, |
574 | (permitted) ? task->stack_start : 0, | 574 | (permitted && mm) ? task->stack_start : 0, |
575 | esp, | 575 | esp, |
576 | eip, | 576 | eip, |
577 | /* The signal information here is obsolete. | 577 | /* The signal information here is obsolete. |
diff --git a/include/asm-generic/fcntl.h b/include/asm-generic/fcntl.h index cd2d7896e34b..495dc8af4044 100644 --- a/include/asm-generic/fcntl.h +++ b/include/asm-generic/fcntl.h | |||
@@ -89,7 +89,7 @@ | |||
89 | 89 | ||
90 | #define F_OWNER_TID 0 | 90 | #define F_OWNER_TID 0 |
91 | #define F_OWNER_PID 1 | 91 | #define F_OWNER_PID 1 |
92 | #define F_OWNER_GID 2 | 92 | #define F_OWNER_PGRP 2 |
93 | 93 | ||
94 | struct f_owner_ex { | 94 | struct f_owner_ex { |
95 | int type; | 95 | int type; |
diff --git a/include/linux/fscache-cache.h b/include/linux/fscache-cache.h index 84d3532dd3ea..7be0c6fbe880 100644 --- a/include/linux/fscache-cache.h +++ b/include/linux/fscache-cache.h | |||
@@ -91,6 +91,8 @@ struct fscache_operation { | |||
91 | #define FSCACHE_OP_WAITING 4 /* cleared when op is woken */ | 91 | #define FSCACHE_OP_WAITING 4 /* cleared when op is woken */ |
92 | #define FSCACHE_OP_EXCLUSIVE 5 /* exclusive op, other ops must wait */ | 92 | #define FSCACHE_OP_EXCLUSIVE 5 /* exclusive op, other ops must wait */ |
93 | #define FSCACHE_OP_DEAD 6 /* op is now dead */ | 93 | #define FSCACHE_OP_DEAD 6 /* op is now dead */ |
94 | #define FSCACHE_OP_DEC_READ_CNT 7 /* decrement object->n_reads on destruction */ | ||
95 | #define FSCACHE_OP_KEEP_FLAGS 0xc0 /* flags to keep when repurposing an op */ | ||
94 | 96 | ||
95 | atomic_t usage; | 97 | atomic_t usage; |
96 | unsigned debug_id; /* debugging ID */ | 98 | unsigned debug_id; /* debugging ID */ |
@@ -102,6 +104,16 @@ struct fscache_operation { | |||
102 | 104 | ||
103 | /* operation releaser */ | 105 | /* operation releaser */ |
104 | fscache_operation_release_t release; | 106 | fscache_operation_release_t release; |
107 | |||
108 | #ifdef CONFIG_SLOW_WORK_PROC | ||
109 | const char *name; /* operation name */ | ||
110 | const char *state; /* operation state */ | ||
111 | #define fscache_set_op_name(OP, N) do { (OP)->name = (N); } while(0) | ||
112 | #define fscache_set_op_state(OP, S) do { (OP)->state = (S); } while(0) | ||
113 | #else | ||
114 | #define fscache_set_op_name(OP, N) do { } while(0) | ||
115 | #define fscache_set_op_state(OP, S) do { } while(0) | ||
116 | #endif | ||
105 | }; | 117 | }; |
106 | 118 | ||
107 | extern atomic_t fscache_op_debug_id; | 119 | extern atomic_t fscache_op_debug_id; |
@@ -125,6 +137,7 @@ static inline void fscache_operation_init(struct fscache_operation *op, | |||
125 | op->debug_id = atomic_inc_return(&fscache_op_debug_id); | 137 | op->debug_id = atomic_inc_return(&fscache_op_debug_id); |
126 | op->release = release; | 138 | op->release = release; |
127 | INIT_LIST_HEAD(&op->pend_link); | 139 | INIT_LIST_HEAD(&op->pend_link); |
140 | fscache_set_op_state(op, "Init"); | ||
128 | } | 141 | } |
129 | 142 | ||
130 | /** | 143 | /** |
@@ -221,8 +234,10 @@ struct fscache_cache_ops { | |||
221 | struct fscache_object *(*alloc_object)(struct fscache_cache *cache, | 234 | struct fscache_object *(*alloc_object)(struct fscache_cache *cache, |
222 | struct fscache_cookie *cookie); | 235 | struct fscache_cookie *cookie); |
223 | 236 | ||
224 | /* look up the object for a cookie */ | 237 | /* look up the object for a cookie |
225 | void (*lookup_object)(struct fscache_object *object); | 238 | * - return -ETIMEDOUT to be requeued |
239 | */ | ||
240 | int (*lookup_object)(struct fscache_object *object); | ||
226 | 241 | ||
227 | /* finished looking up */ | 242 | /* finished looking up */ |
228 | void (*lookup_complete)(struct fscache_object *object); | 243 | void (*lookup_complete)(struct fscache_object *object); |
@@ -297,12 +312,14 @@ struct fscache_cookie { | |||
297 | atomic_t usage; /* number of users of this cookie */ | 312 | atomic_t usage; /* number of users of this cookie */ |
298 | atomic_t n_children; /* number of children of this cookie */ | 313 | atomic_t n_children; /* number of children of this cookie */ |
299 | spinlock_t lock; | 314 | spinlock_t lock; |
315 | spinlock_t stores_lock; /* lock on page store tree */ | ||
300 | struct hlist_head backing_objects; /* object(s) backing this file/index */ | 316 | struct hlist_head backing_objects; /* object(s) backing this file/index */ |
301 | const struct fscache_cookie_def *def; /* definition */ | 317 | const struct fscache_cookie_def *def; /* definition */ |
302 | struct fscache_cookie *parent; /* parent of this entry */ | 318 | struct fscache_cookie *parent; /* parent of this entry */ |
303 | void *netfs_data; /* back pointer to netfs */ | 319 | void *netfs_data; /* back pointer to netfs */ |
304 | struct radix_tree_root stores; /* pages to be stored on this cookie */ | 320 | struct radix_tree_root stores; /* pages to be stored on this cookie */ |
305 | #define FSCACHE_COOKIE_PENDING_TAG 0 /* pages tag: pending write to cache */ | 321 | #define FSCACHE_COOKIE_PENDING_TAG 0 /* pages tag: pending write to cache */ |
322 | #define FSCACHE_COOKIE_STORING_TAG 1 /* pages tag: writing to cache */ | ||
306 | 323 | ||
307 | unsigned long flags; | 324 | unsigned long flags; |
308 | #define FSCACHE_COOKIE_LOOKING_UP 0 /* T if non-index cookie being looked up still */ | 325 | #define FSCACHE_COOKIE_LOOKING_UP 0 /* T if non-index cookie being looked up still */ |
@@ -337,6 +354,7 @@ struct fscache_object { | |||
337 | FSCACHE_OBJECT_RECYCLING, /* retiring object */ | 354 | FSCACHE_OBJECT_RECYCLING, /* retiring object */ |
338 | FSCACHE_OBJECT_WITHDRAWING, /* withdrawing object */ | 355 | FSCACHE_OBJECT_WITHDRAWING, /* withdrawing object */ |
339 | FSCACHE_OBJECT_DEAD, /* object is now dead */ | 356 | FSCACHE_OBJECT_DEAD, /* object is now dead */ |
357 | FSCACHE_OBJECT__NSTATES | ||
340 | } state; | 358 | } state; |
341 | 359 | ||
342 | int debug_id; /* debugging ID */ | 360 | int debug_id; /* debugging ID */ |
@@ -345,6 +363,7 @@ struct fscache_object { | |||
345 | int n_obj_ops; /* number of object ops outstanding on object */ | 363 | int n_obj_ops; /* number of object ops outstanding on object */ |
346 | int n_in_progress; /* number of ops in progress */ | 364 | int n_in_progress; /* number of ops in progress */ |
347 | int n_exclusive; /* number of exclusive ops queued */ | 365 | int n_exclusive; /* number of exclusive ops queued */ |
366 | atomic_t n_reads; /* number of read ops in progress */ | ||
348 | spinlock_t lock; /* state and operations lock */ | 367 | spinlock_t lock; /* state and operations lock */ |
349 | 368 | ||
350 | unsigned long lookup_jif; /* time at which lookup started */ | 369 | unsigned long lookup_jif; /* time at which lookup started */ |
@@ -358,6 +377,7 @@ struct fscache_object { | |||
358 | #define FSCACHE_OBJECT_EV_RELEASE 4 /* T if netfs requested object release */ | 377 | #define FSCACHE_OBJECT_EV_RELEASE 4 /* T if netfs requested object release */ |
359 | #define FSCACHE_OBJECT_EV_RETIRE 5 /* T if netfs requested object retirement */ | 378 | #define FSCACHE_OBJECT_EV_RETIRE 5 /* T if netfs requested object retirement */ |
360 | #define FSCACHE_OBJECT_EV_WITHDRAW 6 /* T if cache requested object withdrawal */ | 379 | #define FSCACHE_OBJECT_EV_WITHDRAW 6 /* T if cache requested object withdrawal */ |
380 | #define FSCACHE_OBJECT_EVENTS_MASK 0x7f /* mask of all events*/ | ||
361 | 381 | ||
362 | unsigned long flags; | 382 | unsigned long flags; |
363 | #define FSCACHE_OBJECT_LOCK 0 /* T if object is busy being processed */ | 383 | #define FSCACHE_OBJECT_LOCK 0 /* T if object is busy being processed */ |
@@ -373,7 +393,11 @@ struct fscache_object { | |||
373 | struct list_head dependents; /* FIFO of dependent objects */ | 393 | struct list_head dependents; /* FIFO of dependent objects */ |
374 | struct list_head dep_link; /* link in parent's dependents list */ | 394 | struct list_head dep_link; /* link in parent's dependents list */ |
375 | struct list_head pending_ops; /* unstarted operations on this object */ | 395 | struct list_head pending_ops; /* unstarted operations on this object */ |
396 | #ifdef CONFIG_FSCACHE_OBJECT_LIST | ||
397 | struct rb_node objlist_link; /* link in global object list */ | ||
398 | #endif | ||
376 | pgoff_t store_limit; /* current storage limit */ | 399 | pgoff_t store_limit; /* current storage limit */ |
400 | loff_t store_limit_l; /* current storage limit */ | ||
377 | }; | 401 | }; |
378 | 402 | ||
379 | extern const char *fscache_object_states[]; | 403 | extern const char *fscache_object_states[]; |
@@ -383,6 +407,10 @@ extern const char *fscache_object_states[]; | |||
383 | (obj)->state >= FSCACHE_OBJECT_AVAILABLE && \ | 407 | (obj)->state >= FSCACHE_OBJECT_AVAILABLE && \ |
384 | (obj)->state < FSCACHE_OBJECT_DYING) | 408 | (obj)->state < FSCACHE_OBJECT_DYING) |
385 | 409 | ||
410 | #define fscache_object_is_dead(obj) \ | ||
411 | (test_bit(FSCACHE_IOERROR, &(obj)->cache->flags) && \ | ||
412 | (obj)->state >= FSCACHE_OBJECT_DYING) | ||
413 | |||
386 | extern const struct slow_work_ops fscache_object_slow_work_ops; | 414 | extern const struct slow_work_ops fscache_object_slow_work_ops; |
387 | 415 | ||
388 | /** | 416 | /** |
@@ -414,6 +442,7 @@ void fscache_object_init(struct fscache_object *object, | |||
414 | object->events = object->event_mask = 0; | 442 | object->events = object->event_mask = 0; |
415 | object->flags = 0; | 443 | object->flags = 0; |
416 | object->store_limit = 0; | 444 | object->store_limit = 0; |
445 | object->store_limit_l = 0; | ||
417 | object->cache = cache; | 446 | object->cache = cache; |
418 | object->cookie = cookie; | 447 | object->cookie = cookie; |
419 | object->parent = NULL; | 448 | object->parent = NULL; |
@@ -422,6 +451,12 @@ void fscache_object_init(struct fscache_object *object, | |||
422 | extern void fscache_object_lookup_negative(struct fscache_object *object); | 451 | extern void fscache_object_lookup_negative(struct fscache_object *object); |
423 | extern void fscache_obtained_object(struct fscache_object *object); | 452 | extern void fscache_obtained_object(struct fscache_object *object); |
424 | 453 | ||
454 | #ifdef CONFIG_FSCACHE_OBJECT_LIST | ||
455 | extern void fscache_object_destroy(struct fscache_object *object); | ||
456 | #else | ||
457 | #define fscache_object_destroy(object) do {} while(0) | ||
458 | #endif | ||
459 | |||
425 | /** | 460 | /** |
426 | * fscache_object_destroyed - Note destruction of an object in a cache | 461 | * fscache_object_destroyed - Note destruction of an object in a cache |
427 | * @cache: The cache from which the object came | 462 | * @cache: The cache from which the object came |
@@ -460,6 +495,7 @@ static inline void fscache_object_lookup_error(struct fscache_object *object) | |||
460 | static inline | 495 | static inline |
461 | void fscache_set_store_limit(struct fscache_object *object, loff_t i_size) | 496 | void fscache_set_store_limit(struct fscache_object *object, loff_t i_size) |
462 | { | 497 | { |
498 | object->store_limit_l = i_size; | ||
463 | object->store_limit = i_size >> PAGE_SHIFT; | 499 | object->store_limit = i_size >> PAGE_SHIFT; |
464 | if (i_size & ~PAGE_MASK) | 500 | if (i_size & ~PAGE_MASK) |
465 | object->store_limit++; | 501 | object->store_limit++; |
diff --git a/include/linux/fscache.h b/include/linux/fscache.h index 6d8ee466e0a0..595ce49288b7 100644 --- a/include/linux/fscache.h +++ b/include/linux/fscache.h | |||
@@ -202,6 +202,8 @@ extern int __fscache_write_page(struct fscache_cookie *, struct page *, gfp_t); | |||
202 | extern void __fscache_uncache_page(struct fscache_cookie *, struct page *); | 202 | extern void __fscache_uncache_page(struct fscache_cookie *, struct page *); |
203 | extern bool __fscache_check_page_write(struct fscache_cookie *, struct page *); | 203 | extern bool __fscache_check_page_write(struct fscache_cookie *, struct page *); |
204 | extern void __fscache_wait_on_page_write(struct fscache_cookie *, struct page *); | 204 | extern void __fscache_wait_on_page_write(struct fscache_cookie *, struct page *); |
205 | extern bool __fscache_maybe_release_page(struct fscache_cookie *, struct page *, | ||
206 | gfp_t); | ||
205 | 207 | ||
206 | /** | 208 | /** |
207 | * fscache_register_netfs - Register a filesystem as desiring caching services | 209 | * fscache_register_netfs - Register a filesystem as desiring caching services |
@@ -615,4 +617,29 @@ void fscache_wait_on_page_write(struct fscache_cookie *cookie, | |||
615 | __fscache_wait_on_page_write(cookie, page); | 617 | __fscache_wait_on_page_write(cookie, page); |
616 | } | 618 | } |
617 | 619 | ||
620 | /** | ||
621 | * fscache_maybe_release_page - Consider releasing a page, cancelling a store | ||
622 | * @cookie: The cookie representing the cache object | ||
623 | * @page: The netfs page that is being cached. | ||
624 | * @gfp: The gfp flags passed to releasepage() | ||
625 | * | ||
626 | * Consider releasing a page for the vmscan algorithm, on behalf of the netfs's | ||
627 | * releasepage() call. A storage request on the page may cancelled if it is | ||
628 | * not currently being processed. | ||
629 | * | ||
630 | * The function returns true if the page no longer has a storage request on it, | ||
631 | * and false if a storage request is left in place. If true is returned, the | ||
632 | * page will have been passed to fscache_uncache_page(). If false is returned | ||
633 | * the page cannot be freed yet. | ||
634 | */ | ||
635 | static inline | ||
636 | bool fscache_maybe_release_page(struct fscache_cookie *cookie, | ||
637 | struct page *page, | ||
638 | gfp_t gfp) | ||
639 | { | ||
640 | if (fscache_cookie_valid(cookie) && PageFsCache(page)) | ||
641 | return __fscache_maybe_release_page(cookie, page, gfp); | ||
642 | return false; | ||
643 | } | ||
644 | |||
618 | #endif /* _LINUX_FSCACHE_H */ | 645 | #endif /* _LINUX_FSCACHE_H */ |
diff --git a/include/linux/i2c-pnx.h b/include/linux/i2c-pnx.h index f13255e06406..9eb07bbc6522 100644 --- a/include/linux/i2c-pnx.h +++ b/include/linux/i2c-pnx.h | |||
@@ -21,7 +21,7 @@ struct i2c_pnx_mif { | |||
21 | int mode; /* Interface mode */ | 21 | int mode; /* Interface mode */ |
22 | struct completion complete; /* I/O completion */ | 22 | struct completion complete; /* I/O completion */ |
23 | struct timer_list timer; /* Timeout */ | 23 | struct timer_list timer; /* Timeout */ |
24 | char * buf; /* Data buffer */ | 24 | u8 * buf; /* Data buffer */ |
25 | int len; /* Length of data buffer */ | 25 | int len; /* Length of data buffer */ |
26 | }; | 26 | }; |
27 | 27 | ||
diff --git a/include/linux/isdn_ppp.h b/include/linux/isdn_ppp.h index 4c218ee7587a..8687a7dc0632 100644 --- a/include/linux/isdn_ppp.h +++ b/include/linux/isdn_ppp.h | |||
@@ -157,7 +157,7 @@ typedef struct { | |||
157 | 157 | ||
158 | typedef struct { | 158 | typedef struct { |
159 | int mp_mrru; /* unused */ | 159 | int mp_mrru; /* unused */ |
160 | struct sk_buff_head frags; /* fragments sl list */ | 160 | struct sk_buff * frags; /* fragments sl list -- use skb->next */ |
161 | long frames; /* number of frames in the frame list */ | 161 | long frames; /* number of frames in the frame list */ |
162 | unsigned int seq; /* last processed packet seq #: any packets | 162 | unsigned int seq; /* last processed packet seq #: any packets |
163 | * with smaller seq # will be dropped | 163 | * with smaller seq # will be dropped |
diff --git a/include/linux/slow-work.h b/include/linux/slow-work.h index b65c8881f07a..5035a2691739 100644 --- a/include/linux/slow-work.h +++ b/include/linux/slow-work.h | |||
@@ -17,13 +17,20 @@ | |||
17 | #ifdef CONFIG_SLOW_WORK | 17 | #ifdef CONFIG_SLOW_WORK |
18 | 18 | ||
19 | #include <linux/sysctl.h> | 19 | #include <linux/sysctl.h> |
20 | #include <linux/timer.h> | ||
20 | 21 | ||
21 | struct slow_work; | 22 | struct slow_work; |
23 | #ifdef CONFIG_SLOW_WORK_PROC | ||
24 | struct seq_file; | ||
25 | #endif | ||
22 | 26 | ||
23 | /* | 27 | /* |
24 | * The operations used to support slow work items | 28 | * The operations used to support slow work items |
25 | */ | 29 | */ |
26 | struct slow_work_ops { | 30 | struct slow_work_ops { |
31 | /* owner */ | ||
32 | struct module *owner; | ||
33 | |||
27 | /* get a ref on a work item | 34 | /* get a ref on a work item |
28 | * - return 0 if successful, -ve if not | 35 | * - return 0 if successful, -ve if not |
29 | */ | 36 | */ |
@@ -34,6 +41,11 @@ struct slow_work_ops { | |||
34 | 41 | ||
35 | /* execute a work item */ | 42 | /* execute a work item */ |
36 | void (*execute)(struct slow_work *work); | 43 | void (*execute)(struct slow_work *work); |
44 | |||
45 | #ifdef CONFIG_SLOW_WORK_PROC | ||
46 | /* describe a work item for /proc */ | ||
47 | void (*desc)(struct slow_work *work, struct seq_file *m); | ||
48 | #endif | ||
37 | }; | 49 | }; |
38 | 50 | ||
39 | /* | 51 | /* |
@@ -42,13 +54,24 @@ struct slow_work_ops { | |||
42 | * queued | 54 | * queued |
43 | */ | 55 | */ |
44 | struct slow_work { | 56 | struct slow_work { |
57 | struct module *owner; /* the owning module */ | ||
45 | unsigned long flags; | 58 | unsigned long flags; |
46 | #define SLOW_WORK_PENDING 0 /* item pending (further) execution */ | 59 | #define SLOW_WORK_PENDING 0 /* item pending (further) execution */ |
47 | #define SLOW_WORK_EXECUTING 1 /* item currently executing */ | 60 | #define SLOW_WORK_EXECUTING 1 /* item currently executing */ |
48 | #define SLOW_WORK_ENQ_DEFERRED 2 /* item enqueue deferred */ | 61 | #define SLOW_WORK_ENQ_DEFERRED 2 /* item enqueue deferred */ |
49 | #define SLOW_WORK_VERY_SLOW 3 /* item is very slow */ | 62 | #define SLOW_WORK_VERY_SLOW 3 /* item is very slow */ |
63 | #define SLOW_WORK_CANCELLING 4 /* item is being cancelled, don't enqueue */ | ||
64 | #define SLOW_WORK_DELAYED 5 /* item is struct delayed_slow_work with active timer */ | ||
50 | const struct slow_work_ops *ops; /* operations table for this item */ | 65 | const struct slow_work_ops *ops; /* operations table for this item */ |
51 | struct list_head link; /* link in queue */ | 66 | struct list_head link; /* link in queue */ |
67 | #ifdef CONFIG_SLOW_WORK_PROC | ||
68 | struct timespec mark; /* jiffies at which queued or exec begun */ | ||
69 | #endif | ||
70 | }; | ||
71 | |||
72 | struct delayed_slow_work { | ||
73 | struct slow_work work; | ||
74 | struct timer_list timer; | ||
52 | }; | 75 | }; |
53 | 76 | ||
54 | /** | 77 | /** |
@@ -67,6 +90,20 @@ static inline void slow_work_init(struct slow_work *work, | |||
67 | } | 90 | } |
68 | 91 | ||
69 | /** | 92 | /** |
93 | * slow_work_init - Initialise a delayed slow work item | ||
94 | * @work: The work item to initialise | ||
95 | * @ops: The operations to use to handle the slow work item | ||
96 | * | ||
97 | * Initialise a delayed slow work item. | ||
98 | */ | ||
99 | static inline void delayed_slow_work_init(struct delayed_slow_work *dwork, | ||
100 | const struct slow_work_ops *ops) | ||
101 | { | ||
102 | init_timer(&dwork->timer); | ||
103 | slow_work_init(&dwork->work, ops); | ||
104 | } | ||
105 | |||
106 | /** | ||
70 | * vslow_work_init - Initialise a very slow work item | 107 | * vslow_work_init - Initialise a very slow work item |
71 | * @work: The work item to initialise | 108 | * @work: The work item to initialise |
72 | * @ops: The operations to use to handle the slow work item | 109 | * @ops: The operations to use to handle the slow work item |
@@ -83,9 +120,40 @@ static inline void vslow_work_init(struct slow_work *work, | |||
83 | INIT_LIST_HEAD(&work->link); | 120 | INIT_LIST_HEAD(&work->link); |
84 | } | 121 | } |
85 | 122 | ||
123 | /** | ||
124 | * slow_work_is_queued - Determine if a slow work item is on the work queue | ||
125 | * work: The work item to test | ||
126 | * | ||
127 | * Determine if the specified slow-work item is on the work queue. This | ||
128 | * returns true if it is actually on the queue. | ||
129 | * | ||
130 | * If the item is executing and has been marked for requeue when execution | ||
131 | * finishes, then false will be returned. | ||
132 | * | ||
133 | * Anyone wishing to wait for completion of execution can wait on the | ||
134 | * SLOW_WORK_EXECUTING bit. | ||
135 | */ | ||
136 | static inline bool slow_work_is_queued(struct slow_work *work) | ||
137 | { | ||
138 | unsigned long flags = work->flags; | ||
139 | return flags & SLOW_WORK_PENDING && !(flags & SLOW_WORK_EXECUTING); | ||
140 | } | ||
141 | |||
86 | extern int slow_work_enqueue(struct slow_work *work); | 142 | extern int slow_work_enqueue(struct slow_work *work); |
87 | extern int slow_work_register_user(void); | 143 | extern void slow_work_cancel(struct slow_work *work); |
88 | extern void slow_work_unregister_user(void); | 144 | extern int slow_work_register_user(struct module *owner); |
145 | extern void slow_work_unregister_user(struct module *owner); | ||
146 | |||
147 | extern int delayed_slow_work_enqueue(struct delayed_slow_work *dwork, | ||
148 | unsigned long delay); | ||
149 | |||
150 | static inline void delayed_slow_work_cancel(struct delayed_slow_work *dwork) | ||
151 | { | ||
152 | slow_work_cancel(&dwork->work); | ||
153 | } | ||
154 | |||
155 | extern bool slow_work_sleep_till_thread_needed(struct slow_work *work, | ||
156 | signed long *_timeout); | ||
89 | 157 | ||
90 | #ifdef CONFIG_SYSCTL | 158 | #ifdef CONFIG_SYSCTL |
91 | extern ctl_table slow_work_sysctls[]; | 159 | extern ctl_table slow_work_sysctls[]; |
diff --git a/include/linux/suspend.h b/include/linux/suspend.h index cd15df6c63cd..5e781d824e6d 100644 --- a/include/linux/suspend.h +++ b/include/linux/suspend.h | |||
@@ -301,6 +301,8 @@ static inline int unregister_pm_notifier(struct notifier_block *nb) | |||
301 | #define pm_notifier(fn, pri) do { (void)(fn); } while (0) | 301 | #define pm_notifier(fn, pri) do { (void)(fn); } while (0) |
302 | #endif /* !CONFIG_PM_SLEEP */ | 302 | #endif /* !CONFIG_PM_SLEEP */ |
303 | 303 | ||
304 | extern struct mutex pm_mutex; | ||
305 | |||
304 | #ifndef CONFIG_HIBERNATION | 306 | #ifndef CONFIG_HIBERNATION |
305 | static inline void register_nosave_region(unsigned long b, unsigned long e) | 307 | static inline void register_nosave_region(unsigned long b, unsigned long e) |
306 | { | 308 | { |
@@ -308,8 +310,23 @@ static inline void register_nosave_region(unsigned long b, unsigned long e) | |||
308 | static inline void register_nosave_region_late(unsigned long b, unsigned long e) | 310 | static inline void register_nosave_region_late(unsigned long b, unsigned long e) |
309 | { | 311 | { |
310 | } | 312 | } |
311 | #endif | ||
312 | 313 | ||
313 | extern struct mutex pm_mutex; | 314 | static inline void lock_system_sleep(void) {} |
315 | static inline void unlock_system_sleep(void) {} | ||
316 | |||
317 | #else | ||
318 | |||
319 | /* Let some subsystems like memory hotadd exclude hibernation */ | ||
320 | |||
321 | static inline void lock_system_sleep(void) | ||
322 | { | ||
323 | mutex_lock(&pm_mutex); | ||
324 | } | ||
325 | |||
326 | static inline void unlock_system_sleep(void) | ||
327 | { | ||
328 | mutex_unlock(&pm_mutex); | ||
329 | } | ||
330 | #endif | ||
314 | 331 | ||
315 | #endif /* _LINUX_SUSPEND_H */ | 332 | #endif /* _LINUX_SUSPEND_H */ |
diff --git a/include/linux/vt.h b/include/linux/vt.h index 7afca0d72139..7ffa11f06232 100644 --- a/include/linux/vt.h +++ b/include/linux/vt.h | |||
@@ -70,8 +70,8 @@ struct vt_event { | |||
70 | #define VT_EVENT_UNBLANK 0x0004 /* Screen unblank */ | 70 | #define VT_EVENT_UNBLANK 0x0004 /* Screen unblank */ |
71 | #define VT_EVENT_RESIZE 0x0008 /* Resize display */ | 71 | #define VT_EVENT_RESIZE 0x0008 /* Resize display */ |
72 | #define VT_MAX_EVENT 0x000F | 72 | #define VT_MAX_EVENT 0x000F |
73 | unsigned int old; /* Old console */ | 73 | unsigned int oldev; /* Old console */ |
74 | unsigned int new; /* New console (if changing) */ | 74 | unsigned int newev; /* New console (if changing) */ |
75 | unsigned int pad[4]; /* Padding for expansion */ | 75 | unsigned int pad[4]; /* Padding for expansion */ |
76 | }; | 76 | }; |
77 | 77 | ||
diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h index 6e5f0e0c7967..0a474568b003 100644 --- a/include/net/sctp/structs.h +++ b/include/net/sctp/structs.h | |||
@@ -893,7 +893,6 @@ struct sctp_transport { | |||
893 | */ | 893 | */ |
894 | /* RTO : The current retransmission timeout value. */ | 894 | /* RTO : The current retransmission timeout value. */ |
895 | unsigned long rto; | 895 | unsigned long rto; |
896 | unsigned long last_rto; | ||
897 | 896 | ||
898 | __u32 rtt; /* This is the most recent RTT. */ | 897 | __u32 rtt; /* This is the most recent RTT. */ |
899 | 898 | ||
@@ -1980,7 +1979,7 @@ void sctp_assoc_set_primary(struct sctp_association *, | |||
1980 | void sctp_assoc_del_nonprimary_peers(struct sctp_association *, | 1979 | void sctp_assoc_del_nonprimary_peers(struct sctp_association *, |
1981 | struct sctp_transport *); | 1980 | struct sctp_transport *); |
1982 | int sctp_assoc_set_bind_addr_from_ep(struct sctp_association *, | 1981 | int sctp_assoc_set_bind_addr_from_ep(struct sctp_association *, |
1983 | gfp_t); | 1982 | sctp_scope_t, gfp_t); |
1984 | int sctp_assoc_set_bind_addr_from_cookie(struct sctp_association *, | 1983 | int sctp_assoc_set_bind_addr_from_cookie(struct sctp_association *, |
1985 | struct sctp_cookie*, | 1984 | struct sctp_cookie*, |
1986 | gfp_t gfp); | 1985 | gfp_t gfp); |
diff --git a/include/scsi/scsi_host.h b/include/scsi/scsi_host.h index 6e728b176904..47941fc5aba7 100644 --- a/include/scsi/scsi_host.h +++ b/include/scsi/scsi_host.h | |||
@@ -797,30 +797,23 @@ static inline unsigned int scsi_host_get_prot(struct Scsi_Host *shost) | |||
797 | 797 | ||
798 | static inline unsigned int scsi_host_dif_capable(struct Scsi_Host *shost, unsigned int target_type) | 798 | static inline unsigned int scsi_host_dif_capable(struct Scsi_Host *shost, unsigned int target_type) |
799 | { | 799 | { |
800 | switch (target_type) { | 800 | static unsigned char cap[] = { 0, |
801 | case 1: | 801 | SHOST_DIF_TYPE1_PROTECTION, |
802 | if (shost->prot_capabilities & SHOST_DIF_TYPE1_PROTECTION) | 802 | SHOST_DIF_TYPE2_PROTECTION, |
803 | return target_type; | 803 | SHOST_DIF_TYPE3_PROTECTION }; |
804 | case 2: | ||
805 | if (shost->prot_capabilities & SHOST_DIF_TYPE2_PROTECTION) | ||
806 | return target_type; | ||
807 | case 3: | ||
808 | if (shost->prot_capabilities & SHOST_DIF_TYPE3_PROTECTION) | ||
809 | return target_type; | ||
810 | } | ||
811 | 804 | ||
812 | return 0; | 805 | return shost->prot_capabilities & cap[target_type] ? target_type : 0; |
813 | } | 806 | } |
814 | 807 | ||
815 | static inline unsigned int scsi_host_dix_capable(struct Scsi_Host *shost, unsigned int target_type) | 808 | static inline unsigned int scsi_host_dix_capable(struct Scsi_Host *shost, unsigned int target_type) |
816 | { | 809 | { |
817 | #if defined(CONFIG_BLK_DEV_INTEGRITY) | 810 | #if defined(CONFIG_BLK_DEV_INTEGRITY) |
818 | switch (target_type) { | 811 | static unsigned char cap[] = { SHOST_DIX_TYPE0_PROTECTION, |
819 | case 0: return shost->prot_capabilities & SHOST_DIX_TYPE0_PROTECTION; | 812 | SHOST_DIX_TYPE1_PROTECTION, |
820 | case 1: return shost->prot_capabilities & SHOST_DIX_TYPE1_PROTECTION; | 813 | SHOST_DIX_TYPE2_PROTECTION, |
821 | case 2: return shost->prot_capabilities & SHOST_DIX_TYPE2_PROTECTION; | 814 | SHOST_DIX_TYPE3_PROTECTION }; |
822 | case 3: return shost->prot_capabilities & SHOST_DIX_TYPE3_PROTECTION; | 815 | |
823 | } | 816 | return shost->prot_capabilities & cap[target_type]; |
824 | #endif | 817 | #endif |
825 | return 0; | 818 | return 0; |
826 | } | 819 | } |
diff --git a/init/Kconfig b/init/Kconfig index 9e03ef8b311e..ab5c64801fe5 100644 --- a/init/Kconfig +++ b/init/Kconfig | |||
@@ -1098,6 +1098,16 @@ config SLOW_WORK | |||
1098 | 1098 | ||
1099 | See Documentation/slow-work.txt. | 1099 | See Documentation/slow-work.txt. |
1100 | 1100 | ||
1101 | config SLOW_WORK_PROC | ||
1102 | bool "Slow work debugging through /proc" | ||
1103 | default n | ||
1104 | depends on SLOW_WORK && PROC_FS | ||
1105 | help | ||
1106 | Display the contents of the slow work run queue through /proc, | ||
1107 | including items currently executing. | ||
1108 | |||
1109 | See Documentation/slow-work.txt. | ||
1110 | |||
1101 | endmenu # General setup | 1111 | endmenu # General setup |
1102 | 1112 | ||
1103 | config HAVE_GENERIC_DMA_COHERENT | 1113 | config HAVE_GENERIC_DMA_COHERENT |
diff --git a/kernel/Makefile b/kernel/Makefile index b8d4cd8ac0b9..776ffed1556d 100644 --- a/kernel/Makefile +++ b/kernel/Makefile | |||
@@ -94,6 +94,7 @@ obj-$(CONFIG_X86_DS) += trace/ | |||
94 | obj-$(CONFIG_RING_BUFFER) += trace/ | 94 | obj-$(CONFIG_RING_BUFFER) += trace/ |
95 | obj-$(CONFIG_SMP) += sched_cpupri.o | 95 | obj-$(CONFIG_SMP) += sched_cpupri.o |
96 | obj-$(CONFIG_SLOW_WORK) += slow-work.o | 96 | obj-$(CONFIG_SLOW_WORK) += slow-work.o |
97 | obj-$(CONFIG_SLOW_WORK_PROC) += slow-work-proc.o | ||
97 | obj-$(CONFIG_PERF_EVENTS) += perf_event.o | 98 | obj-$(CONFIG_PERF_EVENTS) += perf_event.o |
98 | 99 | ||
99 | ifneq ($(CONFIG_SCHED_OMIT_FRAME_POINTER),y) | 100 | ifneq ($(CONFIG_SCHED_OMIT_FRAME_POINTER),y) |
diff --git a/kernel/slow-work-proc.c b/kernel/slow-work-proc.c new file mode 100644 index 000000000000..3988032571f5 --- /dev/null +++ b/kernel/slow-work-proc.c | |||
@@ -0,0 +1,227 @@ | |||
1 | /* Slow work debugging | ||
2 | * | ||
3 | * Copyright (C) 2009 Red Hat, Inc. All Rights Reserved. | ||
4 | * Written by David Howells (dhowells@redhat.com) | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or | ||
7 | * modify it under the terms of the GNU General Public Licence | ||
8 | * as published by the Free Software Foundation; either version | ||
9 | * 2 of the Licence, or (at your option) any later version. | ||
10 | */ | ||
11 | |||
12 | #include <linux/module.h> | ||
13 | #include <linux/slow-work.h> | ||
14 | #include <linux/fs.h> | ||
15 | #include <linux/time.h> | ||
16 | #include <linux/seq_file.h> | ||
17 | #include "slow-work.h" | ||
18 | |||
19 | #define ITERATOR_SHIFT (BITS_PER_LONG - 4) | ||
20 | #define ITERATOR_SELECTOR (0xfUL << ITERATOR_SHIFT) | ||
21 | #define ITERATOR_COUNTER (~ITERATOR_SELECTOR) | ||
22 | |||
23 | void slow_work_new_thread_desc(struct slow_work *work, struct seq_file *m) | ||
24 | { | ||
25 | seq_puts(m, "Slow-work: New thread"); | ||
26 | } | ||
27 | |||
28 | /* | ||
29 | * Render the time mark field on a work item into a 5-char time with units plus | ||
30 | * a space | ||
31 | */ | ||
32 | static void slow_work_print_mark(struct seq_file *m, struct slow_work *work) | ||
33 | { | ||
34 | struct timespec now, diff; | ||
35 | |||
36 | now = CURRENT_TIME; | ||
37 | diff = timespec_sub(now, work->mark); | ||
38 | |||
39 | if (diff.tv_sec < 0) | ||
40 | seq_puts(m, " -ve "); | ||
41 | else if (diff.tv_sec == 0 && diff.tv_nsec < 1000) | ||
42 | seq_printf(m, "%3luns ", diff.tv_nsec); | ||
43 | else if (diff.tv_sec == 0 && diff.tv_nsec < 1000000) | ||
44 | seq_printf(m, "%3luus ", diff.tv_nsec / 1000); | ||
45 | else if (diff.tv_sec == 0 && diff.tv_nsec < 1000000000) | ||
46 | seq_printf(m, "%3lums ", diff.tv_nsec / 1000000); | ||
47 | else if (diff.tv_sec <= 1) | ||
48 | seq_puts(m, " 1s "); | ||
49 | else if (diff.tv_sec < 60) | ||
50 | seq_printf(m, "%4lus ", diff.tv_sec); | ||
51 | else if (diff.tv_sec < 60 * 60) | ||
52 | seq_printf(m, "%4lum ", diff.tv_sec / 60); | ||
53 | else if (diff.tv_sec < 60 * 60 * 24) | ||
54 | seq_printf(m, "%4luh ", diff.tv_sec / 3600); | ||
55 | else | ||
56 | seq_puts(m, "exces "); | ||
57 | } | ||
58 | |||
59 | /* | ||
60 | * Describe a slow work item for /proc | ||
61 | */ | ||
62 | static int slow_work_runqueue_show(struct seq_file *m, void *v) | ||
63 | { | ||
64 | struct slow_work *work; | ||
65 | struct list_head *p = v; | ||
66 | unsigned long id; | ||
67 | |||
68 | switch ((unsigned long) v) { | ||
69 | case 1: | ||
70 | seq_puts(m, "THR PID ITEM ADDR FL MARK DESC\n"); | ||
71 | return 0; | ||
72 | case 2: | ||
73 | seq_puts(m, "=== ===== ================ == ===== ==========\n"); | ||
74 | return 0; | ||
75 | |||
76 | case 3 ... 3 + SLOW_WORK_THREAD_LIMIT - 1: | ||
77 | id = (unsigned long) v - 3; | ||
78 | |||
79 | read_lock(&slow_work_execs_lock); | ||
80 | work = slow_work_execs[id]; | ||
81 | if (work) { | ||
82 | smp_read_barrier_depends(); | ||
83 | |||
84 | seq_printf(m, "%3lu %5d %16p %2lx ", | ||
85 | id, slow_work_pids[id], work, work->flags); | ||
86 | slow_work_print_mark(m, work); | ||
87 | |||
88 | if (work->ops->desc) | ||
89 | work->ops->desc(work, m); | ||
90 | seq_putc(m, '\n'); | ||
91 | } | ||
92 | read_unlock(&slow_work_execs_lock); | ||
93 | return 0; | ||
94 | |||
95 | default: | ||
96 | work = list_entry(p, struct slow_work, link); | ||
97 | seq_printf(m, "%3s - %16p %2lx ", | ||
98 | work->flags & SLOW_WORK_VERY_SLOW ? "vsq" : "sq", | ||
99 | work, work->flags); | ||
100 | slow_work_print_mark(m, work); | ||
101 | |||
102 | if (work->ops->desc) | ||
103 | work->ops->desc(work, m); | ||
104 | seq_putc(m, '\n'); | ||
105 | return 0; | ||
106 | } | ||
107 | } | ||
108 | |||
109 | /* | ||
110 | * map the iterator to a work item | ||
111 | */ | ||
112 | static void *slow_work_runqueue_index(struct seq_file *m, loff_t *_pos) | ||
113 | { | ||
114 | struct list_head *p; | ||
115 | unsigned long count, id; | ||
116 | |||
117 | switch (*_pos >> ITERATOR_SHIFT) { | ||
118 | case 0x0: | ||
119 | if (*_pos == 0) | ||
120 | *_pos = 1; | ||
121 | if (*_pos < 3) | ||
122 | return (void *)(unsigned long) *_pos; | ||
123 | if (*_pos < 3 + SLOW_WORK_THREAD_LIMIT) | ||
124 | for (id = *_pos - 3; | ||
125 | id < SLOW_WORK_THREAD_LIMIT; | ||
126 | id++, (*_pos)++) | ||
127 | if (slow_work_execs[id]) | ||
128 | return (void *)(unsigned long) *_pos; | ||
129 | *_pos = 0x1UL << ITERATOR_SHIFT; | ||
130 | |||
131 | case 0x1: | ||
132 | count = *_pos & ITERATOR_COUNTER; | ||
133 | list_for_each(p, &slow_work_queue) { | ||
134 | if (count == 0) | ||
135 | return p; | ||
136 | count--; | ||
137 | } | ||
138 | *_pos = 0x2UL << ITERATOR_SHIFT; | ||
139 | |||
140 | case 0x2: | ||
141 | count = *_pos & ITERATOR_COUNTER; | ||
142 | list_for_each(p, &vslow_work_queue) { | ||
143 | if (count == 0) | ||
144 | return p; | ||
145 | count--; | ||
146 | } | ||
147 | *_pos = 0x3UL << ITERATOR_SHIFT; | ||
148 | |||
149 | default: | ||
150 | return NULL; | ||
151 | } | ||
152 | } | ||
153 | |||
154 | /* | ||
155 | * set up the iterator to start reading from the first line | ||
156 | */ | ||
157 | static void *slow_work_runqueue_start(struct seq_file *m, loff_t *_pos) | ||
158 | { | ||
159 | spin_lock_irq(&slow_work_queue_lock); | ||
160 | return slow_work_runqueue_index(m, _pos); | ||
161 | } | ||
162 | |||
163 | /* | ||
164 | * move to the next line | ||
165 | */ | ||
166 | static void *slow_work_runqueue_next(struct seq_file *m, void *v, loff_t *_pos) | ||
167 | { | ||
168 | struct list_head *p = v; | ||
169 | unsigned long selector = *_pos >> ITERATOR_SHIFT; | ||
170 | |||
171 | (*_pos)++; | ||
172 | switch (selector) { | ||
173 | case 0x0: | ||
174 | return slow_work_runqueue_index(m, _pos); | ||
175 | |||
176 | case 0x1: | ||
177 | if (*_pos >> ITERATOR_SHIFT == 0x1) { | ||
178 | p = p->next; | ||
179 | if (p != &slow_work_queue) | ||
180 | return p; | ||
181 | } | ||
182 | *_pos = 0x2UL << ITERATOR_SHIFT; | ||
183 | p = &vslow_work_queue; | ||
184 | |||
185 | case 0x2: | ||
186 | if (*_pos >> ITERATOR_SHIFT == 0x2) { | ||
187 | p = p->next; | ||
188 | if (p != &vslow_work_queue) | ||
189 | return p; | ||
190 | } | ||
191 | *_pos = 0x3UL << ITERATOR_SHIFT; | ||
192 | |||
193 | default: | ||
194 | return NULL; | ||
195 | } | ||
196 | } | ||
197 | |||
198 | /* | ||
199 | * clean up after reading | ||
200 | */ | ||
201 | static void slow_work_runqueue_stop(struct seq_file *m, void *v) | ||
202 | { | ||
203 | spin_unlock_irq(&slow_work_queue_lock); | ||
204 | } | ||
205 | |||
206 | static const struct seq_operations slow_work_runqueue_ops = { | ||
207 | .start = slow_work_runqueue_start, | ||
208 | .stop = slow_work_runqueue_stop, | ||
209 | .next = slow_work_runqueue_next, | ||
210 | .show = slow_work_runqueue_show, | ||
211 | }; | ||
212 | |||
213 | /* | ||
214 | * open "/proc/slow_work_rq" to list queue contents | ||
215 | */ | ||
216 | static int slow_work_runqueue_open(struct inode *inode, struct file *file) | ||
217 | { | ||
218 | return seq_open(file, &slow_work_runqueue_ops); | ||
219 | } | ||
220 | |||
221 | const struct file_operations slow_work_runqueue_fops = { | ||
222 | .owner = THIS_MODULE, | ||
223 | .open = slow_work_runqueue_open, | ||
224 | .read = seq_read, | ||
225 | .llseek = seq_lseek, | ||
226 | .release = seq_release, | ||
227 | }; | ||
diff --git a/kernel/slow-work.c b/kernel/slow-work.c index 0d31135efbf4..da94f3c101af 100644 --- a/kernel/slow-work.c +++ b/kernel/slow-work.c | |||
@@ -16,11 +16,8 @@ | |||
16 | #include <linux/kthread.h> | 16 | #include <linux/kthread.h> |
17 | #include <linux/freezer.h> | 17 | #include <linux/freezer.h> |
18 | #include <linux/wait.h> | 18 | #include <linux/wait.h> |
19 | 19 | #include <linux/proc_fs.h> | |
20 | #define SLOW_WORK_CULL_TIMEOUT (5 * HZ) /* cull threads 5s after running out of | 20 | #include "slow-work.h" |
21 | * things to do */ | ||
22 | #define SLOW_WORK_OOM_TIMEOUT (5 * HZ) /* can't start new threads for 5s after | ||
23 | * OOM */ | ||
24 | 21 | ||
25 | static void slow_work_cull_timeout(unsigned long); | 22 | static void slow_work_cull_timeout(unsigned long); |
26 | static void slow_work_oom_timeout(unsigned long); | 23 | static void slow_work_oom_timeout(unsigned long); |
@@ -46,7 +43,7 @@ static unsigned vslow_work_proportion = 50; /* % of threads that may process | |||
46 | 43 | ||
47 | #ifdef CONFIG_SYSCTL | 44 | #ifdef CONFIG_SYSCTL |
48 | static const int slow_work_min_min_threads = 2; | 45 | static const int slow_work_min_min_threads = 2; |
49 | static int slow_work_max_max_threads = 255; | 46 | static int slow_work_max_max_threads = SLOW_WORK_THREAD_LIMIT; |
50 | static const int slow_work_min_vslow = 1; | 47 | static const int slow_work_min_vslow = 1; |
51 | static const int slow_work_max_vslow = 99; | 48 | static const int slow_work_max_vslow = 99; |
52 | 49 | ||
@@ -98,6 +95,32 @@ static DEFINE_TIMER(slow_work_oom_timer, slow_work_oom_timeout, 0, 0); | |||
98 | static struct slow_work slow_work_new_thread; /* new thread starter */ | 95 | static struct slow_work slow_work_new_thread; /* new thread starter */ |
99 | 96 | ||
100 | /* | 97 | /* |
98 | * slow work ID allocation (use slow_work_queue_lock) | ||
99 | */ | ||
100 | static DECLARE_BITMAP(slow_work_ids, SLOW_WORK_THREAD_LIMIT); | ||
101 | |||
102 | /* | ||
103 | * Unregistration tracking to prevent put_ref() from disappearing during module | ||
104 | * unload | ||
105 | */ | ||
106 | #ifdef CONFIG_MODULES | ||
107 | static struct module *slow_work_thread_processing[SLOW_WORK_THREAD_LIMIT]; | ||
108 | static struct module *slow_work_unreg_module; | ||
109 | static struct slow_work *slow_work_unreg_work_item; | ||
110 | static DECLARE_WAIT_QUEUE_HEAD(slow_work_unreg_wq); | ||
111 | static DEFINE_MUTEX(slow_work_unreg_sync_lock); | ||
112 | #endif | ||
113 | |||
114 | /* | ||
115 | * Data for tracking currently executing items for indication through /proc | ||
116 | */ | ||
117 | #ifdef CONFIG_SLOW_WORK_PROC | ||
118 | struct slow_work *slow_work_execs[SLOW_WORK_THREAD_LIMIT]; | ||
119 | pid_t slow_work_pids[SLOW_WORK_THREAD_LIMIT]; | ||
120 | DEFINE_RWLOCK(slow_work_execs_lock); | ||
121 | #endif | ||
122 | |||
123 | /* | ||
101 | * The queues of work items and the lock governing access to them. These are | 124 | * The queues of work items and the lock governing access to them. These are |
102 | * shared between all the CPUs. It doesn't make sense to have per-CPU queues | 125 | * shared between all the CPUs. It doesn't make sense to have per-CPU queues |
103 | * as the number of threads bears no relation to the number of CPUs. | 126 | * as the number of threads bears no relation to the number of CPUs. |
@@ -105,9 +128,18 @@ static struct slow_work slow_work_new_thread; /* new thread starter */ | |||
105 | * There are two queues of work items: one for slow work items, and one for | 128 | * There are two queues of work items: one for slow work items, and one for |
106 | * very slow work items. | 129 | * very slow work items. |
107 | */ | 130 | */ |
108 | static LIST_HEAD(slow_work_queue); | 131 | LIST_HEAD(slow_work_queue); |
109 | static LIST_HEAD(vslow_work_queue); | 132 | LIST_HEAD(vslow_work_queue); |
110 | static DEFINE_SPINLOCK(slow_work_queue_lock); | 133 | DEFINE_SPINLOCK(slow_work_queue_lock); |
134 | |||
135 | /* | ||
136 | * The following are two wait queues that get pinged when a work item is placed | ||
137 | * on an empty queue. These allow work items that are hogging a thread by | ||
138 | * sleeping in a way that could be deferred to yield their thread and enqueue | ||
139 | * themselves. | ||
140 | */ | ||
141 | static DECLARE_WAIT_QUEUE_HEAD(slow_work_queue_waits_for_occupation); | ||
142 | static DECLARE_WAIT_QUEUE_HEAD(vslow_work_queue_waits_for_occupation); | ||
111 | 143 | ||
112 | /* | 144 | /* |
113 | * The thread controls. A variable used to signal to the threads that they | 145 | * The thread controls. A variable used to signal to the threads that they |
@@ -126,6 +158,20 @@ static DECLARE_COMPLETION(slow_work_last_thread_exited); | |||
126 | static int slow_work_user_count; | 158 | static int slow_work_user_count; |
127 | static DEFINE_MUTEX(slow_work_user_lock); | 159 | static DEFINE_MUTEX(slow_work_user_lock); |
128 | 160 | ||
161 | static inline int slow_work_get_ref(struct slow_work *work) | ||
162 | { | ||
163 | if (work->ops->get_ref) | ||
164 | return work->ops->get_ref(work); | ||
165 | |||
166 | return 0; | ||
167 | } | ||
168 | |||
169 | static inline void slow_work_put_ref(struct slow_work *work) | ||
170 | { | ||
171 | if (work->ops->put_ref) | ||
172 | work->ops->put_ref(work); | ||
173 | } | ||
174 | |||
129 | /* | 175 | /* |
130 | * Calculate the maximum number of active threads in the pool that are | 176 | * Calculate the maximum number of active threads in the pool that are |
131 | * permitted to process very slow work items. | 177 | * permitted to process very slow work items. |
@@ -149,8 +195,11 @@ static unsigned slow_work_calc_vsmax(void) | |||
149 | * Attempt to execute stuff queued on a slow thread. Return true if we managed | 195 | * Attempt to execute stuff queued on a slow thread. Return true if we managed |
150 | * it, false if there was nothing to do. | 196 | * it, false if there was nothing to do. |
151 | */ | 197 | */ |
152 | static bool slow_work_execute(void) | 198 | static noinline bool slow_work_execute(int id) |
153 | { | 199 | { |
200 | #ifdef CONFIG_MODULES | ||
201 | struct module *module; | ||
202 | #endif | ||
154 | struct slow_work *work = NULL; | 203 | struct slow_work *work = NULL; |
155 | unsigned vsmax; | 204 | unsigned vsmax; |
156 | bool very_slow; | 205 | bool very_slow; |
@@ -186,6 +235,16 @@ static bool slow_work_execute(void) | |||
186 | } else { | 235 | } else { |
187 | very_slow = false; /* avoid the compiler warning */ | 236 | very_slow = false; /* avoid the compiler warning */ |
188 | } | 237 | } |
238 | |||
239 | #ifdef CONFIG_MODULES | ||
240 | if (work) | ||
241 | slow_work_thread_processing[id] = work->owner; | ||
242 | #endif | ||
243 | if (work) { | ||
244 | slow_work_mark_time(work); | ||
245 | slow_work_begin_exec(id, work); | ||
246 | } | ||
247 | |||
189 | spin_unlock_irq(&slow_work_queue_lock); | 248 | spin_unlock_irq(&slow_work_queue_lock); |
190 | 249 | ||
191 | if (!work) | 250 | if (!work) |
@@ -194,12 +253,19 @@ static bool slow_work_execute(void) | |||
194 | if (!test_and_clear_bit(SLOW_WORK_PENDING, &work->flags)) | 253 | if (!test_and_clear_bit(SLOW_WORK_PENDING, &work->flags)) |
195 | BUG(); | 254 | BUG(); |
196 | 255 | ||
197 | work->ops->execute(work); | 256 | /* don't execute if the work is in the process of being cancelled */ |
257 | if (!test_bit(SLOW_WORK_CANCELLING, &work->flags)) | ||
258 | work->ops->execute(work); | ||
198 | 259 | ||
199 | if (very_slow) | 260 | if (very_slow) |
200 | atomic_dec(&vslow_work_executing_count); | 261 | atomic_dec(&vslow_work_executing_count); |
201 | clear_bit_unlock(SLOW_WORK_EXECUTING, &work->flags); | 262 | clear_bit_unlock(SLOW_WORK_EXECUTING, &work->flags); |
202 | 263 | ||
264 | /* wake up anyone waiting for this work to be complete */ | ||
265 | wake_up_bit(&work->flags, SLOW_WORK_EXECUTING); | ||
266 | |||
267 | slow_work_end_exec(id, work); | ||
268 | |||
203 | /* if someone tried to enqueue the item whilst we were executing it, | 269 | /* if someone tried to enqueue the item whilst we were executing it, |
204 | * then it'll be left unenqueued to avoid multiple threads trying to | 270 | * then it'll be left unenqueued to avoid multiple threads trying to |
205 | * execute it simultaneously | 271 | * execute it simultaneously |
@@ -219,7 +285,18 @@ static bool slow_work_execute(void) | |||
219 | spin_unlock_irq(&slow_work_queue_lock); | 285 | spin_unlock_irq(&slow_work_queue_lock); |
220 | } | 286 | } |
221 | 287 | ||
222 | work->ops->put_ref(work); | 288 | /* sort out the race between module unloading and put_ref() */ |
289 | slow_work_put_ref(work); | ||
290 | |||
291 | #ifdef CONFIG_MODULES | ||
292 | module = slow_work_thread_processing[id]; | ||
293 | slow_work_thread_processing[id] = NULL; | ||
294 | smp_mb(); | ||
295 | if (slow_work_unreg_work_item == work || | ||
296 | slow_work_unreg_module == module) | ||
297 | wake_up_all(&slow_work_unreg_wq); | ||
298 | #endif | ||
299 | |||
223 | return true; | 300 | return true; |
224 | 301 | ||
225 | auto_requeue: | 302 | auto_requeue: |
@@ -227,15 +304,61 @@ auto_requeue: | |||
227 | * - we transfer our ref on the item back to the appropriate queue | 304 | * - we transfer our ref on the item back to the appropriate queue |
228 | * - don't wake another thread up as we're awake already | 305 | * - don't wake another thread up as we're awake already |
229 | */ | 306 | */ |
307 | slow_work_mark_time(work); | ||
230 | if (test_bit(SLOW_WORK_VERY_SLOW, &work->flags)) | 308 | if (test_bit(SLOW_WORK_VERY_SLOW, &work->flags)) |
231 | list_add_tail(&work->link, &vslow_work_queue); | 309 | list_add_tail(&work->link, &vslow_work_queue); |
232 | else | 310 | else |
233 | list_add_tail(&work->link, &slow_work_queue); | 311 | list_add_tail(&work->link, &slow_work_queue); |
234 | spin_unlock_irq(&slow_work_queue_lock); | 312 | spin_unlock_irq(&slow_work_queue_lock); |
313 | slow_work_thread_processing[id] = NULL; | ||
235 | return true; | 314 | return true; |
236 | } | 315 | } |
237 | 316 | ||
238 | /** | 317 | /** |
318 | * slow_work_sleep_till_thread_needed - Sleep till thread needed by other work | ||
319 | * work: The work item under execution that wants to sleep | ||
320 | * _timeout: Scheduler sleep timeout | ||
321 | * | ||
322 | * Allow a requeueable work item to sleep on a slow-work processor thread until | ||
323 | * that thread is needed to do some other work or the sleep is interrupted by | ||
324 | * some other event. | ||
325 | * | ||
326 | * The caller must set up a wake up event before calling this and must have set | ||
327 | * the appropriate sleep mode (such as TASK_UNINTERRUPTIBLE) and tested its own | ||
328 | * condition before calling this function as no test is made here. | ||
329 | * | ||
330 | * False is returned if there is nothing on the queue; true is returned if the | ||
331 | * work item should be requeued | ||
332 | */ | ||
333 | bool slow_work_sleep_till_thread_needed(struct slow_work *work, | ||
334 | signed long *_timeout) | ||
335 | { | ||
336 | wait_queue_head_t *wfo_wq; | ||
337 | struct list_head *queue; | ||
338 | |||
339 | DEFINE_WAIT(wait); | ||
340 | |||
341 | if (test_bit(SLOW_WORK_VERY_SLOW, &work->flags)) { | ||
342 | wfo_wq = &vslow_work_queue_waits_for_occupation; | ||
343 | queue = &vslow_work_queue; | ||
344 | } else { | ||
345 | wfo_wq = &slow_work_queue_waits_for_occupation; | ||
346 | queue = &slow_work_queue; | ||
347 | } | ||
348 | |||
349 | if (!list_empty(queue)) | ||
350 | return true; | ||
351 | |||
352 | add_wait_queue_exclusive(wfo_wq, &wait); | ||
353 | if (list_empty(queue)) | ||
354 | *_timeout = schedule_timeout(*_timeout); | ||
355 | finish_wait(wfo_wq, &wait); | ||
356 | |||
357 | return !list_empty(queue); | ||
358 | } | ||
359 | EXPORT_SYMBOL(slow_work_sleep_till_thread_needed); | ||
360 | |||
361 | /** | ||
239 | * slow_work_enqueue - Schedule a slow work item for processing | 362 | * slow_work_enqueue - Schedule a slow work item for processing |
240 | * @work: The work item to queue | 363 | * @work: The work item to queue |
241 | * | 364 | * |
@@ -260,16 +383,22 @@ auto_requeue: | |||
260 | * allowed to pick items to execute. This ensures that very slow items won't | 383 | * allowed to pick items to execute. This ensures that very slow items won't |
261 | * overly block ones that are just ordinarily slow. | 384 | * overly block ones that are just ordinarily slow. |
262 | * | 385 | * |
263 | * Returns 0 if successful, -EAGAIN if not. | 386 | * Returns 0 if successful, -EAGAIN if not (or -ECANCELED if cancelled work is |
387 | * attempted queued) | ||
264 | */ | 388 | */ |
265 | int slow_work_enqueue(struct slow_work *work) | 389 | int slow_work_enqueue(struct slow_work *work) |
266 | { | 390 | { |
391 | wait_queue_head_t *wfo_wq; | ||
392 | struct list_head *queue; | ||
267 | unsigned long flags; | 393 | unsigned long flags; |
394 | int ret; | ||
395 | |||
396 | if (test_bit(SLOW_WORK_CANCELLING, &work->flags)) | ||
397 | return -ECANCELED; | ||
268 | 398 | ||
269 | BUG_ON(slow_work_user_count <= 0); | 399 | BUG_ON(slow_work_user_count <= 0); |
270 | BUG_ON(!work); | 400 | BUG_ON(!work); |
271 | BUG_ON(!work->ops); | 401 | BUG_ON(!work->ops); |
272 | BUG_ON(!work->ops->get_ref); | ||
273 | 402 | ||
274 | /* when honouring an enqueue request, we only promise that we will run | 403 | /* when honouring an enqueue request, we only promise that we will run |
275 | * the work function in the future; we do not promise to run it once | 404 | * the work function in the future; we do not promise to run it once |
@@ -280,8 +409,19 @@ int slow_work_enqueue(struct slow_work *work) | |||
280 | * maintaining our promise | 409 | * maintaining our promise |
281 | */ | 410 | */ |
282 | if (!test_and_set_bit_lock(SLOW_WORK_PENDING, &work->flags)) { | 411 | if (!test_and_set_bit_lock(SLOW_WORK_PENDING, &work->flags)) { |
412 | if (test_bit(SLOW_WORK_VERY_SLOW, &work->flags)) { | ||
413 | wfo_wq = &vslow_work_queue_waits_for_occupation; | ||
414 | queue = &vslow_work_queue; | ||
415 | } else { | ||
416 | wfo_wq = &slow_work_queue_waits_for_occupation; | ||
417 | queue = &slow_work_queue; | ||
418 | } | ||
419 | |||
283 | spin_lock_irqsave(&slow_work_queue_lock, flags); | 420 | spin_lock_irqsave(&slow_work_queue_lock, flags); |
284 | 421 | ||
422 | if (unlikely(test_bit(SLOW_WORK_CANCELLING, &work->flags))) | ||
423 | goto cancelled; | ||
424 | |||
285 | /* we promise that we will not attempt to execute the work | 425 | /* we promise that we will not attempt to execute the work |
286 | * function in more than one thread simultaneously | 426 | * function in more than one thread simultaneously |
287 | * | 427 | * |
@@ -299,25 +439,221 @@ int slow_work_enqueue(struct slow_work *work) | |||
299 | if (test_bit(SLOW_WORK_EXECUTING, &work->flags)) { | 439 | if (test_bit(SLOW_WORK_EXECUTING, &work->flags)) { |
300 | set_bit(SLOW_WORK_ENQ_DEFERRED, &work->flags); | 440 | set_bit(SLOW_WORK_ENQ_DEFERRED, &work->flags); |
301 | } else { | 441 | } else { |
302 | if (work->ops->get_ref(work) < 0) | 442 | ret = slow_work_get_ref(work); |
303 | goto cant_get_ref; | 443 | if (ret < 0) |
304 | if (test_bit(SLOW_WORK_VERY_SLOW, &work->flags)) | 444 | goto failed; |
305 | list_add_tail(&work->link, &vslow_work_queue); | 445 | slow_work_mark_time(work); |
306 | else | 446 | list_add_tail(&work->link, queue); |
307 | list_add_tail(&work->link, &slow_work_queue); | ||
308 | wake_up(&slow_work_thread_wq); | 447 | wake_up(&slow_work_thread_wq); |
448 | |||
449 | /* if someone who could be requeued is sleeping on a | ||
450 | * thread, then ask them to yield their thread */ | ||
451 | if (work->link.prev == queue) | ||
452 | wake_up(wfo_wq); | ||
309 | } | 453 | } |
310 | 454 | ||
311 | spin_unlock_irqrestore(&slow_work_queue_lock, flags); | 455 | spin_unlock_irqrestore(&slow_work_queue_lock, flags); |
312 | } | 456 | } |
313 | return 0; | 457 | return 0; |
314 | 458 | ||
315 | cant_get_ref: | 459 | cancelled: |
460 | ret = -ECANCELED; | ||
461 | failed: | ||
316 | spin_unlock_irqrestore(&slow_work_queue_lock, flags); | 462 | spin_unlock_irqrestore(&slow_work_queue_lock, flags); |
317 | return -EAGAIN; | 463 | return ret; |
318 | } | 464 | } |
319 | EXPORT_SYMBOL(slow_work_enqueue); | 465 | EXPORT_SYMBOL(slow_work_enqueue); |
320 | 466 | ||
467 | static int slow_work_wait(void *word) | ||
468 | { | ||
469 | schedule(); | ||
470 | return 0; | ||
471 | } | ||
472 | |||
473 | /** | ||
474 | * slow_work_cancel - Cancel a slow work item | ||
475 | * @work: The work item to cancel | ||
476 | * | ||
477 | * This function will cancel a previously enqueued work item. If we cannot | ||
478 | * cancel the work item, it is guarenteed to have run when this function | ||
479 | * returns. | ||
480 | */ | ||
481 | void slow_work_cancel(struct slow_work *work) | ||
482 | { | ||
483 | bool wait = true, put = false; | ||
484 | |||
485 | set_bit(SLOW_WORK_CANCELLING, &work->flags); | ||
486 | smp_mb(); | ||
487 | |||
488 | /* if the work item is a delayed work item with an active timer, we | ||
489 | * need to wait for the timer to finish _before_ getting the spinlock, | ||
490 | * lest we deadlock against the timer routine | ||
491 | * | ||
492 | * the timer routine will leave DELAYED set if it notices the | ||
493 | * CANCELLING flag in time | ||
494 | */ | ||
495 | if (test_bit(SLOW_WORK_DELAYED, &work->flags)) { | ||
496 | struct delayed_slow_work *dwork = | ||
497 | container_of(work, struct delayed_slow_work, work); | ||
498 | del_timer_sync(&dwork->timer); | ||
499 | } | ||
500 | |||
501 | spin_lock_irq(&slow_work_queue_lock); | ||
502 | |||
503 | if (test_bit(SLOW_WORK_DELAYED, &work->flags)) { | ||
504 | /* the timer routine aborted or never happened, so we are left | ||
505 | * holding the timer's reference on the item and should just | ||
506 | * drop the pending flag and wait for any ongoing execution to | ||
507 | * finish */ | ||
508 | struct delayed_slow_work *dwork = | ||
509 | container_of(work, struct delayed_slow_work, work); | ||
510 | |||
511 | BUG_ON(timer_pending(&dwork->timer)); | ||
512 | BUG_ON(!list_empty(&work->link)); | ||
513 | |||
514 | clear_bit(SLOW_WORK_DELAYED, &work->flags); | ||
515 | put = true; | ||
516 | clear_bit(SLOW_WORK_PENDING, &work->flags); | ||
517 | |||
518 | } else if (test_bit(SLOW_WORK_PENDING, &work->flags) && | ||
519 | !list_empty(&work->link)) { | ||
520 | /* the link in the pending queue holds a reference on the item | ||
521 | * that we will need to release */ | ||
522 | list_del_init(&work->link); | ||
523 | wait = false; | ||
524 | put = true; | ||
525 | clear_bit(SLOW_WORK_PENDING, &work->flags); | ||
526 | |||
527 | } else if (test_and_clear_bit(SLOW_WORK_ENQ_DEFERRED, &work->flags)) { | ||
528 | /* the executor is holding our only reference on the item, so | ||
529 | * we merely need to wait for it to finish executing */ | ||
530 | clear_bit(SLOW_WORK_PENDING, &work->flags); | ||
531 | } | ||
532 | |||
533 | spin_unlock_irq(&slow_work_queue_lock); | ||
534 | |||
535 | /* the EXECUTING flag is set by the executor whilst the spinlock is set | ||
536 | * and before the item is dequeued - so assuming the above doesn't | ||
537 | * actually dequeue it, simply waiting for the EXECUTING flag to be | ||
538 | * released here should be sufficient */ | ||
539 | if (wait) | ||
540 | wait_on_bit(&work->flags, SLOW_WORK_EXECUTING, slow_work_wait, | ||
541 | TASK_UNINTERRUPTIBLE); | ||
542 | |||
543 | clear_bit(SLOW_WORK_CANCELLING, &work->flags); | ||
544 | if (put) | ||
545 | slow_work_put_ref(work); | ||
546 | } | ||
547 | EXPORT_SYMBOL(slow_work_cancel); | ||
548 | |||
549 | /* | ||
550 | * Handle expiry of the delay timer, indicating that a delayed slow work item | ||
551 | * should now be queued if not cancelled | ||
552 | */ | ||
553 | static void delayed_slow_work_timer(unsigned long data) | ||
554 | { | ||
555 | wait_queue_head_t *wfo_wq; | ||
556 | struct list_head *queue; | ||
557 | struct slow_work *work = (struct slow_work *) data; | ||
558 | unsigned long flags; | ||
559 | bool queued = false, put = false, first = false; | ||
560 | |||
561 | if (test_bit(SLOW_WORK_VERY_SLOW, &work->flags)) { | ||
562 | wfo_wq = &vslow_work_queue_waits_for_occupation; | ||
563 | queue = &vslow_work_queue; | ||
564 | } else { | ||
565 | wfo_wq = &slow_work_queue_waits_for_occupation; | ||
566 | queue = &slow_work_queue; | ||
567 | } | ||
568 | |||
569 | spin_lock_irqsave(&slow_work_queue_lock, flags); | ||
570 | if (likely(!test_bit(SLOW_WORK_CANCELLING, &work->flags))) { | ||
571 | clear_bit(SLOW_WORK_DELAYED, &work->flags); | ||
572 | |||
573 | if (test_bit(SLOW_WORK_EXECUTING, &work->flags)) { | ||
574 | /* we discard the reference the timer was holding in | ||
575 | * favour of the one the executor holds */ | ||
576 | set_bit(SLOW_WORK_ENQ_DEFERRED, &work->flags); | ||
577 | put = true; | ||
578 | } else { | ||
579 | slow_work_mark_time(work); | ||
580 | list_add_tail(&work->link, queue); | ||
581 | queued = true; | ||
582 | if (work->link.prev == queue) | ||
583 | first = true; | ||
584 | } | ||
585 | } | ||
586 | |||
587 | spin_unlock_irqrestore(&slow_work_queue_lock, flags); | ||
588 | if (put) | ||
589 | slow_work_put_ref(work); | ||
590 | if (first) | ||
591 | wake_up(wfo_wq); | ||
592 | if (queued) | ||
593 | wake_up(&slow_work_thread_wq); | ||
594 | } | ||
595 | |||
596 | /** | ||
597 | * delayed_slow_work_enqueue - Schedule a delayed slow work item for processing | ||
598 | * @dwork: The delayed work item to queue | ||
599 | * @delay: When to start executing the work, in jiffies from now | ||
600 | * | ||
601 | * This is similar to slow_work_enqueue(), but it adds a delay before the work | ||
602 | * is actually queued for processing. | ||
603 | * | ||
604 | * The item can have delayed processing requested on it whilst it is being | ||
605 | * executed. The delay will begin immediately, and if it expires before the | ||
606 | * item finishes executing, the item will be placed back on the queue when it | ||
607 | * has done executing. | ||
608 | */ | ||
609 | int delayed_slow_work_enqueue(struct delayed_slow_work *dwork, | ||
610 | unsigned long delay) | ||
611 | { | ||
612 | struct slow_work *work = &dwork->work; | ||
613 | unsigned long flags; | ||
614 | int ret; | ||
615 | |||
616 | if (delay == 0) | ||
617 | return slow_work_enqueue(&dwork->work); | ||
618 | |||
619 | BUG_ON(slow_work_user_count <= 0); | ||
620 | BUG_ON(!work); | ||
621 | BUG_ON(!work->ops); | ||
622 | |||
623 | if (test_bit(SLOW_WORK_CANCELLING, &work->flags)) | ||
624 | return -ECANCELED; | ||
625 | |||
626 | if (!test_and_set_bit_lock(SLOW_WORK_PENDING, &work->flags)) { | ||
627 | spin_lock_irqsave(&slow_work_queue_lock, flags); | ||
628 | |||
629 | if (test_bit(SLOW_WORK_CANCELLING, &work->flags)) | ||
630 | goto cancelled; | ||
631 | |||
632 | /* the timer holds a reference whilst it is pending */ | ||
633 | ret = work->ops->get_ref(work); | ||
634 | if (ret < 0) | ||
635 | goto cant_get_ref; | ||
636 | |||
637 | if (test_and_set_bit(SLOW_WORK_DELAYED, &work->flags)) | ||
638 | BUG(); | ||
639 | dwork->timer.expires = jiffies + delay; | ||
640 | dwork->timer.data = (unsigned long) work; | ||
641 | dwork->timer.function = delayed_slow_work_timer; | ||
642 | add_timer(&dwork->timer); | ||
643 | |||
644 | spin_unlock_irqrestore(&slow_work_queue_lock, flags); | ||
645 | } | ||
646 | |||
647 | return 0; | ||
648 | |||
649 | cancelled: | ||
650 | ret = -ECANCELED; | ||
651 | cant_get_ref: | ||
652 | spin_unlock_irqrestore(&slow_work_queue_lock, flags); | ||
653 | return ret; | ||
654 | } | ||
655 | EXPORT_SYMBOL(delayed_slow_work_enqueue); | ||
656 | |||
321 | /* | 657 | /* |
322 | * Schedule a cull of the thread pool at some time in the near future | 658 | * Schedule a cull of the thread pool at some time in the near future |
323 | */ | 659 | */ |
@@ -368,13 +704,23 @@ static inline bool slow_work_available(int vsmax) | |||
368 | */ | 704 | */ |
369 | static int slow_work_thread(void *_data) | 705 | static int slow_work_thread(void *_data) |
370 | { | 706 | { |
371 | int vsmax; | 707 | int vsmax, id; |
372 | 708 | ||
373 | DEFINE_WAIT(wait); | 709 | DEFINE_WAIT(wait); |
374 | 710 | ||
375 | set_freezable(); | 711 | set_freezable(); |
376 | set_user_nice(current, -5); | 712 | set_user_nice(current, -5); |
377 | 713 | ||
714 | /* allocate ourselves an ID */ | ||
715 | spin_lock_irq(&slow_work_queue_lock); | ||
716 | id = find_first_zero_bit(slow_work_ids, SLOW_WORK_THREAD_LIMIT); | ||
717 | BUG_ON(id < 0 || id >= SLOW_WORK_THREAD_LIMIT); | ||
718 | __set_bit(id, slow_work_ids); | ||
719 | slow_work_set_thread_pid(id, current->pid); | ||
720 | spin_unlock_irq(&slow_work_queue_lock); | ||
721 | |||
722 | sprintf(current->comm, "kslowd%03u", id); | ||
723 | |||
378 | for (;;) { | 724 | for (;;) { |
379 | vsmax = vslow_work_proportion; | 725 | vsmax = vslow_work_proportion; |
380 | vsmax *= atomic_read(&slow_work_thread_count); | 726 | vsmax *= atomic_read(&slow_work_thread_count); |
@@ -395,7 +741,7 @@ static int slow_work_thread(void *_data) | |||
395 | vsmax *= atomic_read(&slow_work_thread_count); | 741 | vsmax *= atomic_read(&slow_work_thread_count); |
396 | vsmax /= 100; | 742 | vsmax /= 100; |
397 | 743 | ||
398 | if (slow_work_available(vsmax) && slow_work_execute()) { | 744 | if (slow_work_available(vsmax) && slow_work_execute(id)) { |
399 | cond_resched(); | 745 | cond_resched(); |
400 | if (list_empty(&slow_work_queue) && | 746 | if (list_empty(&slow_work_queue) && |
401 | list_empty(&vslow_work_queue) && | 747 | list_empty(&vslow_work_queue) && |
@@ -412,6 +758,11 @@ static int slow_work_thread(void *_data) | |||
412 | break; | 758 | break; |
413 | } | 759 | } |
414 | 760 | ||
761 | spin_lock_irq(&slow_work_queue_lock); | ||
762 | slow_work_set_thread_pid(id, 0); | ||
763 | __clear_bit(id, slow_work_ids); | ||
764 | spin_unlock_irq(&slow_work_queue_lock); | ||
765 | |||
415 | if (atomic_dec_and_test(&slow_work_thread_count)) | 766 | if (atomic_dec_and_test(&slow_work_thread_count)) |
416 | complete_and_exit(&slow_work_last_thread_exited, 0); | 767 | complete_and_exit(&slow_work_last_thread_exited, 0); |
417 | return 0; | 768 | return 0; |
@@ -427,21 +778,6 @@ static void slow_work_cull_timeout(unsigned long data) | |||
427 | } | 778 | } |
428 | 779 | ||
429 | /* | 780 | /* |
430 | * Get a reference on slow work thread starter | ||
431 | */ | ||
432 | static int slow_work_new_thread_get_ref(struct slow_work *work) | ||
433 | { | ||
434 | return 0; | ||
435 | } | ||
436 | |||
437 | /* | ||
438 | * Drop a reference on slow work thread starter | ||
439 | */ | ||
440 | static void slow_work_new_thread_put_ref(struct slow_work *work) | ||
441 | { | ||
442 | } | ||
443 | |||
444 | /* | ||
445 | * Start a new slow work thread | 781 | * Start a new slow work thread |
446 | */ | 782 | */ |
447 | static void slow_work_new_thread_execute(struct slow_work *work) | 783 | static void slow_work_new_thread_execute(struct slow_work *work) |
@@ -475,9 +811,11 @@ static void slow_work_new_thread_execute(struct slow_work *work) | |||
475 | } | 811 | } |
476 | 812 | ||
477 | static const struct slow_work_ops slow_work_new_thread_ops = { | 813 | static const struct slow_work_ops slow_work_new_thread_ops = { |
478 | .get_ref = slow_work_new_thread_get_ref, | 814 | .owner = THIS_MODULE, |
479 | .put_ref = slow_work_new_thread_put_ref, | ||
480 | .execute = slow_work_new_thread_execute, | 815 | .execute = slow_work_new_thread_execute, |
816 | #ifdef CONFIG_SLOW_WORK_PROC | ||
817 | .desc = slow_work_new_thread_desc, | ||
818 | #endif | ||
481 | }; | 819 | }; |
482 | 820 | ||
483 | /* | 821 | /* |
@@ -546,12 +884,13 @@ static int slow_work_max_threads_sysctl(struct ctl_table *table, int write, | |||
546 | 884 | ||
547 | /** | 885 | /** |
548 | * slow_work_register_user - Register a user of the facility | 886 | * slow_work_register_user - Register a user of the facility |
887 | * @module: The module about to make use of the facility | ||
549 | * | 888 | * |
550 | * Register a user of the facility, starting up the initial threads if there | 889 | * Register a user of the facility, starting up the initial threads if there |
551 | * aren't any other users at this point. This will return 0 if successful, or | 890 | * aren't any other users at this point. This will return 0 if successful, or |
552 | * an error if not. | 891 | * an error if not. |
553 | */ | 892 | */ |
554 | int slow_work_register_user(void) | 893 | int slow_work_register_user(struct module *module) |
555 | { | 894 | { |
556 | struct task_struct *p; | 895 | struct task_struct *p; |
557 | int loop; | 896 | int loop; |
@@ -598,14 +937,79 @@ error: | |||
598 | } | 937 | } |
599 | EXPORT_SYMBOL(slow_work_register_user); | 938 | EXPORT_SYMBOL(slow_work_register_user); |
600 | 939 | ||
940 | /* | ||
941 | * wait for all outstanding items from the calling module to complete | ||
942 | * - note that more items may be queued whilst we're waiting | ||
943 | */ | ||
944 | static void slow_work_wait_for_items(struct module *module) | ||
945 | { | ||
946 | DECLARE_WAITQUEUE(myself, current); | ||
947 | struct slow_work *work; | ||
948 | int loop; | ||
949 | |||
950 | mutex_lock(&slow_work_unreg_sync_lock); | ||
951 | add_wait_queue(&slow_work_unreg_wq, &myself); | ||
952 | |||
953 | for (;;) { | ||
954 | spin_lock_irq(&slow_work_queue_lock); | ||
955 | |||
956 | /* first of all, we wait for the last queued item in each list | ||
957 | * to be processed */ | ||
958 | list_for_each_entry_reverse(work, &vslow_work_queue, link) { | ||
959 | if (work->owner == module) { | ||
960 | set_current_state(TASK_UNINTERRUPTIBLE); | ||
961 | slow_work_unreg_work_item = work; | ||
962 | goto do_wait; | ||
963 | } | ||
964 | } | ||
965 | list_for_each_entry_reverse(work, &slow_work_queue, link) { | ||
966 | if (work->owner == module) { | ||
967 | set_current_state(TASK_UNINTERRUPTIBLE); | ||
968 | slow_work_unreg_work_item = work; | ||
969 | goto do_wait; | ||
970 | } | ||
971 | } | ||
972 | |||
973 | /* then we wait for the items being processed to finish */ | ||
974 | slow_work_unreg_module = module; | ||
975 | smp_mb(); | ||
976 | for (loop = 0; loop < SLOW_WORK_THREAD_LIMIT; loop++) { | ||
977 | if (slow_work_thread_processing[loop] == module) | ||
978 | goto do_wait; | ||
979 | } | ||
980 | spin_unlock_irq(&slow_work_queue_lock); | ||
981 | break; /* okay, we're done */ | ||
982 | |||
983 | do_wait: | ||
984 | spin_unlock_irq(&slow_work_queue_lock); | ||
985 | schedule(); | ||
986 | slow_work_unreg_work_item = NULL; | ||
987 | slow_work_unreg_module = NULL; | ||
988 | } | ||
989 | |||
990 | remove_wait_queue(&slow_work_unreg_wq, &myself); | ||
991 | mutex_unlock(&slow_work_unreg_sync_lock); | ||
992 | } | ||
993 | |||
601 | /** | 994 | /** |
602 | * slow_work_unregister_user - Unregister a user of the facility | 995 | * slow_work_unregister_user - Unregister a user of the facility |
996 | * @module: The module whose items should be cleared | ||
603 | * | 997 | * |
604 | * Unregister a user of the facility, killing all the threads if this was the | 998 | * Unregister a user of the facility, killing all the threads if this was the |
605 | * last one. | 999 | * last one. |
1000 | * | ||
1001 | * This waits for all the work items belonging to the nominated module to go | ||
1002 | * away before proceeding. | ||
606 | */ | 1003 | */ |
607 | void slow_work_unregister_user(void) | 1004 | void slow_work_unregister_user(struct module *module) |
608 | { | 1005 | { |
1006 | /* first of all, wait for all outstanding items from the calling module | ||
1007 | * to complete */ | ||
1008 | if (module) | ||
1009 | slow_work_wait_for_items(module); | ||
1010 | |||
1011 | /* then we can actually go about shutting down the facility if need | ||
1012 | * be */ | ||
609 | mutex_lock(&slow_work_user_lock); | 1013 | mutex_lock(&slow_work_user_lock); |
610 | 1014 | ||
611 | BUG_ON(slow_work_user_count <= 0); | 1015 | BUG_ON(slow_work_user_count <= 0); |
@@ -639,6 +1043,10 @@ static int __init init_slow_work(void) | |||
639 | if (slow_work_max_max_threads < nr_cpus * 2) | 1043 | if (slow_work_max_max_threads < nr_cpus * 2) |
640 | slow_work_max_max_threads = nr_cpus * 2; | 1044 | slow_work_max_max_threads = nr_cpus * 2; |
641 | #endif | 1045 | #endif |
1046 | #ifdef CONFIG_SLOW_WORK_PROC | ||
1047 | proc_create("slow_work_rq", S_IFREG | 0400, NULL, | ||
1048 | &slow_work_runqueue_fops); | ||
1049 | #endif | ||
642 | return 0; | 1050 | return 0; |
643 | } | 1051 | } |
644 | 1052 | ||
diff --git a/kernel/slow-work.h b/kernel/slow-work.h new file mode 100644 index 000000000000..3c2f007f3ad6 --- /dev/null +++ b/kernel/slow-work.h | |||
@@ -0,0 +1,72 @@ | |||
1 | /* Slow work private definitions | ||
2 | * | ||
3 | * Copyright (C) 2009 Red Hat, Inc. All Rights Reserved. | ||
4 | * Written by David Howells (dhowells@redhat.com) | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or | ||
7 | * modify it under the terms of the GNU General Public Licence | ||
8 | * as published by the Free Software Foundation; either version | ||
9 | * 2 of the Licence, or (at your option) any later version. | ||
10 | */ | ||
11 | |||
12 | #define SLOW_WORK_CULL_TIMEOUT (5 * HZ) /* cull threads 5s after running out of | ||
13 | * things to do */ | ||
14 | #define SLOW_WORK_OOM_TIMEOUT (5 * HZ) /* can't start new threads for 5s after | ||
15 | * OOM */ | ||
16 | |||
17 | #define SLOW_WORK_THREAD_LIMIT 255 /* abs maximum number of slow-work threads */ | ||
18 | |||
19 | /* | ||
20 | * slow-work.c | ||
21 | */ | ||
22 | #ifdef CONFIG_SLOW_WORK_PROC | ||
23 | extern struct slow_work *slow_work_execs[]; | ||
24 | extern pid_t slow_work_pids[]; | ||
25 | extern rwlock_t slow_work_execs_lock; | ||
26 | #endif | ||
27 | |||
28 | extern struct list_head slow_work_queue; | ||
29 | extern struct list_head vslow_work_queue; | ||
30 | extern spinlock_t slow_work_queue_lock; | ||
31 | |||
32 | /* | ||
33 | * slow-work-proc.c | ||
34 | */ | ||
35 | #ifdef CONFIG_SLOW_WORK_PROC | ||
36 | extern const struct file_operations slow_work_runqueue_fops; | ||
37 | |||
38 | extern void slow_work_new_thread_desc(struct slow_work *, struct seq_file *); | ||
39 | #endif | ||
40 | |||
41 | /* | ||
42 | * Helper functions | ||
43 | */ | ||
44 | static inline void slow_work_set_thread_pid(int id, pid_t pid) | ||
45 | { | ||
46 | #ifdef CONFIG_SLOW_WORK_PROC | ||
47 | slow_work_pids[id] = pid; | ||
48 | #endif | ||
49 | } | ||
50 | |||
51 | static inline void slow_work_mark_time(struct slow_work *work) | ||
52 | { | ||
53 | #ifdef CONFIG_SLOW_WORK_PROC | ||
54 | work->mark = CURRENT_TIME; | ||
55 | #endif | ||
56 | } | ||
57 | |||
58 | static inline void slow_work_begin_exec(int id, struct slow_work *work) | ||
59 | { | ||
60 | #ifdef CONFIG_SLOW_WORK_PROC | ||
61 | slow_work_execs[id] = work; | ||
62 | #endif | ||
63 | } | ||
64 | |||
65 | static inline void slow_work_end_exec(int id, struct slow_work *work) | ||
66 | { | ||
67 | #ifdef CONFIG_SLOW_WORK_PROC | ||
68 | write_lock(&slow_work_execs_lock); | ||
69 | slow_work_execs[id] = NULL; | ||
70 | write_unlock(&slow_work_execs_lock); | ||
71 | #endif | ||
72 | } | ||
diff --git a/kernel/workqueue.c b/kernel/workqueue.c index 12328147132c..67e526b6ae81 100644 --- a/kernel/workqueue.c +++ b/kernel/workqueue.c | |||
@@ -692,31 +692,29 @@ int schedule_on_each_cpu(work_func_t func) | |||
692 | if (!works) | 692 | if (!works) |
693 | return -ENOMEM; | 693 | return -ENOMEM; |
694 | 694 | ||
695 | get_online_cpus(); | ||
696 | |||
695 | /* | 697 | /* |
696 | * when running in keventd don't schedule a work item on itself. | 698 | * When running in keventd don't schedule a work item on |
697 | * Can just call directly because the work queue is already bound. | 699 | * itself. Can just call directly because the work queue is |
698 | * This also is faster. | 700 | * already bound. This also is faster. |
699 | * Make this a generic parameter for other workqueues? | ||
700 | */ | 701 | */ |
701 | if (current_is_keventd()) { | 702 | if (current_is_keventd()) |
702 | orig = raw_smp_processor_id(); | 703 | orig = raw_smp_processor_id(); |
703 | INIT_WORK(per_cpu_ptr(works, orig), func); | ||
704 | func(per_cpu_ptr(works, orig)); | ||
705 | } | ||
706 | 704 | ||
707 | get_online_cpus(); | ||
708 | for_each_online_cpu(cpu) { | 705 | for_each_online_cpu(cpu) { |
709 | struct work_struct *work = per_cpu_ptr(works, cpu); | 706 | struct work_struct *work = per_cpu_ptr(works, cpu); |
710 | 707 | ||
711 | if (cpu == orig) | ||
712 | continue; | ||
713 | INIT_WORK(work, func); | 708 | INIT_WORK(work, func); |
714 | schedule_work_on(cpu, work); | ||
715 | } | ||
716 | for_each_online_cpu(cpu) { | ||
717 | if (cpu != orig) | 709 | if (cpu != orig) |
718 | flush_work(per_cpu_ptr(works, cpu)); | 710 | schedule_work_on(cpu, work); |
719 | } | 711 | } |
712 | if (orig >= 0) | ||
713 | func(per_cpu_ptr(works, orig)); | ||
714 | |||
715 | for_each_online_cpu(cpu) | ||
716 | flush_work(per_cpu_ptr(works, cpu)); | ||
717 | |||
720 | put_online_cpus(); | 718 | put_online_cpus(); |
721 | free_percpu(works); | 719 | free_percpu(works); |
722 | return 0; | 720 | return 0; |
diff --git a/lib/radix-tree.c b/lib/radix-tree.c index 23abbd93cae1..92cdd9936e3d 100644 --- a/lib/radix-tree.c +++ b/lib/radix-tree.c | |||
@@ -200,6 +200,9 @@ radix_tree_node_free(struct radix_tree_node *node) | |||
200 | * ensure that the addition of a single element in the tree cannot fail. On | 200 | * ensure that the addition of a single element in the tree cannot fail. On |
201 | * success, return zero, with preemption disabled. On error, return -ENOMEM | 201 | * success, return zero, with preemption disabled. On error, return -ENOMEM |
202 | * with preemption not disabled. | 202 | * with preemption not disabled. |
203 | * | ||
204 | * To make use of this facility, the radix tree must be initialised without | ||
205 | * __GFP_WAIT being passed to INIT_RADIX_TREE(). | ||
203 | */ | 206 | */ |
204 | int radix_tree_preload(gfp_t gfp_mask) | 207 | int radix_tree_preload(gfp_t gfp_mask) |
205 | { | 208 | { |
@@ -543,7 +546,6 @@ out: | |||
543 | } | 546 | } |
544 | EXPORT_SYMBOL(radix_tree_tag_clear); | 547 | EXPORT_SYMBOL(radix_tree_tag_clear); |
545 | 548 | ||
546 | #ifndef __KERNEL__ /* Only the test harness uses this at present */ | ||
547 | /** | 549 | /** |
548 | * radix_tree_tag_get - get a tag on a radix tree node | 550 | * radix_tree_tag_get - get a tag on a radix tree node |
549 | * @root: radix tree root | 551 | * @root: radix tree root |
@@ -606,7 +608,6 @@ int radix_tree_tag_get(struct radix_tree_root *root, | |||
606 | } | 608 | } |
607 | } | 609 | } |
608 | EXPORT_SYMBOL(radix_tree_tag_get); | 610 | EXPORT_SYMBOL(radix_tree_tag_get); |
609 | #endif | ||
610 | 611 | ||
611 | /** | 612 | /** |
612 | * radix_tree_next_hole - find the next hole (not-present entry) | 613 | * radix_tree_next_hole - find the next hole (not-present entry) |
diff --git a/lib/string.c b/lib/string.c index b19b87af65a3..e96421ab9a9a 100644 --- a/lib/string.c +++ b/lib/string.c | |||
@@ -246,13 +246,17 @@ EXPORT_SYMBOL(strlcat); | |||
246 | #undef strcmp | 246 | #undef strcmp |
247 | int strcmp(const char *cs, const char *ct) | 247 | int strcmp(const char *cs, const char *ct) |
248 | { | 248 | { |
249 | signed char __res; | 249 | unsigned char c1, c2; |
250 | 250 | ||
251 | while (1) { | 251 | while (1) { |
252 | if ((__res = *cs - *ct++) != 0 || !*cs++) | 252 | c1 = *cs++; |
253 | c2 = *ct++; | ||
254 | if (c1 != c2) | ||
255 | return c1 < c2 ? -1 : 1; | ||
256 | if (!c1) | ||
253 | break; | 257 | break; |
254 | } | 258 | } |
255 | return __res; | 259 | return 0; |
256 | } | 260 | } |
257 | EXPORT_SYMBOL(strcmp); | 261 | EXPORT_SYMBOL(strcmp); |
258 | #endif | 262 | #endif |
@@ -266,14 +270,18 @@ EXPORT_SYMBOL(strcmp); | |||
266 | */ | 270 | */ |
267 | int strncmp(const char *cs, const char *ct, size_t count) | 271 | int strncmp(const char *cs, const char *ct, size_t count) |
268 | { | 272 | { |
269 | signed char __res = 0; | 273 | unsigned char c1, c2; |
270 | 274 | ||
271 | while (count) { | 275 | while (count) { |
272 | if ((__res = *cs - *ct++) != 0 || !*cs++) | 276 | c1 = *cs++; |
277 | c2 = *ct++; | ||
278 | if (c1 != c2) | ||
279 | return c1 < c2 ? -1 : 1; | ||
280 | if (!c1) | ||
273 | break; | 281 | break; |
274 | count--; | 282 | count--; |
275 | } | 283 | } |
276 | return __res; | 284 | return 0; |
277 | } | 285 | } |
278 | EXPORT_SYMBOL(strncmp); | 286 | EXPORT_SYMBOL(strncmp); |
279 | #endif | 287 | #endif |
diff --git a/mm/Kconfig b/mm/Kconfig index fd3386242cf0..44cf6f0a3a6d 100644 --- a/mm/Kconfig +++ b/mm/Kconfig | |||
@@ -128,12 +128,9 @@ config SPARSEMEM_VMEMMAP | |||
128 | config MEMORY_HOTPLUG | 128 | config MEMORY_HOTPLUG |
129 | bool "Allow for memory hot-add" | 129 | bool "Allow for memory hot-add" |
130 | depends on SPARSEMEM || X86_64_ACPI_NUMA | 130 | depends on SPARSEMEM || X86_64_ACPI_NUMA |
131 | depends on HOTPLUG && !(HIBERNATION && !S390) && ARCH_ENABLE_MEMORY_HOTPLUG | 131 | depends on HOTPLUG && ARCH_ENABLE_MEMORY_HOTPLUG |
132 | depends on (IA64 || X86 || PPC_BOOK3S_64 || SUPERH || S390) | 132 | depends on (IA64 || X86 || PPC_BOOK3S_64 || SUPERH || S390) |
133 | 133 | ||
134 | comment "Memory hotplug is currently incompatible with Software Suspend" | ||
135 | depends on SPARSEMEM && HOTPLUG && HIBERNATION && !S390 | ||
136 | |||
137 | config MEMORY_HOTPLUG_SPARSE | 134 | config MEMORY_HOTPLUG_SPARSE |
138 | def_bool y | 135 | def_bool y |
139 | depends on SPARSEMEM && MEMORY_HOTPLUG | 136 | depends on SPARSEMEM && MEMORY_HOTPLUG |
diff --git a/mm/backing-dev.c b/mm/backing-dev.c index 11aee09dd2a6..67a33a5a1a93 100644 --- a/mm/backing-dev.c +++ b/mm/backing-dev.c | |||
@@ -604,10 +604,14 @@ static void bdi_wb_shutdown(struct backing_dev_info *bdi) | |||
604 | 604 | ||
605 | /* | 605 | /* |
606 | * Finally, kill the kernel threads. We don't need to be RCU | 606 | * Finally, kill the kernel threads. We don't need to be RCU |
607 | * safe anymore, since the bdi is gone from visibility. | 607 | * safe anymore, since the bdi is gone from visibility. Force |
608 | * unfreeze of the thread before calling kthread_stop(), otherwise | ||
609 | * it would never exet if it is currently stuck in the refrigerator. | ||
608 | */ | 610 | */ |
609 | list_for_each_entry(wb, &bdi->wb_list, list) | 611 | list_for_each_entry(wb, &bdi->wb_list, list) { |
612 | wb->task->flags &= ~PF_FROZEN; | ||
610 | kthread_stop(wb->task); | 613 | kthread_stop(wb->task); |
614 | } | ||
611 | } | 615 | } |
612 | 616 | ||
613 | /* | 617 | /* |
diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c index 821dee596377..2047465cd27c 100644 --- a/mm/memory_hotplug.c +++ b/mm/memory_hotplug.c | |||
@@ -26,6 +26,7 @@ | |||
26 | #include <linux/migrate.h> | 26 | #include <linux/migrate.h> |
27 | #include <linux/page-isolation.h> | 27 | #include <linux/page-isolation.h> |
28 | #include <linux/pfn.h> | 28 | #include <linux/pfn.h> |
29 | #include <linux/suspend.h> | ||
29 | 30 | ||
30 | #include <asm/tlbflush.h> | 31 | #include <asm/tlbflush.h> |
31 | 32 | ||
@@ -447,7 +448,8 @@ int online_pages(unsigned long pfn, unsigned long nr_pages) | |||
447 | } | 448 | } |
448 | #endif /* CONFIG_MEMORY_HOTPLUG_SPARSE */ | 449 | #endif /* CONFIG_MEMORY_HOTPLUG_SPARSE */ |
449 | 450 | ||
450 | static pg_data_t *hotadd_new_pgdat(int nid, u64 start) | 451 | /* we are OK calling __meminit stuff here - we have CONFIG_MEMORY_HOTPLUG */ |
452 | static pg_data_t __ref *hotadd_new_pgdat(int nid, u64 start) | ||
451 | { | 453 | { |
452 | struct pglist_data *pgdat; | 454 | struct pglist_data *pgdat; |
453 | unsigned long zones_size[MAX_NR_ZONES] = {0}; | 455 | unsigned long zones_size[MAX_NR_ZONES] = {0}; |
@@ -484,14 +486,18 @@ int __ref add_memory(int nid, u64 start, u64 size) | |||
484 | struct resource *res; | 486 | struct resource *res; |
485 | int ret; | 487 | int ret; |
486 | 488 | ||
489 | lock_system_sleep(); | ||
490 | |||
487 | res = register_memory_resource(start, size); | 491 | res = register_memory_resource(start, size); |
492 | ret = -EEXIST; | ||
488 | if (!res) | 493 | if (!res) |
489 | return -EEXIST; | 494 | goto out; |
490 | 495 | ||
491 | if (!node_online(nid)) { | 496 | if (!node_online(nid)) { |
492 | pgdat = hotadd_new_pgdat(nid, start); | 497 | pgdat = hotadd_new_pgdat(nid, start); |
498 | ret = -ENOMEM; | ||
493 | if (!pgdat) | 499 | if (!pgdat) |
494 | return -ENOMEM; | 500 | goto out; |
495 | new_pgdat = 1; | 501 | new_pgdat = 1; |
496 | } | 502 | } |
497 | 503 | ||
@@ -514,7 +520,8 @@ int __ref add_memory(int nid, u64 start, u64 size) | |||
514 | BUG_ON(ret); | 520 | BUG_ON(ret); |
515 | } | 521 | } |
516 | 522 | ||
517 | return ret; | 523 | goto out; |
524 | |||
518 | error: | 525 | error: |
519 | /* rollback pgdat allocation and others */ | 526 | /* rollback pgdat allocation and others */ |
520 | if (new_pgdat) | 527 | if (new_pgdat) |
@@ -522,6 +529,8 @@ error: | |||
522 | if (res) | 529 | if (res) |
523 | release_memory_resource(res); | 530 | release_memory_resource(res); |
524 | 531 | ||
532 | out: | ||
533 | unlock_system_sleep(); | ||
525 | return ret; | 534 | return ret; |
526 | } | 535 | } |
527 | EXPORT_SYMBOL_GPL(add_memory); | 536 | EXPORT_SYMBOL_GPL(add_memory); |
@@ -758,6 +767,8 @@ int offline_pages(unsigned long start_pfn, | |||
758 | if (!test_pages_in_a_zone(start_pfn, end_pfn)) | 767 | if (!test_pages_in_a_zone(start_pfn, end_pfn)) |
759 | return -EINVAL; | 768 | return -EINVAL; |
760 | 769 | ||
770 | lock_system_sleep(); | ||
771 | |||
761 | zone = page_zone(pfn_to_page(start_pfn)); | 772 | zone = page_zone(pfn_to_page(start_pfn)); |
762 | node = zone_to_nid(zone); | 773 | node = zone_to_nid(zone); |
763 | nr_pages = end_pfn - start_pfn; | 774 | nr_pages = end_pfn - start_pfn; |
@@ -765,7 +776,7 @@ int offline_pages(unsigned long start_pfn, | |||
765 | /* set above range as isolated */ | 776 | /* set above range as isolated */ |
766 | ret = start_isolate_page_range(start_pfn, end_pfn); | 777 | ret = start_isolate_page_range(start_pfn, end_pfn); |
767 | if (ret) | 778 | if (ret) |
768 | return ret; | 779 | goto out; |
769 | 780 | ||
770 | arg.start_pfn = start_pfn; | 781 | arg.start_pfn = start_pfn; |
771 | arg.nr_pages = nr_pages; | 782 | arg.nr_pages = nr_pages; |
@@ -843,6 +854,7 @@ repeat: | |||
843 | writeback_set_ratelimit(); | 854 | writeback_set_ratelimit(); |
844 | 855 | ||
845 | memory_notify(MEM_OFFLINE, &arg); | 856 | memory_notify(MEM_OFFLINE, &arg); |
857 | unlock_system_sleep(); | ||
846 | return 0; | 858 | return 0; |
847 | 859 | ||
848 | failed_removal: | 860 | failed_removal: |
@@ -852,6 +864,8 @@ failed_removal: | |||
852 | /* pushback to free area */ | 864 | /* pushback to free area */ |
853 | undo_isolate_page_range(start_pfn, end_pfn); | 865 | undo_isolate_page_range(start_pfn, end_pfn); |
854 | 866 | ||
867 | out: | ||
868 | unlock_system_sleep(); | ||
855 | return ret; | 869 | return ret; |
856 | } | 870 | } |
857 | 871 | ||
diff --git a/net/8021q/vlan.c b/net/8021q/vlan.c index 8836575f9d79..a29c5ab5815c 100644 --- a/net/8021q/vlan.c +++ b/net/8021q/vlan.c | |||
@@ -281,8 +281,11 @@ out_uninit_applicant: | |||
281 | if (ngrp) | 281 | if (ngrp) |
282 | vlan_gvrp_uninit_applicant(real_dev); | 282 | vlan_gvrp_uninit_applicant(real_dev); |
283 | out_free_group: | 283 | out_free_group: |
284 | if (ngrp) | 284 | if (ngrp) { |
285 | vlan_group_free(ngrp); | 285 | hlist_del_rcu(&ngrp->hlist); |
286 | /* Free the group, after all cpu's are done. */ | ||
287 | call_rcu(&ngrp->rcu, vlan_rcu_free); | ||
288 | } | ||
286 | return err; | 289 | return err; |
287 | } | 290 | } |
288 | 291 | ||
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c index a9750984f772..b7c4224f4e7d 100644 --- a/net/bluetooth/hci_conn.c +++ b/net/bluetooth/hci_conn.c | |||
@@ -211,6 +211,7 @@ struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst) | |||
211 | conn->type = type; | 211 | conn->type = type; |
212 | conn->mode = HCI_CM_ACTIVE; | 212 | conn->mode = HCI_CM_ACTIVE; |
213 | conn->state = BT_OPEN; | 213 | conn->state = BT_OPEN; |
214 | conn->auth_type = HCI_AT_GENERAL_BONDING; | ||
214 | 215 | ||
215 | conn->power_save = 1; | 216 | conn->power_save = 1; |
216 | conn->disc_timeout = HCI_DISCONN_TIMEOUT; | 217 | conn->disc_timeout = HCI_DISCONN_TIMEOUT; |
diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c index 77e9fb130adb..947f8bbb4bb3 100644 --- a/net/bluetooth/l2cap.c +++ b/net/bluetooth/l2cap.c | |||
@@ -2205,7 +2205,7 @@ static int l2cap_build_conf_req(struct sock *sk, void *data) | |||
2205 | { | 2205 | { |
2206 | struct l2cap_pinfo *pi = l2cap_pi(sk); | 2206 | struct l2cap_pinfo *pi = l2cap_pi(sk); |
2207 | struct l2cap_conf_req *req = data; | 2207 | struct l2cap_conf_req *req = data; |
2208 | struct l2cap_conf_rfc rfc = { .mode = L2CAP_MODE_ERTM }; | 2208 | struct l2cap_conf_rfc rfc = { .mode = L2CAP_MODE_BASIC }; |
2209 | void *ptr = req->data; | 2209 | void *ptr = req->data; |
2210 | 2210 | ||
2211 | BT_DBG("sk %p", sk); | 2211 | BT_DBG("sk %p", sk); |
@@ -2394,6 +2394,10 @@ done: | |||
2394 | rfc.monitor_timeout = L2CAP_DEFAULT_MONITOR_TO; | 2394 | rfc.monitor_timeout = L2CAP_DEFAULT_MONITOR_TO; |
2395 | 2395 | ||
2396 | pi->conf_state |= L2CAP_CONF_MODE_DONE; | 2396 | pi->conf_state |= L2CAP_CONF_MODE_DONE; |
2397 | |||
2398 | l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, | ||
2399 | sizeof(rfc), (unsigned long) &rfc); | ||
2400 | |||
2397 | break; | 2401 | break; |
2398 | 2402 | ||
2399 | case L2CAP_MODE_STREAMING: | 2403 | case L2CAP_MODE_STREAMING: |
@@ -2401,6 +2405,10 @@ done: | |||
2401 | pi->max_pdu_size = rfc.max_pdu_size; | 2405 | pi->max_pdu_size = rfc.max_pdu_size; |
2402 | 2406 | ||
2403 | pi->conf_state |= L2CAP_CONF_MODE_DONE; | 2407 | pi->conf_state |= L2CAP_CONF_MODE_DONE; |
2408 | |||
2409 | l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, | ||
2410 | sizeof(rfc), (unsigned long) &rfc); | ||
2411 | |||
2404 | break; | 2412 | break; |
2405 | 2413 | ||
2406 | default: | 2414 | default: |
@@ -2410,9 +2418,6 @@ done: | |||
2410 | rfc.mode = pi->mode; | 2418 | rfc.mode = pi->mode; |
2411 | } | 2419 | } |
2412 | 2420 | ||
2413 | l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, | ||
2414 | sizeof(rfc), (unsigned long) &rfc); | ||
2415 | |||
2416 | if (result == L2CAP_CONF_SUCCESS) | 2421 | if (result == L2CAP_CONF_SUCCESS) |
2417 | pi->conf_state |= L2CAP_CONF_OUTPUT_DONE; | 2422 | pi->conf_state |= L2CAP_CONF_OUTPUT_DONE; |
2418 | } | 2423 | } |
diff --git a/net/core/dev.c b/net/core/dev.c index b8f74cfb1bfd..fe10551d3671 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
@@ -942,14 +942,15 @@ rollback: | |||
942 | ret = notifier_to_errno(ret); | 942 | ret = notifier_to_errno(ret); |
943 | 943 | ||
944 | if (ret) { | 944 | if (ret) { |
945 | if (err) { | 945 | /* err >= 0 after dev_alloc_name() or stores the first errno */ |
946 | printk(KERN_ERR | 946 | if (err >= 0) { |
947 | "%s: name change rollback failed: %d.\n", | ||
948 | dev->name, ret); | ||
949 | } else { | ||
950 | err = ret; | 947 | err = ret; |
951 | memcpy(dev->name, oldname, IFNAMSIZ); | 948 | memcpy(dev->name, oldname, IFNAMSIZ); |
952 | goto rollback; | 949 | goto rollback; |
950 | } else { | ||
951 | printk(KERN_ERR | ||
952 | "%s: name change rollback failed: %d.\n", | ||
953 | dev->name, ret); | ||
953 | } | 954 | } |
954 | } | 955 | } |
955 | 956 | ||
diff --git a/net/core/pktgen.c b/net/core/pktgen.c index 6eb8d47cbf3a..6e79e96cb4f2 100644 --- a/net/core/pktgen.c +++ b/net/core/pktgen.c | |||
@@ -363,6 +363,7 @@ struct pktgen_dev { | |||
363 | * device name (not when the inject is | 363 | * device name (not when the inject is |
364 | * started as it used to do.) | 364 | * started as it used to do.) |
365 | */ | 365 | */ |
366 | char odevname[32]; | ||
366 | struct flow_state *flows; | 367 | struct flow_state *flows; |
367 | unsigned cflows; /* Concurrent flows (config) */ | 368 | unsigned cflows; /* Concurrent flows (config) */ |
368 | unsigned lflow; /* Flow length (config) */ | 369 | unsigned lflow; /* Flow length (config) */ |
@@ -426,7 +427,7 @@ static const char version[] = | |||
426 | static int pktgen_remove_device(struct pktgen_thread *t, struct pktgen_dev *i); | 427 | static int pktgen_remove_device(struct pktgen_thread *t, struct pktgen_dev *i); |
427 | static int pktgen_add_device(struct pktgen_thread *t, const char *ifname); | 428 | static int pktgen_add_device(struct pktgen_thread *t, const char *ifname); |
428 | static struct pktgen_dev *pktgen_find_dev(struct pktgen_thread *t, | 429 | static struct pktgen_dev *pktgen_find_dev(struct pktgen_thread *t, |
429 | const char *ifname); | 430 | const char *ifname, bool exact); |
430 | static int pktgen_device_event(struct notifier_block *, unsigned long, void *); | 431 | static int pktgen_device_event(struct notifier_block *, unsigned long, void *); |
431 | static void pktgen_run_all_threads(void); | 432 | static void pktgen_run_all_threads(void); |
432 | static void pktgen_reset_all_threads(void); | 433 | static void pktgen_reset_all_threads(void); |
@@ -528,7 +529,7 @@ static int pktgen_if_show(struct seq_file *seq, void *v) | |||
528 | seq_printf(seq, | 529 | seq_printf(seq, |
529 | " frags: %d delay: %llu clone_skb: %d ifname: %s\n", | 530 | " frags: %d delay: %llu clone_skb: %d ifname: %s\n", |
530 | pkt_dev->nfrags, (unsigned long long) pkt_dev->delay, | 531 | pkt_dev->nfrags, (unsigned long long) pkt_dev->delay, |
531 | pkt_dev->clone_skb, pkt_dev->odev->name); | 532 | pkt_dev->clone_skb, pkt_dev->odevname); |
532 | 533 | ||
533 | seq_printf(seq, " flows: %u flowlen: %u\n", pkt_dev->cflows, | 534 | seq_printf(seq, " flows: %u flowlen: %u\n", pkt_dev->cflows, |
534 | pkt_dev->lflow); | 535 | pkt_dev->lflow); |
@@ -1688,13 +1689,13 @@ static int pktgen_thread_show(struct seq_file *seq, void *v) | |||
1688 | if_lock(t); | 1689 | if_lock(t); |
1689 | list_for_each_entry(pkt_dev, &t->if_list, list) | 1690 | list_for_each_entry(pkt_dev, &t->if_list, list) |
1690 | if (pkt_dev->running) | 1691 | if (pkt_dev->running) |
1691 | seq_printf(seq, "%s ", pkt_dev->odev->name); | 1692 | seq_printf(seq, "%s ", pkt_dev->odevname); |
1692 | 1693 | ||
1693 | seq_printf(seq, "\nStopped: "); | 1694 | seq_printf(seq, "\nStopped: "); |
1694 | 1695 | ||
1695 | list_for_each_entry(pkt_dev, &t->if_list, list) | 1696 | list_for_each_entry(pkt_dev, &t->if_list, list) |
1696 | if (!pkt_dev->running) | 1697 | if (!pkt_dev->running) |
1697 | seq_printf(seq, "%s ", pkt_dev->odev->name); | 1698 | seq_printf(seq, "%s ", pkt_dev->odevname); |
1698 | 1699 | ||
1699 | if (t->result[0]) | 1700 | if (t->result[0]) |
1700 | seq_printf(seq, "\nResult: %s\n", t->result); | 1701 | seq_printf(seq, "\nResult: %s\n", t->result); |
@@ -1817,9 +1818,10 @@ static struct pktgen_dev *__pktgen_NN_threads(const char *ifname, int remove) | |||
1817 | { | 1818 | { |
1818 | struct pktgen_thread *t; | 1819 | struct pktgen_thread *t; |
1819 | struct pktgen_dev *pkt_dev = NULL; | 1820 | struct pktgen_dev *pkt_dev = NULL; |
1821 | bool exact = (remove == FIND); | ||
1820 | 1822 | ||
1821 | list_for_each_entry(t, &pktgen_threads, th_list) { | 1823 | list_for_each_entry(t, &pktgen_threads, th_list) { |
1822 | pkt_dev = pktgen_find_dev(t, ifname); | 1824 | pkt_dev = pktgen_find_dev(t, ifname, exact); |
1823 | if (pkt_dev) { | 1825 | if (pkt_dev) { |
1824 | if (remove) { | 1826 | if (remove) { |
1825 | if_lock(t); | 1827 | if_lock(t); |
@@ -1994,7 +1996,7 @@ static void pktgen_setup_inject(struct pktgen_dev *pkt_dev) | |||
1994 | "queue_map_min (zero-based) (%d) exceeds valid range " | 1996 | "queue_map_min (zero-based) (%d) exceeds valid range " |
1995 | "[0 - %d] for (%d) queues on %s, resetting\n", | 1997 | "[0 - %d] for (%d) queues on %s, resetting\n", |
1996 | pkt_dev->queue_map_min, (ntxq ?: 1) - 1, ntxq, | 1998 | pkt_dev->queue_map_min, (ntxq ?: 1) - 1, ntxq, |
1997 | pkt_dev->odev->name); | 1999 | pkt_dev->odevname); |
1998 | pkt_dev->queue_map_min = ntxq - 1; | 2000 | pkt_dev->queue_map_min = ntxq - 1; |
1999 | } | 2001 | } |
2000 | if (pkt_dev->queue_map_max >= ntxq) { | 2002 | if (pkt_dev->queue_map_max >= ntxq) { |
@@ -2002,7 +2004,7 @@ static void pktgen_setup_inject(struct pktgen_dev *pkt_dev) | |||
2002 | "queue_map_max (zero-based) (%d) exceeds valid range " | 2004 | "queue_map_max (zero-based) (%d) exceeds valid range " |
2003 | "[0 - %d] for (%d) queues on %s, resetting\n", | 2005 | "[0 - %d] for (%d) queues on %s, resetting\n", |
2004 | pkt_dev->queue_map_max, (ntxq ?: 1) - 1, ntxq, | 2006 | pkt_dev->queue_map_max, (ntxq ?: 1) - 1, ntxq, |
2005 | pkt_dev->odev->name); | 2007 | pkt_dev->odevname); |
2006 | pkt_dev->queue_map_max = ntxq - 1; | 2008 | pkt_dev->queue_map_max = ntxq - 1; |
2007 | } | 2009 | } |
2008 | 2010 | ||
@@ -3262,7 +3264,7 @@ static int pktgen_stop_device(struct pktgen_dev *pkt_dev) | |||
3262 | 3264 | ||
3263 | if (!pkt_dev->running) { | 3265 | if (!pkt_dev->running) { |
3264 | printk(KERN_WARNING "pktgen: interface: %s is already " | 3266 | printk(KERN_WARNING "pktgen: interface: %s is already " |
3265 | "stopped\n", pkt_dev->odev->name); | 3267 | "stopped\n", pkt_dev->odevname); |
3266 | return -EINVAL; | 3268 | return -EINVAL; |
3267 | } | 3269 | } |
3268 | 3270 | ||
@@ -3464,7 +3466,7 @@ static void pktgen_xmit(struct pktgen_dev *pkt_dev) | |||
3464 | default: /* Drivers are not supposed to return other values! */ | 3466 | default: /* Drivers are not supposed to return other values! */ |
3465 | if (net_ratelimit()) | 3467 | if (net_ratelimit()) |
3466 | pr_info("pktgen: %s xmit error: %d\n", | 3468 | pr_info("pktgen: %s xmit error: %d\n", |
3467 | odev->name, ret); | 3469 | pkt_dev->odevname, ret); |
3468 | pkt_dev->errors++; | 3470 | pkt_dev->errors++; |
3469 | /* fallthru */ | 3471 | /* fallthru */ |
3470 | case NETDEV_TX_LOCKED: | 3472 | case NETDEV_TX_LOCKED: |
@@ -3566,13 +3568,18 @@ static int pktgen_thread_worker(void *arg) | |||
3566 | } | 3568 | } |
3567 | 3569 | ||
3568 | static struct pktgen_dev *pktgen_find_dev(struct pktgen_thread *t, | 3570 | static struct pktgen_dev *pktgen_find_dev(struct pktgen_thread *t, |
3569 | const char *ifname) | 3571 | const char *ifname, bool exact) |
3570 | { | 3572 | { |
3571 | struct pktgen_dev *p, *pkt_dev = NULL; | 3573 | struct pktgen_dev *p, *pkt_dev = NULL; |
3572 | if_lock(t); | 3574 | size_t len = strlen(ifname); |
3573 | 3575 | ||
3576 | if_lock(t); | ||
3574 | list_for_each_entry(p, &t->if_list, list) | 3577 | list_for_each_entry(p, &t->if_list, list) |
3575 | if (strncmp(p->odev->name, ifname, IFNAMSIZ) == 0) { | 3578 | if (strncmp(p->odevname, ifname, len) == 0) { |
3579 | if (p->odevname[len]) { | ||
3580 | if (exact || p->odevname[len] != '@') | ||
3581 | continue; | ||
3582 | } | ||
3576 | pkt_dev = p; | 3583 | pkt_dev = p; |
3577 | break; | 3584 | break; |
3578 | } | 3585 | } |
@@ -3628,6 +3635,7 @@ static int pktgen_add_device(struct pktgen_thread *t, const char *ifname) | |||
3628 | if (!pkt_dev) | 3635 | if (!pkt_dev) |
3629 | return -ENOMEM; | 3636 | return -ENOMEM; |
3630 | 3637 | ||
3638 | strcpy(pkt_dev->odevname, ifname); | ||
3631 | pkt_dev->flows = vmalloc(MAX_CFLOWS * sizeof(struct flow_state)); | 3639 | pkt_dev->flows = vmalloc(MAX_CFLOWS * sizeof(struct flow_state)); |
3632 | if (pkt_dev->flows == NULL) { | 3640 | if (pkt_dev->flows == NULL) { |
3633 | kfree(pkt_dev); | 3641 | kfree(pkt_dev); |
diff --git a/net/core/skbuff.c b/net/core/skbuff.c index 80a96166df39..ec85681a7dd8 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c | |||
@@ -2701,7 +2701,8 @@ int skb_gro_receive(struct sk_buff **head, struct sk_buff *skb) | |||
2701 | 2701 | ||
2702 | NAPI_GRO_CB(skb)->free = 1; | 2702 | NAPI_GRO_CB(skb)->free = 1; |
2703 | goto done; | 2703 | goto done; |
2704 | } | 2704 | } else if (skb_gro_len(p) != pinfo->gso_size) |
2705 | return -E2BIG; | ||
2705 | 2706 | ||
2706 | headroom = skb_headroom(p); | 2707 | headroom = skb_headroom(p); |
2707 | nskb = netdev_alloc_skb(p->dev, headroom + skb_gro_offset(p)); | 2708 | nskb = netdev_alloc_skb(p->dev, headroom + skb_gro_offset(p)); |
diff --git a/net/ipv4/ip_fragment.c b/net/ipv4/ip_fragment.c index 575f9bd51ccd..d3fe10be7219 100644 --- a/net/ipv4/ip_fragment.c +++ b/net/ipv4/ip_fragment.c | |||
@@ -563,7 +563,7 @@ out_oversize: | |||
563 | printk(KERN_INFO "Oversized IP packet from %pI4.\n", | 563 | printk(KERN_INFO "Oversized IP packet from %pI4.\n", |
564 | &qp->saddr); | 564 | &qp->saddr); |
565 | out_fail: | 565 | out_fail: |
566 | IP_INC_STATS_BH(dev_net(dev), IPSTATS_MIB_REASMFAILS); | 566 | IP_INC_STATS_BH(net, IPSTATS_MIB_REASMFAILS); |
567 | return err; | 567 | return err; |
568 | } | 568 | } |
569 | 569 | ||
diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c index 630a56df7b47..99508d66a642 100644 --- a/net/ipv4/ipmr.c +++ b/net/ipv4/ipmr.c | |||
@@ -483,8 +483,10 @@ static int vif_add(struct net *net, struct vifctl *vifc, int mrtsock) | |||
483 | return -EINVAL; | 483 | return -EINVAL; |
484 | } | 484 | } |
485 | 485 | ||
486 | if ((in_dev = __in_dev_get_rtnl(dev)) == NULL) | 486 | if ((in_dev = __in_dev_get_rtnl(dev)) == NULL) { |
487 | dev_put(dev); | ||
487 | return -EADDRNOTAVAIL; | 488 | return -EADDRNOTAVAIL; |
489 | } | ||
488 | IPV4_DEVCONF(in_dev->cnf, MC_FORWARDING)++; | 490 | IPV4_DEVCONF(in_dev->cnf, MC_FORWARDING)++; |
489 | ip_rt_multicast_event(in_dev); | 491 | ip_rt_multicast_event(in_dev); |
490 | 492 | ||
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index 98440ad82558..f1813bc71088 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c | |||
@@ -1183,7 +1183,9 @@ void tcp_cleanup_rbuf(struct sock *sk, int copied) | |||
1183 | #if TCP_DEBUG | 1183 | #if TCP_DEBUG |
1184 | struct sk_buff *skb = skb_peek(&sk->sk_receive_queue); | 1184 | struct sk_buff *skb = skb_peek(&sk->sk_receive_queue); |
1185 | 1185 | ||
1186 | WARN_ON(skb && !before(tp->copied_seq, TCP_SKB_CB(skb)->end_seq)); | 1186 | WARN(skb && !before(tp->copied_seq, TCP_SKB_CB(skb)->end_seq), |
1187 | KERN_INFO "cleanup rbuf bug: copied %X seq %X rcvnxt %X\n", | ||
1188 | tp->copied_seq, TCP_SKB_CB(skb)->end_seq, tp->rcv_nxt); | ||
1187 | #endif | 1189 | #endif |
1188 | 1190 | ||
1189 | if (inet_csk_ack_scheduled(sk)) { | 1191 | if (inet_csk_ack_scheduled(sk)) { |
@@ -1430,11 +1432,13 @@ int tcp_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, | |||
1430 | /* Now that we have two receive queues this | 1432 | /* Now that we have two receive queues this |
1431 | * shouldn't happen. | 1433 | * shouldn't happen. |
1432 | */ | 1434 | */ |
1433 | if (before(*seq, TCP_SKB_CB(skb)->seq)) { | 1435 | if (WARN(before(*seq, TCP_SKB_CB(skb)->seq), |
1434 | printk(KERN_INFO "recvmsg bug: copied %X " | 1436 | KERN_INFO "recvmsg bug: copied %X " |
1435 | "seq %X\n", *seq, TCP_SKB_CB(skb)->seq); | 1437 | "seq %X rcvnxt %X fl %X\n", *seq, |
1438 | TCP_SKB_CB(skb)->seq, tp->rcv_nxt, | ||
1439 | flags)) | ||
1436 | break; | 1440 | break; |
1437 | } | 1441 | |
1438 | offset = *seq - TCP_SKB_CB(skb)->seq; | 1442 | offset = *seq - TCP_SKB_CB(skb)->seq; |
1439 | if (tcp_hdr(skb)->syn) | 1443 | if (tcp_hdr(skb)->syn) |
1440 | offset--; | 1444 | offset--; |
@@ -1443,8 +1447,9 @@ int tcp_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, | |||
1443 | if (tcp_hdr(skb)->fin) | 1447 | if (tcp_hdr(skb)->fin) |
1444 | goto found_fin_ok; | 1448 | goto found_fin_ok; |
1445 | WARN(!(flags & MSG_PEEK), KERN_INFO "recvmsg bug 2: " | 1449 | WARN(!(flags & MSG_PEEK), KERN_INFO "recvmsg bug 2: " |
1446 | "copied %X seq %X\n", *seq, | 1450 | "copied %X seq %X rcvnxt %X fl %X\n", |
1447 | TCP_SKB_CB(skb)->seq); | 1451 | *seq, TCP_SKB_CB(skb)->seq, |
1452 | tp->rcv_nxt, flags); | ||
1448 | } | 1453 | } |
1449 | 1454 | ||
1450 | /* Well, if we have backlog, try to process it now yet. */ | 1455 | /* Well, if we have backlog, try to process it now yet. */ |
diff --git a/net/mac80211/agg-tx.c b/net/mac80211/agg-tx.c index b09948ceec4a..206fd82f0c76 100644 --- a/net/mac80211/agg-tx.c +++ b/net/mac80211/agg-tx.c | |||
@@ -173,12 +173,14 @@ static void sta_addba_resp_timer_expired(unsigned long data) | |||
173 | 173 | ||
174 | /* check if the TID waits for addBA response */ | 174 | /* check if the TID waits for addBA response */ |
175 | spin_lock_bh(&sta->lock); | 175 | spin_lock_bh(&sta->lock); |
176 | if (!(*state & HT_ADDBA_REQUESTED_MSK)) { | 176 | if ((*state & (HT_ADDBA_REQUESTED_MSK | HT_ADDBA_RECEIVED_MSK)) != |
177 | HT_ADDBA_REQUESTED_MSK) { | ||
177 | spin_unlock_bh(&sta->lock); | 178 | spin_unlock_bh(&sta->lock); |
178 | *state = HT_AGG_STATE_IDLE; | 179 | *state = HT_AGG_STATE_IDLE; |
179 | #ifdef CONFIG_MAC80211_HT_DEBUG | 180 | #ifdef CONFIG_MAC80211_HT_DEBUG |
180 | printk(KERN_DEBUG "timer expired on tid %d but we are not " | 181 | printk(KERN_DEBUG "timer expired on tid %d but we are not " |
181 | "expecting addBA response there", tid); | 182 | "(or no longer) expecting addBA response there", |
183 | tid); | ||
182 | #endif | 184 | #endif |
183 | return; | 185 | return; |
184 | } | 186 | } |
@@ -666,21 +668,21 @@ void ieee80211_process_addba_resp(struct ieee80211_local *local, | |||
666 | 668 | ||
667 | state = &sta->ampdu_mlme.tid_state_tx[tid]; | 669 | state = &sta->ampdu_mlme.tid_state_tx[tid]; |
668 | 670 | ||
669 | del_timer_sync(&sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer); | ||
670 | |||
671 | spin_lock_bh(&sta->lock); | 671 | spin_lock_bh(&sta->lock); |
672 | 672 | ||
673 | if (!(*state & HT_ADDBA_REQUESTED_MSK)) | 673 | if (!(*state & HT_ADDBA_REQUESTED_MSK)) |
674 | goto timer_still_needed; | 674 | goto out; |
675 | 675 | ||
676 | if (mgmt->u.action.u.addba_resp.dialog_token != | 676 | if (mgmt->u.action.u.addba_resp.dialog_token != |
677 | sta->ampdu_mlme.tid_tx[tid]->dialog_token) { | 677 | sta->ampdu_mlme.tid_tx[tid]->dialog_token) { |
678 | #ifdef CONFIG_MAC80211_HT_DEBUG | 678 | #ifdef CONFIG_MAC80211_HT_DEBUG |
679 | printk(KERN_DEBUG "wrong addBA response token, tid %d\n", tid); | 679 | printk(KERN_DEBUG "wrong addBA response token, tid %d\n", tid); |
680 | #endif /* CONFIG_MAC80211_HT_DEBUG */ | 680 | #endif /* CONFIG_MAC80211_HT_DEBUG */ |
681 | goto timer_still_needed; | 681 | goto out; |
682 | } | 682 | } |
683 | 683 | ||
684 | del_timer(&sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer); | ||
685 | |||
684 | #ifdef CONFIG_MAC80211_HT_DEBUG | 686 | #ifdef CONFIG_MAC80211_HT_DEBUG |
685 | printk(KERN_DEBUG "switched off addBA timer for tid %d \n", tid); | 687 | printk(KERN_DEBUG "switched off addBA timer for tid %d \n", tid); |
686 | #endif /* CONFIG_MAC80211_HT_DEBUG */ | 688 | #endif /* CONFIG_MAC80211_HT_DEBUG */ |
@@ -699,10 +701,6 @@ void ieee80211_process_addba_resp(struct ieee80211_local *local, | |||
699 | ___ieee80211_stop_tx_ba_session(sta, tid, WLAN_BACK_INITIATOR); | 701 | ___ieee80211_stop_tx_ba_session(sta, tid, WLAN_BACK_INITIATOR); |
700 | } | 702 | } |
701 | 703 | ||
702 | goto out; | ||
703 | |||
704 | timer_still_needed: | ||
705 | add_timer(&sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer); | ||
706 | out: | 704 | out: |
707 | spin_unlock_bh(&sta->lock); | 705 | spin_unlock_bh(&sta->lock); |
708 | } | 706 | } |
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 588005c84a6d..a910bf1f092f 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h | |||
@@ -662,6 +662,14 @@ struct ieee80211_local { | |||
662 | bool suspended; | 662 | bool suspended; |
663 | 663 | ||
664 | /* | 664 | /* |
665 | * Resuming is true while suspended, but when we're reprogramming the | ||
666 | * hardware -- at that time it's allowed to use ieee80211_queue_work() | ||
667 | * again even though some other parts of the stack are still suspended | ||
668 | * and we still drop received frames to avoid waking the stack. | ||
669 | */ | ||
670 | bool resuming; | ||
671 | |||
672 | /* | ||
665 | * quiescing is true during the suspend process _only_ to | 673 | * quiescing is true during the suspend process _only_ to |
666 | * ease timer cancelling etc. | 674 | * ease timer cancelling etc. |
667 | */ | 675 | */ |
diff --git a/net/mac80211/util.c b/net/mac80211/util.c index aeb65b3d2295..e6c08da8da26 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c | |||
@@ -520,9 +520,9 @@ EXPORT_SYMBOL_GPL(ieee80211_iterate_active_interfaces_atomic); | |||
520 | */ | 520 | */ |
521 | static bool ieee80211_can_queue_work(struct ieee80211_local *local) | 521 | static bool ieee80211_can_queue_work(struct ieee80211_local *local) |
522 | { | 522 | { |
523 | if (WARN(local->suspended, "queueing ieee80211 work while " | 523 | if (WARN(local->suspended && !local->resuming, |
524 | "going to suspend\n")) | 524 | "queueing ieee80211 work while going to suspend\n")) |
525 | return false; | 525 | return false; |
526 | 526 | ||
527 | return true; | 527 | return true; |
528 | } | 528 | } |
@@ -1025,13 +1025,9 @@ int ieee80211_reconfig(struct ieee80211_local *local) | |||
1025 | struct sta_info *sta; | 1025 | struct sta_info *sta; |
1026 | unsigned long flags; | 1026 | unsigned long flags; |
1027 | int res; | 1027 | int res; |
1028 | bool from_suspend = local->suspended; | ||
1029 | 1028 | ||
1030 | /* | 1029 | if (local->suspended) |
1031 | * We're going to start the hardware, at that point | 1030 | local->resuming = true; |
1032 | * we are no longer suspended and can RX frames. | ||
1033 | */ | ||
1034 | local->suspended = false; | ||
1035 | 1031 | ||
1036 | /* restart hardware */ | 1032 | /* restart hardware */ |
1037 | if (local->open_count) { | 1033 | if (local->open_count) { |
@@ -1129,11 +1125,14 @@ int ieee80211_reconfig(struct ieee80211_local *local) | |||
1129 | * If this is for hw restart things are still running. | 1125 | * If this is for hw restart things are still running. |
1130 | * We may want to change that later, however. | 1126 | * We may want to change that later, however. |
1131 | */ | 1127 | */ |
1132 | if (!from_suspend) | 1128 | if (!local->suspended) |
1133 | return 0; | 1129 | return 0; |
1134 | 1130 | ||
1135 | #ifdef CONFIG_PM | 1131 | #ifdef CONFIG_PM |
1132 | /* first set suspended false, then resuming */ | ||
1136 | local->suspended = false; | 1133 | local->suspended = false; |
1134 | mb(); | ||
1135 | local->resuming = false; | ||
1137 | 1136 | ||
1138 | list_for_each_entry(sdata, &local->interfaces, list) { | 1137 | list_for_each_entry(sdata, &local->interfaces, list) { |
1139 | switch(sdata->vif.type) { | 1138 | switch(sdata->vif.type) { |
diff --git a/net/netfilter/nf_log.c b/net/netfilter/nf_log.c index c93494fef8ef..d65d3481919c 100644 --- a/net/netfilter/nf_log.c +++ b/net/netfilter/nf_log.c | |||
@@ -128,9 +128,8 @@ EXPORT_SYMBOL(nf_log_packet); | |||
128 | 128 | ||
129 | #ifdef CONFIG_PROC_FS | 129 | #ifdef CONFIG_PROC_FS |
130 | static void *seq_start(struct seq_file *seq, loff_t *pos) | 130 | static void *seq_start(struct seq_file *seq, loff_t *pos) |
131 | __acquires(RCU) | ||
132 | { | 131 | { |
133 | rcu_read_lock(); | 132 | mutex_lock(&nf_log_mutex); |
134 | 133 | ||
135 | if (*pos >= ARRAY_SIZE(nf_loggers)) | 134 | if (*pos >= ARRAY_SIZE(nf_loggers)) |
136 | return NULL; | 135 | return NULL; |
@@ -149,9 +148,8 @@ static void *seq_next(struct seq_file *s, void *v, loff_t *pos) | |||
149 | } | 148 | } |
150 | 149 | ||
151 | static void seq_stop(struct seq_file *s, void *v) | 150 | static void seq_stop(struct seq_file *s, void *v) |
152 | __releases(RCU) | ||
153 | { | 151 | { |
154 | rcu_read_unlock(); | 152 | mutex_unlock(&nf_log_mutex); |
155 | } | 153 | } |
156 | 154 | ||
157 | static int seq_show(struct seq_file *s, void *v) | 155 | static int seq_show(struct seq_file *s, void *v) |
@@ -161,7 +159,7 @@ static int seq_show(struct seq_file *s, void *v) | |||
161 | struct nf_logger *t; | 159 | struct nf_logger *t; |
162 | int ret; | 160 | int ret; |
163 | 161 | ||
164 | logger = rcu_dereference(nf_loggers[*pos]); | 162 | logger = nf_loggers[*pos]; |
165 | 163 | ||
166 | if (!logger) | 164 | if (!logger) |
167 | ret = seq_printf(s, "%2lld NONE (", *pos); | 165 | ret = seq_printf(s, "%2lld NONE (", *pos); |
@@ -171,22 +169,16 @@ static int seq_show(struct seq_file *s, void *v) | |||
171 | if (ret < 0) | 169 | if (ret < 0) |
172 | return ret; | 170 | return ret; |
173 | 171 | ||
174 | mutex_lock(&nf_log_mutex); | ||
175 | list_for_each_entry(t, &nf_loggers_l[*pos], list[*pos]) { | 172 | list_for_each_entry(t, &nf_loggers_l[*pos], list[*pos]) { |
176 | ret = seq_printf(s, "%s", t->name); | 173 | ret = seq_printf(s, "%s", t->name); |
177 | if (ret < 0) { | 174 | if (ret < 0) |
178 | mutex_unlock(&nf_log_mutex); | ||
179 | return ret; | 175 | return ret; |
180 | } | ||
181 | if (&t->list[*pos] != nf_loggers_l[*pos].prev) { | 176 | if (&t->list[*pos] != nf_loggers_l[*pos].prev) { |
182 | ret = seq_printf(s, ","); | 177 | ret = seq_printf(s, ","); |
183 | if (ret < 0) { | 178 | if (ret < 0) |
184 | mutex_unlock(&nf_log_mutex); | ||
185 | return ret; | 179 | return ret; |
186 | } | ||
187 | } | 180 | } |
188 | } | 181 | } |
189 | mutex_unlock(&nf_log_mutex); | ||
190 | 182 | ||
191 | return seq_printf(s, ")\n"); | 183 | return seq_printf(s, ")\n"); |
192 | } | 184 | } |
diff --git a/net/netfilter/xt_limit.c b/net/netfilter/xt_limit.c index 2e8089ecd0af..2773be6a71dd 100644 --- a/net/netfilter/xt_limit.c +++ b/net/netfilter/xt_limit.c | |||
@@ -112,7 +112,7 @@ static bool limit_mt_check(const struct xt_mtchk_param *par) | |||
112 | 112 | ||
113 | priv = kmalloc(sizeof(*priv), GFP_KERNEL); | 113 | priv = kmalloc(sizeof(*priv), GFP_KERNEL); |
114 | if (priv == NULL) | 114 | if (priv == NULL) |
115 | return -ENOMEM; | 115 | return false; |
116 | 116 | ||
117 | /* For SMP, we only want to use one set of state. */ | 117 | /* For SMP, we only want to use one set of state. */ |
118 | r->master = priv; | 118 | r->master = priv; |
diff --git a/net/netfilter/xt_osf.c b/net/netfilter/xt_osf.c index 63e190504656..4d1a41bbd5d7 100644 --- a/net/netfilter/xt_osf.c +++ b/net/netfilter/xt_osf.c | |||
@@ -118,7 +118,7 @@ static int xt_osf_remove_callback(struct sock *ctnl, struct sk_buff *skb, | |||
118 | { | 118 | { |
119 | struct xt_osf_user_finger *f; | 119 | struct xt_osf_user_finger *f; |
120 | struct xt_osf_finger *sf; | 120 | struct xt_osf_finger *sf; |
121 | int err = ENOENT; | 121 | int err = -ENOENT; |
122 | 122 | ||
123 | if (!osf_attrs[OSF_ATTR_FINGER]) | 123 | if (!osf_attrs[OSF_ATTR_FINGER]) |
124 | return -EINVAL; | 124 | return -EINVAL; |
diff --git a/net/rfkill/core.c b/net/rfkill/core.c index ba2efb960c60..a001f7c1f711 100644 --- a/net/rfkill/core.c +++ b/net/rfkill/core.c | |||
@@ -1189,6 +1189,7 @@ static long rfkill_fop_ioctl(struct file *file, unsigned int cmd, | |||
1189 | #endif | 1189 | #endif |
1190 | 1190 | ||
1191 | static const struct file_operations rfkill_fops = { | 1191 | static const struct file_operations rfkill_fops = { |
1192 | .owner = THIS_MODULE, | ||
1192 | .open = rfkill_fop_open, | 1193 | .open = rfkill_fop_open, |
1193 | .read = rfkill_fop_read, | 1194 | .read = rfkill_fop_read, |
1194 | .write = rfkill_fop_write, | 1195 | .write = rfkill_fop_write, |
diff --git a/net/sctp/associola.c b/net/sctp/associola.c index 8450960df24f..7eed77a39d0d 100644 --- a/net/sctp/associola.c +++ b/net/sctp/associola.c | |||
@@ -1485,15 +1485,13 @@ void sctp_assoc_rwnd_decrease(struct sctp_association *asoc, unsigned len) | |||
1485 | * local endpoint and the remote peer. | 1485 | * local endpoint and the remote peer. |
1486 | */ | 1486 | */ |
1487 | int sctp_assoc_set_bind_addr_from_ep(struct sctp_association *asoc, | 1487 | int sctp_assoc_set_bind_addr_from_ep(struct sctp_association *asoc, |
1488 | gfp_t gfp) | 1488 | sctp_scope_t scope, gfp_t gfp) |
1489 | { | 1489 | { |
1490 | sctp_scope_t scope; | ||
1491 | int flags; | 1490 | int flags; |
1492 | 1491 | ||
1493 | /* Use scoping rules to determine the subset of addresses from | 1492 | /* Use scoping rules to determine the subset of addresses from |
1494 | * the endpoint. | 1493 | * the endpoint. |
1495 | */ | 1494 | */ |
1496 | scope = sctp_scope(&asoc->peer.active_path->ipaddr); | ||
1497 | flags = (PF_INET6 == asoc->base.sk->sk_family) ? SCTP_ADDR6_ALLOWED : 0; | 1495 | flags = (PF_INET6 == asoc->base.sk->sk_family) ? SCTP_ADDR6_ALLOWED : 0; |
1498 | if (asoc->peer.ipv4_address) | 1496 | if (asoc->peer.ipv4_address) |
1499 | flags |= SCTP_ADDR4_PEERSUPP; | 1497 | flags |= SCTP_ADDR4_PEERSUPP; |
diff --git a/net/sctp/outqueue.c b/net/sctp/outqueue.c index c9f20e28521b..23e5e97aa617 100644 --- a/net/sctp/outqueue.c +++ b/net/sctp/outqueue.c | |||
@@ -423,16 +423,6 @@ void sctp_retransmit_mark(struct sctp_outq *q, | |||
423 | if ((reason == SCTP_RTXR_FAST_RTX && | 423 | if ((reason == SCTP_RTXR_FAST_RTX && |
424 | (chunk->fast_retransmit == SCTP_NEED_FRTX)) || | 424 | (chunk->fast_retransmit == SCTP_NEED_FRTX)) || |
425 | (reason != SCTP_RTXR_FAST_RTX && !chunk->tsn_gap_acked)) { | 425 | (reason != SCTP_RTXR_FAST_RTX && !chunk->tsn_gap_acked)) { |
426 | /* If this chunk was sent less then 1 rto ago, do not | ||
427 | * retransmit this chunk, but give the peer time | ||
428 | * to acknowlege it. Do this only when | ||
429 | * retransmitting due to T3 timeout. | ||
430 | */ | ||
431 | if (reason == SCTP_RTXR_T3_RTX && | ||
432 | time_before(jiffies, chunk->sent_at + | ||
433 | transport->last_rto)) | ||
434 | continue; | ||
435 | |||
436 | /* RFC 2960 6.2.1 Processing a Received SACK | 426 | /* RFC 2960 6.2.1 Processing a Received SACK |
437 | * | 427 | * |
438 | * C) Any time a DATA chunk is marked for | 428 | * C) Any time a DATA chunk is marked for |
diff --git a/net/sctp/sm_sideeffect.c b/net/sctp/sm_sideeffect.c index 8674d4919556..efa516b47e81 100644 --- a/net/sctp/sm_sideeffect.c +++ b/net/sctp/sm_sideeffect.c | |||
@@ -480,7 +480,6 @@ static void sctp_do_8_2_transport_strike(struct sctp_association *asoc, | |||
480 | * that indicates that we have an outstanding HB. | 480 | * that indicates that we have an outstanding HB. |
481 | */ | 481 | */ |
482 | if (!is_hb || transport->hb_sent) { | 482 | if (!is_hb || transport->hb_sent) { |
483 | transport->last_rto = transport->rto; | ||
484 | transport->rto = min((transport->rto * 2), transport->asoc->rto_max); | 483 | transport->rto = min((transport->rto * 2), transport->asoc->rto_max); |
485 | } | 484 | } |
486 | } | 485 | } |
diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c index c8fae1983dd1..d4df45022ffa 100644 --- a/net/sctp/sm_statefuns.c +++ b/net/sctp/sm_statefuns.c | |||
@@ -384,6 +384,11 @@ sctp_disposition_t sctp_sf_do_5_1B_init(const struct sctp_endpoint *ep, | |||
384 | if (!new_asoc) | 384 | if (!new_asoc) |
385 | goto nomem; | 385 | goto nomem; |
386 | 386 | ||
387 | if (sctp_assoc_set_bind_addr_from_ep(new_asoc, | ||
388 | sctp_scope(sctp_source(chunk)), | ||
389 | GFP_ATOMIC) < 0) | ||
390 | goto nomem_init; | ||
391 | |||
387 | /* The call, sctp_process_init(), can fail on memory allocation. */ | 392 | /* The call, sctp_process_init(), can fail on memory allocation. */ |
388 | if (!sctp_process_init(new_asoc, chunk->chunk_hdr->type, | 393 | if (!sctp_process_init(new_asoc, chunk->chunk_hdr->type, |
389 | sctp_source(chunk), | 394 | sctp_source(chunk), |
@@ -401,9 +406,6 @@ sctp_disposition_t sctp_sf_do_5_1B_init(const struct sctp_endpoint *ep, | |||
401 | len = ntohs(err_chunk->chunk_hdr->length) - | 406 | len = ntohs(err_chunk->chunk_hdr->length) - |
402 | sizeof(sctp_chunkhdr_t); | 407 | sizeof(sctp_chunkhdr_t); |
403 | 408 | ||
404 | if (sctp_assoc_set_bind_addr_from_ep(new_asoc, GFP_ATOMIC) < 0) | ||
405 | goto nomem_init; | ||
406 | |||
407 | repl = sctp_make_init_ack(new_asoc, chunk, GFP_ATOMIC, len); | 409 | repl = sctp_make_init_ack(new_asoc, chunk, GFP_ATOMIC, len); |
408 | if (!repl) | 410 | if (!repl) |
409 | goto nomem_init; | 411 | goto nomem_init; |
@@ -1452,6 +1454,10 @@ static sctp_disposition_t sctp_sf_do_unexpected_init( | |||
1452 | if (!new_asoc) | 1454 | if (!new_asoc) |
1453 | goto nomem; | 1455 | goto nomem; |
1454 | 1456 | ||
1457 | if (sctp_assoc_set_bind_addr_from_ep(new_asoc, | ||
1458 | sctp_scope(sctp_source(chunk)), GFP_ATOMIC) < 0) | ||
1459 | goto nomem; | ||
1460 | |||
1455 | /* In the outbound INIT ACK the endpoint MUST copy its current | 1461 | /* In the outbound INIT ACK the endpoint MUST copy its current |
1456 | * Verification Tag and Peers Verification tag into a reserved | 1462 | * Verification Tag and Peers Verification tag into a reserved |
1457 | * place (local tie-tag and per tie-tag) within the state cookie. | 1463 | * place (local tie-tag and per tie-tag) within the state cookie. |
@@ -1488,9 +1494,6 @@ static sctp_disposition_t sctp_sf_do_unexpected_init( | |||
1488 | sizeof(sctp_chunkhdr_t); | 1494 | sizeof(sctp_chunkhdr_t); |
1489 | } | 1495 | } |
1490 | 1496 | ||
1491 | if (sctp_assoc_set_bind_addr_from_ep(new_asoc, GFP_ATOMIC) < 0) | ||
1492 | goto nomem; | ||
1493 | |||
1494 | repl = sctp_make_init_ack(new_asoc, chunk, GFP_ATOMIC, len); | 1497 | repl = sctp_make_init_ack(new_asoc, chunk, GFP_ATOMIC, len); |
1495 | if (!repl) | 1498 | if (!repl) |
1496 | goto nomem; | 1499 | goto nomem; |
diff --git a/net/sctp/socket.c b/net/sctp/socket.c index c8d05758661d..3a95fcb17a9e 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c | |||
@@ -1080,6 +1080,13 @@ static int __sctp_connect(struct sock* sk, | |||
1080 | err = -ENOMEM; | 1080 | err = -ENOMEM; |
1081 | goto out_free; | 1081 | goto out_free; |
1082 | } | 1082 | } |
1083 | |||
1084 | err = sctp_assoc_set_bind_addr_from_ep(asoc, scope, | ||
1085 | GFP_KERNEL); | ||
1086 | if (err < 0) { | ||
1087 | goto out_free; | ||
1088 | } | ||
1089 | |||
1083 | } | 1090 | } |
1084 | 1091 | ||
1085 | /* Prime the peer's transport structures. */ | 1092 | /* Prime the peer's transport structures. */ |
@@ -1095,11 +1102,6 @@ static int __sctp_connect(struct sock* sk, | |||
1095 | walk_size += af->sockaddr_len; | 1102 | walk_size += af->sockaddr_len; |
1096 | } | 1103 | } |
1097 | 1104 | ||
1098 | err = sctp_assoc_set_bind_addr_from_ep(asoc, GFP_KERNEL); | ||
1099 | if (err < 0) { | ||
1100 | goto out_free; | ||
1101 | } | ||
1102 | |||
1103 | /* In case the user of sctp_connectx() wants an association | 1105 | /* In case the user of sctp_connectx() wants an association |
1104 | * id back, assign one now. | 1106 | * id back, assign one now. |
1105 | */ | 1107 | */ |
@@ -1274,22 +1276,30 @@ SCTP_STATIC int sctp_setsockopt_connectx(struct sock* sk, | |||
1274 | } | 1276 | } |
1275 | 1277 | ||
1276 | /* | 1278 | /* |
1277 | * New (hopefully final) interface for the API. The option buffer is used | 1279 | * New (hopefully final) interface for the API. |
1278 | * both for the returned association id and the addresses. | 1280 | * We use the sctp_getaddrs_old structure so that use-space library |
1281 | * can avoid any unnecessary allocations. The only defferent part | ||
1282 | * is that we store the actual length of the address buffer into the | ||
1283 | * addrs_num structure member. That way we can re-use the existing | ||
1284 | * code. | ||
1279 | */ | 1285 | */ |
1280 | SCTP_STATIC int sctp_getsockopt_connectx3(struct sock* sk, int len, | 1286 | SCTP_STATIC int sctp_getsockopt_connectx3(struct sock* sk, int len, |
1281 | char __user *optval, | 1287 | char __user *optval, |
1282 | int __user *optlen) | 1288 | int __user *optlen) |
1283 | { | 1289 | { |
1290 | struct sctp_getaddrs_old param; | ||
1284 | sctp_assoc_t assoc_id = 0; | 1291 | sctp_assoc_t assoc_id = 0; |
1285 | int err = 0; | 1292 | int err = 0; |
1286 | 1293 | ||
1287 | if (len < sizeof(assoc_id)) | 1294 | if (len < sizeof(param)) |
1288 | return -EINVAL; | 1295 | return -EINVAL; |
1289 | 1296 | ||
1297 | if (copy_from_user(¶m, optval, sizeof(param))) | ||
1298 | return -EFAULT; | ||
1299 | |||
1290 | err = __sctp_setsockopt_connectx(sk, | 1300 | err = __sctp_setsockopt_connectx(sk, |
1291 | (struct sockaddr __user *)(optval + sizeof(assoc_id)), | 1301 | (struct sockaddr __user *)param.addrs, |
1292 | len - sizeof(assoc_id), &assoc_id); | 1302 | param.addr_num, &assoc_id); |
1293 | 1303 | ||
1294 | if (err == 0 || err == -EINPROGRESS) { | 1304 | if (err == 0 || err == -EINPROGRESS) { |
1295 | if (copy_to_user(optval, &assoc_id, sizeof(assoc_id))) | 1305 | if (copy_to_user(optval, &assoc_id, sizeof(assoc_id))) |
@@ -1689,6 +1699,11 @@ SCTP_STATIC int sctp_sendmsg(struct kiocb *iocb, struct sock *sk, | |||
1689 | goto out_unlock; | 1699 | goto out_unlock; |
1690 | } | 1700 | } |
1691 | asoc = new_asoc; | 1701 | asoc = new_asoc; |
1702 | err = sctp_assoc_set_bind_addr_from_ep(asoc, scope, GFP_KERNEL); | ||
1703 | if (err < 0) { | ||
1704 | err = -ENOMEM; | ||
1705 | goto out_free; | ||
1706 | } | ||
1692 | 1707 | ||
1693 | /* If the SCTP_INIT ancillary data is specified, set all | 1708 | /* If the SCTP_INIT ancillary data is specified, set all |
1694 | * the association init values accordingly. | 1709 | * the association init values accordingly. |
@@ -1718,11 +1733,6 @@ SCTP_STATIC int sctp_sendmsg(struct kiocb *iocb, struct sock *sk, | |||
1718 | err = -ENOMEM; | 1733 | err = -ENOMEM; |
1719 | goto out_free; | 1734 | goto out_free; |
1720 | } | 1735 | } |
1721 | err = sctp_assoc_set_bind_addr_from_ep(asoc, GFP_KERNEL); | ||
1722 | if (err < 0) { | ||
1723 | err = -ENOMEM; | ||
1724 | goto out_free; | ||
1725 | } | ||
1726 | } | 1736 | } |
1727 | 1737 | ||
1728 | /* ASSERT: we have a valid association at this point. */ | 1738 | /* ASSERT: we have a valid association at this point. */ |
diff --git a/net/sctp/transport.c b/net/sctp/transport.c index c256e4839316..37a1184d789f 100644 --- a/net/sctp/transport.c +++ b/net/sctp/transport.c | |||
@@ -74,7 +74,7 @@ static struct sctp_transport *sctp_transport_init(struct sctp_transport *peer, | |||
74 | * given destination transport address, set RTO to the protocol | 74 | * given destination transport address, set RTO to the protocol |
75 | * parameter 'RTO.Initial'. | 75 | * parameter 'RTO.Initial'. |
76 | */ | 76 | */ |
77 | peer->last_rto = peer->rto = msecs_to_jiffies(sctp_rto_initial); | 77 | peer->rto = msecs_to_jiffies(sctp_rto_initial); |
78 | peer->rtt = 0; | 78 | peer->rtt = 0; |
79 | peer->rttvar = 0; | 79 | peer->rttvar = 0; |
80 | peer->srtt = 0; | 80 | peer->srtt = 0; |
@@ -308,7 +308,8 @@ void sctp_transport_route(struct sctp_transport *transport, | |||
308 | /* Initialize sk->sk_rcv_saddr, if the transport is the | 308 | /* Initialize sk->sk_rcv_saddr, if the transport is the |
309 | * association's active path for getsockname(). | 309 | * association's active path for getsockname(). |
310 | */ | 310 | */ |
311 | if (asoc && (transport == asoc->peer.active_path)) | 311 | if (asoc && (!asoc->peer.primary_path || |
312 | (transport == asoc->peer.active_path))) | ||
312 | opt->pf->af->to_sk_saddr(&transport->saddr, | 313 | opt->pf->af->to_sk_saddr(&transport->saddr, |
313 | asoc->base.sk); | 314 | asoc->base.sk); |
314 | } else | 315 | } else |
@@ -385,7 +386,6 @@ void sctp_transport_update_rto(struct sctp_transport *tp, __u32 rtt) | |||
385 | tp->rto = tp->asoc->rto_max; | 386 | tp->rto = tp->asoc->rto_max; |
386 | 387 | ||
387 | tp->rtt = rtt; | 388 | tp->rtt = rtt; |
388 | tp->last_rto = tp->rto; | ||
389 | 389 | ||
390 | /* Reset rto_pending so that a new RTT measurement is started when a | 390 | /* Reset rto_pending so that a new RTT measurement is started when a |
391 | * new data chunk is sent. | 391 | * new data chunk is sent. |
@@ -601,7 +601,7 @@ void sctp_transport_reset(struct sctp_transport *t) | |||
601 | */ | 601 | */ |
602 | t->cwnd = min(4*asoc->pathmtu, max_t(__u32, 2*asoc->pathmtu, 4380)); | 602 | t->cwnd = min(4*asoc->pathmtu, max_t(__u32, 2*asoc->pathmtu, 4380)); |
603 | t->ssthresh = asoc->peer.i.a_rwnd; | 603 | t->ssthresh = asoc->peer.i.a_rwnd; |
604 | t->last_rto = t->rto = asoc->rto_initial; | 604 | t->rto = asoc->rto_initial; |
605 | t->rtt = 0; | 605 | t->rtt = 0; |
606 | t->srtt = 0; | 606 | t->srtt = 0; |
607 | t->rttvar = 0; | 607 | t->rttvar = 0; |
diff --git a/net/sunrpc/addr.c b/net/sunrpc/addr.c index 22e8fd89477f..c7450c8f0a7c 100644 --- a/net/sunrpc/addr.c +++ b/net/sunrpc/addr.c | |||
@@ -306,24 +306,25 @@ EXPORT_SYMBOL_GPL(rpc_sockaddr2uaddr); | |||
306 | * @sap: buffer into which to plant socket address | 306 | * @sap: buffer into which to plant socket address |
307 | * @salen: size of buffer | 307 | * @salen: size of buffer |
308 | * | 308 | * |
309 | * @uaddr does not have to be '\0'-terminated, but strict_strtoul() and | ||
310 | * rpc_pton() require proper string termination to be successful. | ||
311 | * | ||
309 | * Returns the size of the socket address if successful; otherwise | 312 | * Returns the size of the socket address if successful; otherwise |
310 | * zero is returned. | 313 | * zero is returned. |
311 | */ | 314 | */ |
312 | size_t rpc_uaddr2sockaddr(const char *uaddr, const size_t uaddr_len, | 315 | size_t rpc_uaddr2sockaddr(const char *uaddr, const size_t uaddr_len, |
313 | struct sockaddr *sap, const size_t salen) | 316 | struct sockaddr *sap, const size_t salen) |
314 | { | 317 | { |
315 | char *c, buf[RPCBIND_MAXUADDRLEN]; | 318 | char *c, buf[RPCBIND_MAXUADDRLEN + sizeof('\0')]; |
316 | unsigned long portlo, porthi; | 319 | unsigned long portlo, porthi; |
317 | unsigned short port; | 320 | unsigned short port; |
318 | 321 | ||
319 | if (uaddr_len > sizeof(buf)) | 322 | if (uaddr_len > RPCBIND_MAXUADDRLEN) |
320 | return 0; | 323 | return 0; |
321 | 324 | ||
322 | memcpy(buf, uaddr, uaddr_len); | 325 | memcpy(buf, uaddr, uaddr_len); |
323 | 326 | ||
324 | buf[uaddr_len] = '\n'; | 327 | buf[uaddr_len] = '\0'; |
325 | buf[uaddr_len + 1] = '\0'; | ||
326 | |||
327 | c = strrchr(buf, '.'); | 328 | c = strrchr(buf, '.'); |
328 | if (unlikely(c == NULL)) | 329 | if (unlikely(c == NULL)) |
329 | return 0; | 330 | return 0; |
@@ -332,9 +333,7 @@ size_t rpc_uaddr2sockaddr(const char *uaddr, const size_t uaddr_len, | |||
332 | if (unlikely(portlo > 255)) | 333 | if (unlikely(portlo > 255)) |
333 | return 0; | 334 | return 0; |
334 | 335 | ||
335 | c[0] = '\n'; | 336 | *c = '\0'; |
336 | c[1] = '\0'; | ||
337 | |||
338 | c = strrchr(buf, '.'); | 337 | c = strrchr(buf, '.'); |
339 | if (unlikely(c == NULL)) | 338 | if (unlikely(c == NULL)) |
340 | return 0; | 339 | return 0; |
@@ -345,8 +344,7 @@ size_t rpc_uaddr2sockaddr(const char *uaddr, const size_t uaddr_len, | |||
345 | 344 | ||
346 | port = (unsigned short)((porthi << 8) | portlo); | 345 | port = (unsigned short)((porthi << 8) | portlo); |
347 | 346 | ||
348 | c[0] = '\0'; | 347 | *c = '\0'; |
349 | |||
350 | if (rpc_pton(buf, strlen(buf), sap, salen) == 0) | 348 | if (rpc_pton(buf, strlen(buf), sap, salen) == 0) |
351 | return 0; | 349 | return 0; |
352 | 350 | ||
diff --git a/scripts/kconfig/Makefile b/scripts/kconfig/Makefile index 6d69c7ccdcc7..80599e3a7994 100644 --- a/scripts/kconfig/Makefile +++ b/scripts/kconfig/Makefile | |||
@@ -30,7 +30,7 @@ silentoldconfig: $(obj)/conf | |||
30 | $< -s $(Kconfig) | 30 | $< -s $(Kconfig) |
31 | 31 | ||
32 | localmodconfig: $(obj)/streamline_config.pl $(obj)/conf | 32 | localmodconfig: $(obj)/streamline_config.pl $(obj)/conf |
33 | $(Q)perl $< $(Kconfig) > .tmp.config | 33 | $(Q)perl $< $(srctree) $(Kconfig) > .tmp.config |
34 | $(Q)if [ -f .config ]; then \ | 34 | $(Q)if [ -f .config ]; then \ |
35 | cmp -s .tmp.config .config || \ | 35 | cmp -s .tmp.config .config || \ |
36 | (mv -f .config .config.old.1; \ | 36 | (mv -f .config .config.old.1; \ |
@@ -44,7 +44,7 @@ localmodconfig: $(obj)/streamline_config.pl $(obj)/conf | |||
44 | $(Q)rm -f .tmp.config | 44 | $(Q)rm -f .tmp.config |
45 | 45 | ||
46 | localyesconfig: $(obj)/streamline_config.pl $(obj)/conf | 46 | localyesconfig: $(obj)/streamline_config.pl $(obj)/conf |
47 | $(Q)perl $< $(Kconfig) > .tmp.config | 47 | $(Q)perl $< $(srctree) $(Kconfig) > .tmp.config |
48 | $(Q)sed -i s/=m/=y/ .tmp.config | 48 | $(Q)sed -i s/=m/=y/ .tmp.config |
49 | $(Q)if [ -f .config ]; then \ | 49 | $(Q)if [ -f .config ]; then \ |
50 | cmp -s .tmp.config .config || \ | 50 | cmp -s .tmp.config .config || \ |
diff --git a/scripts/kconfig/streamline_config.pl b/scripts/kconfig/streamline_config.pl index 95984db8e1e0..0d800820c3cd 100644 --- a/scripts/kconfig/streamline_config.pl +++ b/scripts/kconfig/streamline_config.pl | |||
@@ -43,7 +43,6 @@ | |||
43 | # make oldconfig | 43 | # make oldconfig |
44 | # | 44 | # |
45 | my $config = ".config"; | 45 | my $config = ".config"; |
46 | my $linuxpath = "."; | ||
47 | 46 | ||
48 | my $uname = `uname -r`; | 47 | my $uname = `uname -r`; |
49 | chomp $uname; | 48 | chomp $uname; |
@@ -111,7 +110,11 @@ sub find_config { | |||
111 | 110 | ||
112 | find_config; | 111 | find_config; |
113 | 112 | ||
114 | my @makefiles = `find $linuxpath -name Makefile`; | 113 | # Get the build source and top level Kconfig file (passed in) |
114 | my $ksource = $ARGV[0]; | ||
115 | my $kconfig = $ARGV[1]; | ||
116 | |||
117 | my @makefiles = `find $ksource -name Makefile`; | ||
115 | my %depends; | 118 | my %depends; |
116 | my %selects; | 119 | my %selects; |
117 | my %prompts; | 120 | my %prompts; |
@@ -119,9 +122,6 @@ my %objects; | |||
119 | my $var; | 122 | my $var; |
120 | my $cont = 0; | 123 | my $cont = 0; |
121 | 124 | ||
122 | # Get the top level Kconfig file (passed in) | ||
123 | my $kconfig = $ARGV[0]; | ||
124 | |||
125 | # prevent recursion | 125 | # prevent recursion |
126 | my %read_kconfigs; | 126 | my %read_kconfigs; |
127 | 127 | ||
@@ -132,7 +132,7 @@ sub read_kconfig { | |||
132 | my $config; | 132 | my $config; |
133 | my @kconfigs; | 133 | my @kconfigs; |
134 | 134 | ||
135 | open(KIN, $kconfig) || die "Can't open $kconfig"; | 135 | open(KIN, "$ksource/$kconfig") || die "Can't open $kconfig"; |
136 | while (<KIN>) { | 136 | while (<KIN>) { |
137 | chomp; | 137 | chomp; |
138 | 138 | ||
diff --git a/security/integrity/ima/ima_iint.c b/security/integrity/ima/ima_iint.c index b8dd693f8790..a4e2b1dac943 100644 --- a/security/integrity/ima/ima_iint.c +++ b/security/integrity/ima/ima_iint.c | |||
@@ -58,11 +58,11 @@ struct ima_iint_cache *ima_iint_insert(struct inode *inode) | |||
58 | 58 | ||
59 | if (!ima_initialized) | 59 | if (!ima_initialized) |
60 | return iint; | 60 | return iint; |
61 | iint = kmem_cache_alloc(iint_cache, GFP_KERNEL); | 61 | iint = kmem_cache_alloc(iint_cache, GFP_NOFS); |
62 | if (!iint) | 62 | if (!iint) |
63 | return iint; | 63 | return iint; |
64 | 64 | ||
65 | rc = radix_tree_preload(GFP_KERNEL); | 65 | rc = radix_tree_preload(GFP_NOFS); |
66 | if (rc < 0) | 66 | if (rc < 0) |
67 | goto out; | 67 | goto out; |
68 | 68 | ||
diff --git a/sound/arm/aaci.c b/sound/arm/aaci.c index 1f0f8213e2d5..6c160a038b23 100644 --- a/sound/arm/aaci.c +++ b/sound/arm/aaci.c | |||
@@ -504,6 +504,10 @@ static int aaci_pcm_hw_params(struct snd_pcm_substream *substream, | |||
504 | int err; | 504 | int err; |
505 | 505 | ||
506 | aaci_pcm_hw_free(substream); | 506 | aaci_pcm_hw_free(substream); |
507 | if (aacirun->pcm_open) { | ||
508 | snd_ac97_pcm_close(aacirun->pcm); | ||
509 | aacirun->pcm_open = 0; | ||
510 | } | ||
507 | 511 | ||
508 | err = devdma_hw_alloc(NULL, substream, | 512 | err = devdma_hw_alloc(NULL, substream, |
509 | params_buffer_bytes(params)); | 513 | params_buffer_bytes(params)); |
@@ -517,7 +521,7 @@ static int aaci_pcm_hw_params(struct snd_pcm_substream *substream, | |||
517 | else | 521 | else |
518 | err = snd_ac97_pcm_open(aacirun->pcm, params_rate(params), | 522 | err = snd_ac97_pcm_open(aacirun->pcm, params_rate(params), |
519 | params_channels(params), | 523 | params_channels(params), |
520 | aacirun->pcm->r[1].slots); | 524 | aacirun->pcm->r[0].slots); |
521 | 525 | ||
522 | if (err) | 526 | if (err) |
523 | goto out; | 527 | goto out; |
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 84a52efdb2d6..70583719282b 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c | |||
@@ -11462,6 +11462,7 @@ static struct snd_pci_quirk alc262_cfg_tbl[] = { | |||
11462 | SND_PCI_QUIRK(0x104d, 0x9016, "Sony VAIO", ALC262_AUTO), /* dig-only */ | 11462 | SND_PCI_QUIRK(0x104d, 0x9016, "Sony VAIO", ALC262_AUTO), /* dig-only */ |
11463 | SND_PCI_QUIRK(0x104d, 0x9025, "Sony VAIO Z21MN", ALC262_TOSHIBA_S06), | 11463 | SND_PCI_QUIRK(0x104d, 0x9025, "Sony VAIO Z21MN", ALC262_TOSHIBA_S06), |
11464 | SND_PCI_QUIRK(0x104d, 0x9035, "Sony VAIO VGN-FW170J", ALC262_AUTO), | 11464 | SND_PCI_QUIRK(0x104d, 0x9035, "Sony VAIO VGN-FW170J", ALC262_AUTO), |
11465 | SND_PCI_QUIRK(0x104d, 0x9047, "Sony VAIO Type G", ALC262_AUTO), | ||
11465 | SND_PCI_QUIRK_MASK(0x104d, 0xff00, 0x9000, "Sony VAIO", | 11466 | SND_PCI_QUIRK_MASK(0x104d, 0xff00, 0x9000, "Sony VAIO", |
11466 | ALC262_SONY_ASSAMD), | 11467 | ALC262_SONY_ASSAMD), |
11467 | SND_PCI_QUIRK(0x1179, 0x0001, "Toshiba dynabook SS RX1", | 11468 | SND_PCI_QUIRK(0x1179, 0x0001, "Toshiba dynabook SS RX1", |
diff --git a/sound/soc/codecs/tlv320aic23.c b/sound/soc/codecs/tlv320aic23.c index 0b8dcb5cd729..90a0264f7538 100644 --- a/sound/soc/codecs/tlv320aic23.c +++ b/sound/soc/codecs/tlv320aic23.c | |||
@@ -265,8 +265,8 @@ static const int bosr_usb_divisor_table[] = { | |||
265 | #define UPPER_GROUP ((1<<8) | (1<<9) | (1<<10) | (1<<11) | (1<<15)) | 265 | #define UPPER_GROUP ((1<<8) | (1<<9) | (1<<10) | (1<<11) | (1<<15)) |
266 | static const unsigned short sr_valid_mask[] = { | 266 | static const unsigned short sr_valid_mask[] = { |
267 | LOWER_GROUP|UPPER_GROUP, /* Normal, bosr - 0*/ | 267 | LOWER_GROUP|UPPER_GROUP, /* Normal, bosr - 0*/ |
268 | LOWER_GROUP|UPPER_GROUP, /* Normal, bosr - 1*/ | ||
269 | LOWER_GROUP, /* Usb, bosr - 0*/ | 268 | LOWER_GROUP, /* Usb, bosr - 0*/ |
269 | LOWER_GROUP|UPPER_GROUP, /* Normal, bosr - 1*/ | ||
270 | UPPER_GROUP, /* Usb, bosr - 1*/ | 270 | UPPER_GROUP, /* Usb, bosr - 1*/ |
271 | }; | 271 | }; |
272 | /* | 272 | /* |
@@ -625,11 +625,10 @@ static int tlv320aic23_resume(struct platform_device *pdev) | |||
625 | { | 625 | { |
626 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); | 626 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); |
627 | struct snd_soc_codec *codec = socdev->card->codec; | 627 | struct snd_soc_codec *codec = socdev->card->codec; |
628 | int i; | ||
629 | u16 reg; | 628 | u16 reg; |
630 | 629 | ||
631 | /* Sync reg_cache with the hardware */ | 630 | /* Sync reg_cache with the hardware */ |
632 | for (reg = 0; reg < ARRAY_SIZE(tlv320aic23_reg); i++) { | 631 | for (reg = 0; reg < TLV320AIC23_RESET; reg++) { |
633 | u16 val = tlv320aic23_read_reg_cache(codec, reg); | 632 | u16 val = tlv320aic23_read_reg_cache(codec, reg); |
634 | tlv320aic23_write(codec, reg, val); | 633 | tlv320aic23_write(codec, reg, val); |
635 | } | 634 | } |
diff --git a/sound/soc/omap/omap3evm.c b/sound/soc/omap/omap3evm.c index 9114c263077b..13aa380de162 100644 --- a/sound/soc/omap/omap3evm.c +++ b/sound/soc/omap/omap3evm.c | |||
@@ -144,4 +144,4 @@ module_exit(omap3evm_soc_exit); | |||
144 | 144 | ||
145 | MODULE_AUTHOR("Anuj Aggarwal <anuj.aggarwal@ti.com>"); | 145 | MODULE_AUTHOR("Anuj Aggarwal <anuj.aggarwal@ti.com>"); |
146 | MODULE_DESCRIPTION("ALSA SoC OMAP3 EVM"); | 146 | MODULE_DESCRIPTION("ALSA SoC OMAP3 EVM"); |
147 | MODULE_LICENSE("GPLv2"); | 147 | MODULE_LICENSE("GPL v2"); |
diff --git a/sound/soc/omap/omap3pandora.c b/sound/soc/omap/omap3pandora.c index ad219aaf7cb8..0cd06f5dd356 100644 --- a/sound/soc/omap/omap3pandora.c +++ b/sound/soc/omap/omap3pandora.c | |||
@@ -134,7 +134,7 @@ static int omap3pandora_hp_event(struct snd_soc_dapm_widget *w, | |||
134 | * |P| <--- TWL4030 <--------- Line In and MICs | 134 | * |P| <--- TWL4030 <--------- Line In and MICs |
135 | */ | 135 | */ |
136 | static const struct snd_soc_dapm_widget omap3pandora_out_dapm_widgets[] = { | 136 | static const struct snd_soc_dapm_widget omap3pandora_out_dapm_widgets[] = { |
137 | SND_SOC_DAPM_DAC("PCM DAC", "Playback", SND_SOC_NOPM, 0, 0), | 137 | SND_SOC_DAPM_DAC("PCM DAC", "HiFi Playback", SND_SOC_NOPM, 0, 0), |
138 | SND_SOC_DAPM_PGA_E("Headphone Amplifier", SND_SOC_NOPM, | 138 | SND_SOC_DAPM_PGA_E("Headphone Amplifier", SND_SOC_NOPM, |
139 | 0, 0, NULL, 0, omap3pandora_hp_event, | 139 | 0, 0, NULL, 0, omap3pandora_hp_event, |
140 | SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), | 140 | SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), |
@@ -181,6 +181,7 @@ static int omap3pandora_out_init(struct snd_soc_codec *codec) | |||
181 | snd_soc_dapm_nc_pin(codec, "CARKITR"); | 181 | snd_soc_dapm_nc_pin(codec, "CARKITR"); |
182 | snd_soc_dapm_nc_pin(codec, "HFL"); | 182 | snd_soc_dapm_nc_pin(codec, "HFL"); |
183 | snd_soc_dapm_nc_pin(codec, "HFR"); | 183 | snd_soc_dapm_nc_pin(codec, "HFR"); |
184 | snd_soc_dapm_nc_pin(codec, "VIBRA"); | ||
184 | 185 | ||
185 | ret = snd_soc_dapm_new_controls(codec, omap3pandora_out_dapm_widgets, | 186 | ret = snd_soc_dapm_new_controls(codec, omap3pandora_out_dapm_widgets, |
186 | ARRAY_SIZE(omap3pandora_out_dapm_widgets)); | 187 | ARRAY_SIZE(omap3pandora_out_dapm_widgets)); |
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c index d89f6dc00908..66d4c165f99b 100644 --- a/sound/soc/soc-dapm.c +++ b/sound/soc/soc-dapm.c | |||
@@ -973,9 +973,19 @@ static int dapm_power_widgets(struct snd_soc_codec *codec, int event) | |||
973 | if (!w->power_check) | 973 | if (!w->power_check) |
974 | continue; | 974 | continue; |
975 | 975 | ||
976 | power = w->power_check(w); | 976 | /* If we're suspending then pull down all the |
977 | if (power) | 977 | * power. */ |
978 | sys_power = 1; | 978 | switch (event) { |
979 | case SND_SOC_DAPM_STREAM_SUSPEND: | ||
980 | power = 0; | ||
981 | break; | ||
982 | |||
983 | default: | ||
984 | power = w->power_check(w); | ||
985 | if (power) | ||
986 | sys_power = 1; | ||
987 | break; | ||
988 | } | ||
979 | 989 | ||
980 | if (w->power == power) | 990 | if (w->power == power) |
981 | continue; | 991 | continue; |
@@ -999,8 +1009,12 @@ static int dapm_power_widgets(struct snd_soc_codec *codec, int event) | |||
999 | case SND_SOC_DAPM_STREAM_RESUME: | 1009 | case SND_SOC_DAPM_STREAM_RESUME: |
1000 | sys_power = 1; | 1010 | sys_power = 1; |
1001 | break; | 1011 | break; |
1012 | case SND_SOC_DAPM_STREAM_SUSPEND: | ||
1013 | sys_power = 0; | ||
1014 | break; | ||
1002 | case SND_SOC_DAPM_STREAM_NOP: | 1015 | case SND_SOC_DAPM_STREAM_NOP: |
1003 | sys_power = codec->bias_level != SND_SOC_BIAS_STANDBY; | 1016 | sys_power = codec->bias_level != SND_SOC_BIAS_STANDBY; |
1017 | break; | ||
1004 | default: | 1018 | default: |
1005 | break; | 1019 | break; |
1006 | } | 1020 | } |
diff --git a/sound/usb/usbmixer.c b/sound/usb/usbmixer.c index 9efcfd08d747..c998220b99c6 100644 --- a/sound/usb/usbmixer.c +++ b/sound/usb/usbmixer.c | |||
@@ -1071,6 +1071,15 @@ static int parse_audio_feature_unit(struct mixer_build *state, int unitid, unsig | |||
1071 | channels = (ftr[0] - 7) / csize - 1; | 1071 | channels = (ftr[0] - 7) / csize - 1; |
1072 | 1072 | ||
1073 | master_bits = snd_usb_combine_bytes(ftr + 6, csize); | 1073 | master_bits = snd_usb_combine_bytes(ftr + 6, csize); |
1074 | /* master configuration quirks */ | ||
1075 | switch (state->chip->usb_id) { | ||
1076 | case USB_ID(0x08bb, 0x2702): | ||
1077 | snd_printk(KERN_INFO | ||
1078 | "usbmixer: master volume quirk for PCM2702 chip\n"); | ||
1079 | /* disable non-functional volume control */ | ||
1080 | master_bits &= ~(1 << (USB_FEATURE_VOLUME - 1)); | ||
1081 | break; | ||
1082 | } | ||
1074 | if (channels > 0) | 1083 | if (channels > 0) |
1075 | first_ch_bits = snd_usb_combine_bytes(ftr + 6 + csize, csize); | 1084 | first_ch_bits = snd_usb_combine_bytes(ftr + 6 + csize, csize); |
1076 | else | 1085 | else |